# Do I need idempotency keys?

**IDEALLY**—if your code retries

> Networks fail mid-request and retries are how you cope—but a retried send without an idempotency key is how a customer gets three copies of one receipt. One header makes retries safe.

Here's the failure mode: your code calls the email API, the request times out, and you retry—sensible. Except a timeout doesn't mean the request failed; it means you didn't hear the answer. If the first attempt actually went through, your retry just sent the email twice. Email is the worst place for this bug, because the duplicate lands somewhere a human is guaranteed to look.

## What a key does

An idempotent operation can run more than once with the same input and produce the same outcome, side effects included—which for email means: sent exactly once. You opt in by attaching a unique key to each *logical* send:

```txt
Idempotency-Key: order-confirmation-8412
```

Retry with the same key and the API recognizes the operation, returns the original result, and does not send again. The key should identify the event, not the attempt—derive it from something stable like `order-confirmation-${orderId}`, never a random value generated per request (that would defeat the whole mechanism).

## When it matters

- **Anything that retries automatically.** Queue consumers, serverless functions with retry policies, cron jobs that re-run after a crash—all of them will eventually replay a send.
- **At-least-once delivery systems.** Webhook handlers and message queues promise "at least once", and email is a side effect you want "exactly once".
- **Transactional mail specifically.** A duplicate newsletter is mildly embarrassing; a duplicate "your payment was processed" makes customers file support tickets.

On Resend it's the `Idempotency-Key` header (or the equivalent SDK option) on the send-email endpoint.

## The verdict logic

This is an *ideally* rather than a yes because a low-volume app doing fire-and-forget sends with no retry logic has nothing to protect against—no retries, no duplicates. But the moment there's a retry path anywhere between your event and the send call (and in production systems there almost always is), the key is one line of code that removes a whole class of embarrassing bugs. Cheap insurance, like a [plain-text part](https://doineed.email/plain-text-version), but for your reputation with your own customers.

---

- Canonical: https://doineed.email/idempotency-keys
- Learn more: https://resend.com/blog/engineering-idempotency-keys
- All questions: https://doineed.email/llms.txt

An opinionated answer from the [Resend](https://resend.com) team.
