Skip to main content
Gradium’s real-time APIs use the same WebSocket lifecycle for TTS and STT:
  1. Connect with authentication.
  2. Send a setup message.
  3. Wait for, or lazily receive, ready.
  4. Send input messages (text for TTS, audio for STT).
  5. Optionally flush buffered input.
  6. Send end_of_stream.
  7. Read output until the server sends end_of_stream or error.
The Python SDK handles the connection for you, but the lifecycle is the same if you use the wire protocol directly.

Endpoints

Authentication

Server-side clients should send the API key in the x-api-key header:
Browser clients should not expose API keys. Generate a short-lived, single-use token on your server and connect with ?token=...; see Browser WebSockets.

Setup

The first logical message for every request is setup.
TTS setup
STT setup
Shared setup fields: TTS-specific setup fields: STT-specific setup fields:

Ready

After setup, the server sends ready. You can wait for this before sending input, or start sending immediately and let the SDK capture it while receiving.
TTS ready
STT ready
Use request_id in logs and support tickets. For STT, use delay_in_frames when tuning turn-taking or forced flush behavior.

Input

TTS accepts text messages:
When streaming text from an LLM, split on whitespace or sentence boundaries. Do not split inside a word or separate punctuation into a standalone message; the server treats successive text messages as separate chunks and inserts spacing between them. STT accepts base64-encoded audio messages:
For raw PCM, use 80 ms chunks when possible:

Flush

TTS supports model-level flushing with the <flush> tag inside text:
Use this when an upstream LLM has finished a thought and you want the model to emit remaining buffered audio without waiting for more text. Avoid flushing after every token; small text fragments reduce prosody. STT supports a flush message:
The server processes outstanding audio and responds with:
Use STT flush when your application has detected a turn boundary and needs any pending transcript before passing the turn to an agent.

End

Send end_of_stream when you are done sending input for a request:
For a single-use connection, the server sends final output and closes the WebSocket. For a reusable or multiplexed connection, set close_ws_on_eos: false in setup and keep sending new setup/input groups.

Multiplexing

To run multiple logical requests over one socket:
  1. Set close_ws_on_eos: false.
  2. Attach a unique client_req_id to every message for a request.
  3. Route every response by its matching client_req_id.
See Multiplexing for full examples.

Errors

WebSocket errors are sent as JSON and then the socket closes:
Treat error as terminal for that socket. Open a new connection when retrying. Common codes: For REST and WebSocket error contracts, see Errors.

Next steps

Text-to-Speech WebSocket

Stream text in and receive audio chunks back.

Speech-to-Text WebSocket

Stream audio in and receive text, VAD, and flush events.

Multiplexing

Run several logical requests on one WebSocket.

Browser WebSockets

Use short-lived tokens without exposing API keys.