Result Statuses

Every validation result tells you what it means for sending in four fields: status, sub_status, explanation and recommended_action. This page lists every value they can have.


The fields

The four fields are the last fields of every result: from the validation endpoint, from the getInfo tool of the MCP server, in the JSON results of bulk jobs and with sandbox keys.

{
    ...
    "status": "invalid",
    "sub_status": "mailbox_not_found",
    "explanation": "The mail server said that this mailbox does not exist.",
    "recommended_action": "suppress"
}
  • Name
    status
    Type
    string
    Description

    What the result means for sending: valid, invalid, catch_all, risky, do_not_mail or unknown.

  • Name
    sub_status
    Type
    string or null
    Description

    Why the result has its status. null for a plain valid result.

  • Name
    explanation
    Type
    string
    Description

    One fixed English sentence per sub_status that you can show to people. It never quotes the mail server's reply.

  • Name
    recommended_action
    Type
    string
    Description

    What to do with the address: send, send_with_caution, suppress or retry_later.

Statuses

statusMeaningrecommended_action
validThe mailbox existssend; send_with_caution for a role address or a possible typo
invalidMail to the address bounces: the format is not valid, the domain does not accept mail, or the mailbox does not existsuppress
catch_allThe domain accepts mail for any address, so whether this mailbox exists cannot be confirmedsend_with_caution
riskyThe mailbox may exist, but sending to it is a risk. Live validation returns it for a full mailboxretry_later for a full mailbox; send_with_caution for the risky sandbox addresses
do_not_mailThe address belongs to a disposable (temporary) email providersuppress
unknownWe could not get a definite answer from the mail serverretry_later; send_with_caution when the mail server's anti-spam system blocked the check permanently

Reserved statuses

spamtrap and abuse are reserved for future risk data (spam traps and addresses known to complain). They are not returned yet. If your code switches on status, give them a branch now, for example the same as do_not_mail.

Sub-statuses

sub_statusstatusexplanationrecommended_action
nullvalidThe mail server confirmed that this mailbox exists.send
relay_addressvalidThe address is a forwarding alias of a privacy relay service (such as Apple Hide My Email); mail reaches the owner's own inbox.send
aliasvalidThe mailbox exists; the +tag in the address is delivered to the same mailbox as the address without it.send
role_basedvalidThe mailbox exists, but it is a role address (such as info@ or support@), usually read by a team rather than one person.send_with_caution
possible_typovalidThe mailbox exists, but the address looks like a typo; see did_you_mean for the likely intended address.send_with_caution
 
failed_syntax_checkinvalidThe address is not a valid email address.suppress
does_not_accept_mailinvalidThe domain declares that it does not accept email (null MX record).suppress
no_dns_entriesinvalidThe domain does not exist or has no mail server, so mail to it cannot be delivered.suppress
unroutable_ipinvalidThe domain's mail server has only private or reserved IP addresses, which cannot be reached from the internet.suppress
mailbox_not_foundinvalidThe mail server said that this mailbox does not exist.suppress
mailbox_disabledinvalidThe mail server said that this mailbox is disabled or inactive.suppress
 
accept_allcatch_allThe domain accepts mail for any address (catch-all), so whether this mailbox exists cannot be confirmed.send_with_caution
 
mailbox_fullriskyThe mailbox exists but is full; mail bounces until its owner frees up space.retry_later
nullriskyThe mailbox may exist, but sending to it is a risk. (Sandbox keys only.)send_with_caution
 
disposabledo_not_mailThe address belongs to a disposable (temporary) email provider.suppress
 
antispam_systemunknownThe mail server's anti-spam system refused the check, so the mailbox could not be verified.retry_later when the block was temporary, send_with_caution when it was permanent
greylistedunknownThe mail server asked to try again later (greylisting), so the mailbox could not be verified yet.retry_later
mail_server_temporary_errorunknownThe mail server reported a temporary problem, so the mailbox could not be verified.retry_later
timeout_exceededunknownThe mail server did not answer in time, so the mailbox could not be verified.retry_later
failed_smtp_connectionunknownThe domain's mail server could not be reached, so the mailbox could not be verified.retry_later
forcible_disconnectunknownThe mail server closed the connection during the check, so the mailbox could not be verified.retry_later
dns_lookup_failedunknownThe domain's DNS servers failed to answer the mail server lookup, so the mailbox could not be verified.retry_later
exception_occurredunknownThe check failed on our side, so the mailbox could not be verified.retry_later

An anti-spam block that is permanent says something about our connection to the mail server, not about the mailbox, which is why it is send_with_caution rather than retry_later.

New sub_status values may be added. Handle a value you do not know by its status and recommended_action.

When several apply

A result has one status and one sub-status. When more than one applies, the first match in this order wins:

  1. The address has no valid format, or the mail server or DNS showed that mail to it bounces: invalid.
  2. The address belongs to a disposable email provider: do_not_mail. This applies even when the mail server gave no answer, but not to privacy relay services (see 5), which are on some disposable lists.
  3. The mail server gave no definite answer: unknown.
  4. The mailbox is full: risky / mailbox_full.
  5. The address belongs to a privacy relay service: valid / relay_address, even when disposable is true.
  6. The domain is a catch-all domain: catch_all / accept_all.
  7. The address is a role address: valid / role_based.
  8. There is a did_you_mean suggestion: valid / possible_typo.
  9. The address has a +tag: valid / alias.

For example, info@ on a catch-all domain is catch_all, not role_based; the role field is still true.

Status and state / reason

status and sub_status come from the same check as state and reason, which are still returned. They give a finer breakdown: reason low_deliverability, for example, can mean a catch-all domain, a disposable address or a full mailbox, and status tells them apart. The usual combinations:

statereasonstatus (sub_status)
deliverablevalid_mailboxvalid (null, relay_address, alias or possible_typo)
deliverablelow_qualityvalid (role_based)
deliverablelow_deliverabilitycatch_all (accept_all), do_not_mail (disposable) or risky (mailbox_full)
 
undeliverableinvalid_formatinvalid (failed_syntax_check)
undeliverableinvalid_mxinvalid (no_dns_entries, does_not_accept_mail or unroutable_ip)
undeliverableinvalid_mailboxinvalid (mailbox_not_found or mailbox_disabled)
 
unknownunavailable_smtpunknown (antispam_system, greylisted or mail_server_temporary_error)
unknowntimeoutunknown (timeout_exceeded, or exception_occurred when our validation service could not be reached)
unknownno_connectunknown (failed_smtp_connection or forcible_disconnect)
unknownunexpected_errorunknown (dns_lookup_failed or exception_occurred)

A disposable address is do_not_mail whatever its state, unless it is undeliverable or belongs to a privacy relay service. What a check costs depends on state and reason, not on status; see Rate Limit & Quotas.

Catch-all on every plan

status is catch_all for an address on a catch-all domain on every plan, whether or not you set the catch_all parameter. The catch_all field itself stays null unless you send catch_all=1 on a plan that includes catch-all detection.

recommended_actionWhat to do
sendSend to the address.
send_with_cautionThe address exists or may exist, but carries a risk. Decide by sub_status whether it fits your use: for example, ask a user who signs up with a possible_typo address to confirm it, or send to catch_all addresses in a separate, smaller batch.
suppressDo not send to the address.
retry_laterCheck the address again later. The mail server may answer next time, and a full mailbox may be emptied.

Bulk jobs

The JSON results of bulk jobs have all four fields. The CSV results have emailvalidation_status, emailvalidation_sub_status and emailvalidation_recommended_action as their last three columns; the explanation is in the JSON results only. The results of jobs that finished before these fields were added were saved then: they have only the earlier 15 fields and columns.

Testing

Sandbox keys return these fields too. Their test addresses cover each status, including a full mailbox, a greylisted check and an anti-spam block.