Emails
Idempotency keys
Retry HTTP submissions without queuing another copy.
How it works
Retry HTTP submissions without queuing another copy. Send a stable Idempotency-Key on a POST. Keep the method, path, and exact JSON body unchanged when retrying.
Example
curl "$OPENSEND_BASE_URL/emails" \
-H "Authorization: Bearer $OPENSEND_API_KEY" \
-H "Idempotency-Key: order-123-confirmation" \
-H "Content-Type: application/json" \
-d '{"from":"hello@example.com","to":"you@example.net","subject":"Order confirmed","text":"Thank you"}'Things to know
Keys last 24 hours and have 1–256 characters. Reusing one with a different request returns 409. API idempotency does not eliminate ambiguous SES outcomes: a timed-out provider send is marked failed without automatic resend.
Replays and concurrent requests
Resource creation and the stored HTTP status and response body commit in the same database transaction. Retrying after a crash or a logging failure replays that committed response without creating another resource. The key is scoped to your team, not to one API key.
A different method, path, or exact request body returns 409 invalid_idempotent_request. A matching request still in progress returns 409 concurrent_idempotent_requests; retry later with the same request. An uncommitted reservation can be retried after its 60-second lease. A stale worker is fenced before it can write.
A server error releases only an uncommitted reservation. It cannot erase a response already committed with its resource. Non-server refusals are also stored for replay. After 24 hours, the key may be used for a new request.
SMTP retries
Set the Opensend-Idempotency-Key message header to a stable value for an SMTP retry. The gateway passes it to the same idempotency mechanism and removes the header from the delivered message. Keep the sender, recipients, and message unchanged. See SMTP gateway.