返回首页
Lanson Flow 文档库

How silence, pauses, and speech interruptions are handled in realtime transcription.

VAD and speech segmentation

Server-side VAD automatically detects speech segments. The WebSocket events pushed to your client are:

1. Speech detected → input_audio_buffer.speech_started (abbreviated as speech_started) 2. Speech continues → audio accumulated 3. Silence detected → input_audio_buffer.speech_stopped (abbreviated as speech_stopped) 4. Transcription complete → conversation.item.input_audio_transcription.completed (abbreviated as completed)

Use the full type string in your event dispatcher. See [Server Events](/docs/api-reference/server-events) for the complete payload schemas.

Clients do not need to implement VAD — just consume events.

Silence behavior

Short pauses

Normal speaking pauses (commas, sentence ends) do not trigger segment splits. VAD has a silence threshold (vadSilenceMs); only silence exceeding this duration triggers end-of-speech.

Long silence

  • Silence exceeding idle_timeout_seconds closes the connection with code 4408.
  • The actual value is returned in session.created.limits.idle_timeout_seconds; do not hard-code it.
  • To keep the connection alive, continue sending PCM16LE audio frames, even when they contain silence (all-zero samples).
  • For example, a 100 ms silent binary frame at 16 kHz mono is new Int16Array(1600).fill(0). See [Audio Input](/docs/realtime/audio-input) for frame-size guidance and [Connection Lifecycle](/docs/realtime/connection-lifecycle) for close-code details.

    Manual flush

    Send input_audio_buffer.flush (or its alias flush) to force-end the current speech segment:

    { "type": "input_audio_buffer.flush" }
    

    Use cases:

  • You know a speech segment has ended (e.g. the user released a push-to-talk button or tapped an end-of-utterance button).
  • Force the upstream to process already-sent audio instead of waiting for VAD.
  • Reduce latency by not waiting for vadSilenceMs.
  • Max speech segment duration

    vadMaxSpeechMs limits the maximum duration of a single speech segment. When exceeded:

  • The current segment is finalized: input_audio_buffer.speech_stoppedconversation.item.input_audio_transcription.completed.
  • A new segment starts immediately with input_audio_buffer.speech_started.
  • The reason field of speech_stopped explains why the segment ended (e.g. end_of_speech or max_duration). See [Server Events](/docs/api-reference/server-events) for the full list of reason values.
  • Interruption handling

    Speaker interrupted

    In live scenarios, if a speaker is interrupted:

  • Upstream detects the speech boundary.
  • Current segment: input_audio_buffer.speech_stoppedconversation.item.input_audio_transcription.completed.
  • A new segment starts with input_audio_buffer.speech_started.
  • Client strategy

    1. Each conversation.item.input_audio_transcription.completed event is independent and final. 2. No need to cancel or roll back already-displayed text. 3. New segments are ordered by utterance_index. If two segments overlap in time, use audio_duration_ms / speech_duration_ms to position them on a timeline rather than relying on arrival order.

    Recommended client handling

    ws.onmessage = (event) => {
      if (typeof event.data !== "string") return;
      const data = JSON.parse(event.data);
    

    if (data.type === "input_audio_buffer.speech_started") { showListeningIndicator(data.utterance_index); } else if (data.type === "input_audio_buffer.speech_stopped") { showProcessingIndicator(data.utterance_index); } else if (data.type === "conversation.item.input_audio_transcription.completed") { appendTranscript(data.utterance_index, data.text); hideIndicators(data.utterance_index); } };

    Related

  • [Transcript Lifecycle](/docs/realtime/transcript-lifecycle) — state transitions
  • [Session Configuration](/docs/realtime/session-configuration) — VAD parameters
  • [Connection Lifecycle](/docs/realtime/connection-lifecycle) — idle timeout and reconnect
  • [Client Messages](/docs/api-reference/client-messages) — input_audio_buffer.flush
  • [Server Events](/docs/api-reference/server-events) — event schemas and reason values