Avatar sync wait: timed_out vs capacity_exhausted, and what to do
A sync avatar submit can return 2xx with sync.timed_out or sync.capacity_exhausted true. Both mean keep the job: poll status_url, never submit a new paid job.
If a sync avatar submit returns a 2xx with sync.timed_out or sync.capacity_exhausted set to true, the job exists and is still running. Poll status_url and do not submit a new paid job for the same intent. If you must retry the submit itself, send the same Idempotency-Key and you get the original job back.
What the two flags mean
Sume clamps wait_timeout_seconds to 0-30. That sets how long the HTTP request may block, not how long the job takes. Avatar-video jobs usually take longer than 30 seconds, so a sync submit often ends before the job does. The response is still a 2xx and still carries the job id, because the end of the wait budget is not an admission failure.
| Flag | Meaning | Your next step |
|---|---|---|
| sync.timed_out true | Wait ended before a terminal state | GET status_url, obey next_poll_after_seconds |
| sync.capacity_exhausted true | Sume skipped the wait; waiter budget of the process was full | Same: poll, do not resubmit |
| sync is null | Mode was async or webhook | Normal polling or webhook |
| Terminal result in body | Job finished within the wait | Read the result |
Handle it in code
Branch on the envelope and not on the HTTP status. A 2xx without a terminal state is not a failure and not a success; it is an in-flight job. The docs recommend async or webhook for work that can last longer than 30 seconds, and say that sync stays supported.
def next_step(envelope):
sync = envelope.get("sync") or {}
if envelope.get("terminal"):
return "fetch" if envelope.get("result_ready") else "inspect_events"
if sync.get("timed_out") or sync.get("capacity_exhausted"):
return "poll " + envelope["status_url"]
return "poll " + envelope["status_url"]
print(next_step({"terminal": False, "status_url": "/v1/jobs/x/status",
"sync": {"timed_out": True}}))Why not just raise the timeout
You cannot: the API clamps the wait at 30 seconds. A client-side timeout, which can be minutes, is the right place for a longer deadline, and the docs state that a client timeout does not cancel the job. The job keeps running and keeps billing, so store the id and read it again later, or cancel it explicitly if you no longer need it.
A worked timeline
Suppose you submit a 40-second avatar script in sync mode with a 30-second wait. At second 30 the request returns a 2xx with sync.timed_out: true, a status_url, and often a next_poll_after_seconds. Your code stores the id, sleeps for the suggested interval, and reads the status. It sees processing, sleeps again, and eventually sees completed with next_action: fetch_result. At no point did you pay for a second job, and at no point did you need to guess.
The same timeline holds when the waiter budget is full: the call returns at once with capacity_exhausted: true and no wait at all. If your code treats an immediate return as a failure and retries in a loop, you will hammer the API for no gain, so handle both flags the same way.
Checklist
- Always store
avatar_video_idandstatus_urlbefore you wait. - Use async plus polling for avatar renders, or a webhook for terminal events.
- Reuse the same
Idempotency-Keyfor an exact retry of the submit. - Do not treat
capacity_exhaustedasqueue_full; they are different conditions, and onlyqueue_fullis a rejection.
Sources
Related posts
More in Developers
- Avatar script too long? The 4 to 60 second window and how to split it
Sume accepts an avatar talking video only when the script estimates 4 to 60 seconds. Split longer scripts into scenes or jobs; costs from $0.74 to $33.
- Avatar video 400: script must include at least one word
A Sume talking-video request with an empty or whitespace-only script returns 400 invalid_request, with no job or ledger entry. Guard blank template fields.
- Avatar video 404 "Avatar was not found": handle from another workspace
A talking-video request with an unknown handle, or one from another workspace, returns 404 not_found and no job. Check the handle and the key's workspace.
- Preview regenerate too early: 409 avatar_video_preview_busy, no charge
Calling regenerate on an avatar video preview that is still queued or processing returns 409 avatar_video_preview_busy and refunds the reservation. What to do.
Written by Sume