Same Idempotency-Key replay: bulk run answers 202, single run 200

Replaying a Format bulk-run create returns 202 and the original queue with no idempotency_hit flag. A single run returns 200 with idempotency_hit true.

5 min readSume
All posts

If you replay a Sume Format bulk-run create with the same Idempotency-Key and the same body, you get 202 and the queue that already exists. You do not get 200, and the queue has no idempotency_hit field. A single Format run behaves differently: the replay returns 200 with idempotency_hit: true. Stripe's idempotency page describes the idea both follow, saving the result of the first request for a key and returning it for later requests, but the status code is where a Sume client can trip.

Two surfaces, two replay signals

On POST /v1/formats/{handle}/{slug}/runs, 202 means a fresh run and 200 means an idempotent replay. Both carry the full receipt. On POST /v1/formats/{handle}/{slug}/bulk-runs, a replay stays 202. The queue object carries id, counts and items, and nothing marks it as a replay, so a client that branches on 202 versus 200 to detect a duplicate will mis-handle bulk creates.

The scope of the key is one Format. The header form wins if you also send idempotency_key in the body. A different payload under the same key gives 409 idempotency_conflict, and details.queue_id names the original queue.

Replay behavior, from Sume docs and Stripe (read 2026-10-05)
CallFreshSame key, same bodySame key, other body
Single Format run202200 with idempotency_hit: true409 idempotency_conflict
Bulk run create202202, the existing queue409, details.queue_id names the first queue
Stripe (reference)Result savedSame result, including 500sError on mismatched parameters

How to detect a bulk replay

Do not infer replay from the status code. Persist the data.id (frq_...) you received for each batch key. When a create returns, compare: the same id means you are looking at the queue you already know. A new id under a key you thought was new means the key was not spent the way you expected, so stop and investigate before any further submit.

curl -sS -X POST "https://api.sume.com/v1/formats/chase/product-promo/bulk-runs" \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: promo-2026-10-05-batch-1" \
  -d '{"concurrency": 2, "items": [{"instruction": "clip 1"}, {"instruction": "clip 2"}]}' \
  | jq -r '.data.id, .data.status, .data.counts.total'

Mint a fresh key for each batch

The expensive mistake is the opposite one. If you reuse a spent key for a new list that happens to be identical, you will quietly get the old queue back and run nothing new. Build the key from the thing that makes the batch unique, such as a date and a batch number, and keep it with the queue id in your own table. Stripe notes that keys may be pruned after 24 hours, so do not treat an old key as a permanent lock; Sume's docs describe no such window, so store both ids and rely on the queue id for lookups.

Sources

Related posts

More in Formats

All Formats posts

Written by Sume