Idempotency-Key to replay a stored result when you retry the same request. It reduces duplicate operations, but a server error, an interrupted request, or an expired record can allow the operation to run again. Reconcile uncertain sends before retrying when duplicates are unacceptable.
Available on Free, Pro and Max. See plans and features.
Idempotency is particularly important for critical operations like sending emails, creating resources, or processing payments where duplicate actions could cause problems.
How It Works
When you make a request with anIdempotency-Key header:
- First Request: The API processes your request normally and stores the response
- Subsequent Requests: If you retry with the same key, the API returns the stored response instead of processing the request again
- Server Errors Are Retriable: If the original attempt failed with a server error (HTTP 5xx) or never completed, no response is stored — retrying with the same key re-executes the request and can repeat a side effect
- Automatic Cleanup: Stored idempotency responses expire after 24 hours. The exception is API key creation: because its response carries a one-time
secret_key, the replayable response expires after 5 minutes
Supported Operations
Supported Operations
Only the operations in the Supported Operations table declare the idempotency header. These cover:
- API Keys: Create API keys
- Domains: Create domains
- Messages: Send messages
- Account Members: Add team members
- Suppressions: Create email suppressions
- Routes: Create message routes
- Webhooks: Create webhook endpoints
- SMTP Credentials: Create SMTP credentials
- Sub-Accounts: Create sub-accounts
- Sub-Account API Keys: Create sub-account API keys
One-Time Secrets (API Key Creation)
One-Time Secrets (API Key Creation)
API-key creation endpoints — Create API Key and Create Sub-Account API Key — return a one-time
secret_key in the response.Their idempotent replay response is encrypted and expires after 5 minutes (instead of the usual 24 hours). Within that window, an exact retry with the same Idempotency-Key replays the same secret_key. After it, the secret can no longer be retrieved — if you lose it, create a new key.Other operations that declare idempotency store responses for 24 hours.Key Requirements
Key Requirements
- Header Name:
Idempotency-Key - Key Format: Any string up to 255 characters
- Uniqueness: Keys are scoped to your account
- Expiration: Stored responses expire after 24 hours — except API key creation, whose secret-bearing response expires after 5 minutes
- Request Method: Only the operations listed below support idempotency; other POST operations do not gain it implicitly
Request Matching
Request Matching
Requests are matched based on:
- Account ID
- Idempotency key
- Request method and path, including path parameters
- Request body content (SHA256 hash)
422 Unprocessable Entity.Supported Operations
A fresh execution has no
Idempotent-Replayed header. A completed replay returns the original status and body with Idempotent-Replayed: true. An in-progress request returns 409, Idempotent-Replayed: false, and a positive integer Retry-After. A mismatched request returns 422 with neither of these headers. The API has no 412 failed-key response.
Key Selection Best Practices
A client generates an idempotency key, which is a unique key that the server uses to recognize subsequent retries of the same request. How you create unique keys is up to you, but we suggest using V4 UUIDs, or another random string with enough entropy to avoid collisions. Idempotency keys are up to 255 characters long.Key Generation Examples
Key Collision Risk: With V4 UUIDs, the probability of generating duplicate keys is approximately 1 in 5.3 x 10^36. For practical purposes, this is negligible even at massive scale.
Usage Example
Include theIdempotency-Key header only on an operation that declares it:
Response Behavior
The API responds differently based on the idempotency key status:- First Request
- Replayed Response
- Concurrent Request
- Failed Original
- Payload Mismatch
Status:
202 Accepted for Create Message (201 Created for resource creation)Headers:- Standard response headers
- No special idempotency headers
Best Practices
Unique Keys
Use unique, descriptive keys that won’t conflict with other operations. Consider including timestamps or UUIDs.
Retry Logic
Implement exponential backoff when retrying requests. Always use the same idempotency key for retries.Pass a
makeRequest(key) callback that sends the same body each time and throws an object with HTTP status and retryAfter seconds on failure. Only use this retry policy after deciding that retrying an uncertain send is acceptable.Key Expiration
Stored responses expire after 24 hours — don’t reuse a key after this period, as it can execute again. API key creation is shorter: its one-time
secret_key is only replayable for 5 minutes.Error Handling
Handle different response codes appropriately:
409: Concurrent request in progress — wait for theRetry-Afterinterval, then retry with the same key422: Key reused with a different request — use a new idempotency key, or retry with the original payload and endpoint5xx: Transient failure — retry with the same idempotency key2xx/4xxwithIdempotent-Replayed: trueheader: replayed original outcome
Error Scenarios
Request Already in Progress (409 Conflict)
Request Already in Progress (409 Conflict)
This happens when you make concurrent requests with the same idempotency key.What it means: Another request with the same key is currently being processed.What to do: Wait for the interval indicated by the
Retry-After response header, then retry with the same key. The retry will either get a 409 again (still processing), the stored result once complete, or — if the original request never completed (e.g. it was interrupted) — it will re-execute the request once the in-flight lease expires (at most 5 minutes).Response
Original Request Failed with a Server Error
Original Request Failed with a Server Error
If the original request failed with an HTTP
5xx error, no response is stored for the idempotency key.What it means: The failure is treated as transient, and the key remains usable.What to do: Retry with the same idempotency key — the request is re-executed as if it were the first attempt. (Ordinary operations store deterministic 4xx responses after idempotency middleware. Authentication, IP allow list failures, and the two API-key create operations have the exceptions described above.)Key Mismatch
Key Mismatch
If you use the same idempotency key with different request data — or with the same data against a different endpoint or resource — the API returns
422 Unprocessable Entity.What it means: The request doesn’t match the original request for that key.What to do: Ensure you’re using the exact same request (payload and endpoint) when retrying, or use a different idempotency key for different requests.Response
Implementation Details
Request Hashing
The API uses SHA256 hashing of the request method, path, and body to detect changes between requests with the same idempotency key. This ensures that different requests don’t accidentally match — including the same payload sent to a different resource.Concurrency Protection
Claiming an idempotency key happens atomically; While a request is in flight, concurrent requests with the same key receive409 Conflict with a Retry-After header instead of waiting.
Execution Leases
An in-flight request holds a lease on its idempotency key for up to 5 minutes. If the original request never completes (for example, it was interrupted by a deploy or crash), the key unblocks automatically when the lease expires and the next retry re-executes the request.Storage Duration
Ordinary stored results expire after 24 hours; successful API-key creation results expire after 5 minutes. After expiry, the same key can run a new operation. Responses that contain a one-time secret — API key creation and sub-account API key creation — are stored encrypted and their replayable response expires after 5 minutes. Within that window an exact retry replays the samesecret_key; afterward the secret can no longer be returned.

