Text to speech API: generate speech in an avatar's voice
Sume's text to speech API, POST /v1/tts-1.0/generate, speaks up to 20,000 characters in a ready avatar's voice, with word timestamps and sentence audio slices.

To convert text to speech with the Sume API, send POST /v1/tts-1.0/generate with a transcript of up to 20,000 characters and a voice: the avatar_id or avatar_handle of an avatar whose voice is ready, or a voice.id. TTS 1.0 runs as a job and returns the audio as a Sume-hosted file, with optional word timestamps and per-sentence clips.
Details come from the TTS request schemas in the Sume API reference, the OpenAPI document behind the API reference docs, read on 2026-09-26. The price is read from the code behind API pricing. For a finished talking video from a script, use the talking avatar video API instead.
How do I choose the voice?
The discoverable voice is an avatar's. GET /v1/avatar-1.0/avatars lists your avatars, and each summary carries voice.status: processing, ready, or failed (voice is null for an avatar with no voice). Pass a ready avatar's avatar_id or avatar_handle at the top level of the body, not inside voice, and Sume resolves that avatar's voice at submit time. How to create a reusable AI avatar covers making one.
If you already hold a Sume voice id, send it as voice.id: a voice UUID or a Voices library id (voi_ plus 32 hex characters). Any other shape fails with 400 and invalid_voice_id before a job is queued or credits are reserved. If you send an avatar and voice.id together, they must match, or the request fails with 400.
What does a text to speech request look like?
This request speaks one line in a ready avatar's voice as a 44,100 Hz pcm_s16le wav, with word timings and one audio slice per sentence:
curl -X POST https://api.sume.com/v1/tts-1.0/generate \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: tts-welcome-001" \
-d '{
"transcript": "Welcome back. Today we test the new travel mug.",
"avatar_handle": "product_host",
"language": "en",
"output_format": { "container": "wav", "encoding": "pcm_s16le", "sample_rate": 44100 },
"timestamps": { "words": true },
"segmentation": { "mode": "sentence" }
}'Which fields shape the audio?
transcript plus one voice selector is the minimum. Everything else is optional.
| Field | What it takes |
|---|---|
transcript | 1–20,000 characters. Spaces and punctuation count toward usage. |
language | A BCP-47 / ISO-639 code such as ko, ja, or en. |
output_format.container | mp3 (default), wav, or raw. |
output_format.sample_rate | 8000, 16000, 22050, 24000, 44100 (default), or 48000 Hz. |
output_format.bit_rate | For mp3: 32000, 64000, 96000, 128000 (default), or 192000. Required for mp3 when you override the defaults. |
output_format.encoding | For wav or raw: pcm_f32le, pcm_s16le, pcm_mulaw, or pcm_alaw. |
generation_config | volume 0.5–2.0, speed 0.6–1.5, and an optional emotion guide. |
pronunciation_dict_id | An optional pronunciation dictionary id. |
mode | async (default), sync, subscribe, or webhook. |
How do I get word timestamps and per-sentence audio?
Two options turn one synthesis into timed pieces you can caption or cut. A sentence clip on the Sume media host is also the typical audio_url for lip sync on a still image.
timestamps: { "words": true }addswords[]to the completed job result: monotonic word timings with start and end in seconds.segmentation: { "mode": "sentence" }requirestimestamps.words: trueand returns gaplesssegments[], each ending exactly where the next begins.sentenceis the only mode in v1.boundary_lead_ms(0–500, default 70) places the cut that many milliseconds after a sentence's last word; the next segment absorbs the pause.- With
emit_audio(defaulttrue) and awavorrawcontainer, each segment carries a sample-exactaudio_url. With mp3 you get the timings without per-segment audio.
When should I use the TTS Router instead?
TTS 1.0 has no engine picker, and a model or model_id in its body is rejected with 400. To choose the engine, call POST /v1/tts-router/generate with a required model: sonic-3.6, sonic-3.5, sonic-3, sonic-latest, sonic-preview. Voice selection, transcript rules, and billing match TTS 1.0. job.model echoes the id you sent, and an unknown id fails with 400 model_not_found.
GET /v1/tts-router/models lists those ids with each model's capabilities (text_to_speech, max_characters), pricing, and constraints. The sonic-preview entry's constraints mark it as the provider's beta channel, whose output and availability can change without notice. GET /v1/tts-router/models/{model_id} returns one model, or 404 for an id it does not know.
What are the limits, and what does it cost?
TTS 1.0 costs $0.0475 per 1,000 characters, plus a 5.5% agent fee by default, and the TTS Router bills the same way. Usage is priced per transcript character, spaces and punctuation included, so a full 20,000-character transcript comes to $0.95 before the fee.
- Synthesized audio longer than 1,200 seconds fails with
tts_duration_exceeded, and no credits are captured. - Set
languagefor every non-English transcript. Omitted, it defaults to English, with Korean or Japanese inferred from a Hangul- or kana-only transcript as a fallback. - The route is non-streaming.
syncandsubscribeblock for at most 30 seconds, and/resultreturns409 job_not_completeduntilresult_readyis true. - The top-level
speedenum (slow,normal,fast) is deprecated; usegeneration_config.speed.
Sources
Related posts
Written by Sume