Same idempotency key, new body: Sume Format run 409 vs 200 replay
Same Idempotency-Key and body on a Sume Format run gives 200 with idempotency_hit true. A changed body or attachments gives 409. Bulk replays stay 202.

Send the same Idempotency-Key with the same body to POST /v1/formats/{handle}/{slug}/runs and Sume returns 200 with the original receipt and idempotency_hit: true, with no second run and no second charge. Send the same key with a different body and you get 409 idempotency_conflict, and nothing runs.
The behavior is in the Calling a Format docs. A different instruction or a different attachment list counts as a different body, which is the part people forget.
Replay outcomes
The scope of a key is one Format, and a key can be up to 255 characters. The same key sent to two Formats starts two runs.
| Situation | Result |
|---|---|
| Same key, same body | 200, original receipt, idempotency_hit: true |
| Same key, different body or attachments | 409 idempotency_conflict, nothing runs |
| Same key, two requests at the same moment | One wins; the other gets 409 idempotency_key_in_use, retryable after about one second |
| Same key after a failed create (402, 503, ...) | Key was released; fix the cause and retry with the same key |
| Bulk queue, same key, same payload | 202 with the old queue (no idempotency_hit field) |
| Bulk queue, same key, different payload | 409 idempotency_conflict, details.queue_id names the original |
Deriving the key
Derive the key from the item the run makes: your order id plus a version number that you bump only when you want a re-run. Do not use the time of the request, and do not call a new uuidgen per attempt, because then the header does nothing and a retry after a timeout starts a second paid run.
Example: order 8841 with version 1 gives the key order-8841-v1. A network timeout, then a retry with the same key and body, returns the same run. A deliberate re-run with new copy uses order-8841-v2.
import uuid
def run_key(order_id: int, version: int) -> str:
return f"order-{order_id}-v{version}"
print(run_key(8841, 1)) # retry-safe
print(run_key(8841, 2)) # deliberate re-run
print(str(uuid.uuid4())[:8], "<- a fresh uuid per attempt defeats the header")Handling the 409s
A conflict means your code reused a key for new work, so look for a version that did not change. idempotency_key_in_use is the other 409 and it is retryable: wait about one second, then send again to get the original run.
- Bulk queues take the key as the header or a body
idempotency_key; the header wins if both are sent. - Mint a fresh key per batch, because a spent key returns the old queue.
- Store
data.idfrom the first response and use the receipt URLs it carries.
Why the same-moment case matters
Two workers that retry on a timeout at the same instant can both send the key. Only one wins. The other gets idempotency_key_in_use, and the docs call it retryable: wait roughly a second, send again, and you receive the original run. Build the retry as part of the client and you never need a lock of your own. If a create fails with a 402 or 503, the key is released, so the same key is safe to reuse once the cause is fixed, for example after topping up credits.
Sources
Related posts
More in Formats
- Before-after video for cleaning and organizing products, Q4
The Sume before-after Format builds a transformation video with matched framing and a clear reveal. Brief it with a real before photo and call it by API.
- Sume Format output_error codes: which to retry and which to fix
output_extraction_failed is transient: re-read the run, then retry with a new key. output_schema_unsatisfied means the schema or recipe is wrong. Six codes.
- Sume Format run spend cap: 0 is rejected, null means $500
generation_spend_cap_usd on a Sume Format run: up to 500 is accepted, null uses the $500 maximum, 0 or above 500 returns 400. An unset Format defaults to $400.
- Team Format returns 403 workspace_key_required: which key to mint
A personal key on a team Format gets 403 workspace_key_required. details.workspace_id names the workspace. Create the key there. Other keys see 404.
Written by Sume