This page explains why deliverability works the way it does — the mental model behind inbox placement, and how to read Telnyx delivery signals when mail fails. For step-by-step setup instructions, see Deliverability and Domain Warm-up.
How receiving providers evaluate mail
No mailbox provider publishes its filtering algorithm, but the evaluation consistently happens across four layers. A message must satisfy all four — strength in one layer does not compensate for failure in another.Authentication: proving the mail is really yours
Authentication answers a single question: is this sender permitted to use this domain? Providers check three mechanisms, and each proves something different. SPF authorizes sending IPs. Your domain publishes a DNS record naming which servers may send on its behalf, and the receiver compares the connecting IP against that list. SPF alone is fragile — it breaks when mail is forwarded, because the forwarding server isn’t in your record. DKIM proves message integrity. Telnyx signs each outbound message with a private key; the receiver fetches the matching public key from<selector>._domainkey.<domain> and verifies the signature. Because the signature travels with the message, DKIM survives forwarding where SPF does not. This is why DKIM is the load-bearing authentication mechanism for most senders.
DMARC ties the first two to the domain your recipient actually sees. SPF and DKIM validate technical identifiers that a recipient never reads. DMARC requires that one of them aligns with the visible From: domain, and tells receivers what to do when alignment fails.
DMARC is the only mechanism that constrains the
From: header your recipients see. A message can pass SPF and DKIM for an attacker-controlled domain while displaying your brand in the From: field — alignment is what closes that gap. This is why publishing SPF and DKIM without DMARC leaves the impersonation problem unsolved.Reputation: the accumulated record
Authentication proves identity. Reputation determines whether that identity is welcome. Providers maintain scores for both the sending IP and your authenticated domain, built from behavior over time. The signals that matter most are the ones recipients generate: opening messages, replying, moving mail out of spam — and the negative ones, marking as spam or deleting unread. Bounce rate matters heavily because sending to addresses that don’t exist is the clearest available evidence that a list was not built from genuine consent. Reputation is asymmetric. It accrues slowly through consistent, wanted mail and collapses quickly after a bad send. It is also per-provider — a strong Gmail reputation tells Microsoft nothing.Content: what the message itself signals
Content filters look for the statistical fingerprint of unwanted mail: mismatches between subject line and body, link shorteners obscuring destinations, image-only messages carrying no analyzable text, malformed HTML, and missing plain-text alternatives. The underlying logic is that legitimate senders have no reason to obscure what they’re sending. Most content heuristics detect evasion rather than specific words.Infrastructure: whether the sending setup looks legitimate
Receivers check operational hygiene: does the sending IP have a reverse DNS (PTR) record that resolves back consistently? Does the domain have valid MX records? Is TLS offered? Is volume steady, or does it spike unpredictably? Telnyx operates and maintains this layer for you. It matters to your mental model because it explains why a brand-new domain with perfect DNS still doesn’t reach the inbox reliably: the infrastructure is trusted, but your domain’s history on it is empty.The delivery lifecycle and where it fails
A Telnyx send passes through distinct stages, and knowing which stage failed determines what — if anything — you should do about it.email.queued does not mean the message reached the MTA. It fires as soon as the API has validated the request and persisted the message — before the message is produced to the internal queue and before the outbound MTA has seen it. email.sent does not mean the recipient received the message either: it means the MTA accepted the message for delivery. Remote acceptance is reported separately by email.delivered. Treating queued or sent as success is the most common source of inflated delivery numbers.Suppression: the send that never happens
When a recipient is on your suppression list, the message is not attempted at all — and the recipient is removed from the send before any per-recipient record exists. Telnyx suppresses automatically after a qualifying hard bounce or a spam complaint, so the platform enforces the list hygiene that protects your reputation. Suppressed addresses are stripped fromto, cc, and bcc during request handling, so they never get a recipient row and never produce a delivery attempt. If every recipient on the request is suppressed, the API rejects the request with recipient_suppressed and no message, recipient row, or detail record is created at all. The response includes a top-level suppressed array naming the blocked addresses.
Understanding delivery error codes
Telnyx reports failures at two distinct levels. Confusing them sends you looking in the wrong place.API-level errors (10xxx)
These occur before a message exists — your request was rejected. They are about your API call, not about deliverability.10007 is a service-wide code, not a domain-authentication signal. Several unrelated policy failures share it, so branching on the code alone will mislead you — always inspect the detail string (and, where present, source) to identify the actual cause before acting on it.10007 and reputation_suspended are the two that most often carry genuine deliverability meaning: the first frequently indicates your domain isn’t verified or your from address isn’t authorized, the second says your reputation has already degraded far enough that Telnyx stopped sending. See Error Codes for the complete reference.
Delivery-level errors
These occur after the message was accepted — the send happened and delivery failed.bounce_category appears on email.bounced events and identifies why the bounce occurred:
permanent is the default category assigned to any Bounce record — it is derived from the record type, not from the SMTP code. A permanent bounce is therefore not the same thing as a confirmed invalid address, and it does not by itself mean the recipient was suppressed. Suppression is decided separately, by narrower enhanced-code rules, and it happens asynchronously.transient as a bounce category is likewise not the same as an email.deferred event. A deferral is still being retried. A transient bounce means retrying already happened and failed — the message is permanently undelivered even though every individual failure was temporary.error_evidence is the structured error field on the Email Detail Record (EDR). It is populated for every error status — bounced, failed, deferred, expired, suppressed, and gw_reject — and is null for successful ones:
error_evidence.code is always a normalized 30xxx code — never a raw SMTP code. The raw SMTP response lives in smtp_status. If your integration matches on code == "550" it will never fire; match on code == "30001" and read smtp_status when you need the remote server’s exact response.Normalized delivery error codes (30xxx)
Raw SMTP codes are a poor integration surface: they vary per remote MX, they collide across unrelated failure modes, and they are absent entirely for failures that never reached SMTP (queue expiry, suppression, gateway rejection). Telnyx therefore normalizes every delivery failure into a small product-level taxonomy.
The status is the primary axis of classification; the SMTP code only disambiguates where one status covers both a permanent and a transient failure. A
bounced recipient carrying a 4xx response is classified 30002 (retryable) rather than 30001, because the remote server’s own code says the rejection was temporary.
The message field is the most diagnostically useful and the least structured. It carries whatever delivery detail the callback supplied, and its provenance depends on who generated the failure: an SMTP rejection carries the receiving provider’s own free text — frequently a URL explaining a block, or a specific reason the numeric code cannot convey — while an operator-initiated failure such as an admin bounce carries Telnyx-generated text instead. Do not assume the string came from the remote host. Failures that never produced a callback at all — suppression and gateway rejection — have no delivery detail to carry, so message is null there rather than fabricated.
Enhanced codes drive suppression. Telnyx uses the X.Y.Z class — not the 30xxx code — to decide whether a bounce reflects a bad address or a policy decision. Codes in the 5.1.x (bad destination address) and 5.2.x (mailbox status — disabled, full) ranges indicate a recipient-side problem and qualify for auto-suppression. Codes in the 5.7.x range are security and policy rejections and are not suppressed, because the address may be perfectly valid while your sending configuration is not. A bounce with no enhanced code at all falls back to the raw SMTP code: 5xx qualifies for suppression, anything else does not.
That distinction matters when you are diagnosing a spike in bounces. A wave of 5.1.1 responses means your list has decayed. A wave of 5.7.x responses means the receiver is rejecting your mail on security or policy grounds and the recipients themselves are probably fine.
Record status values
The EDR carries astatus field describing the recipient’s delivery outcome. For outbound mail the possible values are queued, sending, sent, deferred, delivered, bounced, failed, expired, suppressed, cancelled, and gw_reject. Inbound records use received and delivered.
Three values are easy to misread. failed means a sender-side or operator-side non-delivery — the remote MX never rejected the recipient — which is why an admin bounce maps to failed rather than bounced. expired is its own terminal status, not a flavor of failed: it means the MTA exhausted its retries and gave up (30005). gw_reject means the message was refused before entering the queue, and is never billable.
injection_timeout: a recipient state with no detail record
injection_timeout is a recipient and webhook state, not an EDR status. It occurs when the injection request to the MTA times out ambiguously — the MTA may or may not have accepted the recipient, and Telnyx cannot tell which. Retrying would risk a duplicate send, so the recipient is parked in this terminal state instead.
Because the outcome is genuinely unknown, no detail record is emitted. The recipient enters a terminal injection_timeout state. Note: injection_timeout is not currently available as a subscribable webhook event type. If the MTA did in fact accept the message, its later Reception callback reconciles the recipient to sent and a detail record is published then. If no callback ever arrives, the recipient stays in injection_timeout and no EDR is ever produced.
Reconcile on the webhook, not on the absence of a record. An
injection_timeout webhook with no corresponding EDR does not mean the message failed — it means the outcome is not yet known. Treat the delivery outcome as unknown and do not retry — a later sent transition may reconcile the state, but if no callback arrives, injection_timeout remains terminal and no definitive delivery outcome is available.Best practices, and the reasoning behind them
Authentication — Publish SPF, DKIM, and DMARC, and verify your domain. DMARC is what makes the other two meaningful to a receiver evaluating theFrom: header your recipient reads.
Reputation — Increase volume gradually and keep bounce and complaint rates low. Providers evaluate rate, not count: a hundred bounces out of a hundred sends is catastrophic, while a hundred out of a million is unremarkable.
Content — Always send a plain-text alternative alongside HTML, keep subject lines honest, and avoid obscuring links. Filters are detecting evasion; give them nothing to detect.
List hygiene — Remove hard bounces, honor unsubscribes including RFC 8058 one-click, and let suppression lists do their job. Every send to a dead address is evidence that your consent process is weak.
Monitoring — Subscribe to bounce and complaint webhooks before your first production send. Deliverability problems compound: by the time you notice degraded delivery without instrumentation, the reputation damage is already done.
What to do when delivery fails
The general rule: 4xx means wait, 5xx means stop. Telnyx handles the waiting for you, and handles the stopping by suppressing recipients whose bounces qualify under the enhanced-code rules above. Your job is the layer neither of those can address — understanding why the address was bad or the content unwanted in the first place.
Related documentation
- Deliverability and Domain Warm-up — setup and warm-up procedures
- Error Codes — complete error reference
- Webhooks & Events — event types and payloads
- Domains & DKIM — domain registration and DNS records
- Suppressions — suppression list behavior