Skip to content
Docs

How-to

Use the Idempotency-Key header to retry send and forward requests safely. Key format, the 24-hour window, replays, 409 and 503 responses, and key strategies.

Updated Oct 1, 2026

Networks fail. When a send request times out, you can’t tell whether Emailit received it, and sending it again might email your customer twice. An Idempotency-Key header makes the retry safe: Emailit processes the first request and returns the same response for any repeat with the same key.

How it works

Add an Idempotency-Key header to POST /emails or POST /emails/{id}/forward.

  1. First request. Emailit reserves the key for your workspace and processes the request.
  2. Success. Emailit stores the response for 24 hours. Any request with the same key in that window gets the stored response back with 200, and no new email is created.
  3. Failure. If the request fails, for example with a 400 or 402, Emailit releases the key. Fix the problem and retry with the same key.
  4. Overlap. If a second request arrives while the first is still running, it gets 409 and nothing is sent. Retry shortly with the same key.

Keys are scoped to your workspace, so two workspaces can use the same key without conflict.

Key format

Rule Value
Length 1 to 256 characters
Characters Letters A–Z and a–z, digits 0–9, hyphen - and underscore _
Scope Per workspace
Window 24 hours after the first successful response

A key with other characters, such as : or /, is rejected with 400 Invalid Idempotency-Key.

Choose a key

Derive the key from the event that causes the email, so every retry path produces the same key:

Email Example key
Order receipt order-1042-receipt
Password reset password-reset-7f3c9a1e (the reset token’s ID)
Weekly digest digest-user-881-2026-w40
Background job The job’s ID, or a UUID you generate when you enqueue the job and store with it

Avoid keys that change between attempts, such as timestamps or a UUID generated inside the retry loop. They make every retry look like a new request.

Send with an idempotency key

The Node.js, Python and PHP examples retry on network errors and on 409, 429 and 5xx responses, reusing the same key each time. The cURL example uses curl’s built-in retry, which covers timeouts, 429 and most 5xx responses.

Terminal
curl https://api.emailit.com/v2/emails \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-receipt" \
  --retry 3 \
  -d '{
    "from": "Acme <orders@acme.com>",
    "to": "ada@example.com",
    "subject": "Receipt for order 1042",
    "text": "Thanks for your order."
  }'

Responses

Status When What to do
200 First successful request, or a replay of it within 24 hours Use the response. A replay has the same body, including the same id.
400 Invalid Idempotency-Key The key is empty, too long or has invalid characters Fix the key.
409 Idempotency key in progress A request with the same key is still being processed Wait a moment, then retry with the same key.
503 Idempotency unavailable Emailit couldn’t reach its idempotency store, so it refused the request rather than risk a duplicate Retry with the same key.
Any other error The request failed and the key was released Fix the cause and retry with the same key.

Rate limits are checked before the key, so a retry can still get 429. Wait for the retry-after header and send the same key again.

Was this page helpful?

Thanks for the feedback.

Thanks, we read every message.