Overview
Idempotency ensures that retrying a request (due to network failures, timeouts, or application errors) won’t result in duplicate emails. This is critical for transactional emails where sending the same message twice can confuse recipients or cause unintended actions.How it works
When you include anIdempotency-Key header, Lettermint:
- Hashes the request body to create a fingerprint of your email content
- Stores the key + hash for 24 hours, scoped to your project
- On subsequent requests with the same key:
- If the body hash matches → returns the cached response (no duplicate sent)
- If the body hash differs → returns a
409 Conflicterror
Idempotency keys are scoped per project. The same key can be used across different projects without conflict. Within a single project, each key must be unique per email.
Usage
Header
Key requirements
| Requirement | Value |
|---|---|
| Length | 1–255 characters |
| Format | Any string (UUID v4 recommended) |
| Validity | 24 hours from first use |
| Scope | Per project |
Request scenarios
| Scenario | Result |
|---|---|
| First request with new key | Email sent, response cached |
| Same key + same body (retry) | Cached response returned, no duplicate |
| Same key + different body | 409 Conflict error |
| Same key + request in progress | 409 Conflict error |
| Key used 24+ hours ago | Treated as new key |
Examples
Send with idempotency key
Response (202 Accepted)
Safe retry (same key + same body)
If you retry the exact same request with the same idempotency key and body, you receive a202 Accepted with the same message_id. No duplicate email is sent.
Conflict (same key + different body)
If you use an existing key with a different request body: HTTP 409 ConflictConcurrent requests
If another request with the same key is still being processed: HTTP 409 ConflictSMTP
TheIdempotency-Key header works the same way when sending via SMTP relay.
Error reference
| Error Code | HTTP Status | Message |
|---|---|---|
invalid_idempotency_key | 422 | The idempotency key must be between 1-255 characters. |
invalid_idempotent_request | 409 | This idempotency key has already been used on a request with a different payload. |
concurrent_idempotent_requests | 409 | Another request with the same idempotency key is currently being processed. |
Best practices
When to use idempotency
| Use Case | Recommendation |
|---|---|
| Order confirmations, receipts | Always use idempotency |
| Password resets, verification emails | Always use idempotency |
| Webhook-triggered emails | Use if webhook might retry |
| Marketing campaigns (batch) | Optional, typically single-shot |
| Test emails during development | Skip, duplicates are harmless |
Troubleshooting
Why am I getting 'key already used' errors?
Why am I getting 'key already used' errors?
This happens when you reuse an idempotency key with a different email body. Common causes:
- Using a static key instead of generating per-email keys
- Changing the email content (subject, body, recipients) between retries
What's the difference between 409 and 422?
What's the difference between 409 and 422?
- 422 (Unprocessable Entity): Your idempotency key is invalid (empty, too long, or wrong format)
- 409 (Conflict): The key is valid but conflicts with an existing request (different body or concurrent request)
How long do idempotency keys last?
How long do idempotency keys last?
Keys expire 24 hours after first use. After expiration, the same key can be reused as if it were new. This prevents permanent key exhaustion while providing a reasonable retry window.
Can I use the same key across different projects?
Can I use the same key across different projects?
Yes. Idempotency keys are scoped per project, so
order-123 in Project A is independent from order-123 in Project B.