Audio job failed: read /events and /status before you retry
A failed TTS, STT or music job is terminal. Read GET /v1/jobs/{id}/events and status, fix the cause, then resubmit under a new key. A new TTS job bills again.

When a Sume TTS, STT or music job fails, it is terminal: read the status envelope and GET /v1/jobs/{id}/events for the reason, fix the input, and resubmit under a new Idempotency-Key. Resending the old key with the same body returns the same failed job, not a fresh attempt.
Failure causes and fixes
Codes below are the ones documented for audio routes; the fix column is what to change before the retry.
| Code | Route | Fix |
|---|---|---|
| tts_duration_exceeded | TTS | Split the script; audio over 1,200 s fails |
| negative_prompt_unsupported | Music | Omit negative_prompt or send an empty string |
| detach_source_has_no_audio | Audio detach | Source has no audio track; pick another file |
| idempotency_conflict (409) | Any | Same key, different body; use a new key |
Fetch the reason
The submit envelope includes events_url, status_url and result_url. Terminal state is data.terminal on the status read.
import os, requests
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
job = "job_123"
s = requests.get(f"https://api.sume.com/v1/jobs/{job}/status", headers=H).json()["data"]
print(s["terminal"], s["sume_status"])
if s["terminal"] and s["sume_status"] != "completed":
ev = requests.get(f"https://api.sume.com/v1/jobs/{job}/events", headers=H)
print(ev.json())Gotchas
GET /result returns 409 job_not_completed until a job is done, so do not treat that as a failure. Whether a failed job is billed depends on how far it got; read usage on the job and the errors-and-credits page rather than assuming either way.
Sources
Related posts
More in Developers
- Avatar video image URLs: product_image, scene photo and backgrounds
Sume avatar video takes three kinds of image URL: product_image, scene.image_url and scene-background images. All must be public HTTPS. Checks to run first.
- File-size cap and max length: the average bitrate ceiling
Divide a platform's size cap by its longest allowed video to get an average bitrate ceiling: LinkedIn about 2.2 Mbps, TikTok 6.7, Pinterest 17.8. Python check.
- Before a 20-clip MCP burst: dry_run, admission preview, max_spend_usd
A single Sume MCP create needs none of these. A 20-job burst should use dry_run or generation_admission_preview, set max_spend_usd, and wait in one jobs_wait.
- Duration dropdown from supported_durations: 27, 29 and 8 choices
Seedance 2.5 offers 27 lengths, Wan 3.0 29, Omni Flash 1.1 8. Map supported_durations to options in TypeScript, with the price of the longest option.
Written by Sume