Generate speech

Send text, receive audio, and understand request limits and usage.
View as Markdown

POST https://api.narilabs.com/v1/audio/speech converts complete text into speech. Set stream: true for progressive audio delivery, or omit it to receive the complete response.

Prepare your text

Use normal capitalization and punctuation. All-lowercase text or text without punctuation can severely degrade speech quality.

Capitalize sentence starts and proper nouns, and include commas and sentence-ending punctuation where appropriate. The server does not automatically restore capitalization or missing punctuation. This is a speech-quality guideline, not an additional input validation requirement.

RecommendedAvoid
Hello, how are you? I'm glad you're here.hello how are you i'm glad you're here

Make a request

With your API key in NARI_API_KEY, run:

$curl --fail --silent --show-error \
> https://api.narilabs.com/v1/audio/speech \
> -H "Authorization: Bearer $NARI_API_KEY" \
> -H "Content-Type: application/json" \
> --data '{
> "model": "qwen3-tts:free",
> "input": "Your order has shipped.",
> "voice": "english_female_professional",
> "language": "en",
> "response_format": "wav",
> "stream": false
> }' \
> --dump-header response-headers.txt \
> --output speech.wav
FieldHow to use it
modelRequired. Select a Standard or Fast model; append :free for Free access.
inputRequired. Send all text to synthesize in this request, with normal capitalization and punctuation.
voiceSelect a voice ID. Defaults to english_female_professional.
languageUse en, or omit it to select the voice’s language with auto.
response_formatwav (default) or raw pcm.
streamfalse (default) for a complete response; true for progressive delivery.

The API reference defines field types, validation, and all error responses.

Read the response

A successful request returns HTTP 200 with binary audio, rather than JSON or an audio URL. The example saves it to speech.wav, ready to open in an audio player.

HeaderMeaning
Content-Typeaudio/wav for WAV, or audio/pcm for raw PCM.
x-usage-input-charactersInput character count after trimming surrounding whitespace.
x-request-idRequest identifier for tracing failures and support.

Both formats contain 24 kHz, signed PCM16 little-endian, mono audio. WAV includes a container header; PCM requires you to configure the playback format. Streaming audio covers playback and progressive delivery.

Errors detected before response headers are sent return a non-2xx status with a JSON body. Check the status before treating the body as audio; Errors and troubleshooting explains error codes and how to inspect them with cURL.

Input limits

LimitValue
Text length1–2,048 Unicode code points after trimming surrounding whitespace
Complete JSON body64 KiB (65,536 bytes), including keys, values, and escaping

Whitespace-only text is rejected. Body size is checked before trimming. Text validation failures return 400; oversized bodies return 413. Split longer text into separate requests at sentence boundaries.

Usage and access

Both Free and Partner models measure TTS usage by input characters. x-usage-input-characters reports the count for this request; Usage and billing defines how characters are counted. The daily Free allowance is separate from this measurement.

Successful Partner requests debit credits. Failed and cancelled requests do not debit credits. Partner models require early access and available credits. Usage and billing explains pricing and credit handling.

Rate limits

Free speech endpoints have endpoint-specific concurrent session and daily request limits. Free tier and rate limits lists the current limits, response headers, and retry behavior for each 429 error.