Skip to content

Idempotency & retries

How to retry safely, what a replay looks like, and what 409 in_progress means.

Updated 2026-09-22

Networks fail, processes restart, people click twice. Every write in the API is designed so that repeating it is safe.

Events: the key is the event

For POST /v1/events the idempotency key is, in order: the Idempotency-Key header, the event's own id, or a key derived from the event (order.paid:ORDER-1001). So the same order sent twice is the same event: the second call returns the original with replayed: true and nothing is enqueued again. In a batch, each event's id is its key.

Even if an event were processed twice, ledger entries carry their own keys — a reprocessed event cannot double-credit.

Other writes: send Idempotency-Key

Enrol, redeem, reserve, adjust, webhook endpoints — send a header with a value that is unique per intent (an order id, a cart id, your own request id):

POST /v1/members/M-6EFEAB76DFCC/redemptions
Idempotency-Key: pos-7781-redeem
You sendYou get
A new keyThe request runs.
The same key, same bodyThe original response, with Idempotent-Replay: true. Nothing runs again.
The same key, different body409 conflict — a key collision or a retry bug on your side.
The same key while the first call is still running409 conflict with reason: in_progress and Retry-After — wait and retry.
A key whose first call failed (4xx/5xx)The request runs again. Failures are never remembered.

Keys are kept for 30 days.

What to retry

ResponseRetry?
Network error, timeoutYes, same key.
429Yes, after Retry-After.
500, 502, 503Yes, same key, backing off.
409 in_progressYes, after Retry-After.
Any other 4xxNo — it is a fact about the request. Retrying unchanged gets the same answer.

The SDKs do all of this for you and never repeat a write that has no key.

Idempotency & retries — StickyTier API