The synthesis layer for voice agents.
1 socket
per live call, an utterance per turn
The same unlimited-stream platform that narrates audiobooks also drives conversational voice. We sell the synthesis layer, the mouth, not the whole stack, on one flat stream.
The session, end to end
Your orchestrator holds one WebSocket per live call and sends an utterance per turn; binary PCM streams back with timing metadata on completion. Barge-in is not a feature flag, it is the shape of the protocol.
listing 01
wss://tts.gandr.ai/ws, one call, one socket
const call = new WebSocket("wss://tts.gandr.ai/ws")
// an utterance per turn, once the socket is open
call.onopen = () => call.send(JSON.stringify({
text: "I can move that appointment for you.",
lang: "en", voice_id: "front-desk",
output_sample_rate: 24000
}))
call.onmessage = (ev) =>
typeof ev.data === "string"
? endTurn(JSON.parse(ev.data)) // {"ttfa_ms":…,"audio_ms":…}
: jitter.write(ev.data) // binary PCM frames
// caller barged in: stop mid-word, answer the interruption
function bargeIn(answer) {
stopPlayback()
call.send(JSON.stringify({ text: answer, lang: "en" }))
}
What the layer owes you
- First audio byte in 146 ms over the open internet, 116 ms p50 first audio, server side warm.
- A voice per caller or campaign, cloned from ten seconds, in 23 languages.
- Failure that respects the call: past capacity the API refuses fast with a retryable busy signal, and automatic failover covers your primary vendor’s bad night.
Why streams fit agents
Agent fleets scale by simultaneous conversations, not by monthly characters, so the price is per stream: one conversation at a time, everything said on it unmetered, $150 a month annual. Bursts spill to burst streams at $10 a stream-day instead of failing.
Notes
How does barge-in work on the socket?
Stop your playback the moment your VAD fires, then send the next utterance on the same open socket, the previous synthesis is abandoned mid-word. The interrupted characters cost nothing because nothing is metered.
Does one socket handle a whole call?
Yes, one socket per live call, any number of turns, each turn one utterance up and a PCM stream back with its own ttfa_ms receipt. Setup is paid once per call, not once per turn.
A key, one stream, your own script, nothing on it counted while you build.
Get a key, run your own script