Text-to-Speech (TTS) API: send text, get a link to the synthesized speech (platform CDN direct link, mono 24kHz), optionally with a precisely aligned SRT subtitle file.
Synchronous — one request returns the result directly, no polling and no taskId. 32 curated Chinese / English voices (322 in the full catalog), adjustable rate / pitch / volume, and per-sentence prosody control; long text is auto-segmented and stitched. Three output formats: mp3 / mp3-high / webm.
Billed by synthesized audio seconds: charged synchronously, non-refundable, minimum 1 credit per call; subtitles cost nothing extra.
⚡ Synchronous call:a single request returns the result directly — no taskId, no polling
Text to synthesize (long text is auto-segmented and stitched); up to ~256KB. Mutually exclusive with segments
segments
array
Either
—
Per-sentence rate / pitch / volume — see “Per-sentence control”. Mutually exclusive with text, max 200 segments
voice
string
—
zh-CN-XiaoxiaoNeural
Voice — use a shortName from GET /v1/tts/voices; if set it must be a supported voice
format
string
—
mp3
Output format: mp3 (default) / mp3-high / webm (web playback, max 2000 chars per request) — see “Output formats”
rate
string
—
+0%
Rate: x-slow / slow / medium / fast / x-fast / default, or percentage +40% / -20%, or a multiplier like 1.0
pitch
string
—
+0Hz
Pitch: x-low ~ x-high / default, or a signed offset +2st / -5Hz / +10%, or an absolute value like 150Hz
volume
string
—
+0%
Volume: silent / x-soft / soft / medium / loud / x-loud / default, or +20% / +6dB / 0–100
subtitle
bool
—
false
Also return an SRT subtitle strictly aligned to the audio — see “Subtitles”. No extra charge
When pitch uses a semitone / hertz / percentage offset it must carry a sign: +2st is fine, 2st is rejected.
An unrecognized rate / pitch / volume returns 400 immediately with the expected shape — no synthesis is run and no credits are spent.
Output formats
format
File
Use case
mp3
24kHz 48kbps mono mp3
General purpose, smallest size; use this for long text
mp3-high
24kHz 96kbps mono mp3
Better quality, roughly 2× the size
webm
24kHz Opus (WebM)
Direct web playback; limited to 2000 characters per request
The webm length cap comes from the format itself: long text must be synthesized in several passes and stitched, but a stitched WebM only plays its first part in most players. Rather than hand you a file that contains half the text yet bills the full length, an over-long webm request returns 400 — use mp3 instead, or split the text across requests yourself.
Per-sentence control (segments)
Use segments instead of text to give each sentence its own rate / pitch / volume — e.g. a normal-paced opening, a slower and louder key sentence, then a quick wrap-up. Up to 200 segments.
Param
Type
Required
Default
Description
text
string
Required
—
Text of this segment
rate
string
—
—
Rate for this segment; inherits the top-level rate when omitted
pitch
string
—
—
Pitch for this segment; inherits the top-level pitch when omitted
volume
string
—
—
Volume for this segment; inherits the top-level volume when omitted
Fields omitted in a segment inherit the top-level value, so you only write what you want to change.
All segments share one voice (voice is top-level only). A single request cannot mix voices — use separate requests for multiple characters.
There is no pause tag between segments — the speech service cannot insert silence. Use punctuation for pauses, or split into multiple requests and stitch them yourself.
Add "subtitle": true to the request and the response gains a subtitleUrl. The timeline is exact, not recognized — it comes from the word-boundary positions the speech engine reports while synthesizing, so there are no ASR typos and nothing drifts out of sync.
No extra charge and no extra latency (the data falls out of synthesis itself).
The text matches exactly what you sent (nothing is rewritten by recognition).
Stays aligned after rate / segments changes the pace (the timeline shifts and the subtitle shifts with it).
subtitle works with all three formats (the subtitle file is independent of the audio format).
Use it for a web player’s <track kind="subtitles">, import into an editor, or pass subtitleUrl straight to the video subtitle burn-in endpoint (FFmpeg burn_subtitle).
Layout rules (fixed, not configurable yet): single line; up to ~20 Chinese characters / 40 Latin characters per line; each cue lasts 0.7–7 seconds; breaks at sentence-final punctuation and at pauses longer than 0.6 s. The file is standard SubRip, UTF-8 without BOM, LF line endings.
subtitleUrl only appears when the request set subtitle: true — it is never returned as an empty string.
In rare cases the speech service returns no word boundaries; the whole request then fails (502, nothing charged, safe to retry) rather than succeeding with audio but no subtitle.
Link to the synthesized speech (platform CDN direct link, mono 24kHz)
duration
number
Duration of synthesized audio (seconds)
cost
number
Credits consumed by this call
format
string
Actual output format
subtitleUrl
string
SRT subtitle link. Present only when the request set subtitle: true — never an empty string
Supported voices
Loading…
Voice (shortName)
Name
Gender
Locale
The voice list is loaded live from GET /v1/tts/voices (the docs page shows curated voices by default; switch to “Full catalog” for all 322 across 142 locales). voice accepts any shortName listed there.
For mixed Chinese/English text use AvaMultilingual / AndrewMultilingual — one voice reads both, no per-language switching.
In ?all=1 the voices array may occasionally be empty (the catalog is still loading right after start-up); loadedAt is then an empty string — fall back to presets rather than treating it as “no voices”.
Charged synchronously, non-refundable: charged once synthesis succeeds and a link is produced; on insufficient balance nothing is charged and no link is returned.
Subtitles are free: subtitle: true costs exactly the same as without it (the timestamps come out of synthesis itself, nothing is computed twice).
Parameter errors (400) are returned before synthesis starts and consume no credits.
Minimum 1 credit per call. Final credits settle at your user rate; a dedicated unit price takes precedence if configured.
Common Errors
Code
msg
Meaning
401
unauthorized
Missing valid credentials
400
invalid JSON
Request body is not valid JSON
400
text required
No text provided (both text and segments are empty)
400
text and segments are mutually exclusive; send one
Send only one of the two fields
400
segments contain no text
Every segment’s text is blank
400
too many segments (max 200)
More than the 200-segment limit
400
unsupported voice
Voice not in the supported list
400
unsupported format "xxx"; want one of mp3, mp3-high, webm
Malformed rate / pitch / volume — the message states the expected shape and which segment failed
400
format "webm" cannot be concatenated, so it is limited to 2000 characters …
webm text too long — see “Output formats”
400
edge tts rejected the request: …
The speech service rejected the content (should not normally happen — please report it)
413
text too long
Request body exceeds the 256KB limit
402
insufficient balance
Insufficient balance (nothing charged, no link returned)
502
tts synthesis failed
Synthesis temporarily unavailable — safe to retry (nothing charged)
500
upload failed
Result upload failed, retry (nothing charged)
Set the client read timeout to ≥ 180s: the endpoint is synchronous and normally returns in seconds, but concurrent synthesis is gated, so a request may queue before it runs at peak times. Exceeding the queue limit also returns 502 tts synthesis failed (nothing charged, safe to retry).