Quickstart
This guide takes you from a new account to your first validation result. It uses a free test address, so it does not spend any of the 500 free credits you get when you sign up.
1. Create an account and an API key
- Sign in or create an account with an email code, Google or a passkey. No card is needed.
- Open API keys in the dashboard and create a key. Copy it right away: we show it only once.
- Store it as an environment variable on the machine that will call the API:
export EV_API_KEY="ev_live_…"Keys start with ev_live_. Keep them on your server: anyone with the key can spend your credits. See Authentication for scopes, rotation and browser keys.
2. Send your first request
curl
curl https://api.email-validation.org/v1/validate \
-H "Authorization: Bearer $EV_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "accepted@sandbox.email-validation.org"}'JavaScript
// Node.js 18+, Deno, Bun or Cloudflare Workers: fetch is built in.
const res = await fetch('https://api.email-validation.org/v1/validate', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.EV_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email: 'accepted@sandbox.email-validation.org' }),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.status, body.reason, body.action);Python
import os
import requests
resp = requests.post(
"https://api.email-validation.org/v1/validate",
headers={"Authorization": f"Bearer {os.environ['EV_API_KEY']}"},
json={"email": "accepted@sandbox.email-validation.org"},
timeout=20,
)
body = resp.json()
if not resp.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["status"], body["reason"], body["action"])The address accepted@sandbox.email-validation.org is a test address: it always returns the same answer and costs nothing.
3. Read the result
{
"email": "accepted@sandbox.email-validation.org",
"status": "deliverable",
"reason": "accepted",
"action": "send",
"account": "accepted",
"domain": "sandbox.email-validation.org",
"did_you_mean": null,
"free_email": false,
"role_account": false,
"disposable": false,
"catch_all_domain": false,
"mx_found": true,
"mx_record": "mx.sandbox.email-validation.org",
"smtp_provider": "other",
"domain_age_days": 3650,
"processed_at": "2026-11-02T09:30:00.000Z",
"credits_used": 0,
"request_id": "req_7Hq2LmX9cV4bN8tR1zK6wD"
}The three fields that matter most:
status:deliverable,undeliverable,riskyorunknown. See statuses and reasons.reason: why the address got that status, for exampleacceptedorcatch_all.action: what we recommend:send,send_with_caution,removeorretry_later.
credits_used tells you whether the check cost a credit. Results with the status unknown are always free, and so are requests that end in an error.
4. Try other answers
Swap the address for any <reason>@sandbox.email-validation.org, for example catch_all@sandbox.email-validation.org (risky) or timeout@sandbox.email-validation.org (unknown), to see how your code handles each case. The full list covers every reason.
5. Go further
- Handle errors and retries and respect the rate limits.
- Validate addresses as people sign up.
- Check whole lists with a bulk job.
- Use an official SDK for JavaScript, TypeScript or Python, or the code samples for other languages.