A network can drop after the server saves your request but before you see the answer. An idempotency key lets you send the request again and get the first answer back. You will be able to retry any write without creating a second record.
Before you start #
A client that can set a request header.
Steps #
- Make a unique key for each write you intend to make. Use 8 to 80 characters from letters, digits, dot, colon, underscore and hyphen. A random UUID works well.
- Send the key as the
Idempotency-Keyheader on a POST, PATCH or DELETE. - If you get no answer, send the identical request with the identical key.
- A replayed answer carries the header
Idempotent-Replay: true. The body and status match the first answer.
Rules #
- The key belongs to one token. Another token with the same key has a separate history.
- The key covers the method, the path with its query and the body. The same key with a different request answers
conflict(409). Pick a new key for a new request. - Two identical requests that arrive together run once. The second waits and gets the first result.
- Errors are never stored, so a request that failed validation can be corrected and sent again with the same key.
- Stored answers last 14 days.
- Webhook secret calls refuse a key, so a secret never sits in the answer store.
Where it matters most #
Taking a tow call, creating a customer, recording a payment, and every write a queued mobile app replays. Payments also keep the key on the payment itself, so a retry after the stored answer is lost still returns the first payment.
Technical details
POST /batchreplays up to 20 queued writes. Each one goes through the same routes, guards and key store as a direct call, using the batch key as itsIdempotency-Key.- Bodies over 16 MiB are refused on the idempotent path.
- Stored answers are removed in small sweeps as writes arrive. The backup scrub removes them all from every backup.
If something goes wrong #
conflict(409) "That idempotency key was already used for a different request.": use a new key.validation_failed(422) on the header (webhook secret calls): remove the header.