List single-email validation results
Download OpenAPI specList the single-email validations submitted with this API key's account, newest first.
This is how a result is recovered when its id was not kept: every other read is by id,
and an id you no longer hold cannot be guessed.
In-flight checks are listed too, with status: pending and a null result — so a
verification submitted with a callback_url is findable before it finishes, not only after.
Filter on status to select one lifecycle, on outcome to select a verdict, or on both.
Only work submitted through the API is returned — validations run from the web dashboard belong to the dashboard, not to this key.
Paging — the response is a cursor-paged list object. Follow next_cursor as
starting_after to walk towards older results; pass it as ending_before to walk back
towards newer ones. has_more tells you whether another page exists in the direction you
are walking, and next_cursor is present only when it does. A cursor that will not decode
is 400 invalid_request with param naming the parameter it arrived in — answering the
first page instead would give the while (has_more) drain loop a fresh cursor forever.
Omitting the parameter is still the first page, and a cursor that decodes but points past
the end is still an empty page.
Retention — results are removed 7 days after submission. Once removed, a check is
indistinguishable from one that never existed and GET /api/v1/verify/{id} answers 404.
Parameters
query · parameters
| Parameter | Type | Description |
|---|---|---|
| limit | integer 1–100 · default 25 | Number of results to return per page. Values outside 1–100 are clamped. example: 25 |
| starting_after | string | Cursor from a previous response's next_cursor. Returns the page of results immediately after it, walking towards older results. example: MTc0OTU2NzIwMDAwMDAwMDAwfDNmYTg1... |
| ending_before | string | Cursor from a previous response. Returns the page of results immediately before it, walking back towards newer results. Ignored when starting_after is also supplied, and — like starting_after — a value that will not decode is rejected with 400 invalid_request rather than silently treated as the first page, even when starting_after would have taken precedence. example: MTc0OTU2NzIwMDAwMDAwMDAwfDNmYTg1... |
| status | string |
Return only verifications in this LIFECYCLE state. Matched case-insensitively; any other value — including a verdict word like deliverable — is a 400 naming status, rather than a silently unfiltered list. The two filters have separate vocabularies on purpose.
pending
complete
example: complete
|
| outcome | string |
Return only verifications carrying this VERDICT. Matched case-insensitively; any other value — including a lifecycle word like pending — is a 400 naming outcome. Only completed verifications can match one, since a pending check has no outcome.
deliverable
invalid
catch-all
unknown
example: deliverable
|
Responses
status filter is not one of the documented lifecycle states, the outcome filter is not one of the documented verdicts, or a supplied starting_after / ending_before cursor could not be decoded. All are code: invalid_request with param naming the offending parameter.
· application/json
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
Response schema · 200 · VerificationList
| Field | Type | Description |
|---|---|---|
| object | string |
Always list — the discriminator that marks a paged collection.
list
example: list
|
| data | array of object |
The verifications on this page, ordered newest first — in-flight ones included, with status: pending. credits_remaining is null on a list row: a balance is a per-request figure, so read it from GET /api/v1/credits.
|
| has_more | boolean | Whether more results exist beyond this page in the direction being paged. There is no total count: a cursor walk reveals it, and a per-page count would be stale on arrival. example: true |
| next_cursor | string | Opaque cursor for the next page, present only when has_more is true. Send it back as starting_after to continue forwards, or as ending_before to continue backwards. example: MTc0OTU2NzIwMDAwMDAwMDAwfDNmYTg1... |
data · Verification · array of object
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.
| Field | Type | Description |
|---|---|---|
| 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:
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
|
| 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 Shape: |
result · VerificationResult · object
null while status is pending.| Field | Type | Description |
|---|---|---|
| outcome | string |
The verification VERDICT, carried by
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 Broadly: 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
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
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.| Field | Type | Description |
|---|---|---|
| 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
null while pending, and null when no recovery was surfaced.| Field | Type | Description |
|---|---|---|
| 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
400 401 403 429 500 · ApiProblem · object
| Field | Type | Description |
|---|---|---|
| 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 |
Example response · 200
{
"object": "list",
"data": [
{
"object": "verification",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2025-06-10T14:02:09.180Z",
"livemode": true,
"status": "complete",
"email": "alice@example.com",
"result": {
"outcome": "deliverable",
"sub_status": "",
"risk": "none",
"free_email": false,
"account": "alice",
"domain": "example.com",
"details": {
"role": false,
"disposable": false,
"catch_all": false,
"mx_found": true,
"mx_record": "mail.example.com",
"smtp_provider": "Google",
"smtp_code": 250
}
},
"recovery": "openapi-json-null-sentinel-value-2BF93600-0FE4-4250-987A-E5DDB203E464",
"completed_at": "2025-06-10T14:02:11.432Z",
"credits_remaining": "openapi-json-null-sentinel-value-2BF93600-0FE4-4250-987A-E5DDB203E464"
},
{
"object": "verification",
"id": "8c1d0f22-9a44-4e31-b0aa-6f2e5c7d1234",
"created_at": "2025-06-10T14:02:10.006Z",
"livemode": true,
"status": "pending",
"email": "bob@example.com",
"result": "openapi-json-null-sentinel-value-2BF93600-0FE4-4250-987A-E5DDB203E464",
"recovery": "openapi-json-null-sentinel-value-2BF93600-0FE4-4250-987A-E5DDB203E464",
"completed_at": "openapi-json-null-sentinel-value-2BF93600-0FE4-4250-987A-E5DDB203E464",
"credits_remaining": "openapi-json-null-sentinel-value-2BF93600-0FE4-4250-987A-E5DDB203E464",
"result_url": "/api/v1/verify/8c1d0f22-9a44-4e31-b0aa-6f2e5c7d1234"
}
],
"has_more": true,
"next_cursor": "MTc0OTU2NzIwMDAwMDAwMDAwfDNmYTg1..."
}