← All articles
Transactional email

Email API idempotency: retry requests without sending duplicate emails

Learn how idempotency keys prevent duplicate email submissions, how to handle conflicts and which failures are safe to retry in InboxIt.

INBOXIT JOURNAL
Retry the request.Not the welcome email.inboxit ↗

The timeout that can send two emails

Your app requests a welcome email. The provider accepts it, but the connection drops before your app receives the response. Your worker sees a timeout and submits the same message again. Without a stable identity for that operation, both submissions may become separate sends.

Idempotency lets your app identify a retry as the same logical request. It is useful for uncertain outcomes, not just deliberate double clicks. It also does not replace an application-level decision about whether two events should produce one email or two.

Choose a key for the logical message

Generate the key when your application decides an email should exist, then persist it with the intended payload. Reuse both for retries. Avoid generating a new random key inside the retry loop: that makes every attempt look like a different message.

Event: account-created-4821
Logical email: welcome-account-4821
Attempt 1: welcome-account-4821
Attempt 2 after timeout: welcome-account-4821
Different account: welcome-account-4822

These are illustrative identifiers. In InboxIt, Idempotency-Key is required for HTTP sends and accepts 1–100 letters, digits, underscores or hyphens. Do not put an email address, password or reset token into the key. Use an internal event identifier instead.

A genuinely new reset request should normally receive a new logical identity. A retry caused by a network interruption should retain the original identity and payload.

Keep the payload stable across retries

InboxIt returns a conflict when the same key is reused with a different payload. This protects against accidentally assigning two intentions to one identifier. A retry that regenerates a timestamp, changes the text or creates a new token can therefore fail even if it still looks like “the same email” to a person.

Persist the payload you intend to send. If it includes a time-sensitive link, define what happens when that link expires before delivery. Do not silently change it under the old key. Resolve the original operation first, then create a new authorized message when appropriate.

Read the sending guide and send endpoint reference for the exact contract. This guide describes HTTP sending; do not assume a different SMTP or third-party integration accepts the same header.

Use a durable workflow, not just a retry loop

  1. Record the application event and intended email in durable storage.
  2. Assign the key and store the message payload before the first send.
  3. Submit the request and record any returned email identifier and status.
  4. After a timeout, reconcile what you can from existing records and retry with the same key and payload when appropriate.
  5. Stop after a bounded number of attempts and surface an actionable failure.

For applications with a database and background worker, an outbox record is one way to keep the event and the work to be performed together. It still needs worker coordination and failure handling. An idempotency key does not fix two application events that were incorrectly created in the first place.

Distinguish retryable failures from setup problems

  • 400: fix invalid input rather than submitting it repeatedly.
  • 401 or 403: investigate credentials, permissions and account eligibility.
  • 409: inspect the conflict; do not automatically generate a new key to bypass it.
  • 429: respect Retry-After and reduce the request rate.
  • Timeout or temporary failure: treat the outcome as potentially uncertain, reconcile, and use bounded backoff.

InboxIt’s error guide explains the response categories. Backoff should include a stopping point; an outage should not produce an endless request loop.

Prevent duplicate effects after the send too

Sending and event processing are separate operations. A delivery webhook can arrive more than once, so deduplicate webhook event IDs before updating your application. Otherwise one email can still produce two “delivered” notifications or two downstream jobs.

Idempotency does not guarantee inbox placement, nor does it prove that a recipient read the message. Track the relevant delivery state separately and avoid claiming “exactly once” for the entire email journey.

Test a repeated identical request, a changed-payload conflict and an interrupted response in a controlled environment. Confirm the resulting email records and recipient mailbox. Use the email testing guide to make that check part of your release process.

Follow the quickstart

Your next big thing.
Ready for its first email?

Your domain. Your design. Send emails and receive replies with InboxIt.

Start free1,000 emails / month · No card requiredStart sending after confirming your email. No manual approval required.