Skip to content

capability

verified July 2026

Streaming synthesis that keeps up with a call.

A voice agent cannot wait for a file. Streaming here means the first chunk is in flight while the rest is still being synthesized — measured, on the endpoint you would ship.

01

Consume the stream

The SSE surface is one POST whose response body is the stream — no socket state, so it runs anywhere an HTTP response streams, including serverless and edge runtimes. Each data: line carries a base64 PCM chunk; the last line carries the timing receipt.

POST /v1/tts/sse — play chunks as they land
const res = await fetch("https://tts.gandr.ai/v1/tts/sse", {
  method: "POST",
  headers: { "x-api-key": "gnd_yourkey",
             "content-type": "application/json" },
  body: JSON.stringify({
    transcript: "The first chunk is already in flight.",
    voice: { mode: "clone", wav_b64: ref },
    output_format: { container: "raw",
                     encoding: "pcm_s16le",
                     sample_rate: 24000 }
  })
})

for await (const line of sseLines(res.body)) {
  if (line.done) break     // {"done": true, "ttfa_ms": 107, …}
  player.write(decode(line.data))   // raw PCM, no transcode
}

02

Two transports, one behavior

  • SSE for request-scoped streams: one HTTP response per utterance, a done flag with timing metadata at the end.
  • WebSocket for conversations: one socket per call, an utterance per turn, binary frames back — the session shape is on the voice-agent sheet.
  • Raw PCM at your telephony stack’s sample rate on either transport, so no transcode sits in the hot path.

03

The number that matters

Time to first chunk: 107 ms p50, 108 ms p95, measured server-side on the production API under call-shaped load — the published methodology reruns on request.

04

Notes — an engineer's checklist

01Which output formats can a stream carry?

Raw PCM (pcm_s16le) at the sample rate you request — 24000 in the examples — or WAV on the one-shot surface. Telephony stacks usually want raw PCM so nothing re-encodes in the hot path.

02How do I know when an utterance is finished?

The stream ends with an explicit receipt: {"done": true, "ttfa_ms": …, "audio_ms": …}. Log ttfa_ms per utterance and you have a per-call latency audit for free.

03Does streaming cost more than one-shot synthesis?

No. All three surfaces are unmetered on a line — transport choice is an engineering decision, never a billing one.

See also

Related sheets.

Your script, this API, thirty minutes — and the recording leaves with you.

Hear it on your own script