Idempotency
Retry sends safely with the Idempotency-Key header.
POST /v1/email and POST /v1/email/batch accept an Idempotency-Key
header. A retried request with the same key returns the original result — no
second send, no second charge.
curl https://api.emitd.com/v1/email \
-H "Authorization: Bearer $EMITD_API_KEY" \
-H "Idempotency-Key: order-4021-receipt" \
-H "Content-Type: application/json" \
-d '{ ... }'How it behaves
- First request with a key executes normally and its result is stored.
- Replay (same tenant, same key) returns the stored result directly —
for single sends marked
idempotent_replay: true— without re-sending or re-consuming quota. - Replays can short-circuit before quota is consumed, so a client safely retrying a 5xx or timeout with the same key never burns a fresh quota unit.
- Keys are scoped to your tenant and do not expire on their own.
Single sends return 200 on replay (the original result is returned as-is);
first-time sends that queue return 202.
When to use it
- HTTP clients that auto-retry on timeout or 5xx.
- Webhook-driven jobs where the same event may be delivered twice.
- Anything where "send exactly once, or tell me what happened last time" is the contract.
Same key = same request
A key replays the stored result of the first request with that key, even
if the body differs. Generate keys per logical operation (for example
receipt:{order_id}), not one global key.
HTTP/2 200
{
"message_id": "msg_2h8Kd0Rk9Qa",
"status": "queued",
"idempotent_replay": true
}