Avatar 409 idempotency_conflict: reuse a key only for exact retries

Sume returns 409 idempotency_conflict when a key is reused with a different payload. When to keep a key, when to mint a new one, and how to name batch keys.

5 min readSume
All posts

409 idempotency_conflict means you sent an Idempotency-Key that Sume already saw on a different operation or payload. Reuse a key only for an exact retry; if you changed the script, avatar handle or quality, mint a new key.

The rule is in the admission table on Generation admission, read 2026-10-02: 409, idempotency_conflict, "Reuse keys only for exact retries."

What does a key protect against?

The key makes a paid submit safe to retry. If your worker times out, you can send the same request with the same key and get the original job back instead of a second charge. The docs ask for a key on every paid submit that may be retried and warn against resubmitting just because a local worker timed out.

The flip side is the conflict: a key identifies one intent. The same key with a different body is, to Sume, a mistake that could have bought something you did not mean to buy, so it refuses.

Exact retry or new request?

Decide by asking whether the paid result you want is the same one. The table lists common avatar cases.

Same key or new key (read 2026-10-02)
SituationKey
Network error before any responseSame key, same body
Sync wait timed out, job id knownNo resubmit: poll the job id
429 queue_full or 503 provider_capacity_exceededSame key, same body, after capacity opens
Script, handle or quality editedNew key
Next avatar in a batchNew key per item

How should I name keys in a batch?

Make the key a function of the item, not of the time of day. The docs' own example is avatar-batch-001-item-001: batch number plus item number. A retry of item 7 then recomputes the same string, and item 8 gets its own, so a crashed worker can restart the loop without double-billing or conflicting.

curl -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: avatar-batch-001-item-007" \
  -d '{"avatar_handle":"sume_clawra","script":"Meet the new spring set.","mode":"async"}'

If you later fix the script for item 7, change the key, for example by adding a revision suffix, and keep the old job's id so you can stop it if it is still queued.

What about previews?

The preview flow is separate. After a preview, generate-video on the preview id may override quality only; script, video_inputs, avatar_handle, scene and aspect_ratio need a new preview, and a new preview is a new operation that needs its own key.

If a retry yields 409 and you are sure the body is identical, check for differences you did not intend, such as a timestamp or a random id inside the script text, since any change in payload counts.

What does a good retry wrapper do?

Put the key on the item, store it before you send, and look it up on retry. A wrapper that generates a random key inside the retry loop defeats the protection, since every attempt looks like a new purchase; a wrapper that stores the key with the payload makes the second attempt an exact retry by construction.

Handle the other statuses in the same table at the same place. 400 invalid_request means fix the request before retrying. 401 means fix authentication. 402 insufficient_credits means Sume cannot reserve the estimated cost, so do not loop on it. 429 rate_limited asks you to back off using retry-after when present.

Keep a log line per submit with key, job id and status. When a 409 appears, that log shows at once which two payloads collided, which is far quicker than guessing.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume