API Documentation v1

Verify email addresses in real-time using SMTP probing, MX analysis, and catch-all detection. Integrates in minutes with any language.

Authentication

Every API request requires your API key. Pass it in the Authorization header:

Authorization: Bearer ev_live_YOUR_API_KEY_HERE

Alternatively, use the X-API-Key header:

X-API-Key: ev_live_YOUR_API_KEY_HERE
Security: Never expose your API key in frontend code, URLs, or query strings. Keys passed via query params are rejected.

Base URL

https://your-domain.com/api/v1

All endpoints below are relative to this base URL.

Rate Limits

PlanRequests/minMonthly IncludedOverage
Free10100Hard cap
Starter ($29/mo)605,000$0.008/each
Pro ($99/mo)30025,000$0.005/each
Enterprise ($299/mo)1,000100,000$0.003/each

When you hit your rate limit, the API returns 429 Too Many Requests with a Retry-After header.

Error Handling

Errors return a JSON body with error and message fields:

{
  "error":   "usage_limit_reached",
  "message": "Monthly limit reached (100 verifications). Upgrade to continue.",
  "used":    100,
  "limit":   100
}
StatusMeaning
400Bad request (missing/invalid params)
401Invalid or missing API key
402Monthly usage limit reached
403Forbidden (email not verified, account suspended)
429Rate limit exceeded
500Server error

Verify Single Email

POST /api/v1/verify

Verify one email address in real-time. Response takes 2-15 seconds depending on the mail server.

Request

curl -X POST https://your-domain.com/api/v1/verify \
  -H "Authorization: Bearer ev_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "john@example.com"}'
FieldTypeRequiredDescription
emailstringYesEmail address to verify (max 320 chars)
refreshbooleanNoSet true to skip cache and force a fresh SMTP probe

Response (200 OK)

{
  "email":       "john@example.com",
  "domain":      "example.com",
  "score":       92,
  "tier":        "deliverable",
  "tierLabel":   "OK",
  "result":      "ok",
  "quality":     "deliverable",
  "provider":    "Google Workspace",
  "isRole":      false,
  "isDisposable": false,
  "mx": [
    { "exchange": "aspmx.l.google.com", "priority": 1 }
  ],
  "smtp": {
    "connected":     true,
    "mailboxExists": true,
    "responseCode":  250,
    "latencyMs":     342
  },
  "catchAll": {
    "isCatchAll": false
  },
  "spf":          true,
  "dmarc":        true,
  "verifiedAt":  "2026-05-15T10:30:00.000Z",
  "cached":      false
}

Verify Bulk (Async)

POST /api/v1/verify/bulk

Submit up to 50,000 emails for asynchronous verification. Returns a job ID to poll for results.

Request

curl -X POST https://your-domain.com/api/v1/verify/bulk \
  -H "Authorization: Bearer ev_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["alice@gmail.com", "bob@yahoo.com", "invalid@fake.xyz"]}'

Response (202 Accepted)

{
  "jobId":   "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status":  "processing",
  "total":   3,
  "message": "Job created. Poll GET /api/v1/jobs/{jobId} for status."
}

Job Status

GET /api/v1/jobs/{jobId}

Poll the status of a bulk verification job.

curl https://your-domain.com/api/v1/jobs/a1b2c3d4-... \
  -H "Authorization: Bearer ev_live_YOUR_KEY"

Response

{
  "id":            "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status":        "completed",     // queued | processing | completed | failed
  "total_emails":  3,
  "completed":     3,
  "deliverable":   2,
  "risky":         0,
  "undeliverable": 1,
  "created_at":    "2026-05-15T10:30:00.000Z"
}

Job Results

GET /api/v1/jobs/{jobId}/results

Get paginated verification results for a completed job.

curl "https://your-domain.com/api/v1/jobs/a1b2c3d4-.../results?page=1&limit=100" \
  -H "Authorization: Bearer ev_live_YOUR_KEY"
Query ParamDefaultDescription
page1Page number
limit100Results per page (max 1000)
tierallFilter by tier: deliverable, risky, undeliverable

Download CSV

GET /api/v1/jobs/{jobId}/download

Download all results as a CSV file.

curl -O https://your-domain.com/api/v1/jobs/a1b2c3d4-.../download \
  -H "Authorization: Bearer ev_live_YOUR_KEY"

Account Info

GET /api/v1/account

Get your current plan, usage, and remaining quota.

curl https://your-domain.com/api/v1/account \
  -H "Authorization: Bearer ev_live_YOUR_KEY"

Response

{
  "plan":         "free",
  "planName":     "Free",
  "month":        "2026-05",
  "used":         42,
  "included":     100,
  "remaining":    58,
  "overage":      0,
  "overageRate":  null,
  "rateLimit":    10
}

Result Tiers

Every verification returns a tier and score (0-100):

TierResultScore RangeMeaningAction
deliverable ok 80-100 Mailbox exists, SMTP confirmed Safe to send
risky risky / catch_all 40-79 Catch-all domain, role address, or inconclusive Send with caution
undeliverable invalid 0-39 Mailbox doesn't exist, domain dead, or hard bounce Do not send
unknown unknown varies Server unreachable, timeout, or blocked Retry later

Response Fields

FieldTypeDescription
emailstringNormalized email address
domainstringDomain part of the email
scorenumberConfidence score 0-100
tierstringdeliverable | risky | undeliverable | unknown
resultstringok | catch_all | risky | invalid | unknown
providerstringEmail provider (Google, Microsoft 365, etc.)
isRolebooleanTrue if role-based (info@, admin@, etc.)
isDisposablebooleanTrue if disposable/temporary email
mxarrayMX records for the domain
smtp.connectedbooleanWhether SMTP connection was established
smtp.mailboxExistsbooleanWhether RCPT TO was accepted
smtp.responseCodenumberSMTP response code (250, 550, etc.)
smtp.latencyMsnumberSMTP probe round-trip time in ms
catchAll.isCatchAllbooleanTrue if domain accepts all addresses
spfbooleanWhether domain has SPF record
dmarcbooleanWhether domain has DMARC record
verifiedAtstringISO 8601 timestamp of verification
cachedbooleanTrue if result was served from cache

Plans & Pricing

View available plans programmatically:

GET /api/v1/plans (no auth required)

Code Examples

cURL

# Single verification
curl -X POST https://your-domain.com/api/v1/verify \
  -H "Authorization: Bearer ev_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "test@gmail.com"}'

# Bulk verification
curl -X POST https://your-domain.com/api/v1/verify/bulk \
  -H "Authorization: Bearer ev_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["a@gmail.com", "b@yahoo.com"]}'

# Check job status
curl https://your-domain.com/api/v1/jobs/JOB_ID \
  -H "Authorization: Bearer ev_live_YOUR_KEY"

Python

# pip install requests
import requests

API_KEY = "ev_live_YOUR_KEY"
BASE    = "https://your-domain.com/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Single verify
r = requests.post(f"{BASE}/verify",
    json={"email": "test@gmail.com"},
    headers=headers)

data = r.json()
print(f"{data['email']} -> {data['tier']} (score: {data['score']})")

# Bulk verify
r = requests.post(f"{BASE}/verify/bulk",
    json={"emails": ["a@gmail.com", "b@yahoo.com"]},
    headers=headers)

job_id = r.json()["jobId"]
print(f"Job submitted: {job_id}")

# Poll until complete
import time
while True:
    status = requests.get(f"{BASE}/jobs/{job_id}", headers=headers).json()
    if status["status"] == "completed":
        break
    time.sleep(5)

# Get results
results = requests.get(f"{BASE}/jobs/{job_id}/results", headers=headers).json()

JavaScript / Node.js

const API_KEY = "ev_live_YOUR_KEY";
const BASE    = "https://your-domain.com/api/v1";
const headers = {
  "Authorization": `Bearer ${API_KEY}`,
  "Content-Type": "application/json"
};

// Single verify
const res = await fetch(`${BASE}/verify`, {
  method: "POST",
  headers,
  body: JSON.stringify({ email: "test@gmail.com" })
});
const data = await res.json();
console.log(`${data.email} -> ${data.tier} (score: ${data.score})`);

// Bulk verify
const bulk = await fetch(`${BASE}/verify/bulk`, {
  method: "POST",
  headers,
  body: JSON.stringify({ emails: ["a@gmail.com", "b@yahoo.com"] })
});
const { jobId } = await bulk.json();

// Poll until complete
let status;
do {
  await new Promise(r => setTimeout(r, 5000));
  const poll = await fetch(`${BASE}/jobs/${jobId}`, { headers });
  status = await poll.json();
} while (status.status !== "completed");

// Get results
const results = await fetch(`${BASE}/jobs/${jobId}/results`, { headers });
console.log(await results.json());

PHP

$apiKey = "ev_live_YOUR_KEY";
$base   = "https://your-domain.com/api/v1";

$ch = curl_init("$base/verify");
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer $apiKey",
        "Content-Type: application/json"
    ],
    CURLOPT_POSTFIELDS => json_encode(["email" => "test@gmail.com"])
]);

$response = json_decode(curl_exec($ch), true);
echo "{$response['email']} -> {$response['tier']} (score: {$response['score']})\n";

Need help? Contact support or check the Dashboard