Speaker diarization
Diarization labels each word and utterance with an integer speaker id in the same response you already get for transcription. One API call, no separate diarization vendor, no reconciliation of two timelines.
Available on Pulse in both batch (POST /waves/v1/stt/) and streaming (WSS /waves/v1/stt/live).
Language-agnostic: works across every language Pulse supports.
Enable
Add diarize=true. Pair with word_timestamps=true if you want per-word speaker labels (per-utterance labels come regardless).
Batch (Pre-Recorded)
Streaming (Real-Time WebSocket)
Response shape
The response carries two arrays that both gain speaker labels when diarize=true:
words[]. Per-word entries. Present whenword_timestamps=true(batch) or on final events (streaming). Each entry gainsspeaker(integer) andspeaker_confidence(0.0 to 1.0) when diarization is on.utterances[]. Sentence-level entries. Present by default on batch, and on streaming withsentence_timestamps=true. Each entry gainsspeaker(integer) when diarization is on.
Speaker labels are integers, zero-indexed (0, 1, 2, …) on both batch and streaming. Labels are stable within a single response or session, not across separate requests. Speaker 0 in one call is not necessarily the same physical speaker as speaker 0 in the next.
Batch response
Streaming response
Streaming emits transcription events. Only events with is_final: true carry the words[] array; interim (partial) events send a running transcript string only.
Practical consequences of the interim/final split:
- Do not render speaker attribution off interim events. They are transcript-string only. Speaker labels are correct only from
is_final: trueevents. - If you are driving live captions and want a running speaker chip on-screen, hold the current speaker from the last
is_finalevent and update on the next one.
Response fields
Every other field on words (word, start, end, confidence) is present regardless of diarize. Same for utterances (text, start, end).
Gotchas
- Pulse Pro does not diarize.
POST /waves/v1/stt/?model=pulse-pro&diarize=truereturns a transcript-only response with nospeakerfields onwords[]and noutterances[]. Route diarization traffic to?model=pulse. - Interim events on streaming carry no speaker. Only finals do. See the note above.
- Labels are not identity.
speaker: 0in call A andspeaker: 0in call B are unrelated. If you need to persist “this is Alice” across calls, do the mapping yourself (voice-print embedding, dashboard tagging, etc). word_timestamps=trueis required for per-word speakers on batch. Without it,words[]is empty and onlyutterances[]carries speaker labels.

