s2.1-pro, s2-pro, and deprecated s1 models, from the API directly, the Python library, or JavaScript.
Use it in the web app
No code: type, pick a voice, generate.
API reference
Every parameter for
POST /v1/tts.Cookbooks
Ready-made recipes: streaming, telephony, and more.
When to use it
Voiceovers & narration
Audiobooks, explainers, ads, and video narration.
Conversational AI
Speak an assistant’s replies. Pair with streaming for low latency.
Accessibility & IVR
Read content aloud, phone menus, notifications.
Custom voices
Speak in a cloned voice you own.
Quick start
Send text, get back audio. Choose your implementation:Use a specific voice
Pass a voice model id (reference_id). Find ids in the Voice Library or create your own via Voice Cloning.
Implementation details
Models
s2.1-pro: recommended for production, with improved quality, latency, and throughput over S2-Pro.s2.1-pro-free: the same model at $0 for testing, prototyping, development, and smaller businesses, without TTFA or DPA guarantees.drama-3: model you direct in plain language, with sounds, pauses, and paired tags for specific words. See Drama 3.s2-pro: previous-generation S2 model with multi-speaker and natural-language expression control.s1: previous generation,(parenthesis)emotion tags. S1 is deprecated and will be retired on December 31, 2026. After that date, requests that specifys1are served bys2.1-pro. See Migrate from S1.
model request header; requests without it use s2.1-pro. The Python SDK always sends a model and defaults to model="s2-pro". See Choosing a Model.
Output formats
mp3 (default), wav, pcm, opus. Set format (and optionally mp3_bitrate, sample_rate).
Speed & prosody
Adjust speech speed (0.5–2.0) and volume.Generation methods (Python)
The Python SDK exposes three ways to generate, depending on whether you have the full text upfront and how you want to consume the audio:stream_websocket(), see Realtime Streaming.
Instant voice cloning (reference audio)
Instead of a savedreference_id, pass raw audio plus its transcript to clone a voice on the fly, with no training step. Best with a clean 10–30s sample.
reference_id instead.
Format & bitrate
Pick a format for your delivery channel, and tune bitrate to trade size against quality:Latency & chunk length
latency trades stability for speed; chunk_length controls how much text the engine batches before it starts generating.
latency="balanced"(default): lower time-to-first-audio (~300ms). Good for interactive use.latency="normal": most stable output, at slightly higher latency.chunk_length(100–300, default200): smaller chunks start audio sooner; larger chunks are more efficient for long text.
Direct API (MessagePack)
POST /v1/tts also accepts a MessagePack body (Content-Type: application/msgpack), the path the API reference is built around. Use it to send binary reference audio in the request without base64 overhead, or when you don’t want the SDK.
model header is omitted or set to an unrecognized value, the request falls back to s2.1-pro. JSON and MessagePack accept the same fields.
Advanced generation tuning
For finer control,TTSConfig exposes the model’s sampling parameters. The defaults are well-tuned. Reach for these only when you need to dial in determinism or curb artifacts.
TTSConfig once and pass it to many convert() calls. See the full field list for every parameter and default.
Language
language is an optional BCP-47 tag for the language of your text, such as en, es-MX, zh-CN, or zh-TW. It is case-insensitive, and _ is read as -.
It is used only by text normalization (how numbers, dates, units, and symbols are spelled out before synthesis) and by word-timestamp alignment. It is not passed to the speech model and does not change the voice, accent, or audio quality. A wrong tag only changes how those tokens are spelled out.
The official SDKs don’t expose language yet, so send it in the request body:
API (curl)
- Default: omit
language, or send"auto"or an empty string, and the language is detected for each text chunk. This is the same behavior as before the field was added. - Regional conventions: Spanish without a region follows Spain conventions, so
$300becomes “trescientos dólares” and decimals use a comma. Sendes-MXfor Mexican readings (“pesos”, “punto”). For Traditional Chinese, sendzh-TW, which uses its own rules. - Tags without rules: a tag with no dedicated normalization rules skips normalization instead of failing. See Supported normalization languages.
- Mixed-language text: leave
languageunset. normalize: false:languagethen only affects word timestamps.- Validation: values longer than 35 characters, or containing anything other than letters, digits,
-, and_, are rejected with HTTP 400.
POST /v1/tts (JSON and MessagePack), the with-timestamps HTTP and SSE routes, and the WebSocket start event as request.language. On WebSocket, it applies to the whole session.
Supported normalization languages
Text normalization has dedicated rules for the languages below. Tags match case-insensitively, and_ is read as -.
Each row has its own rules, so the tag you pick changes the readings. For example, with
es or es-ES, $300 is read as “trescientos dólares” and the 0.9 in 0.9% as “cero coma nueve”. With es-MX, they are read as “trescientos pesos” and “cero punto nueve”. In the same way, zh-TW uses Traditional Chinese rules, not the Simplified Chinese ones.
- Any other tag skips normalization, with no error, and the text is still synthesized as written. Today that includes
zh-HK,yue,pt-BR,pt-PT,es-419, andes-US. - With
languageunset, the language of each chunk is auto-detected among the languages above. Chunks whose language can’t be detected are synthesized without normalization. - The list grows over time as normalization rules are added.
Going further
Stream as it generates
Lowest latency for conversational and live apps.
Emotion & expression
Direct delivery with tags and prosody.
Full API parameters
Every field, type, and default.
Python reference
tts.convert / stream / stream_websocket.
