This page is a reference for error codes returned by the Telnyx Email API. It covers two distinct families: synchronous HTTP errors returned on the API request itself, and asynchronous delivery errors (the 30xxx taxonomy) reported later via webhooks and detail records. They are not interchangeable — a 30xxx code never appears in an HTTP response body, and an HTTP code never appears in
error_evidence. For endpoint-specific errors, see the response examples in each endpoint’s API reference.Error response format
Most errors follow the standard Telnyx v2 error shape (exceptions: batch errors use{index, code, message} — see Batch-specific errors — and some template render errors use {code, message}):
Request and message size limits
Size failures are a common source of confusion because three different ceilings apply at three different layers. They are not the same number.8 MB is not a request-body limit. It is the Edge gateway’s
request_body_cap_bytes for idempotency-keyed replay only. A keyed request over 8 MB is rejected at the Edge with 413 Payload Too Large — it never reaches the Email API. Unkeyed requests bypass this cap entirely. The limits that actually reject a message body are the 1 MB body and 25 MB total enforced by the Email API, which return 422.HTTP status codes
Error code reference
Every code in this section is a synchronous error — returned in the HTTP response to your API request. Delivery failures that happen after a
202 Accepted use the separate 30xxx taxonomy.400 — Bad Request
401 — Unauthorized
403 — Forbidden
404 — Not Found
409 — Conflict
422 — Unprocessable Entity
429 — Too Many Requests
Do not treat every
429 as a transient rate limit. Branch on the error code, not the status. 10011 clears on its own at midnight UTC. reputation_suspended does not clear by waiting — retrying it in a backoff loop will never succeed and worsens the reputation signal. Stop sending on that domain and remediate the underlying bounce/complaint rates first.500 — Internal Server Error
503 — Service Unavailable
WebSocket upgrade errors
GET /email_events/ws is an upgrade endpoint, so it returns HTTP errors before the socket is established:
Asynchronous delivery errors (30xxx)
A
202 Accepted means Telnyx accepted the message for sending — not that it was delivered. Delivery failures are reported asynchronously through webhooks and detail records, using this separate 30xxx taxonomy. These codes never appear in an HTTP response body.error_evidence structure
Failure events carry the normalized contract as error_evidence:
The same normalized error is also published in array form as
errors[], where each entry adds a human-readable title and renames message to detail. See Error evidence on failure events.
The webhook event type does not uniquely identify the failure. An ordinary bounce, a queue expiration, an administrative bounce, and an out-of-band bounce all publish
email.bounced. Branch on error_evidence.code — for example 30001 versus 30005 — and read the recipient status for the authoritative outcome. bounce_category is an internal field: it is not part of normal recipient-scoped webhook payloads and is not written to normal recipient-scoped stored events. A legacy message-scoped fallback path may persist it in stored events, and the Events API sanitizer does not explicitly strip it. Do not build consumer logic that reads bounce_category from any public surface.Idempotency-specific errors
When using theIdempotency-Key header, idempotency is enforced at the Telnyx Edge (API gateway) before the request reaches the Email API. The same key can produce three distinct outcomes, and they must be handled differently:
Two further failure modes are specific to the idempotency layer itself:
A replay only works while the gateway holds the stored response. Requests whose body exceeds the Edge 8 MB replay cap are rejected at the Edge with
413 Payload Too Large before reaching the Email API — see Request and message size limits.Batch-specific errors
Batch requests (POST /email_messages/batch, up to 50 messages) return 207 Multi-Status when one or more messages fail — including an all-failed batch — with per-message errors:
index (position in your messages array), code, and message:
Codes owned by other services
The Telnyx email product spans several services. A few codes documented here are returned by services other than the Email API, which means their exact status, code, and detail can change independently of this page. Verify these against the owning service’s API reference before depending on the precise shape:Error codes are not globally unique across Telnyx email services.
10008 is the clearest example: the email-domains service returns it as a 403 Forbidden for shared-domain mutation, while the Email API returns the same code as a 503 Service Unavailable when diagnostics authentication is unavailable. Always interpret a code together with both the HTTP status and the endpoint that returned it — never on the code alone.Troubleshooting
”Domain is not verified”
- Check
GET /v2/email_domainsto see the domain status. - Ensure all required DNS records — ownership and DKIM, plus MX if
inbound_enabledis true — are published and match the records returned byGET /v2/email_domains/{domain_id}/dns_records. - Call
POST /v2/email_domains/{domain_id}/verifyafter DNS propagates. - For a controlled zero-setup test, use
onboarding@<shared-domain>and send only to the account owner’s verified email address.
”sender address is not allowed”
Thefrom address must be on a verified domain you own. Shared-domain sends must use onboarding@<shared-domain> and can target only the account owner’s verified email address.
”Idempotency-Key header is invalid”
- Generate a UUID v4 (
uuidgenorcrypto.randomUUID()). - Pass it as an HTTP header:
Idempotency-Key: 8e03978e-40d5-43e8-bc93-6894a57f9326. - Do not include it in the JSON body — it’s a header only.
- One key per logical request. Reuse only for exact retries.
Sending suspended (reputation_suspended)
Your domain’s reputation band dropped to poor — usually from high bounce or complaint rates. See Deliverability and Domain Warm-up for recovery guidance.
Choosing a retry strategy
Retry decisions belong on the error code, not the HTTP status. Two errors that share a status can need opposite handling.Never retry a
4xx other than 409 and 429 without changing the request — the outcome is deterministic. And when you do retry a send, always reuse the original Idempotency-Key so a retry that races a slow success cannot deliver the message twice.Delivery failed after a 202 Accepted
A 202 only confirms acceptance for sending. If the message never arrived, the failure is asynchronous — look at the 30xxx delivery error on the recipient’s webhook or event, not at the HTTP response. Start with error_evidence.code:
30001— permanent rejection. Remove the address.30002— temporary; Telnyx is already retrying. Do not resubmit.30004— the recipient was suppressed before any attempt.30005— retries were exhausted; the recipient status isexpired.