---
title: "How to interpret email verification results - Emvero"
description: "Read status, action, checks, reason codes, confidence and freshness. Use two complete examples to decide whether to allow, confirm, retry, hold or reject."
url: https://emvero.io/blog/reading-a-verification-result/
language: en
updated: 2026-10-07
---

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 2026-09-07

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.

## Read the conclusion and the recommended action

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](https://docs.emvero.io/answers/verdicts/) 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](https://docs.emvero.io/answers/reason-codes/) 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](https://emvero.io/compare/unknown-kept-apart/) 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](https://docs.emvero.io/answers/confidence/) explains the score; the [score versus evidence comparison](https://emvero.io/compare/score-vs-evidence/) 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](https://emvero.io/blog/when-to-reverify-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](https://emvero.io/guides/signup-form-validation/), 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](https://emvero.io/guides/cleaning-an-email-list/), 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](https://emvero.io/email-verification-api/) page shows how to request a check and retrieve its result.

## Terms used here

### Catch-all domain

A domain that accepts arbitrary recipient names, so an accepted address may have no individual mailbox.

### Greylisting

A receiving-server policy that temporarily defers an unfamiliar SMTP attempt; a later attempt may pass.

### Ambiguous rejection

A negative recipient reply whose cause is unclear, leaving the mailbox check inconclusive.

## Situations this applies to

### Validating an address in a signup form

Somebody is waiting on the other side of the request, so latency decides the design and a wrong rejection costs you the customer.

### Cleaning a list before a send

You are protecting the reputation of the sending domain, so the question is not which addresses are bad but which ones this send can afford.

[All articles](https://emvero.io/blog/)

## Choose what to check next.

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

Start for free
