Skip to main content

Email Verification

Check whether an email address is valid and likely deliverable before you send to it. Verification runs a series of cheap-to-expensive checks (syntax, your suppression/bounce history, disposable/role detection, and an MX lookup) and caches results to avoid repeated lookups.

POST /api/v1/emails/verify
tip

For the full request/response schema, see the interactive API Reference at /docs on your Posta instance.

note

No SMTP probe is performed, so mailbox existence is never confirmed — checks.smtp is always reported as "skipped". A valid result means the address is syntactically correct and the domain accepts mail, not that the specific mailbox exists.

Request​

curl -X POST http://localhost:9000/api/v1/emails/verify \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com"
}'
FieldTypeDescription
emailstring (required)The address to verify. Validated as an email format; a syntactically malformed address is rejected with 400 before any lookup.

Query parameters​

ParameterTypeDescription
freshboolWhen true, bypasses the cache and re-checks the address. Example: ?fresh=true.

Checks performed​

Verification runs the following checks in order, returning early once the verdict is conclusive:

  1. Syntax — the address is parsed; a malformed address is conclusively invalid.
  2. Suppression / bounce history (per workspace, no network) — if the address is on your suppression list or has previously hard-bounced for you, it is conclusively invalid for your account.
  3. Disposable detection — the domain is matched against a known set of throwaway/disposable providers. A match short-circuits to disposable without a DNS lookup.
  4. Role-account detection — the local part is matched against role addresses (e.g. info, admin, support); a match downgrades the verdict to risky.
  5. MX lookup — the domain's mail exchangers are resolved. A domain with no MX (and no A/AAAA fallback) is invalid. Per RFC 5321, a domain with only an A/AAAA record is treated as having an implicit MX.

The verdict precedence is: invalid syntax → disposable → no MX → role account (risky) → valid.

Cache behavior​

  • The intrinsic result (syntax, disposable, role, MX) is cached in Redis per address, and MX answers are cached per domain. The same address and domain are not re-checked on every call.
  • The per-workspace flags (suppressed, previously_bounced) are always re-evaluated on each request and layered onto the (possibly cached) intrinsic result, so they reflect your current state even on a cache hit.
  • cached is true in the response when the intrinsic result came from the cache.
  • Pass ?fresh=true to bypass the cache and recompute the intrinsic result.

Response​

{
"success": true,
"data": {
"email": "user@example.com",
"status": "valid",
"score": 90,
"checks": {
"syntax": true,
"mx": true,
"disposable": false,
"role_account": false,
"smtp": "skipped"
},
"reason": "",
"mailbox_verified": false,
"suppressed": false,
"previously_bounced": false,
"cached": false,
"checked_at": "2026-05-31T12:00:00Z"
}
}
FieldTypeDescription
emailstringThe normalized (lowercased, trimmed) address that was checked.
statusstringOverall verdict: valid, invalid, risky, disposable, or unknown.
scoreintConfidence score (0–100). Higher is better; e.g. 90 valid, 60 role account, 10 disposable, 0 invalid.
checksobjectIndividual check outcomes (see below).
reasonstringHuman-readable explanation when the address is not plainly valid. Omitted when empty.
mailbox_verifiedboolAlways false — no SMTP RCPT probe is performed.
suppressedboolThe address is on your workspace's suppression list.
previously_bouncedboolThe address has previously hard-bounced for your workspace.
cachedboolWhether the intrinsic result was served from cache.
checked_atstringTimestamp (UTC) of when the result was computed.

checks object​

FieldTypeDescription
syntaxboolThe address is syntactically valid.
mxboolThe domain has resolvable MX (or A/AAAA fallback) records.
disposableboolThe domain is a known disposable/throwaway provider.
role_accountboolThe local part is a role address (e.g. info@, admin@).
smtpstringAlways "skipped" — no SMTP probe is performed.

Status values​

StatusMeaning
validSyntax OK and the domain accepts mail (mailbox not probed).
invalidDefinitely undeliverable (bad syntax, no MX, suppressed, or previously bounced).
riskyDeliverable but discouraged, e.g. a role-based address.
disposableA throwaway/disposable email provider.
unknownCould not be determined (e.g. a transient DNS error).

Errors​

StatusWhen
400The email field is missing or not a valid email format.
404Email verification is disabled on this instance.
429The per-user hourly verification rate limit was exceeded.