Skip to main content
Generate natural speech from text with the 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 specify s1 are served by s2.1-pro. See Migrate from S1.
In the API, select with the 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:
For real-time text streaming with stream_websocket(), see Realtime Streaming.

Instant voice cloning (reference audio)

Instead of a saved reference_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.
To reuse a voice across many requests, clone it once and pass the resulting 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, default 200): 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.
If the 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.
Define a 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 $300 becomes “trescientos dólares” and decimals use a comma. Send es-MX for Mexican readings (“pesos”, “punto”). For Traditional Chinese, send zh-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 language unset.
  • normalize: false: language then only affects word timestamps.
  • Validation: values longer than 35 characters, or containing anything other than letters, digits, -, and _, are rejected with HTTP 400.
The same field is accepted by 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, and es-US.
  • With language unset, 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.