Skip to content

Verdicts and pending

status identifies either a completed technical conclusion or work still in progress. There are four terminal statuses: deliverable, undeliverable, risky and unknown. pending is a separate state while evidence is being gathered.

status What it means Typical action
deliverable Mail is routable and a destination accepted this recipient, with no overriding risk signal. allow
undeliverable A deterministic failure: invalid syntax, a domain that does not exist, or a null MX record declaring that the domain accepts no mail. reject
risky The recipient may be accepted, but a signal changes how it should be handled - a disposable domain, catch-all behaviour or a mailbox problem. allow or allow_with_email_confirmation, depending on the evidence
unknown No safe determination was possible. allow_with_email_confirmation

pending means recipient evidence is queued or in flight. It is not a final verdict; poll for the completed result after the returned interval. Do not use it as an address decision.

A 250 to RCPT TO does not prove a mailbox exists. It can come from a domain that accepts every recipient, a gateway that validates after acceptance, a provider that hides mailbox existence as a matter of policy, or a system that accepts now and bounces later. A 550 does not prove a mailbox does not exist either - 5.7.x is usually a decision about the sender.

Collapsing that into exists: true|false would be a claim the protocol cannot support. Everything else on this page follows from refusing to make it.

status is what the evidence says. action is what a registration flow should probably do about it. They are separate fields because different products weigh the same evidence differently: a disposable domain is a hard no for a paid trial and completely fine for a newsletter.

There are three actions and there is deliberately no fourth:

  • allow - proceed.
  • allow_with_email_confirmation - proceed, behind a confirmation message. This is the answer to almost everything uncertain, and it is not a hedge: confirmation is the only thing that establishes control of a mailbox anyway.
  • reject - refuse.

Nothing more interactive than that is recommended, because anything more is your layer rather than ours.

unknown is the correct answer far more often than it feels like it should be. Policy blocks, timeouts, greylisting, TLS failures and providers that decline to answer all produce it, and every one of them is a statement about the conversation rather than about the person signing up.

A mailbox-not-found SMTP reply is also inconclusive under the current policy: it returns unknown, allow_with_email_confirmation and SMTP_RECIPIENT_REJECTED_AMBIGUOUS. It does not turn the address into a deterministic failure, even if a provider profile treats the reply as specific to the recipient.

Unavailable evidence can produce a completed unknown result. An HTTP error is a separate request or service failure, not an address verdict; see Errors. Keep unknown separate from undeliverable so that uncertainty does not silently become a rejection.

Use reason_codes if you want to distinguish kinds of unknown. Every code is tagged with what it is evidence about, and four of the groups say plainly that they are about us and not about the address: see Reason codes.

The verdict is a summary. checks reports each question separately:

Field Values
syntax valid, invalid
domain valid, invalid, unknown
mail_routing valid, invalid, unknown
smtp accepted, rejected, skipped, unknown, pending
accept_all yes, no, unknown
disposable boolean
role_account boolean
public_provider boolean
smtp_utf8_required boolean

skipped and unknown under smtp are not the same thing, and the difference is worth branching on: skipped means no probe was sent - we declined, or you bought the shallower depth - while unknown means a conversation happened and established nothing.

public_provider answers in one direction only

Section titled “public_provider answers in one direction only”

true says the domain belongs to a provider that hands mailboxes to the general public - Gmail, Outlook, Posteo, an ISP’s consumer mail - so the address identifies nobody in particular.

false says only that nothing established it. The domain may be a company’s, or it may be one of the long tail of small providers no list reaches. There is deliberately no corporate flag beside this one, because we cannot earn one: a list of every public provider on earth does not exist, and the field that claimed to be its complement would be wrong about exactly the domains you would most want it to be right about. Reading false as “this is a work address” is the misreading to guard against.

The asymmetry is on purpose rather than a gap to be closed later. A wrong true tells you an employee’s work address is a personal one; a missing entry costs you only the signal. So the list covers the providers people actually use and does not chase the tail.

It is not a quality judgement, and it never moves a verdict. A Gmail address is a perfectly good address. The signal exists for products that treat a personal mailbox differently from a company one - a B2B trial, a sales lead, an invoice address - and that is a business decision the field informs rather than makes.

It costs nothing to obtain at either depth. It is read from the address alone, before anything is resolved or asked of a destination, so it is present on a domain-depth answer and on a pending one exactly as it is on a finished full check. It is also available on its own, free and without a verification, through the public-provider lookup.

id names one conclusion. A terminal result never changes for a given identifier: re-checking an address that does new work produces a new identifier or a new generation, so you are never contradicted about something you were already told. A re-check answered from cache keeps the original identifier, which is the same rule from the other side - the same conclusion keeps the same name.