Skip to main content
Detect when a speaker has finished their turn. Streaming transcription is delivered in turns. A turn is one continuous unit of speech belonging to a single speaker. Deciding when a turn has ended, called endpointing, determines how an interactive voice application feels. End turns too early and you cut speakers off mid-thought or split a complex entity like a phone number into multiple parts. End turns too late and your voice agent feels unresponsive.

How turn detection works

Universal-3.5 Pro Streaming does not endpoint on silence alone. When a speaker pauses, the model evaluates both acoustic and contextual cues, meaning how the speech sounded and what has been said so far, to judge whether the speaker is finished or just pausing mid-thought. Two silence thresholds control this behavior.
ParameterWhat it doesDefault
min_turn_silenceSilence in milliseconds before the model runs an end-of-turn check. If the turn reads as complete, the turn ends. Otherwise a partial is emitted and the turn stays open.Set by mode (min_latency: 128, balanced: 224, max_accuracy: 800)
max_turn_silenceMaximum silence in milliseconds before the turn is forced to end, regardless of content. This is the fallback for turns that never read as complete.1536
Lower values end turns faster. Higher values tolerate longer pauses without fragmenting the turn. Both parameters can be set on the connection and updated mid-stream, and their defaults come from the mode preset you select.
Speaker labels change the defaultsWhen speaker_labels is enabled, the server applies diarization-tuned defaults instead (min_turn_silence: 640, max_turn_silence: 768, continuous partials disabled) so turns break cleanly at speaker changes.

The lifecycle of a turn

Each turn produces a predictable message sequence of one SpeechStarted message, one or more partial Turn messages, and a final Turn message. Every Turn message re-transcribes the full turn audio, so each message supersedes the previous one. Always replace what you have rendered rather than appending. This also means transcripts get more accurate as the turn progresses, since each pass gives the model more audio and more context to work with. For maximum accuracy, use the final transcript marked end_of_turn: true. Use partials where responsiveness matters more than accuracy.

SpeechStarted

The server sends SpeechStarted once per turn, immediately before the turn’s first Turn message. It carries the turn’s start timestamp in milliseconds from the start of the audio stream, and the confidence of a new turn starting.
{
  "type": "SpeechStarted",
  "timestamp": 1216,
  "confidence": 0.98
}
SpeechStarted is only emitted once the model produces an actual transcript, so background noise alone does not trigger it. That makes it a reliable barge-in signal for voice agents. When it arrives, stop your agent’s TTS playback and start listening.

Partials

While the speaker talks, the session emits Turn messages with end_of_turn: false.
{
  "type": "Turn",
  "turn_order": 0,
  "end_of_turn": false,
  "turn_is_formatted": false,
  "transcript": "my number is five five five",
  "end_of_turn_confidence": 0.0
}
Partials are emitted at three points.
  • Early partials are emitted shortly after speech begins, timed by the interruption_delay parameter.
  • Pause partials are emitted when a pause triggers an end-of-turn check but the turn reads as incomplete.
  • Continuous partials are emitted roughly every 3 seconds during uninterrupted speech (continuous_partials, enabled by default), so long utterances keep updating even without pauses.
Partials are suited to live captions, barge-in handling, and speculative LLM prefetching, where you want text immediately and can tolerate it being revised.

Finals

When the turn ends, the session emits a Turn message with end_of_turn: true. The final is fully formatted, with punctuation, casing, and numbers and entities rendered in written form.
{
  "type": "Turn",
  "turn_order": 0,
  "end_of_turn": true,
  "turn_is_formatted": true,
  "transcript": "My number is 555-0134.",
  "end_of_turn_confidence": 1.0
}
The final is the most accurate transcript of the turn. Send it to your LLM, store it, and act on it whenever accuracy matters.

Tuning interruption sensitivity

SpeechStarted and early partials are what trigger interruptions in a voice agent, and two parameters control how eagerly they fire.
ParameterWhat it doesDefault
vad_thresholdConfidence between 0 and 1 required to classify an audio frame as speech.0.2
interruption_delayHow long in milliseconds after speech begins the first partial is emitted, from 0 to 1000.Set by mode (min_latency: 0, balanced: 500, max_accuracy: 500)
If quiet or distant speech is being missed, lower vad_threshold so softer audio counts as speech. If background noise or the agent’s own TTS audio is triggering false interruptions, raise vad_threshold so the session requires stronger evidence of speech, increase interruption_delay so it waits longer before emitting the first partial, or enable Voice Focus to suppress background audio before it reaches the model. Like the silence thresholds, both can be set on the connection and updated mid-stream.

Capturing entities like phone numbers

Speakers naturally pause between the groups of a phone number, credit card, or address, and each of those pauses can read as a completed thought, splitting one entity across several turns. When your application knows an entity is coming (for example, your voice agent just asked for a callback number), raise min_turn_silence mid-stream so those pauses don’t end the turn. Afterward, set your mode again to restore the preset’s defaults. Changes take effect immediately, without reconnecting.
# Before capturing the entity
websocket.send('{"type": "UpdateConfiguration", "min_turn_silence": 1000}')

# After the response, re-apply your mode to restore its defaults
websocket.send('{"type": "UpdateConfiguration", "mode": "balanced"}')
If turns are still force-ended during very long pauses, raise max_turn_silence the same way. See Updating configuration mid-stream for the full list of mid-stream parameters.

Bring your own turn detection

If you run your own VAD or turn detection model, send a ForceEndpoint message to end the current turn immediately. The server responds with the turn’s final Turn message right away, without waiting for silence.
websocket.send('{"type": "ForceEndpoint"}')

Going further