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.

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.