EmailVerify Pro

REST API

Complete EmailVerify Pro REST API guide: authentication, single and bulk email verification, catch-all resolution, email finder, suppression lists, and webhooks across 152 endpoints.

View as Markdown →

The REST API is the foundation — the CLI, the SDKs and the MCP server are all thin wrappers over it. Base URL:

https://emailverifypro.com

All responses are JSON. All requests that send a body use Content-Type: application/json. There are 152 endpoints; this page covers the ones almost everybody uses. The full reference lists the rest, and https://emailverifypro.com/openapi.json is the machine-readable spec.

Authentication

Pass your key in the X-API-Key header:

curl -H "X-API-Key: evp_your_key" "https://emailverifypro.com/validate?email=a@example.com"

Or as a query parameter, where headers are awkward:

curl "https://emailverifypro.com/validate?email=a@example.com&api_key=evp_your_key"

Warning. A key in a query string ends up in browser history, proxy logs and server access logs. Prefer the header.

Requests without a key still work and are rate limited by IP. A key raises your limits and attributes usage to your account. See API keys.

Verify a single address

GET /validate

The workhorse. Every signal layer, one address.

curl -H "X-API-Key: evp_your_key" \
  "https://emailverifypro.com/validate?email=someone@example.com"
ParameterTypeDefaultPurpose
emailstringrequiredThe address to verify
smtpbooltruePerform the live SMTP probe. Turning this off is much faster but far less accurate
rblbooltrueCheck the MX IP against blacklists
gravatarbooltrueLook for a Gravatar as a signal the address is real
breachboolfalseCheck breach databases — strong evidence an address existed
web_presencebooltrueLook for the address on the domain's website
domain_agebooltrueDomain registration age; very new domains are riskier
enrichboolfalseAdd the ML prediction and an activity score
suppressionbooltrueCheck your suppression list first

POST /validate

Same thing with a JSON body — use it when the address may contain characters awkward in a URL.

curl -X POST https://emailverifypro.com/validate \
  -H "X-API-Key: evp_your_key" \
  -H "Content-Type: application/json" \
  -d '{"email":"someone@example.com","breach":true,"enrich":true}'

The response

{
  "email": "someone@example.com",
  "status": "valid",
  "sub_status": "mailbox_verified",
  "confidence_score": 99,
  "deliverability": "deliverable",
  "deliverability_score": {
    "score": 96,
    "grade": "A+",
    "band": "excellent",
    "can_send": true,
    "recommendation": "Send",
    "primary_risk": null,
    "email_type": "personal",
    "breakdown": {
      "mx_found": 10,
      "smtp_valid": 25,
      "corporate_domain": 5,
      "name_pattern": 5
    }
  },
  "account": "someone",
  "domain": "example.com",
  "mx_found": true,
  "mx_records": ["aspmx.l.google.com"],
  "smtp_provider": "google",
  "smtp_response_code": "250",
  "catch_all": false,
  "is_disposable": false,
  "is_role": false,
  "is_free": false,
  "did_you_mean": null
}
FieldWhy you care
deliverability_score.can_sendThe decision. Boolean, already weighs every signal
deliverability_score.score0–100, if you want your own threshold
statusRaw SMTP verdict: valid, invalid, accept_all, unknown
sub_statusWhy — e.g. mailbox_verified, mailbox_not_found, catch_all_address
catch_allThe domain accepts everything; per-address proof is impossible
is_disposableTemporary/burner provider
is_rolesupport@, info@, sales@ — real, but not a person
did_you_meanTypo suggestion, e.g. gmial.comgmail.com

Verify many addresses

POST /validate/bulk — synchronous, up to 100

curl -X POST https://emailverifypro.com/validate/bulk \
  -H "X-API-Key: evp_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "emails": ["a@example.com", "b@example.com"],
    "deduplicate": true,
    "check_suppression": true,
    "max_concurrent": 10
  }'
{
  "total": 2,
  "processing_time_ms": 8652,
  "summary": {"valid": 1, "invalid": 1},
  "results": [
    {"email": "a@example.com", "status": "valid", "confidence_score": 95},
    {"email": "b@example.com", "status": "invalid", "sub_status": "mailbox_not_found"}
  ]
}

The whole call blocks until every address finishes, so it takes as long as the slowest one. For more than about 25 addresses, prefer the async endpoint.

POST /validate/bulk/async — a job you poll

curl -X POST https://emailverifypro.com/validate/bulk/async \
  -H "X-API-Key: evp_your_key" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["a@example.com", "b@example.com"]}'
{"job_id": "job_a1b2c3", "status": "queued", "total": 2}
curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/jobs/job_a1b2c3

Poll every few seconds until status is completed, then read results. GET /jobs/{job_id}/dead-letter lists addresses that failed permanently, and POST /jobs/{job_id}/retry-dead-letter re-queues them.

POST /validate/bulk/turbo

Same shape as /validate/bulk, tuned for throughput over per-address depth. Use it when you are cleaning a very large list and can accept slightly lower confidence.

Faster, cheaper checks

EndpointCostUse when
GET /validate/syntaxfree, instantForm validation — is it even a well-formed address?
GET /validate/quickfastDNS and MX only, no SMTP probe
GET /validate/fastfastCached result if present, otherwise a shallow check
GET /validatefullYou are about to send mail to this address
curl "https://emailverifypro.com/validate/syntax?email=not-an-email"
{"email": "not-an-email", "valid": false, "normalized": "", "did_you_mean": null}

Catch-all domains

A catch-all domain accepts mail for every address, so no verifier on earth can prove a specific mailbox exists there over SMTP. When status is accept_all, resolve it with additional signals:

curl -X POST https://emailverifypro.com/resolve-catchall \
  -H "X-API-Key: evp_your_key" \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@catchall-example.com"}'

This runs a nine-signal pipeline — Microsoft credential probing, LinkedIn presence, breach records, Gravatar, domain cohort behaviour and more — and returns a resolved verdict where it can.

Warning. Treat accept_all as its own risk tier, not as a pass or a fail. Roughly a quarter of business domains are catch-all.

Finding an address

curl -X POST https://emailverifypro.com/find-email \
  -H "X-API-Key: evp_your_key" \
  -H "Content-Type: application/json" \
  -d '{"domain":"example.com","first_name":"Jane","last_name":"Doe"}'

Detects the domain's naming convention (first.last@, flast@, first@) from known addresses, then constructs and verifies the most likely candidates.

Related: GET /domain-formats/{domain} returns the learned pattern on its own.

Suppression list

Stop sending to addresses that bounced, complained or unsubscribed.

curl -X POST https://emailverifypro.com/suppression/add \
  -H "X-API-Key: evp_your_key" \
  -H "Content-Type: application/json" \
  -d '{"email":"unsubscribed@example.com","reason":"unsubscribe"}'

curl -H "X-API-Key: evp_your_key" \
  "https://emailverifypro.com/suppression/check?email=unsubscribed@example.com"

With check_suppression: true (the default), bulk verification skips suppressed addresses automatically.

Feedback improves accuracy

Report real outcomes and the model learns from them:

curl -X POST https://emailverifypro.com/bounce \
  -H "Content-Type: application/json" \
  -d '{"email":"bounced@example.com","bounce_type":"hard"}'

curl -X POST https://emailverifypro.com/delivered \
  -H "Content-Type: application/json" \
  -d '{"email":"delivered@example.com"}'

Your ESP can post these directly — there are ready-made receivers at /webhooks/sendgrid, /webhooks/ses, /webhooks/postmark and /webhooks/mailchimp.

Account and usage

curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/me/usage    # quota remaining
curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/me/stats    # verification statistics
curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/me/recent-verifications

Errors

{"detail": "Invalid or revoked API key"}
CodeMeaningDo this
200Success
401Key missing, invalid or revokedCheck the key. If you just created it, wait up to 2 minutes
404No such resource, or it belongs to another account
422Invalid parametersThe body names the offending field
429Rate limitedBack off and retry; the SDKs do this automatically
500Server errorRetry once

Full detail in errors and limits.

Machine-readable specs

OpenAPI 3.1https://emailverifypro.com/openapi.json
Interactive explorerhttps://emailverifypro.com/docs
Tooling manifesthttps://emailverifypro.com/tooling
These docs as Markdownhttps://emailverifypro.com/llms-full.txt

Generate a client for any language straight from the spec:

npx @openapitools/openapi-generator-cli generate \
  -i https://emailverifypro.com/openapi.json -g go -o ./emailverify-go