Reference
Idempotency
How the Idempotency-Key header makes POST retries safe, and what each outcome means.
Networks fail. A request can time out after the server has already done the work, and a retry would then create the record twice. An idempotency key makes that retry safe.
The rule
Every POST must carry an Idempotency-Key header. PATCH accepts one but it is optional.
Idempotency-Key: signup-form-8f3a1c2e-0001- 8 to 128 characters, using letters, digits and
. _ : -. - Generate one unique key per logical operation (one form submission, one order import row, one invoice). Reuse the same key only when retrying that same operation.
- A missing key on a POST is
422 idempotency_key_required; a malformed one is422 idempotency_key_invalid.
What happens
| Situation | Result |
|---|---|
| First request with a key | Processed normally. The result is remembered. |
| Same key, same request | The original response (same status and body) is replayed with the header Idempotent-Replayed: true. Nothing is created or changed again. |
| Same key, different request (different body, path or query) | 409 idempotency_key_reused. Use a new key for a new request. |
| Same key while the first request is still running | 409 idempotency_request_in_progress with a Retry-After header. Wait and retry. |
A key is scoped to your API key, the HTTP method and the endpoint, so the same string used on a different endpoint is independent.
Failures
- A
4xxresponse (validation error, not found, conflict, and so on) is not remembered. Fix the request and send it again with the same key. - A
5xxresponse or a crash rolls back everything the request did and releases the key, so retrying with the same key is safe. - A request that is abandoned mid-flight is released automatically after a couple of minutes.
How long keys are kept
Responses are remembered for 7 days. After that the same key is treated as new. Do not reuse keys across unrelated operations.
PATCH
A PATCH is a partial update: sending the same body twice converges on the same record state, so a key is not forced. If you do send a key on a PATCH, it behaves exactly like on a POST.
Recommended client behaviour
- Create the key when you decide to perform the operation, and store it with your own record of that operation.
- On a network error, a timeout, a
5xxor a429, retry with the same key and the same body, with exponential back-off. - On
409 idempotency_request_in_progress, wait forRetry-Afterand retry. - Never retry a
4xxunchanged: change the request, and keep the key only if it never succeeded.