How It Works
Include anIdempotency-Key header with a unique value for each logical operation:
Behavior
- First Request: Processed normally. A successful (
2xx) response is stored, encrypted, for 24 hours - Retry with Same Key: Returns the stored response with an
X-Idempotency-Cached: trueheader. The operation is not run again - Retry While the First Is Still Running: Returns
409 Conflictwith aRetry-Afterheader. The operation is not run a second time; wait, then retry with the same key (see Retrying a request that is still running) - Retry After a Failure: Only successful responses are stored. If the first attempt failed (any non-
2xxresponse), retrying with the same key runs the operation again - Retry When the Stored Response Is Gone: In the rare case the first request is known to have succeeded but its response can no longer be returned, the retry returns
409 Conflictand the operation is not run again (see When the stored response is no longer available) - Same Key, Different Body: Returns
422. A key names exactly one request - Different Key: Processed as new request
What Counts as the Same Request
A key only matches a request with the same:- Account (or organization, for organization API keys)
- HTTP method
- URL, including path parameters and query string
Supported Methods
A call takes a key when the API Reference listsIdempotency-Key among its parameters, and the reference says so for every call that does, including the PUT and PATCH calls that change something. Where a call requires a key, omitting the header returns 400.
GET requests are naturally idempotent and don’t need keys, and most deletions don’t take one either. The call that makes an editor session takes none: its answer holds a token that is never stored where a retry could read it back, so a retry makes a new session.
Key Requirements
- Unique per operation: Use a combination of action + context + timestamp
- Client-generated: You control the key generation
- Format: 8 to 50 characters — letters, digits, dashes and underscores (a UUID works well)
- Expiration: Stored responses expire after 24 hours
Generating Good Keys
Example Implementation
Retrying a Request That Is Still Running
If your client times out and retries while the first request is still being processed, the retry is refused instead of running the operation twice:Retry-After seconds and send the request again with the same key. You will receive either the stored response (the first request succeeded) or a fresh run (the first request failed and released the key). Do not generate a new key: that would run the operation twice.
A request that is interrupted (for example, the server restarts mid-request) frees its key within about a minute, so a retry is never blocked for long.
When the Stored Response Is No Longer Available
A stored response is kept encrypted, and only for the request that produced it. In the rare case the first request is known to have succeeded but its response can no longer be returned (for example, it was written while our storage was being reconfigured), the retry is refused instead of running the operation a second time:Retry-After: waiting does not help, and the same key will never return that response. details.originalStatusCode is the status the first attempt answered, when it is known. Do not send the request again under the same key.
- Read what the request changed. If it created something (a widget, an API key), list or fetch it instead of creating it again. A response that showed a secret once, such as a new API key, cannot be shown again: create a new one and remove the old one.
- Repeat it under a new key only when repeating is safe, that is, when running the operation twice would not do harm.