API reference
Verify one address per request. Authenticate with a key from your dashboard. Each request costs 1 credit. Malformed addresses and unknown results are not billed (see billed in the response).
Verify an address
curl -X POST https://mailsure.co/api/v1/verify \
-H "Authorization: Bearer ev_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"email": "john@example.com"}'
# or: GET /api/v1/verify?email=john@example.com
# add "evidence": true (or ?evidence=true) to include the mailbox conversationResponse
{
"email": "John@Example.com",
"normalized": "john@example.com",
"status": "valid", // valid | risky | invalid | unknown
"score": 100, // 0-100
"reason": "valid",
"reasons": ["valid"],
"syntax_valid": true,
"domain": "example.com",
"mx_found": true,
"mx_hosts": ["mx1.example.com"],
"provider": null, // google, microsoft, … when recognised
"disposable": false,
"role": false,
"free": false,
"suggestion": null, // e.g. "john@gmail.com" for john@gmial.com
"suggested_action": "accept", // accept | accept_and_confirm | reject
"mailbox": "not_checked", // exists | missing | catch_all | unknown | not_checked
"mailbox_detail": null, // e.g. "blocked", "temporary_451", "skipped_provider"
"evidence": { ... }, // only with evidence=true and when a mailbox check ran: {mx_host, steps[{step, code, text, ms, error}]}
"billed": true, // false for malformed addresses and unknown results
"latency_ms": 412,
"credits_remaining": 99
}Statuses
- valid: well-formed, and the domain has working mail servers.
- risky: deliverable in principle, but a disposable domain, a shared role address (info@, sales@) or a probable typo.
- invalid: malformed, or the domain doesn't exist or accepts no mail.
- unknown: we couldn't reach a verdict (for example DNS didn't answer, or the mail provider was limiting checks, reason
provider_busy). Try again later. Never billed. - When mailbox probing is on: a mailbox the server rejects makes the address invalid; a domain that accepts every address (
catch_all) is risky. Gmail, Hotmail/Outlook, Google Workspace and Microsoft 365 are probed like any other server. Yahoo, iCloud and Proton are not probed (not_checked), because they throttle or block unknown senders.
Unless mailbox is exists, a valid result only proves the domain can receive mail, not that the individual mailbox exists.
Account and balance
Free to call. Useful for a “test connection” button or to check credits before a large job.
curl https://mailsure.co/api/v1/account -H "Authorization: Bearer ev_live_xxxxxxxx"
{ "email": "you@example.com", "plan": "starter", "concurrent_requests": 5, "credits_remaining": 8421 }Bulk jobs
For lists, start a job and poll it. Up to 200,000 addresses per job and 25 MB per request. Duplicates and malformed addresses are free, and credits for unknown results are given back when the job ends. Results are kept for 30 days.
# 1. start a job
curl -X POST https://mailsure.co/api/v1/jobs \
-H "Authorization: Bearer ev_live_xxxxxxxx" -H "Content-Type: application/json" \
-d '{"name": "Spring list", "emails": ["a@example.com", "b@example.com"]}'
# -> 201 {"id": "6f1c…", "status": "queued"}
# 2. poll until status is "done" (queued | running | done | canceled | failed)
curl https://mailsure.co/api/v1/jobs/6f1c… -H "Authorization: Bearer ev_live_xxxxxxxx"
# -> {"id": "6f1c…", "status": "running", "total": 2, "processed": 1, "counts": {…}, …}
# 3a. results as JSON, a page at a time (limit 1-1000). Pass next_after back as ?after= until it is null.
curl "https://mailsure.co/api/v1/jobs/6f1c…/results?limit=1000&status=valid,risky" -H "Authorization: Bearer ev_live_xxxxxxxx"
# -> {"job_status": "done", "results": [ {…same fields as a single check…} ], "next_after": null}
# 3b. or the whole list as CSV (?only=valid,risky to filter)
curl -o results.csv https://mailsure.co/api/v1/jobs/6f1c…/download -H "Authorization: Bearer ev_live_xxxxxxxx"An insufficient balance returns 402 insufficient_credits before anything is queued. A key may start 30 jobs an hour.
Libraries and plugins
Ready-made clients wrap everything above, including retries on 429, bulk jobs and error handling. See integrations for downloads and examples.
# Node.js 18+
npm install https://mailsure.co/downloads/mailsure-node.tgz
const ms = new Mailsure({ apiKey });
const { job, results } = await ms.bulk.verify(emails); // creates, waits, collects
# Python 3.8+
pip install https://mailsure.co/downloads/mailsure-python.tar.gz
job, results = Mailsure(api_key).bulk.verify(emails)
# PHP 7.4+ (download https://mailsure.co/downloads/mailsure-php.zip)
[$job, $results] = (new \Mailsure\Client($apiKey))->bulk->verify($emails);WordPress and WooCommerce: the plugin needs no code.
Errors
| 400 | missing_email / invalid_email |
| 401 | invalid_api_key |
| 402 | insufficient_credits |
| 429 | rate_limited (50 requests/second per key) or too_many_concurrent_requests (your plan's limit on simultaneous requests: 2 free, 5 Starter, 10 Professional, 20 Enterprise). Honour Retry-After. |