Verify an email
Verify a single email address in real time.
POST /v1/email-verifications?timeout=30Request
Section titled “Request”Send a JSON body with the address to check.
| Field | Type | Required | Description |
|---|---|---|---|
email |
string | Yes | The address to verify, 1–320 characters. A malformed address is not a request error — it comes back as a 200 with an undeliverable verdict and sub_status: "invalid_syntax". |
source |
string | No | A free-form label for your own attribution (for example which form the address came from). |
You may also send an Idempotency-Key header (up to 200 characters). Repeating
a request with the same key returns the same verification instead of starting a
second one.
Query parameters
Section titled “Query parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
timeout |
integer | 5 |
How many seconds to hold the request open while waiting for the verdict, from 1 to 90. Values above 90 are treated as 90. A value that is not a positive whole number returns 400 {"error":"Invalid timeout"}. |
timeout only controls how long this HTTP request waits. It does not
shorten or stop the verification: if the mail server is still answering when
the timeout runs out, you get a 202 and the check keeps running. Set it to
match how long your client can wait. Automation platforms with a 30-second
step limit should send timeout=25; a script that would rather block than
poll can send timeout=90.
Repeating a request
Section titled “Repeating a request”If you POST the same address again while your earlier check of it is still
pending, you get the same id back rather than a second check. No second
probe runs and no second credit is held. The repeat waits up to its own
timeout and answers 200 if the check finishes by then, 202 if not.
This only applies while the earlier check is pending. Once it has finished, a
POST for the same address starts a new check and costs a new credit; to read
the finished verdict for free, poll by id
instead.
curl -X POST https://api.tryverifyemail.com/v1/email-verifications \ -H "Authorization: Bearer sk_your_api_key" \ -H "Content-Type: application/json" \ -d '{"email":"jane@example.com"}'const res = await fetch("https://api.tryverifyemail.com/v1/email-verifications", { method: "POST", headers: { Authorization: `Bearer ${process.env.VERIFYEMAIL_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ email: "jane@example.com" }),});const body = await res.json();import os, requests
res = requests.post( "https://api.tryverifyemail.com/v1/email-verifications", headers={"Authorization": f"Bearer {os.environ['VERIFYEMAIL_API_KEY']}"}, json={"email": "jane@example.com"},)body = res.json()A body that is not valid JSON returns 400 {"error":"Request body must be valid JSON"}; a JSON body with a missing, empty, or unknown field returns
400 {"error":"Invalid request body"}.
Response
Section titled “Response”The call answers in one of two ways, distinguished by status.
200 — completed
Section titled “200 — completed”The live check finished inside the request. The verdict sits under result —
every field is described on the result object.
{ "id": "5f1c9d2e-8b1a-4f5e-9c3d-2a7b6e4d1f08", "status": "completed", "result": { "email": "jane@example.com", "normalized_email": "jane@example.com", "verdict": "deliverable", "sub_status": "mailbox_exists", "quality_score": 95, "confidence": 92, "signals": { "syntax": "pass", "domain": "pass", "mx": "pass", "smtp": "pass", "catch_all": "pass", "role_account": "pass", "disposable": "pass", "dnsbl": "pass", "toxic": "pass", "greylisting": "pass" }, "verified_at": "2026-09-05T06:35:01.000Z" }}202 — pending
Section titled “202 — pending”The check had not finished when your timeout ran out. A slow or greylisting
mail server is the usual cause. A 202 means “not finished yet”, not
“unknown”. The verification keeps running, and the body has no result. The
API never invents a verdict because your timeout expired.
{ "id": "5f1c9d2e-8b1a-4f5e-9c3d-2a7b6e4d1f08", "status": "pending", "poll_after_ms": 2000, "next_retry_at": "2026-09-05T06:35:03.000Z"}| Field | Description |
|---|---|
poll_after_ms |
The minimum wait before you poll again, in milliseconds. |
next_retry_at |
The same wait as an absolute timestamp. |
The response also carries a Location header pointing at the poll URL,
/v1/email-verifications/{id}.
Getting the verdict after a 202
Section titled “Getting the verdict after a 202”There are three ways to get the verdict later:
- Poll by id. Call
GET /v1/email-verifications/{id}, optionally with its owntimeoutso the request waits for the result. - Send the same
POSTagain, while the check is still pending. You get the sameidback, with no second credit. Once the check has finished this no longer applies: a repeatPOSTstarts a new check and costs a new credit. - Read your history. Finished checks appear in
GET /v1/email-verificationsand on the dashboard.
See also
Section titled “See also”- Poll a pending verification — the next step when you get a
202 - The result object — every field under
result - Verify a single email — overview