Poll for a single-email validation result

Download OpenAPI spec
GET /api/v1/verify/{id}
API key required Base https://api.emailvalidator.ai 60 requests per minute per account

Fetch a single-email verification by its ID. The ID is returned by POST /api/v1/verify and appears on every list row.

The response is the SAME Verification object in both states — there is no separate "pending stub". While processing you get status: pending with result and recovery null and a result_url; once finished, status: complete and a populated result.

On this page

Parameters

path · parameters

ParameterTypeDescription
id required string · uuid Validation ID returned by POST /api/v1/verify. example: 3fa85f64-5717-4562-b3fc-2c963f66afa6

Responses

200
The verification. status: pending while still processing (null result/recovery), status: complete once finished. · application/json
401
Missing or invalid API key. · application/json
403
The API key authenticated but is not scoped for this endpoint (code: insufficient_scope). It is a 403 rather than a 401 on purpose — the credential is valid, so retrying with it can never help; a key holding the read scope is needed. · application/json
404
Validation ID not found or belongs to a different key. · application/json
429
Rate limit exceeded. · application/json
500
Unexpected server error. The body carries code internal_error plus a request_id to quote in a support request, and never any exception detail. · application/json

Response schema · 200 · Verification

A single-email verification. This ONE object is what every representation of the resource returns: the synchronous 200, the 202 that accepts an async or timed-out request, both states of GET /api/v1/verify/{id}, every row of GET /api/v1/verify, and the verify.completed webhook payload.

Two axes. status is the LIFECYCLE (pending or complete) and never carries a verdict. The verdict is result.outcome, in the same vocabulary the CSV export and the dashboard use. result and recovery are both null while pending, because a check that has not finished has reached no conclusion — the terminal unknown is a conclusion, not an absence of one.

Test and live are separate namespaces. livemode says which one this verification belongs to, and a key only ever sees resources of its own mode: a sandbox (ev_test_) key cannot list or fetch a live verification, and a live key never sees a canned sandbox one.

FieldTypeDescription
object string Always verification — the discriminator that marks this resource type. verification example: verification
id string · uuid The verification's ID, present on every representation. Pass it to GET /api/v1/verify/{id}. example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
created_at string · date-time UTC timestamp when the verification was accepted. It does not change when the verification completes, which is what makes the list's cursor stable while checks finish. example: 2025-06-10T14:02:09.180Z
livemode boolean true when the verification was submitted with a LIVE key; false when it came from an ev_test_ sandbox key and the verdict is therefore a canned test result rather than a real probe. Test and live are separate namespaces — a key only ever sees resources of its own mode — so this is constant for any one key, and it is what makes a stored response, a log line or a webhook body self-describing after the fact. example: true
status string

The verification's LIFECYCLE — and only its lifecycle:

  • pending — accepted and still running. result and recovery are both null.
  • complete — finished. result carries the verdict.

It never carries a verdict word. A client can switch on it without knowing whether the check happened to finish inside the request.

pending complete example: complete
email string The address as submitted. A recovery never replaces it. example: alice@example.com
result object · null The verdict. null while status is pending.
recovery object · null A probe-confirmed alternative address, when contact recovery found one. null while pending, and null when no recovery was surfaced.
completed_at string · date-time · null UTC timestamp when the verification finished. null while pending. example: 2025-06-10T14:02:11.432Z
credits_remaining integer · null Credit balance after this request. null for system/demo accounts, and null on list rows, webhook payloads and SSE frames — a balance is a per-request figure, so read it from GET /api/v1/credits. example: 4820
result_url string Where to fetch the finished verification. Present only while status is pending; once complete you are already holding what it would point at. example: /api/v1/verify/3fa85f64-5717-4562-b3fc-2c963f66afa6
callback_secret string

A per-verification override of the account signing secret, revealed EXACTLY ONCE — on the 202 that accepts a request carrying a callback_url. It is deliberately absent from GET /api/v1/verify/{id}, from list rows and from the webhook payload. Verifying with the account secret (whsec_…) works without it.

Shape: cs_ + 64 hex characters for a single verification (bv_ + 64 hex for a batch job). It is NOT whsec_-shaped — that prefix belongs to the ACCOUNT signing secret, a different value with a different lifetime.

example: cs_9f2a4c6e...

result · VerificationResult · object

The verdict. null while status is pending.
FieldTypeDescription
outcome string

The verification VERDICT, carried by result.outcome (and accepted by the list's outcome filter):

  • deliverable — mailbox confirmed deliverable via SMTP.
  • invalid — mailbox does not exist or hard-rejected.
  • catch-all — domain accepts all addresses; deliverability unconfirmable.
  • unknown — could not determine (DNS failure, transient error, or no SMTP probe data).
deliverable invalid catch-all unknown example: deliverable
sub_status string Additional signal within the top-level status. Empty string when none applies. Derivation is first-match: disposable > role_based > accept_all > no_dns_entries > mailbox_not_found > greylisted > mail_server_did_not_respond. "" disposable role_based accept_all no_dns_entries mailbox_not_found greylisted mail_server_did_not_respond example: ""
risk string

Deliverability risk, assessed at PROBE TIME from everything the check observed — not derived from outcome, and not derivable from the other fields in this object. It reads the SMTP conversation's real status, the domain's mail-server state, DNS transience and the address's own syntax, several of which are not reported anywhere else on this response. So it is a genuinely independent signal, and it will sometimes disagree with what outcome and details on their own would suggest.

Broadly: high for a definitive rejection, a disposable domain, a domain with no mail server, or a structurally suspect address (a quoted or commented local part); medium for an accept-all domain, a role address, a non-ASCII local part, or a mailbox whose probe was DEFERRED by the server (a 4xx temporary failure — a real, common case whose outcome is unknown); low for a free-mail domain or an address we could not verify conclusively; none for a clean, confirmed mailbox with no such signal. Treat the four values as an ordered scale rather than as a formula over the other fields.

Returned for both live and test-mode keys (a test-mode key returns the canned risk the address's local part maps to). OMITTED — not reported as none — whenever the check carries no recorded assessment. This rule is WIDER than free_email's and details': those two are withheld only when the stored probe detail cannot be read, while risk is also absent on a healthy row that has no stored detail at all (a check completed before this became a recorded value, until it is backfilled), and while a check is still pending. An absent risk means unknown, never none.

none low medium high example: none
free_email boolean Whether the domain is a known free-email provider. Derived from the stored probe detail, so it is OMITTED — not reported as false — on the rare row whose stored detail cannot be read; see details. example: false
account string Local part of the email address (before @). example: alice
domain string Domain part of the email address (after @). example: example.com
details object Low-level DNS/SMTP signal. OMITTED on the rare row whose stored probe detail exists but cannot be read — a server-side data fault. The verdict in outcome comes from a separate, intact field and stays trustworthy, so the detail is withheld rather than reported as a row of falses that would read as a confident all-clear. A row that simply has no stored detail is not that case and still returns this object with its default values.

details · VerifyDetails · object

Low-level DNS/SMTP signal. OMITTED on the rare row whose stored probe detail exists but cannot be read — a server-side data fault. The verdict in outcome comes from a separate, intact field and stays trustworthy, so the detail is withheld rather than reported as a row of falses that would read as a confident all-clear. A row that simply has no stored detail is not that case and still returns this object with its default values.
FieldTypeDescription
role boolean Whether the local part is a role alias (e.g. admin, support, noreply). example: false
disposable boolean Whether the domain belongs to a known disposable/temporary email provider. example: false
catch_all boolean Whether the domain is configured to accept all addresses. example: false
mx_found boolean Whether at least one MX record was found for the domain. example: true
mx_record string · null The highest-priority MX hostname, or null when no MX records exist. example: mail.example.com
smtp_provider string · null Detected SMTP provider name (e.g. Google, Microsoft), or null when unknown. example: Google
smtp_code integer · null SMTP response code from the final RCPT TO probe, or null when no SMTP probe was attempted. example: 250

recovery · VerificationRecovery · object

A probe-confirmed alternative address, when contact recovery found one. null while pending, and null when no recovery was surfaced.
FieldTypeDescription
email string The recovered address. Never a substitute for email — that is what you sent. example: alice@gmail.com
outcome string deliverable when a probe confirmed a mailbox at the recovered address; catch-all when the fix landed on a domain that accepts everything. Drawn from the same vocabulary as result.outcome and the CSV's Outcome column, and identical to the CSV's RecoveredOutcome cell for the same row. deliverable catch-all example: deliverable

Error responses

401 403 404 429 500 · ApiProblem · object

Standard error response shape used by all error status codes.
FieldTypeDescription
status required integer HTTP status code mirrored in the body. example: 400
code required string Stable, machine-readable error code. Branch your code on this — never on the error text, which is prose and may be reworded at any time. example: invalid_email
error required string Human-readable error message. example: Invalid email format.
param string The request field the failure is attributable to. Omitted when the failure is not about one specific field. example: email
details array of string · null Optional per-field validation messages. Null when not applicable. example: ["email: required"]
doc_url string Link to the documentation for this error code. example: https://emailvalidator.ai/docs/get-started/errors
request_id string Correlation id for this request. Quote it in a support request — it is how a single call is found in the server logs. example: 0HNCV1TQ3PLRK:00000003