Sume 409 idempotency_conflict: same key, different body
Reusing an Idempotency-Key on a different body returns 409 on Sume. An exact retry returns the original job instead. How to build keys that behave.

Sume returns 409 idempotency_conflict when you reuse an Idempotency-Key with a different operation or payload. An exact retry with the same key returns the original job and does not create or bill a second one. Treat a key as the identity of one intended generation, not as a session token.
Where it applies
Send the header on every paid submit that a client could retry: /v1/videos, /v1/images, TTS Router and the product routes. Without it, Sume's docs say not to retry a timed-out submit, since a second request could create a second job.
A safe retry
This submit can be repeated any number of times after a timeout. The second call returns the job the first one created.
curl -X POST https://api.sume.com/v1/videos \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: promo-clip-2026-10-05-001" \
-d '{"model":"seedance-2","prompt":"A paper boat on a rain puddle"}'Why you see the 409
The usual causes are a key built from something too coarse, such as the date, and a prompt edit followed by a retry with the old key. Both reuse a key for a new intent.
- Derive the key from your own item id plus an attempt counter that only changes when the intent changes.
- Persist the key next to the job id before you send the request.
- On
409, do not retry. Change the key if the intent changed, or read the stored job if it did not.
What not to do
Do not generate a random key per HTTP attempt. That defeats the guarantee, because every retry becomes a new paid job. Generate the key once per intended generation and reuse it for all retries of that one.
Pair it with polling
Idempotency covers the submit. After it, treat the job id as your handle. If your process restarts, read status_url for the stored id instead of submitting again. A client-side timeout never cancels the job, so the original keeps running and billing until it ends.
Together the two rules give you at-most-once billing per intent: one key per intent on submit, one stored job id for everything after.
Related posts
More in Developers
- Retry a lip-sync submit after a timeout without double billing
A timed-out submit may or may not have created a job. Resend the same body with the same Idempotency-Key and Sume returns the same job, not a second charge.
- Idempotency-Key per shot: rerun one failed AI video shot in Python
One key per shot, derived from project, shot number and revision: a retry returns the same Sume job, a changed prompt gets a new key. Python key helper inside.
- Chain Ideogram 4.5 edits with webhooks: job.completed starts pass 2
Run a multi-turn Ideogram 4.5 edit chain on Sume without polling: submit with mode webhook, verify the signature, and start the next pass from job.completed.
- Ideogram 4.5 seed on Sume returns 400: how to repeat an edit
Ideogram's own API takes a seed for 4.5 edits, but Sume returns 400 unsupported_parameter for seed on every image model. Keep the output URL, not the seed.
Written by Sume