Sume video sync submit: timed_out and capacity_exhausted flags
A sync submit returns 2xx with a job id even when the wait runs out. What the sync object says and what to do next.

A sync submit on a Sume generation endpoint blocks for at most 30 seconds and returns the same job envelope either way. When the wait ends before the job does, the response is still 2xx, still carries the job id, and carries a sync object. sync.timed_out is true when the wait returned before a terminal state. sync.capacity_exhausted is true when Sume skipped the wait because the per-process waiter budget was full. Both mean the same thing for you: the job exists, paid work is in flight, and you must keep polling.
Video jobs routinely take longer than 30 seconds, so these flags are the normal case for video, not an edge case.
Reading the envelope
From the jobs page, read 2026-10-03.
| Field | Meaning | Next step |
|---|---|---|
| job id | The job exists in every mode | Store it first |
| terminal | Whether the job finished | If true, read the result |
| result_ready | Whether the result can be fetched | If true, GET result_url |
| sync.timed_out | Wait returned before a terminal state | GET status_url and keep polling |
| sync.capacity_exhausted | Wait skipped because waiter capacity was full | Same as above |
What you must do and must not do
You must continue with GET status_url, honoring next_poll_after_seconds when it is present and backing off otherwise. You must not submit a new paid job for the same intent. Retrying the submit itself is fine if you reuse the same Idempotency-Key, because the retry returns the original job instead of billing a second one.
The wait budget is a bound on the HTTP request, not on the job. wait_timeout_seconds is clamped to 0 through 30. For video, async with polling or webhook is the better default, and the docs say sync is the wrong tool for anything that can outlast 30 seconds.
subscribe is not a stream
The subscribe mode is an alias of sync. It is one bounded HTTP wait, not an event stream, and there is no SSE or WebSocket transport on the Developer API. For progress, submit async and read GET /v1/jobs/{id}/events, a pull snapshot, or take a webhook. The sync object is null on async and webhook responses.
A defensive client
This client treats a timed out wait as a handoff to polling and never as a failure.
- After any submit, store the job id before reading anything else.
- If
terminalis true, read the job from the response and stop. - Otherwise poll status with backoff until
terminalis true. - Fetch the result only when
result_readyis true; otherwise/resultanswers409 job_not_completed.
Choosing a mode for video
For video, start with async and poll, or use a webhook and keep polling as a backup. Use sync only for a short job where a 30 second wait is acceptable and you can handle the timeout flags. The jobs page lays out four modes in a table: async returns 202 with polling URLs, sync and subscribe wait, and webhook stores a callback.
Sending callback_url without a mode selects webhook delivery, so the intent is clear from the request. In every mode, the job id is in the first response.
Limits
The docs do not give the per-process waiter budget, so you cannot predict capacity_exhausted. Write your client so that every response may carry either flag.
Sources
Related posts
More in Developers
- Sume webhooks plus a sweeper: recover jobs whose callback never came
Webhook delivery can fail after 10 attempts while the Sume job still finishes. Run a sweeper that polls jobs stuck non-terminal in your own table.
- SvelteKit +server.js endpoint to verify a Sume webhook signature
A SvelteKit +server.js POST handler gets a Fetch Request, so request.text() gives the raw body Sume signs. Verify the HMAC, then handle job.completed.
- Swap the TTS engine, keep the voice: Sonic 3.5 to 3.6 on Sume
Cartesia treats the TTS model and the voice as separate things. On Sume the model id and voice id are separate fields, so you can A/B 3.5 and 3.6 on one voice.
- Swift 6.4 CryptoKit: verify a Sume webhook signature
Verify x-sume-webhook-signature in Swift with CryptoKit HMAC<SHA256>: timestamp window, comma-separated entries, constant-time compare, empty secret refused.
Written by Sume