Sending an idempotency key
Add anIdempotency-Key header to any POST, PATCH, PUT or DELETE request. The key is a value you generate, unique to the operation you want to perform. We recommend a UUID v4.
GET requests, which never change data.
How retries are handled
The first request with a given key runs normally, and its response is saved, whatever its status code, including errors. Responses larger than 1 MiB are not saved, nor are responses that cannot be saved as JSON text, such as streamed or binary ones. A retry of such a request is rejected withIDEMPOTENCY_RESPONSE_NOT_STORED rather than run again: the operation already ran.
Any later request with the same key and the same body returns the saved response, with the same status code and body, without running the operation again.
A replay returns the saved response once your API key and workspace membership are checked again, but without checking your access to individual groups again, as the response belongs to an operation you were allowed to run.
A replayed response carries an Idempotent-Replayed: true header. Its body is the original one, including the original requestId.
Of the original headers, only Content-Type, Deprecation and Sunset are replayed. The others describe the retry: its X-Request-Id header identifies the retry, and its rate limit headers reflect your current usage.
Keys are scoped to your user and workspace, and are kept for 24 hours after the request completes. Once a key has expired, a request with that key runs as a new request.
While a request is still being processed, its key is held for up to 5 minutes. If its response could not be saved, for instance because of a server failure, the key is freed after that delay and a retry runs the operation again.
A key is tied to the request it was first used with: its method, route and path parameters, query parameters, API version and body. The order of keys in the JSON body does not matter, and a request without a body is treated like one with an empty {} body.
Reusing a key for a different request returns an IDEMPOTENCY_KEY_REUSED error instead of replaying the earlier response.
Responses to requests rejected before they run are not saved: authentication errors, rate limit errors, and validation errors for an unsupported API version or an invalid body, query or path parameter. You can fix the request and retry it with the same key.
Retrying safely
We recommend the following retry strategy:- Generate a new key for every operation, and keep it with the request until you get a final response.
- On a timeout, a network error, a
409or a5xxerror other than500, retry the same request with the same key, using exponential backoff. - On a
429, wait for the delay given by theRetry-Afterheader, then retry with the same key. Rate-limited requests never run. - A
500returned once the operation has started is saved like any other response, so retrying with the same key returns it again. Check whether the operation took effect before sending it again with a new key. - On
IDEMPOTENCY_RESPONSE_NOT_STORED, the operation already ran: check its outcome, for instance by listing the records it created, before sending it again with a new key. - To send the same payload again as a new operation, use a new key.
Errors
Invalid key
Status code:400Code:
IDEMPOTENCY_KEY_INVALID
The Idempotency-Key header is empty, sent more than once, longer than 255 characters, or contains a space or a character outside printable ASCII.
Request in progress
Status code:409Code:
IDEMPOTENCY_REQUEST_IN_PROGRESS
A request with the same key is still being processed. Retry once it has completed.
Key reused
Status code:422Code:
IDEMPOTENCY_KEY_REUSED
The key was already used for a different request. Use a new key.
Response not stored
Status code:422Code:
IDEMPOTENCY_RESPONSE_NOT_STORED
The request with this key already ran, but its response was not kept: it was larger than 1 MiB, or could not be saved as JSON text. Check the outcome of the operation before sending it again with a new key.
Idempotency unavailable
Status code:503Code:
IDEMPOTENCY_UNAVAILABLE
folk could not claim the key, so the request was not processed rather than processed without protection. Retry with the same key.