Sume TTS voice.id 400: why 'alloy' fails and a UUID works
Sume TTS voice.id must be a UUID or a voi_ library id, not a voice name. Names borrowed from other vendors return a 400 before any work starts.

Sume TTS accepts voice.id only as a UUID in 8-4-4-4-12 hex form or a Voices library id that is voi_ followed by 32 hex characters. A name such as alloy or ko-KR-SunHiNeural is rejected with a 400 before the job is queued. Copy the id from the voice catalog, Assets, or send an avatar handle and let Sume resolve the voice.
What gets accepted
The shape check exists because callers, including agents, were filling voice.id with names from other ecosystems or dropping a character from a real UUID. Those used to be admitted and then failed deep in the pipeline with an opaque error. Now the request fails fast with a message that says what to send instead. The check is shape only; whether the UUID exists is still answered later.
| Value | Accepted? |
|---|---|
| 123e4567-e89b-12d3-a456-426614174000 (UUID shape) | Shape ok |
| voi_ plus 32 hex characters | Shape ok |
| alloy | 400 invalid voice id |
| ko-KR-SunHiNeural | 400 invalid voice id |
| UUID missing one character | 400 invalid voice id |
Three ways to pick a voice
Send voice.id with a UUID or voi_ id, send avatar_id, or send avatar_handle. You need at least one; with none the request is rejected with a missing-selector message. An avatar must have a usable TTS voice, otherwise the avatar route returns its own 400. The TTS Router uses the same voice selectors as TTS 1.0, so there is no second voice namespace.
{
"transcript": "Welcome back.",
"avatar_handle": "speaker",
"language": "en"
}Why not accept names?
A friendly name feels convenient, but names are ambiguous and vary by vendor. A UUID or library id points at exactly one voice, which is what you need if you want to recreate a voiceover next month. Store the id with the script, the language and the model, and a take can be reproduced from the record rather than from memory.
If you do not know any ids yet, audition a voice from the library first, note its id, and only then script against it.
Do this next
Fix the id, then check the voice language against your request language, or the 409 guard will be the next error you meet.
Sources
Related posts
More in Developers
- Sume TTS: webhook_url, sync wait or polling? The four modes
Sume TTS jobs take mode async, sync, subscribe or webhook. A webhook needs a public HTTPS webhook_url, and sync waits at most 30 seconds.
- Sume TypeScript SDK createImage: a retired model id fails tsc
Sume's @sume-com/sdk lists accepted image model ids as a string union, so gpt-image-1 fails to compile. Use tsc as the migration checklist.
- TypeScript types for a Sume job status: narrow on sume_status
Type the Sume job envelope as a discriminated union on sume_status, so a switch covers queued to canceled and the compiler flags a missed case. Runs on Node 22.
- Unit test a transcription retry loop with a fake 429 in Python
Test your Sume STT retry code without calling the API: inject the POST and sleep, return a 429 with retry-after, and assert the same key is sent twice.
Written by Sume