REST API · JSON · free plan
Email Validation API
Check any email address from your own code. One GET request returns the syntax, MX, SMTP mailbox, disposable, role and free-provider checks, a deliverability state with its reason and a quality score. Whole lists go through the bulk endpoint, up to 100,000 addresses per job.
- 100 free requests a month
- No credit card
- Checks run in Germany
curl -H "apikey: YOUR-API-KEY" "https://api.emailvalidation.io/v1/info?email=anna@example.com"
Try the live API
Send a request, see the real response
Type an address and it goes to the same API your code will call. The JSON on the right is replaced with the response you get back.
Validate an email address
No signupEach request runs these checks:
- format_valid
- mx_found
- smtp_check
- disposable
- role
- free
curl "https://api.emailvalidation.io/v1/info?email=support@emailvalidation.io" \ -H "apikey: YOUR-API-KEY"
const res = await fetch( "https://api.emailvalidation.io/v1/info?email=" + encodeURIComponent(email), { headers: { apikey: process.env.EMAILVALIDATION_KEY } } ); const { state, did_you_mean } = await res.json(); if (state === "undeliverable") // ask the user to fix the address
import os, requests r = requests.get( "https://api.emailvalidation.io/v1/info", params={"email": email}, headers={"apikey": os.environ["EMAILVALIDATION_KEY"]}, timeout=10, ) state = r.json()["state"] # deliverable | risky | undeliverable | unknown
$ch = curl_init("https://api.emailvalidation.io/v1/info?email=" . urlencode($email)); curl_setopt($ch, CURLOPT_HTTPHEADER, ["apikey: YOUR-API-KEY"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true);
200 · GET /v1/info?email=support@emailvalidation.io
{
"email": "support@emailvalidation.io",
"user": "support",
"tag": "",
"domain": "emailvalidation.io",
"format_valid": true,
"mx_found": true,
"smtp_check": true,
"catch_all": null,
"role": true,
"disposable": false,
"free": false,
"score": 0.64,
"state": "deliverable",
"reason": "valid_mailbox",
"did_you_mean": ""
}From API key to first result in three steps
No SDK needed: any language that can send an HTTPS request can call the API.
- Step
Create a free account
Sign up and copy your API key from the dashboard. The free plan includes 100 requests a month, at up to 10 requests a minute.
apikey: YOUR-API-KEY
- Step
Call GET /v1/info
Pass the address as
emailand your key in theapikeyheader. The header is better than the query parameter, which can end up in access logs.GET /v1/info?email=anna@example.com
- Step
Act on the state
Branch on
stateand logreason: accept deliverable addresses, ask for a correction when an address is undeliverable, and decide case by case for risky and unknown ones."state": "deliverable"
Endpoints
Seven endpoints, one base URL
Every call goes to https://api.emailvalidation.io and returns JSON. Authenticate with your API key in the apikey header or the apikey query parameter.
- One key, header or querySend the key as a header to keep it out of URLs and logs. Medium and Large plans can create more than one key.
- Catch-all on requestAdd catch_all=1 to /v1/info or catch_all to a bulk job to test whether the domain accepts every address. Available from the Small plan.
- Also an MCP serverAI agents reach the same checks at https://api.emailvalidation.io/mcp. Set up the MCP server.
- GET
/v1/infoValidate one address. Parameters: email, catch_all (1 or 0). - POST
/v1/bulkStart a bulk job from a JSON array or a CSV or TXT file, up to 100,000 addresses. - GET
/v1/bulkList your bulk jobs, newest first. - GET
/v1/bulk/{job_id}Status, counts and progress of one job. - GET
/v1/bulk/{job_id}/resultsDownload the results as JSON or CSV. - DELETE
/v1/bulk/{job_id}Delete a job together with its list and results. - GET
/v1/statusYour monthly quota: total, used and remaining. Free to call.
GET /v1/info
What the response tells you
Every response has the same 15 fields, so your code never has to guess which keys exist.
| Field | Type | Meaning |
|---|---|---|
email | string | The address that was checked. |
user | string | The local part before the @. |
tag | string | The tag part of the address, if it has one. |
domain | string | The domain part after the @. |
format_valid | boolean | Whether the address follows the email syntax rules. |
mx_found | boolean | Whether the domain has MX records, the usual sign that it can receive email. |
smtp_check | boolean | Whether the receiving mail server accepted the mailbox in the SMTP check. |
catch_all | boolean | null | Whether the domain accepts mail for every address. null unless you send catch_all=1. |
role | boolean | A role address such as support@ or postmaster@. |
disposable | boolean | An address at a disposable email service. |
free | boolean | An address at a free email provider such as Gmail or Yahoo. |
score | number | Quality score from 0 (bad) to 1 (good). |
state | string | deliverable, undeliverable, risky or unknown. |
reason | string | Why the address got its state, see the table below. |
did_you_mean | string | A suggested correction for a likely domain typo, for example gmail.com for gmial.com. A suggestion only: it does not change the other fields. |
Four states, eleven reasons
Branch on the state, keep the reason for your logs and support team.
deliverable
The mailbox exists. Accept the address.
valid_mailbox- A valid mailbox that can receive email.
risky
Accepted, but delivery or engagement is doubtful. Accept with care or ask again.
low_deliverability- A person is unlikely to read the email.
low_quality- Several people appear to use the address.
undeliverable
Mail will bounce. Block it or ask for a correction.
invalid_format- The address format is invalid.
invalid_mx- MX records are missing or invalid.
invalid_smtp- The mail server did not respond correctly.
invalid_mailbox- The mail server refused the address.
unknown
The server could not be asked. Retry later.
no_connect- No connection to the mail server.
timeout- The SMTP connection timed out.
unavailable_smtp- The server did not allow verification.
unexpected_error- An unexpected error occurred.
Full definitions in the /v1/info documentation.
Bulk email verification API
A whole list in one request
POST a JSON array or upload a CSV or TXT file with up to 100,000 addresses (25 MB). The job runs in the background: poll its status or let us call your webhook, then download the results.
- Only unique, valid addresses are billedDuplicates (ignoring case and surrounding spaces) and empty or malformed rows are free, and a job that needs more than your remaining quota is refused before anything is charged.
- Refunds for checks we could not finishAddresses left unknown because of a timeout on our side are refunded when the job completes; a failed job is refunded in full.
- Signed webhookOne POST when the job completes or fails, signed with HMAC-SHA256, with up to six delivery attempts. It carries the job, never the addresses.
queuedAccepted, quota chargedprocessingChecked per mail servercompletedResults ready for 30 daysfailedFully refunded
curl -X POST "https://api.emailvalidation.io/v1/bulk" \ -H "apikey: YOUR-API-KEY" \ -F "file=@contacts.csv" \ -F "email_column=email" \ -F "webhook_url=https://example.com/hooks/emailvalidation"
201 · job created
{
"job_id": "629954218123464704",
"status": "queued",
"counts": {
"total": 5,
"unique": 3,
"duplicates": 1,
"invalid": 1,
…
},
"quota": { "charged": 3, "refunded": 0 },
…
}Results your way
- JSON with a row number, the input and all 15 result fields per address
- CSV: your original columns plus 15
emailvalidation_*columns - Cells starting with = + - or @ are escaped, so the CSV is safe to open in a spreadsheet
- Download as often as you like until the job expires, or delete it right away
Errors and limits
Predictable errors, clear limits
Every error has an HTTP status and a code, so your integration can tell a bad request from a full quota.
- You only pay for successful checksValidation errors and errors on our side do not count against your quota. Status checks, job lists, downloads and deletions are free.
- Rate limits in the headersThe free plan allows 10 requests a minute. Responses carry
X-RateLimit-Remaining-Quota-Month, andX-Costshows what a call counted.
| Status | Meaning |
|---|---|
| 200 | Success. |
| 201 | Bulk job created. |
| 401 | No API key, or the key is invalid. |
| 403 | Key not allowed, or plan_upgrade_required for a feature your plan does not include. |
| 404 | Endpoint or job not found, or results no longer available. |
| 409 | job_not_completed: results requested before the job finished. |
| 422 | Validation error; the errors object names the field. |
| 429 | Rate limit or monthly quota exceeded. |
| 500 | Internal error on our side. Contact support. |
Rate limit and quota headers
| Header | Meaning |
|---|---|
X-RateLimit-Limit-Quota-Month | Your monthly quota. |
X-RateLimit-Remaining-Quota-Month | Requests left this month. |
X-RateLimit-Limit-Quota-Minute | Requests allowed per minute, on plans with a minute limit such as the free plan (10). |
X-RateLimit-Remaining-Quota-Minute | Requests left in the current minute. |
X-Cost | What the call counted against your quota: 1 for a validation, 0 for sandbox requests; for a bulk job, the number of unique valid addresses. |
X-RateLimit-Remaining-Overage-Month | Overage left, when overage is enabled and the monthly quota is used up (with X-RateLimit-Limit-Overage-Month). |
Official SDKs and integrations
Install a client library or call the REST API directly.
JavaScript
npm install @everapi/emailvalidation-js --save
Python
pip install emailvalidationio
PHP
composer require everapi/emailvalidation-php
Official SDKs are also listed for Ruby, Go, C#, R, Rust and Perl.
MCP server
Let Claude, Cursor and other AI agents validate addresses and run bulk jobs.
MCP setupZapier
Validate new contacts from forms, CRMs and spreadsheets without code.
Zapier integrationStep-by-step guides
Validate email addresses in JavaScript, Python and PHP, with a regex check first.
JavaScript guideWhere teams call the API
Check an address at the moment it enters your system, before it costs you a bounce.
Signup forms
Catch typos and throwaway inboxes before the account exists, and suggest the right domain.
Checkout
Make sure order confirmations and invoices reach the buyer.
CRM imports
Keep invalid and role addresses out of your contact database.
Email marketing
Clean lists before a campaign to protect your sender reputation.
API pricing
The same plans as the app: one request validates one address.
Cancel any time · Two months free on yearly plans · All prices excl. VAT · Compare all plans
Email validation API FAQ
Short answers to what developers ask before they integrate.
Is the email validation API free?
How does the API check an address without sending an email?
What does a catch-all result mean?
Can I validate a whole list through the API?
Which programming languages can I use?
Do failed requests count against my quota?
Is an email verification API the same as an email validation API?
What happens when I reach my monthly quota?
Is the API GDPR compliant?
Start validating emails for free
100 free checks every month. No credit card required. Upgrade when you need more.