Text to speech for language learning: slow sentence audio

Make language-learning audio with text to speech: set the target language, slow the voice to 0.6×, and get one clip per sentence with word timings.

5 min readSume
All posts

To make language-learning audio with text to speech, synthesize each passage in the target language, slow the voice when learners need it, and cut the audio into one clip per sentence for listening drills or flashcards. With Sume's API, one POST /v1/tts-1.0/generate request covers all three: language sets the target language, generation_config.speed goes as low as 0.6, and sentence segmentation returns a WAV clip for each sentence plus word timings.

The fields come from the TTS schema in the Sume API reference, the OpenAPI document behind the API reference docs, read on 2026-09-27. Behavior described as current is read from Sume's code, and the price from the code behind API pricing.

How do I set the target language?

Send language as a BCP-47 / ISO-639 code, such as ko, ja, or en, with every non-English passage. Omitted, it defaults to English at the provider; Sume infers only Korean or Japanese on its own, from a Hangul- or kana-only transcript. In the current code, a voice whose primary language on record differs from the request stops the submit with 409 tts_voice_language_mismatch until you resend with confirm_language_mismatch: true. Text to speech in Korean and Multilingual text to speech API cover these rules.

How do I slow the voice down?

Set generation_config.speed, a multiplier from 0.6 to 1.5; 0.6 is the lowest value it accepts. The older top-level speed enum (slow, normal, fast) is deprecated in favor of it. A slow version and a normal-speed version of the same passage are two requests, each billed on its own characters.

How do I get one audio clip per sentence?

Add timestamps: { "words": true } and segmentation: { "mode": "sentence" }, and pick a wav or raw container. The completed result then has one entry per sentence in segments[], each with its own sample-exact audio_url to pair with a flashcard or a drill line, plus words[] with each word's start and end in seconds.

  • Punctuate every sentence. In the current code, a sentence ends at a word ending in ., !, ?, …, 。, !, or ?, so a word list without end marks comes back as one clip.
  • The clips are gapless, so the pause before a sentence belongs to that sentence's clip. Each cut falls 70 ms after a sentence's last word by default (boundary_lead_ms, 0–500).
  • With mp3 you get the timings but no per-sentence files.
  • Text to speech with highlighted words shows how to highlight each word from words[] as it plays, and Text to speech API lists every segmentation field.
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: lesson-12-slow" \
  -d '{
    "transcript": "역이 어디에 있어요? 두 블록만 가면 돼요.",
    "voice": { "id": "voi_0123456789abcdef0123456789abcdef" },
    "language": "ko",
    "generation_config": { "speed": 0.7 },
    "output_format": { "container": "wav", "encoding": "pcm_s16le", "sample_rate": 44100 },
    "timestamps": { "words": true },
    "segmentation": { "mode": "sentence" }
  }'

What are the limits, and what does it cost?

Text to speech is billed per transcript character at $0.0475 per 1,000 characters, spaces and punctuation included, plus a 5.5% agent fee by default. The request is a job, not a stream: poll it, or pass a webhook_url.

From the TTS request schema in the Sume API reference, read 2026-09-27.
SettingRule
transcript1–20,000 characters per request
languageOne BCP-47 / ISO-639 code per request
generation_config.speed0.6–1.5
segmentation.modesentence only; needs timestamps.words: true
segmentation.boundary_lead_ms0–500, default 70
Per-sentence audio_urlwav or raw container only
Audio lengthOver 1,200 seconds fails with tts_duration_exceeded; no credits are captured

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume