Network timeouts can leave you unsure whether an email send succeeded. Add an Idempotency-Key header so you can safely retry the same logical send without creating a second message.
Send with an idempotency key
Generate one unique key for each logical send. UUID v4 values are a good choice. Put the key in the HTTP header—not in the JSON body:
curl -i -X POST "https://api.telnyx.com/v2/email_messages" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7e85df5e-9f71-4ce9-a57a-811dd96c031a" \
-d '{
"from": "sender@mail.yourcompany.com",
"to": ["recipient@example.com"],
"subject": "Your receipt",
"text_body": "Thanks for your order."
}'
If the client times out or loses the response, repeat the same request with the same key and the same body:
curl -i -X POST "https://api.telnyx.com/v2/email_messages" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7e85df5e-9f71-4ce9-a57a-811dd96c031a" \
-d '{
"from": "sender@mail.yourcompany.com",
"to": ["recipient@example.com"],
"subject": "Your receipt",
"text_body": "Thanks for your order."
}'
When Edge replays a stored successful response, the response includes Idempotent-Replayed: true. The original HTTP status and body are replayed; a successful replay is not automatically changed to 200.
Follow these key rules
- Use 1 to 255 letters, numbers, hyphens, or underscores.
- Use one key per logical operation.
- Reuse a key only for the same method, path, query, and request body.
- Retry uncertain outcomes with the same key; use a new key for an intentionally new email.
- Successful responses are retained for 24 hours. After that window, the same key may no longer prevent a duplicate.
Do not send idempotency_key in the JSON body. The Email API ignores the legacy body field, so two direct requests with only that field can create two different messages.
Handle key-related responses
| Response | Meaning and action |
Idempotent-Replayed: true | The stored successful response was replayed. Do not create another send. |
400 / 10015 | The header was empty, duplicated, malformed, or longer than 255 bytes. Generate one valid value. |
409 / 10036 | The same key is still being processed. Retry later with the same key and unchanged request. |
422 / 10027 | The key was already used with a different request. Do not force a retry; use a new key only if you intend to create a new operation. |
413 Payload Too Large | A keyed request body exceeded the 8,000,000-byte Edge replay-protection cap. Reduce the request before retrying. |
Only successful 2xx responses are stored for replay. If the API returns a normal validation or authorization error, fix the error before deciding whether the corrected operation needs a new key.
Use one key for the whole batch
For a batch send, the header protects the complete request. It does not assign a separate key to each item:
curl -i -X POST "https://api.telnyx.com/v2/email_messages/batch" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 1c5c7c41-1bf0-463e-a99a-47c5620cc699" \
-d '{
"messages": [
{
"from": "sender@mail.yourcompany.com",
"to": ["one@example.com"],
"subject": "First message",
"text_body": "Hello one"
},
{
"from": "sender@mail.yourcompany.com",
"to": ["two@example.com"],
"subject": "Second message",
"text_body": "Hello two"
}
]
}'
Reusing the original key replays the stored whole-batch response. If a batch response contains failed items and you want to retry only those items, create a new batch containing only the failed items and use a new key.
Avoid the most common duplicate-send bugs
- Do not generate a new key for every network retry.
- Do not reuse one static key for different emails.
- Do not change whitespace, recipients, content, or query parameters while retrying the same key.
- Do not rely on a key after the 24-hour retention window.
Related Articles