Text to speech
Generate speech from text using the OpenAI-compatible TTS endpoint at POST /api/ext/tts/generations. Put the text in input and the target voice id in voice (see “Choosing the voice”). response_format picks the encoding — mp3, wav or pcm — and stream picks the delivery: false returns one complete file, true streams the audio as it is produced. Every format works in both modes. Switch the scenario tab in “Try it” to load a matching body.
curl --request POST \
--url 'https://api.nabrah.ai/api/ext/tts/generations' \
--header 'X-API-Key: <your-api-key>' \
--header 'Content-Type: application/json' \
--data '{
"model": "nabrah_tts_v1",
"input": "Hello from Nabrah!",
"voice": "00000000-0000-4000-8000-000000000000",
"response_format": "mp3",
"stream": false,
"use_cache": true
}'// No example body for this response.All three encodings are available whether or not you stream. model is always nabrah_tts_v1.
audio/mpegCompressed audio at 192 kbps. The smallest payload and the easiest to play in a browser. This is the default when stream is false or omitted.
response_formataudio/wavUncompressed 16-bit PCM in a RIFF container, 48 kHz mono. Lossless and self-describing — the header carries the sample rate and channel count. This is the default when stream is true.
response_formataudio/L16; rate=48000; channels=1Raw signed 16-bit little-endian mono samples at 48 kHz, with no container and no header at all. Use it when you are feeding an audio pipeline that wants frames directly; you must already know the sample rate, since nothing in the payload states it.
response_formatOmit response_format and you get mp3 for a buffered request or wav for a streamed one.
stream controls when the bytes reach you, not what they contain.
The response arrives once synthesis has finished. A wav response carries correct length fields, so it can be written straight to disk. The same rules apply to POST /api/ext/tts/quick_generate.
streamresponse_formatuse_cacheBytes are forwarded as the engine produces them, so playback can start before synthesis finishes. speed is forced to 1.0 while streaming, and apply_enhancements must be none.
streamresponse_formatGenerated audio is cached for a short period. A cache hit is marked with the X-Cache: HIT response header; send use_cache: false to force a fresh generation.
Set stream: true and send a matching Accept header — audio/wav, audio/mpeg or audio/L16. Do not await the whole payload; read the response body as a stream while the connection stays open.
In a browser read them with response.body.getReader(); on a server pipe the response stream straight to a file or audio sink. The first bytes typically arrive within a few hundred milliseconds.
modelinputvoicestreamresponse_formatA streamed clip cannot know its own length up front, so the first 44 bytes are a WAV header whose two size fields are set to the conventional 0xFFFFFFFF unknown-length marker. Players read until the connection closes. If you write the stream to a file and need exact sizes, rewrite bytes 4–7 and 40–43 once you know the total, or request stream: false instead. mp3 and pcm have no such header and stream through untouched.
When the stream ends you hold the full clip; keep the accumulated bytes to offer a download. For a file with correct length fields, request the same response_format with stream: false.
WAV is not appendable to a MediaSource SourceBuffer, so browsers generally buffer the streamed chunks before playback; mp3 is the friendlier choice for progressive playback in a browser.
voice field)The voice field in the request body is a voice ID, not a name. Get a valid ID before calling this endpoint.
Call GET /api/ext/tts/voices. It returns a voices array containing the public platform voices plus your project’s cloned voices. Copy the id of the voice you want and pass it as voice here.
voiceThe chosen voice must have is_ready: true. A freshly cloned voice stays is_ready: false until its background job finishes; passing a not-ready voice will fail.
To use a custom voice, create one with POST /api/ext/tts/clone_voice, then poll GET /api/ext/tts/voices (or GET /api/ext/tts/voices/{voice_id}) until it is ready, and use the returned id here.
These are the same voice IDs used to configure an agent’s voice.
X-API-KeystringheaderrequiredYour workspace API key. Create one in the dashboard under API keys.
inputstringrequiredThe text to synthesize.
1–4096 characters after normalization. Text that normalizes to nothing is rejected with 422.
voicestring (uuid)requiredThe voice ID to speak with — an id from GET /api/ext/tts/voices.
Must belong to your project (or be a public voice) and have is_ready: true.
model"nabrah_tts_v1"The synthesis model. nabrah_tts_v1 is the only accepted value.
Defaults to nabrah_tts_v1; any other value is rejected with 422.
response_format"mp3" | "wav" | "pcm"Audio encoding. All three work with or without stream.
Defaults to mp3 when stream is false and wav when it is true. mp3 returns audio/mpeg; wav returns audio/wav (16-bit PCM in a RIFF container, 48 kHz mono); pcm returns audio/L16; rate=48000; channels=1 — raw signed 16-bit little-endian mono frames with no container.
streambooleanDeliver the audio progressively instead of as one finished file.
Defaults to false. When true, bytes are forwarded as the engine produces them, speed is forced to 1.0, apply_enhancements must be none, and a streamed wav carries an unknown-length header (both size fields set to 0xFFFFFFFF).
use_cachebooleanReuse a recently generated clip for the same text, voice and format.
Defaults to true. A cache hit is marked with the X-Cache: HIT response header; set to false to force a fresh generation.
apply_enhancements"none" | "simple" | "ultra"Post-processing enhancement level.
Defaults to none. Must be none when stream is true, otherwise the request is rejected with 422. Accepted for compatibility on buffered requests but not currently applied to the generated audio.
speednumberPlayback speed multiplier.
Accepted between 0.01 and 4.0 and forced to 1.0 while streaming. Not currently applied to the generated audio.
expressivenessnumberHow much inflection the voice uses.
Accepted between 0.1 and 1.0. Not currently applied to the generated audio.
speech_smoothnessnumberBlend duration between synthesized segments.
Accepted between 0.1 and 1.0. Not currently applied to the generated audio.
remove_silencebooleanTrim long pauses from the start and end of the clip.
Defaults to false. Not currently applied to the generated audio.
One finished MP3. This is what you get when stream and response_format are both omitted.
{
"model": "nabrah_tts_v1",
"input": "Hello from Nabrah!",
"voice": "00000000-0000-4000-8000-000000000000",
"response_format": "mp3",
"stream": false,
"use_cache": true
}Successful Response
Validation Error
application/json