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

  1. Sign in or create an account with an email code, Google or a passkey. No card is needed.
  2. Open API keys in the dashboard and create a key. Copy it right away: we show it only once.
  3. 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, risky or unknown. See statuses and reasons.
  • reason: why the address got that status, for example accepted or catch_all.
  • action: what we recommend: send, send_with_caution, remove or retry_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

Updated · Maintained by the email-validation.org team