Docs
ChangelogالعربيةDashboard
DocumentationAPI reference
API referenceGenerate speech
  • Introduction
  • Authentication
    • GETVerify API key
  • Agents
    • POSTCreate agent
    • GETList agents
    • GETGet agent
    • PUTUpdate agent
    • DELDelete agent
    • POSTLink analysis groups to an agent
    • GETList analysis groups for an agent
  • Tools
    • POSTCreate tool
    • GETList tools
    • GETGet tool
    • PUTUpdate tool
    • DELDelete tool
    • POSTLink a tool to an agent
    • DELUnlink a tool from an agent
    • GETList tools for an agent
    • GETList agents for a tool
  • Analysis groups
    • POSTCreate analysis group
    • GETList analysis groups
    • GETGet analysis group
    • PUTUpdate analysis group
    • DELDelete analysis group
    • POSTLink an agent to an analysis group
    • POSTLink agents to an analysis group
    • GETList agents for an analysis group
    • DELUnlink an analysis group from an agent
  • Knowledge bases
    • POSTCreate knowledge base
    • GETList knowledge bases
    • GETGet knowledge base
    • PATCHUpdate knowledge base
    • DELDelete knowledge base
  • Documents
    • POSTAdd PDF document
    • POSTAdd text document
    • POSTAdd URL document
    • GETList documents
    • GETGet document
    • DELDelete document
  • Calls
    • POSTCreate outbound call
    • GETGet call
    • POSTSearch calls
    • POSTGet call analytics
    • POSTExport calls
    • GETGet recording download URL
    • POSTCreate outbound call (legacy path)
  • Web calls
    • POSTCreate web call
    • POSTCreate web call (legacy path)
  • SIP inbound
    • POSTCreate SIP inbound trunk
    • GETList SIP inbound trunks
    • GETGet SIP inbound trunk
    • DELDelete SIP inbound trunk
  • SIP outbound
    • POSTCreate SIP outbound trunk
    • GETList SIP outbound trunks
    • GETGet SIP outbound trunk
    • DELDelete SIP outbound trunk
  • Agent inbound links
    • POSTLink an agent to an inbound trunk
    • GETList agent inbound links
    • DELDelete agent inbound link
  • Text to speech
    • POSTGenerate speech
    • GETList voices
    • GETGet voice
    • POSTClone a voice
    • DELDelete cloned voice
  • Speech to text
    • POSTTranscribe an audio file
    • GETGet transcription job
    • GETList transcription jobs
    • WSStream speech to text
  • Contacts
    • POSTCreate contact
    • GETList contacts
    • GETSearch contacts
    • GETGet contact
    • PATCHUpdate contact
    • GETList conversations for a contact
  • Conversations
    • GETList conversations
    • POSTFilter conversations
    • POSTList conversations by contact
    • GETGet conversation
    • GETList conversation messages
    • POSTSend a message
    • POSTSend a message with an attachment
    • GETList conversation attachments
    • POSTAssign conversation
    • POSTChange conversation status
    • POSTChange conversation priority
    • POSTMark conversation as seen
  • Tickets
    • POSTCreate ticket
    • GETList tickets
    • POSTFilter tickets
    • POSTList tickets by contact
    • GETGet ticket
    • GETList ticket messages
    • POSTAdd a ticket message
    • POSTAdd a ticket message with attachments
    • POSTAssign ticket
    • POSTChange ticket status
    • POSTChange ticket priority
    • POSTChange ticket type
    • POSTCreate ticket inbox
    • GETList ticket inboxes
    • PATCHUpdate ticket inbox
    • DELDelete ticket inbox
  • WhatsApp
    • POSTConnect a WhatsApp number
    • GETList WhatsApp inboxes
    • GETGet WhatsApp inbox
    • PATCHUpdate WhatsApp inbox
    • DELDelete WhatsApp inbox
    • POSTCreate WhatsApp conversation
    • GETList WhatsApp conversations
    • POSTFilter WhatsApp conversations
    • POSTList WhatsApp conversations by contact
    • POSTAssign an agent to a WhatsApp number
    • GETGet the agent on a WhatsApp number
    • DELRemove the agent from a WhatsApp number
    • POSTGet WhatsApp analytics
  • Instagram
    • GETList Instagram accounts
    • GETGet Instagram account
    • DELDelete Instagram account
    • GETList Instagram conversations
    • POSTFilter Instagram conversations
    • POSTList Instagram conversations by contact
    • POSTAssign an agent to an Instagram account
    • GETGet the agent on an Instagram account
    • DELRemove the agent from an Instagram account
  • TikTok
    • GETList TikTok accounts
    • GETGet TikTok account
    • DELDelete TikTok account
    • GETList TikTok conversations
    • POSTFilter TikTok conversations
    • POSTList TikTok conversations by contact
    • POSTAssign an agent to a TikTok account
    • GETGet the agent on a TikTok account
    • DELRemove the agent from a TikTok account

Text to speech

Generate 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.

POST
https://api.nabrah.ai/api/ext/tts/generations
Generate speech
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.

Formats

All three encodings are available whether or not you stream. model is always nabrah_tts_v1.

mp3 — audio/mpeg

Compressed 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_format
wav — audio/wav

Uncompressed 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_format
pcm — audio/L16; rate=48000; channels=1

Raw 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_format

Omit response_format and you get mp3 for a buffered request or wav for a streamed one.

Delivery modes

stream controls when the bytes reach you, not what they contain.

stream false (default) — complete file

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_cache
stream true — progressive

Bytes 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_format

Generated 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.

Reading a streamed response

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.

Read chunks as they arrive

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_format
The streamed WAV header

A 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.

Completion & download

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.

Choosing the voice (the voice field)

The voice field in the request body is a voice ID, not a name. Get a valid ID before calling this endpoint.

List available voices

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.

voice
Voice must be ready

The 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.

Use your own cloned voice

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.

Authorization

X-API-Keystringheaderrequired

Your workspace API key. Create one in the dashboard under API keys.

Body

application/json
inputstringrequired

The text to synthesize.

1–4096 characters after normalization. Text that normalizes to nothing is rejected with 422.

voicestring (uuid)required

The 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.

streamboolean

Deliver 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_cacheboolean

Reuse 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.

speednumber

Playback speed multiplier.

Accepted between 0.01 and 4.0 and forced to 1.0 while streaming. Not currently applied to the generated audio.

expressivenessnumber

How much inflection the voice uses.

Accepted between 0.1 and 1.0. Not currently applied to the generated audio.

speech_smoothnessnumber

Blend duration between synthesized segments.

Accepted between 0.1 and 1.0. Not currently applied to the generated audio.

remove_silenceboolean

Trim 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.

File — MP3 (default)
{
  "model": "nabrah_tts_v1",
  "input": "Hello from Nabrah!",
  "voice": "00000000-0000-4000-8000-000000000000",
  "response_format": "mp3",
  "stream": false,
  "use_cache": true
}

Response

200

Successful Response

422

Validation Error

application/json

PreviousText to speechNextList voices
© 2026 Nabrah. All rights reserved.
ChangelogPrivacy PolicyTerms of Service