Connection
/ws/translate is the same endpoint. Authenticate the handshake as for /ws/tts: an Authorization: Bearer or X-API-Key header, or ?api_key= where headers cannot be set. In a browser, pass a short-lived wst_ ticket rather than your key (Authentication).
One translation session holds one concurrent-session slot of your account, the same pool as text-to-speech sockets.
Messages
Client to server: config
The first message, within 10 seconds of connecting:
Languages:
es, ca, gl, eu, en, fr, de, it, pt (GET /languages).
Client to server: audio
Binary frames of the speaker’s microphone: PCM16 little-endian, mono, atinput_rate, any frame size (20-100 ms is typical). Send them as you capture them, continuously; silence is fine. Phrases are cut at the speaker’s pauses.
{"type":"end"} (text) finishes the session: the phrase in progress is translated, everything queued is spoken, then the server sends {"type":"end"} and closes. Closing the socket stops everything at once.
Server to client
seq numbers phrases from 1. The speaker can keep talking while earlier phrases are still being spoken: their transcripts arrive immediately and their audio queues behind the current one. Nothing is reordered or dropped silently. If the backlog grows past 64 phrases, a phrase is dropped and an error says so.
If a phrase is already in the target language it is not translated; the words are spoken as they are.
Incremental mode (default)
While the speaker talks, the server re-transcribes the growing phrase about every 500 ms. Words that two consecutive transcripts agree on (less the last two, which are the least reliable) are committed and translated as a clause, cut at punctuation or after about six words, as a sentence in progress so the translation continues naturally. Audio already sent is never retracted or repeated: committed words are final. When the speaker pauses, the whole phrase is transcribed once more and only the words after the committed ones are translated. Expect the first translated audio to start before the speaker has finished the sentence. The cost is that a clause is translated before the rest of the sentence is known, so word order and nuance can be a little less polished than withincremental: false. At most one extra recognition request per session is in flight at a time, and none are made for the part of a phrase beyond 12 s of speech (the final transcription covers it).
Latency frames
Fields are
null when not measured (no audio). The values above only show the shape.
One production test (2026-10-27) measured the first translated audio about 2.7 s after the speaker starts, and the median about 0.25 s after a sentence ends. That is one test, not a guarantee: read the latency frames of your own sessions.
Errors
Two refusals come before the WebSocket opens, as plain HTTP responses on the handshake:
Concurrency and capacity
Your sessions count against your account’s concurrent-session limit, the same pool as text-to-speech sockets (auth.rate_limited past it).
Separately, the number of translation sessions in flight is capped across all customers, because each session asks the shared recognition service for about 1.5 requests per second of speech and a few sessions would slow every voice agent. When the cap is reached, new connections get the 503 above until a session ends. Treat it as retryable, with a short backoff. If you need guaranteed capacity for an event, contact us in advance.
Pricing
$0.08 a minute of speech, all-in (before tax;translation_per_minute on the rate card, GET /v1/pricing), charged per second of session time from the moment the socket is accepted until it closes. The price includes recognition, the translation model and the synthesized voice: no tokens, characters or speech-to-text seconds are charged on top, and the session is not billed as a text-to-speech socket. It is debited from your prepaid wallet like the other usage lines and appears as a translation line in your usage. A session left open with nobody talking is still a session: send end or close the socket when you are done.