# Turns The WebSocket API provides turn-level speech-to-text. You send audio data and receive events at the start and end of each turn, along with the transcript of each turn. Use it for voice agents, where every millisecond of processing time counts: the turn end tells the agent to respond, and the turn start lets it stop talking when the user interrupts (barge-in). If you build voice agents with LiveKit, the [LiveKit integration](/integrations/livekit/) uses this endpoint for you. When in doubt, see [Choosing an Endpoint](/choosing-an-endpoint/). [Speaker diarization](/speech-to-text/features/diarization/) is not available on this endpoint. ## Turn Detection A turn opens with a `turn_start` message when speech begins. As the model grows more confident that the turn is ending, it emits `turn_end_candidate` messages carrying the transcript so far - each new candidate replaces the previous one. A `turn_end` message confirms the last candidate as the final transcript of the turn. The `eager_turn_probability` [query parameter](/api/speech-to-text/turns/#query-parameters) controls how early candidates appear; `final_turn_probability` controls when the turn end is confirmed. End-of-turn detection is not based on silence alone: the model combines acoustic cues with the semantic content of what has been said. A thinking pause mid-sentence is less likely to end a turn than a pause after a completed thought. ## Audio Format With the default `encoding=auto`, the server detects the audio format from the container headers at the start of the stream; for raw audio, set `encoding` explicitly. See [Audio Formats](/speech-to-text/features/audio-formats/) for the supported formats, streaming containers, and the reconnecting caveat. ## Language The server auto-detects the language by default; use the `language` query parameter to pin one or constrain detection to a list. See [Languages](/speech-to-text/features/languages/). To decide which language to pin on future connections, set `include_language=true` to receive the detected language on each `turn_end_candidate`. ## How It Works 1. **Connect** - Open a WebSocket connection to `wss://api.reson8.dev/v1/speech-to-text/turns` with an [authentication](/authentication/) header. 2. **Configure** - Use [query parameters](/api/speech-to-text/turns/#query-parameters) to set the audio encoding, language, phrases, and turn probability thresholds. 3. **Stream audio** - Send audio data as binary WebSocket frames. 4. **Receive turn events** - The server emits JSON text frames for turn start, candidate transcripts, and the final turn end. 5. **Optionally flush** - Send `{"type":"flush_request"}` as a JSON text frame to end the current turn immediately. 6. **Close** - Close the WebSocket connection when done. See the [API reference](/api/speech-to-text/turns/) for full details on messages, fields, and error codes. ## Sequence Diagram >Server: Create Connection (auth + query params) activate Server Client->>Server: Audio (binary) Server->>Client: Turn Start Client->>Server: Audio (binary) Server->>Client: Turn End Candidate (text) Client->>Server: Audio (binary) Server->>Client: Turn End Candidate (text) Client->>Server: Audio (binary) Server->>Client: Turn End Client->>Server: Audio (binary) Server->>Client: Turn Start Client->>Server: Close Connection deactivate Server`} /> ## Ping / Pong The server sends a WebSocket ping frame every 30 seconds to keep the connection alive. This uses the built-in WebSocket ping/pong mechanism - clients should respond with a pong for every ping received. Most WebSocket libraries and browsers handle this automatically. ## Flush a Turn Send a `flush_request` text message when the client needs to finalize the current turn without waiting for turn-end detection: ```json { "type": "flush_request" } ``` For an active turn, the server responds with a final `turn_end_candidate` and then `turn_end`. See the [API reference](/api/speech-to-text/turns/#sending-messages) for the complete message format.