Skip to content
Docs

Reference

Retry email sends safely with the Idempotency-Key header. Which endpoints support it, key format and scope, the 24-hour replay window and its errors.

Updated Oct 1, 2026

Network errors and timeouts leave you unsure whether a send went through. An idempotency key makes the send safe to retry: if Emailit already accepted a request with the same key, it returns the original response instead of sending the email again. This page is the reference for the Idempotency-Key header. For a walkthrough, see Idempotent sends.

Supported endpoints

Endpoint
POST /emails Send an email
POST /emails/{id}/forward Forward an email

Other endpoints ignore the header. Creating a domain, API key, audience or contact is already safe to retry: a second request with the same name or email returns 409 and the existing object instead of creating a duplicate.

Send a key

Add an Idempotency-Key header with a value that’s unique to the email you’re sending, such as a UUID or an ID from your own system:

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

Generate the key once per email, before the first attempt, and send the same key on every retry of that email.

How keys work

Rule Details
Format 1 to 256 characters. Letters, digits, hyphens (-) and underscores (_) only.
Scope Per workspace. Keys from different workspaces never collide, but both endpoints share one namespace, so don’t reuse a send key for a forward.
Lifetime The response to a successful request is kept for 24 hours after it completes.
Replays A request with a stored key returns the stored response with status 200. No email is sent, no credits are used, and the sending limits aren’t counted.
Matching Only the key is compared, not the request body. A different request with a used key returns the first response.
Failures If a request fails with any error, nothing is stored and the key is released, so you can fix the request and retry with the same key.
Concurrency While a request with a key is still running, another request with the same key returns 409. The lock is released when the first request finishes, and it expires after 15 minutes at most.

A replayed request still goes through authentication and the per-second and daily sending limits check, so it can return 401 or 429. Forwards also count against the hourly forward limit, even when the response is replayed.

Errors

JSON
{
  "error": "Invalid Idempotency-Key"
}
Status error Cause What to do
400 Invalid Idempotency-Key The key is empty, longer than 256 characters, or has other characters than letters, digits, - and _. Use a UUID or another safe value.
409 Idempotency key in progress A request with the same key is still being processed. Wait a second and retry with the same key. You’ll get the stored response once the first request finishes.
503 Idempotency unavailable Emailit can’t check the key right now. The request wasn’t processed. Retry with the same key after a short delay.

Emailit never sends a request without its idempotency check: if the key can’t be checked, the request fails with 503 rather than risk a duplicate.

Choose good keys

  • Derive the key from the thing you’re notifying about, such as order-1042-confirmation or password-reset-<token-id>, so a retry from another worker or after a restart uses the same key.
  • Use a fresh UUID only when the email has no natural ID, and store it with the job before the first attempt.
  • Don’t reuse a key for a different email within 24 hours. You’d get the first email’s response and the second email wouldn’t be sent.
A guide to retry-safe sending.
Back off and retry with example code.

Was this page helpful?

Thanks for the feedback.

Thanks, we read every message.