Skip to content

Verify an email

Verify a single email address in real time.

POST /v1/email-verifications?timeout=30

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.

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.

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.

Terminal window
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"}'

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"}.

The call answers in one of two ways, distinguished by status.

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"
}
}

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}.

There are three ways to get the verdict later:

  1. Poll by id. Call GET /v1/email-verifications/{id}, optionally with its own timeout so the request waits for the result.
  2. Send the same POST again, while the check is still pending. You get the same id back, with no second credit. Once the check has finished this no longer applies: a repeat POST starts a new check and costs a new credit.
  3. Read your history. Finished checks appear in GET /v1/email-verifications and on the dashboard.