Sume TTS source errors: which are safe to retry (status table)
Every tts_ error code in Sume's script-source API with its HTTP status, whether it charges, and whether a retry can help. A table for client error handling.

Sume's script-source API for text-to-speech returns a small, fixed set of tts_ error codes. The question for client code is simple: retry, fix the request, or re-read state first. Every code below is raised before a provider call is dispatched, so a failed request creates no job and is not billed. Branch on code, not on the message wording.
Sume bills Sume TTS at $0.0475 per 1,000 characters, rounded up to the cent per job, and only for jobs that run.
Code by code
| Code | HTTP | Retry as is? | What to do |
|---|---|---|---|
| tts_text_source_required | 400 | No | Send exactly one of transcript or transcript_source; source needs a thread. |
| tts_text_source_conflict | 400 | No | Remove one of the two inputs, or fix a malformed transcript_source. |
| tts_source_edit_unchanged | 400 | No | The replacement text equals the current words; skip the edit. |
| tts_source_edit_interactive_only | 400 | No | Speech edits require an interactive thread. |
| tts_source_not_found | 404 | No | Re-read the manifest; check thread, revision, sentence and job ids. |
| tts_source_revision_mismatch | 409 | After re-reading | Fetch the current revision, reapply your change, resubmit with the new id. |
| tts_sentence_selection_invalid | 422 | No | Make the selection contiguous, complete and in order; list each job once. |
| tts_source_too_large | 422 | No | Split the selection so each job resolves to 20,000 characters or fewer. |
| tts_source_integrity_mismatch | 422 | No | Regenerate the job from the current revision or pass explicit sentence_ids. |
| tts_source_store_unavailable | 503 | Yes, with backoff | Durable source storage is unavailable; retry the same request later. |
Idempotency
Generate calls take an idempotency-key header. Keep the same key when you retry the same request after a 503, so one logical line becomes one job. Change the key when you change the request, since the key names the request, not the attempt.
A small handler
Only the 503 is retried blindly. The 409 triggers a re-read.
RETRY_BLIND = {"tts_source_store_unavailable"}
REREAD = {"tts_source_revision_mismatch"}
def action(status, code):
if code in RETRY_BLIND or status == 503:
return "retry-with-backoff"
if code in REREAD:
return "reread-manifest"
return "fix-request"
print(action(409, "tts_source_revision_mismatch"))
print(action(503, "tts_source_store_unavailable"))
print(action(422, "tts_source_too_large"))Sources
Related posts
More in Developers
- Word timestamps to video frame numbers at 29.97 fps in Python
Sume STT words[] carry start and end in seconds. Convert them to frame indexes with exact 30000/1001 math so cuts do not drift on long timelines.
- Zed context_servers for the hosted Sume server: no header means OAuth
Add the hosted Sume server to Zed's settings.json context_servers with a url. With no Authorization header Zed runs the MCP OAuth flow, so start with mcp:read.
- Which MCP server lets Claude Code or Cursor generate video and images?
MCP servers that let Claude Code and Cursor make video and images: Sume, fal, Replicate, Runway, Higgsfield. Endpoints, sign-in, billing, setup.
- Idempotency keys for AI video APIs: retry without paying twice
An idempotency key makes a retried create return the original run or job instead of a second paid one. How Sume's Idempotency-Key works on each API.
Written by Sume