Retry an avatar video request without paying twice
A timed-out avatar video submit can be retried safely with the same Idempotency-Key. What Sume returns, what causes a 409, and how to build the key.
If your request to POST /v1/avatar-1.0/talking-video times out, retry the exact same request with the exact same Idempotency-Key; Sume returns the original job instead of creating and billing a second one. Do not generate a new key for a retry, and do not reuse a key for a different script. A reused key with a different operation or payload is rejected as 409 idempotency_conflict.
The reason this matters for video is cost and time. An avatar render is billed per second, from $0.184 on standard to $0.55 on max, and it runs for longer than the 30 seconds a submit call may wait. A client that gives up and resubmits is the usual way to pay twice.
What each situation should do
The rules come from Sume's generation admission and jobs docs.
| What happened | Do this | Not this |
|---|---|---|
| Your HTTP client timed out after submit | Resubmit with the same key, or poll the status_url if you stored it | Submit with a fresh key |
sync wait ended with sync.timed_out | Poll status_url; the job exists | Treat it as a failure and resubmit |
429 queue_full | Wait for jobs to finish, then retry with the same key | Hammer the endpoint in a loop |
503 provider_capacity_exceeded | Retry later with the same key unless the error says otherwise | Change the payload to dodge it |
409 idempotency_conflict | Use a new key for the new operation | Overwrite the old key with a different script |
Building a good key
A key should name the intent, not the attempt. Include the business object and the content version, for example order-8841-intro-v3. When the script changes, the version changes, and so does the key. When only the network failed, nothing changes.
Store the key in your own database before you send the request. After a crash you can retry with the same value without guessing.
KEY="onboarding-step2-v1"
for attempt in 1 2 3; do
curl -sS --max-time 20 -X POST https://api.sume.com/v1/avatar-1.0/talking-video \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $KEY" \
-d '{"avatar_handle":"studio_presenter","script":"Open Settings, then choose Team.","mode":"async"}' \
&& break
sleep $((attempt * 5))
doneAfter the job exists
- Keep
status_url,result_url,events_urlandcancel_urlfrom the first response. - Poll with backoff until
terminalis true, or use a signed webhook and keep polling as the backup. - Cancel with
POST /v1/jobs/{id}/cancelif the script was wrong; cancelling an already canceled job returns the same canceled job. - Failed jobs and failed queue admission release or refund their reserved usage.
Limits
An idempotency key protects the submit call. It does not stop you from sending two different scripts that you both meant to send, and it does not make a render cheaper. If you fan out many videos, also watch generation_limits on the response and stop adding work when queue capacity is low.
Sources
Related posts
More in Developers
- Ruby Net::HTTP: submit and poll a Sume job with one key
A Ruby recipe using only Net::HTTP: submit a Sume image job with an Idempotency-Key, set open and read timeouts, poll status_url, and return the artifact URLs.
- Feed scraped product copy to a Format run: input, not instruction
Putting a supplier's text into a Format's instruction lets it steer the run. Sume's input field is treated as data, with a 64-key and 2 MiB limit.
- script_run budgets: call, paid-call and timeout limits on MCP
script_run caps a Sume MCP program by timeout (5-55 s), max_calls and max_paid_calls, and stops with a named error code. Defaults, ceilings and what to do next.
- Seedance 2.5 first frame plus references in one request: 400
On Sume's Video Router, image_url plus reference_*_urls returns 400 for seedance-2.5. Pick image-to-video or reference-to-video; /v1/videos lets frames win.
Written by Sume