Email Verification API

One POST request to find out whether an email address actually exists. Real SMTP handshakes, catch-all resolution through our proprietary resolution engine, and honest unknowns — refunded.

Real SMTP checks Catch-all resolution 120 req/min per key Unknowns refunded Bulk up to 50k

100 free credits on signup · no card required

POST /v1/verify live

Hits the same verification engine as the API. 5 free checks/day, no key needed.

Overview

This email verification API tells you whether an address can receive mail before you send to it. Every verification runs the full stack: syntax validation, MX resolution, a live SMTP handshake against the recipient's mail server, disposable-domain and role-account detection, and — where the domain accepts everything — our proprietary resolution engine that sees straight through accept-all domains and resolves catch-all addresses other APIs return as "risky".

Every response carries one of four statuses:

deliverable

The mailbox exists and accepts mail. Safe to send.

undeliverable

The mailbox does not exist or rejects mail. Sending will bounce.

risky

The address may accept mail but carries risk — e.g. an unresolvable catch-all or a disposable domain.

unknown

The server gave no usable answer (timeouts, greylisting). Never charged; refunded in bulk jobs.

Alongside the status you get a machine-readable reason plus boolean flags — is_catch_all, is_disposable, is_role_based, is_free_provider — so your application can apply its own policy (for example: send to deliverable, suppress role accounts, queue risky for review).

Quickstart

Grab a key from the dashboard, then verify your first address. Base URL: https://api.emailverificationapi.io/v1

curl https://api.emailverificationapi.io/v1/verify \
  -H "X-API-Key: ev_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"email": "jane@acme.com"}'
const res = await fetch('https://api.emailverificationapi.io/v1/verify', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.EVAPI_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ email: 'jane@acme.com' }),
});
const data = await res.json();
console.log(data.status); // "deliverable"
import os, requests

res = requests.post(
    "https://api.emailverificationapi.io/v1/verify",
    headers={"X-API-Key": os.environ["EVAPI_KEY"]},
    json={"email": "jane@acme.com"},
)
print(res.json()["status"])  # "deliverable"

Response 200

{
  "email": "jane@acme.com",
  "status": "deliverable",
  "reason": "deliverable",
  "is_catch_all": false,
  "is_disposable": false,
  "is_role_based": false,
  "is_free_provider": false,
  "duration_ms": 2840,
  "credits_used": 1,
  "credits_remaining": 4999
}

SMTP handshakes run live, so a verification typically takes 1–10 seconds; slow or greylisting servers can take up to 30. Set client timeouts accordingly.

Authentication

Authenticate every request with your secret key in the X-API-Key header. Keys are created and rotated from the dashboard; live keys are prefixed ev_live_. Keep keys server-side — never ship them in browser or mobile code.

X-API-Key: ev_live_xxxxxxxxxxxx

Requests without a valid key return 401; requests exceeding your rate limit return 429 with a Retry-After header.

Endpoints

POST /v1/verify

Verify a single email address synchronously. Charges 1 credit unless the result is unknown.

Request

{ "email": "jane@acme.com" }

Response 200

{
  "email": "jane@acme.com",
  "status": "deliverable",
  "reason": "deliverable",
  "is_catch_all": false,
  "is_disposable": false,
  "is_role_based": false,
  "is_free_provider": false,
  "duration_ms": 2840,
  "credits_used": 1,
  "credits_remaining": 4999
}
POST /v1/verify/bulk

Queue an asynchronous bulk job — up to 50,000 emails per request. Credits are charged up front; unknown rows are refunded automatically when the job completes.

Request

{ "emails": ["jane@acme.com", "ops@firma.de", "noreply@store.io"] }

Response 202

{
  "id": "job_9f2c81d4",
  "status": "queued",
  "total_emails": 18452,
  "credits_charged": 18452
}
GET /v1/verify/jobs/:id

Poll a bulk job for progress and rolling counts per status.

Response 200

{
  "id": "job_9f2c81d4",
  "status": "processing",
  "total_emails": 18452,
  "processed": 11210,
  "counts": {
    "deliverable": 8473,
    "undeliverable": 1675,
    "risky": 588,
    "unknown": 474
  }
}
GET /v1/verify/jobs/:id/results?format=csv

Download per-row results for a completed job. format=csv streams a CSV; omit it for JSON.

Response 200 text/csv

email,status,reason,is_catch_all,is_disposable,is_role_based,is_free_provider
jane@acme.com,deliverable,deliverable,false,false,false,false
ops@firma.de,deliverable,deliverable,true,false,true,false
ghost@oldcorp.com,undeliverable,undeliverable,false,false,false,false
GET /v1/verify/credits

Check your remaining credit balance. Free to call — it never consumes credits.

Response 200

{ "balance": 4999 }

Rate limits & credits

Every key is limited to 120 requests per minute. Exceeding it returns 429 with a Retry-After header — back off and retry. For high-volume cleaning, prefer one bulk job over thousands of single calls: a 50,000-row job is one request.

Billing is strictly per result: 1 credit = 1 verification. unknown results are never charged on single verifications and are refunded automatically on bulk jobs, so you only ever pay for answers.

Pricing

Start with 100 free API credits — no card required. Pay-as-you-go: buy credits in packs, top up any time, and credits never expire. Credits work across single, bulk and API verification.

Dev

$6

1,000 API credits

$6.00 / 1k credits

Growth

$380

100,000 API credits

$3.80 / 1k credits

Volume

$1,950

1,000,000 API credits

$1.95 / 1k credits

Scale

$8,500

5,000,000 API credits

$1.70 / 1k credits

Unknown verdicts are not billed — never charged on single checks and refunded automatically on bulk jobs.

Create free account — 100 API credits

FAQ

How is this different from a regex or MX check?

Syntax and MX checks only prove a domain can receive mail in principle. This email verification API opens a live SMTP connection to the recipient's mail server and walks the start of a real delivery to confirm the specific mailbox exists, then layers disposable, role-based and free-provider detection on top.

How does the API handle catch-all domains?

When a domain accepts every recipient during the SMTP handshake, the API escalates to our proprietary resolution engine — purpose-built algorithms and proprietary data sources that see straight through accept-all domains, resolving most catch-all addresses to a definitive deliverable or undeliverable instead of a generic risky.

What happens when a result is unknown?

Unknown verdicts are not billed. Single verifications returning unknown are not charged, and unknown rows in bulk jobs are refunded to your API credit balance automatically.

What are the rate and size limits?

Each API key can make 120 requests per minute. Bulk verification jobs accept up to 50,000 email addresses per job, processed asynchronously with progress polling and CSV export.

Do I need a credit card to try the API?

No. Signing up gives you 100 free API credits with no card required — one credit per verification. You can also run 5 free checks per day from the live demo on this page without an account.