Email checks and Domain Intelligence share one credit balance. See how credits work

Start for free

Blog

How to interpret an email verification result

A verification response separates its conclusion, recommendation, evidence, and age. Read those fields in the right order before you accept or reject an address.

Published

On this page

To interpret an email verification result, first check whether it is finished. Poll pending; for a completed result, read status and action, then use reason_codes and checks to understand the decision. confidence summarises the evidence, while freshness tells you when it was collected.

Keep those fields together. An address with weak evidence needs a different response from an address whose input or domain gives a definite reason to reject it.

Emvero has four terminal statuses. The separate pending state means work is still queued or in progress.

status What the result establishes What to do next
deliverable The recipient was accepted and no overriding risk signal changed the conclusion. Follow action, normally allow; delivery and ownership remain unproven.
risky A signal changes how the address should be handled, such as disposable or catch-all evidence. Read the cause and the action: either allow or allow_with_email_confirmation may apply.
undeliverable A deterministic rejection reason was found, such as invalid input, DNS_NXDOMAIN or null MX. Follow reject and ask for a corrected or different address when appropriate.
unknown The evidence does not settle the address. Consider confirmation, later checking or holding it aside, according to the cause.
pending The verification has not finished. Retrieve the same check after retry_after_ms before applying a terminal-result rule.

The verdict reference describes the fields. A status summarises the technical evidence; an action recommends a workflow. They are not interchangeable. A disposable address can be risky with allow, while established catch-all behaviour can produce risky with allow_with_email_confirmation.

A negative SMTP observation needs care too. Emvero currently reports mailbox-not-found probe evidence as unknown with SMTP_RECIPIENT_REJECTED_AMBIGUOUS. Its action is allow_with_email_confirmation. The probe is not sufficient evidence for a rejection like a deterministic syntax or domain failure.

Find the cause in reason_codes and checks

reason_codes contains machine-readable names for observations and limits. SMTP_RCPT_ACCEPTED concerns recipient acceptance; DISPOSABLE_DOMAIN concerns a domain attribute; DNS_NXDOMAIN records a missing domain; SMTP_GREYLISTED records a temporary SMTP deferral. Read which part of the process the code describes before making it a rule about an address.

A destination-policy restriction describes what a remote server allowed the probe to learn. A service failure describes trouble in the verifier. Neither proves a bad mailbox. The reason-code reference owns the complete vocabulary. Codes are stable identifiers, but new ones can be added: retain an unfamiliar value and use a fallback rather than rejecting on its name alone.

The checks fields show how far the check got:

  • syntax is valid or invalid. domain and mail_routing can also be unknown.
  • smtp is accepted, rejected, skipped, unknown or pending. A skipped stage did not run. A check with smtp: rejected can coexist with overall unknown.
  • accept_all is yes, no or unknown.
  • disposable, role_account, public_provider and smtp_utf8_required describe address or domain attributes.

For example, mail_routing: valid with smtp: unknown points to a different gap from domain: unknown. The first has routing evidence; the second has not settled the domain. Use the cause to decide whether another check could help. The unknown versus undeliverable comparison covers that narrower decision.

Use confidence and freshness within their limits

confidence is an evidence score from 0 to 1. It is not a calibrated delivery probability: 0.7 does not mean that 70% of messages will arrive. A rule such as confidence > 0.85 cannot establish ownership or guarantee delivery either. Use it for sorting within a status or ordering a review queue. The confidence documentation explains the score; the score versus evidence comparison shows why it cannot replace the other fields.

freshness records separate DNS and SMTP observation times:

{
  "freshness": {
    "dns_checked_at": "2026-09-05T09:14:22Z",
    "smtp_checked_at": "2026-09-05T09:14:23Z"
  }
}

These are the times the evidence was collected, not the time you received the response. A cached answer keeps its original timestamps. Choose an acceptable age for your use case, and inspect the timestamps when asking again: another request can return the same cached evidence. The guide on when to reverify an email list explains the policy choice.

Example: an accepted disposable address

This complete response is illustrative, with a reserved example domain. It is not a live check or a measurement of a particular provider.

{
  "id": "00000000-0000-4000-8000-000000000001",
  "generation": 1,
  "email": "person@disposable.example",
  "normalized": { "domain": "disposable.example", "ascii_domain": "disposable.example" },
  "status": "risky",
  "confidence": 0.85,
  "action": "allow",
  "checks": {
    "syntax": "valid",
    "domain": "valid",
    "mail_routing": "valid",
    "smtp": "accepted",
    "accept_all": "unknown",
    "disposable": true,
    "role_account": false,
    "public_provider": false,
    "smtp_utf8_required": false
  },
  "reason_codes": ["SMTP_RCPT_ACCEPTED", "DISPOSABLE_DOMAIN"],
  "freshness": {
    "dns_checked_at": "2026-09-05T09:14:22Z",
    "smtp_checked_at": "2026-09-05T09:14:23Z"
  }
}

The SMTP recipient was accepted, but DISPOSABLE_DOMAIN changes the status to risky. The action remains allow. A temporary mailbox can work technically while its durability conflicts with your product’s needs.

Decide that business rule separately. You might accept it for a newsletter or ask for a durable address for a paid trial. Keep the returned evidence intact so the policy decision does not masquerade as a failed technical check.

Example: a greylisted probe

This second complete response is illustrative too. Syntax and routing passed, but the receiving server deferred the session.

{
  "id": "00000000-0000-4000-8000-000000000002",
  "generation": 1,
  "email": "person@greylisted.example",
  "normalized": { "domain": "greylisted.example", "ascii_domain": "greylisted.example" },
  "status": "unknown",
  "confidence": 0.4,
  "action": "allow_with_email_confirmation",
  "checks": {
    "syntax": "valid",
    "domain": "valid",
    "mail_routing": "valid",
    "smtp": "unknown",
    "accept_all": "unknown",
    "disposable": false,
    "role_account": false,
    "public_provider": false,
    "smtp_utf8_required": false
  },
  "reason_codes": ["SMTP_GREYLISTED"],
  "freshness": {
    "dns_checked_at": "2026-09-05T09:14:22Z",
    "smtp_checked_at": "2026-09-05T09:14:23Z"
  }
}

SMTP_GREYLISTED leaves the result unknown. It neither establishes the mailbox nor proves it absent. In a signup form, follow the action and have your application send confirmation when access matters; Emvero’s probe sends no email. A later check may add evidence, without a promised outcome.

During email-list cleaning, retain the address and its reason in a separate group until you decide whether to recheck or hold it. Automatically sending to every unknown address assumes more than this response establishes.

Keep the decision trace with the address

Poll unfinished checks first. For terminal results, use action as the starting branch, reason_codes for a narrower policy decision, and checks to diagnose what remains untested or uncertain. Use confidence for ordering and freshness to judge the age of the inputs.

Store the evidence with your decision so you can explain a later acceptance, confirmation request or rejection. The email verification API page shows how to request a check and retrieve its result.

Choose what to check next.

Run a check from your account and inspect the evidence in its result.