API reference / Email verification
Verify email addresses
Written and maintained by The ProspectAPIs team
POST/v1/email/verify
POST /v1/email/verify is the ProspectAPIs operation verifyEmails, in the Email verification group of the REST API. Check 1 to 25 email addresses for deliverability. Each result has a status of valid, invalid, catch-all or unknown. A valid or invalid result is charged at the verification price; catch-all and unknown results are free (the charged and free statuses are listed in GET /pricing under email_verification). A paced or timed-out check returns unknown, free. When the balance covers only some addresses, the call verifies as many as it can pay for, the rest come back unknown with reason not_checked_insufficient_credits, free, and the response carries X-Result-Capped: balance. A balance that covers none answers 402. Cost: $0.004 per valid or invalid result; catch-all and unknown are free. Send your API key as a Bearer token in the Authorization header.
How this fits with the rest of the email verification API, with worked examples, is in the email verification guide.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| Idempotency-Key | header | string | Make a retry safe: the same key and body within 24 hours replays the first answer, unbilled. |
Request body
JSON (EmailVerifyRequest).
| Field | Type | Description |
|---|---|---|
| emails required | array of any | 1 to 25 addresses. An item may be an object with first_name and last_name to also check the address against the person's name (flag name_match). |
| depth | string: full, quick | full checks the mailbox; quick never contacts the mail server (DNS, lists and recent results only) and costs $0.001 per address, whatever the status. Default "full". |
{
"emails": [
"jane@acme.com",
"sales@example.com"
]
}Responses
| Status | Meaning |
|---|---|
| 200 | One result per address. |
| 400 | The request was invalid (e.g. a bad filter or input); nothing was charged. |
| 401 | The API key is missing or invalid. |
| 402 | Out of credits. The body carries top_up_url; nothing was charged. |
| 429 | Too many requests; retry after the window. |
Every error answers with the same JSON body, an error string and sometimes a code; the errors page lists each status and when it happens. A per-key 429 carries Retry-After; see rate limits.
200 response fields
One result per address. The body is a EmailVerifyResponse.
| Field | Type | Description |
|---|---|---|
| data required | array of EmailVerifyResult | |
| data[].email required | string | |
| data[].status required | string: valid, invalid, catch-all, unknown | |
| data[].reason required | string | Why the address got its status, e.g. not_checked_insufficient_credits. |
| data[].reason_text required | string | The reason in plain words. |
| data[].score required | integer | How likely mail to this address is to arrive, from every signal the check returned. 0 to 100. |
| data[].recommendation required | string: send, send_with_caution, retry_later, do_not_send | The action to take with this address. |
| data[].charged required | boolean | Whether this result was billed. |
| data[].flags required | array of string | |
| data[].smtp_code required | integer or null | The mail server's reply code, when the check reached one. |
| data[].catch_all_tier required | string or null | For a catch-all domain, how likely the address is to be real. |
| data[].did_you_mean | string or null | A likely typo of a common mail domain, for example gmail.com for gmial.com. |
| data[].mail_provider | string or null: google, microsoft, yahoo, proofpoint, mimecast, other, | Who runs the domain's mail. |
| data[].checked_at | string (date-time) | When the mail server was asked; for a cached result, when that check ran. |
| data[].cache_age_days | integer | Present when the result came from a check of the same address in the last 30 days (valid) or 90 days (invalid): its age in days. Billed like a fresh check. |
| count required | integer | Results returned. |
| charged_count required | integer | Results billed. |
| amount_usd required | number | What this call cost. |
| Header | Meaning |
|---|---|
| X-Credits-Remaining | USD credits left after this call settles. |
| X-Result-Capped | Present and set to balance when some addresses were not checked because the balance ran out; those come back unknown with reason not_checked_insufficient_credits, free. |
Code samples
Each sample sends the same request. Set PROSPECTAPIS_KEY in your environment first. Values come from the spec's examples; replace them with your own.
curl -X POST https://api.prospectapis.com/v1/email/verify \
-H "Authorization: Bearer $PROSPECTAPIS_KEY" \
-H "Content-Type: application/json" \
-d '{ "emails": [ "jane@acme.com", "sales@example.com" ] }'const res = await fetch("https://api.prospectapis.com/v1/email/verify", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PROSPECTAPIS_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"emails": [
"jane@acme.com",
"sales@example.com"
]
}),
});
if (!res.ok) throw new Error(`${res.status}: ${(await res.json().catch(() => ({}))).error ?? res.statusText}`);
const data = await res.json();
console.log(data);import os, requests
res = requests.post(
"https://api.prospectapis.com/v1/email/verify",
headers={"Authorization": f"Bearer {os.environ['PROSPECTAPIS_KEY']}"},
json={
"emails": ["jane@acme.com", "sales@example.com"],
},
timeout=30,
)
res.raise_for_status()
data = res.json()
print(data)Billing
Billing reserves before it serves: the call holds what it may cost, serves at most what that hold covers, and refunds the rest when the response closes. Any non-2xx answer refunds the whole hold, so a failed call costs nothing. The response reports your balance in X-Credits-Remaining.
Related
The email verification guide covers this area end to end. Previous operation: Poll a research brief. Next operation: Your email verification stats. Every operation, grouped by area, is on the API reference index.
Create a free account to get a key, then run the samples above with your own values (this call acts for real, so use real inputs).
Was this page helpful?