Soniox
Real-time API

Stream termination

Learn how to terminate a stream and handle finalization and errors in the Soniox Text-to-Speech WebSocket API.

Overview

A real-time stream ends with a well-defined three-step handshake: the client signals the end of input with text_end: true, the server emits a final audio chunk with audio_end: true, and then the server confirms cleanup with terminated: true. Only after terminated: true is it safe to release stream state or reuse the stream_id.

Stream termination does not close the WebSocket connection. Other streams on the same connection continue normally, and you can start new streams on the same socket.


Normal termination sequence

  1. Client sends final text chunk with text_end: true:
{
  "text": "Final chunk of text.",
  "text_end": true,
  "stream_id": "stream-001"
}
  1. Server sends the last audio chunk with audio_end: true:
{
  "audio": "<base64-audio-bytes>",
  "audio_end": true,
  "stream_id": "stream-001"
}
  1. Server sends the final stream event:
{
  "terminated": true,
  "stream_id": "stream-001"
}
  • audio_end: true indicates the audio payload sequence is complete, no more audio chunks will arrive for this stream.
  • terminated: true indicates stream lifecycle cleanup is complete on the server, it is now safe to release stream state and reuse the stream_id.

Client-initiated cancellation

If you need to stop a stream early, for example, user interruption in a voice agent or a timeout on the calling side — send a cancel message. The server finalizes the stream without sending further audio chunks.

Cancel request:

{
  "stream_id": "stream-001",
  "cancel": true
}

Finalization response:

{
  "terminated": true,
  "stream_id": "stream-001"
}

Error termination

If a stream fails, the server responds with an error message followed by terminated: true for that stream_id:

{
  "stream_id": "stream-001",
  "error_code": 400,
  "error_message": "Missing required field: model"
}
{
  "terminated": true,
  "stream_id": "stream-001"
}

The WebSocket connection stays open unless there is a connection-level failure, so other streams continue. For the full list of error codes and messages, see the WebSocket API reference.