Synthesis comes in two modes. They share voices, credentials, and pricing, and differ in when you get audio back.
Non-streaming
Send a block of text, get the complete audio back in the response, plus its sample rate and duration in headers.
Best for prompts, notifications, IVR menus, and anything where you already have the whole text.
Streaming
Open a WebSocket and push text in as it becomes available. Audio chunks come back as they are generated, so you can start playing the first sentence before the last one exists.
Best for LLM output, live agents, and anything latency-sensitive.
Choosing between them
| Non-streaming | Streaming | |
|---|---|---|
| Endpoint | POST tts.navana.ai/tts/bytes |
wss://tts.navana.ai/v1 |
| Auth | X-API-Key header |
auth_token in the hello frame |
| Input | One block of text | Many text frames over one connection |
| Output | Complete audio buffer | Audio chunks as generated |
| Time to first audio | After the whole text is synthesized | After the first sentence |
| Billed on | Characters of input text | Characters of input text |
Both modes bill the same way. Streaming costs nothing extra. It changes when you receive audio, not what you pay for it. If latency matters, stream. Characters are counted by Unicode code point, so an Indic script is not penalised for its encoding.
The one thing to know about the output
Both modes return raw audio with no container. Not a WAV, not an MP3, just samples. Handing those bytes to an audio player will not work, because nothing in them says what sample rate they are.
Non-streaming tells you the rate in the X-Sample-Rate response header.
Streaming tells you in its ready frame. To get a playable file, prepend a
44-byte WAV header, which Python’s wave module will do for you.
Headerless output is what makes streaming work: chunks concatenate with no seams and can be fed straight into a live audio sink.
What you can build
Speak an LLM’s answer as it is generated. Stream tokens into the synthesis socket sentence by sentence and play audio while the model is still writing. That is the difference between a voice product that feels responsive and one that pauses for several seconds before every reply.
Localise a product’s voice across ten languages. The same request shape and
the same key work for all of them. Change lang, and keep voice constant if
you want the same speaker throughout.
Generate telephony prompts at the right rate. Synthesize directly at 8 kHz and skip a resampling step in your call pipeline.
Languages and voices
Ten languages, with voices that carry across all of them under a single id. See Voices and languages for the list and how to find a voice.