A practical taxonomy for delivery failures
Stable delivery reason codes help developers decide whether to retry, fix DNS, clean recipients, or escalate reputation work.
Developer guide
from no_mx to ip_reputation_low, each code maps to an action
Separate transport failure from policy failure
A retryable network issue and a permanent mailbox failure should not look the same in an API response. The first belongs in a queue with backoff. The second belongs in suppression or customer action.
Stable reason codes let developers automate the right response without parsing provider-specific SMTP strings.
Use codes that map to decisions
no_mx points to recipient-domain DNS. mailbox_not_found points to the address. rate_limited suggests backoff. tls_failed points to transport security. spf_failed and dkim_failed point to sender authentication.
blocked_by_remote and ip_reputation_low are escalation signals. They require evidence, provider context, and sometimes traffic shaping rather than blind retries.
Show the same truth to users and admins
Admins need raw SMTP details and node context. Users need the cause and the next action. Both views should share the same underlying delivery reason code so support can talk from one source of truth.
Operator checklist
- Keep codes stable even if human copy changes.
- Document retry guidance for each code.
- Attach reason codes to webhook events and dashboard logs.
- Preserve raw provider responses for operator review.

