EmailVerifier
Log in Sign up free

API documentation

Check whether an email address is safe to send to. We probe the recipient's mail server directly and never send a message.

Authentication

Create an API key on the API keys page, then send it on every request as a Bearer token (or in an X-Api-Key header). Always add Accept: application/json.

Authorization: Bearer evk_xxxxxxxxxxxxxxxx
Accept: application/json

Missing or wrong credentials always return 401 with {"error":"unauthorized"}.

Daily limit

Each account may check 100 addresses per day (website, API and MCP combined). A name search (find) counts as one check, and each account may run 20 name searches a day. Repeat questions are answered from a cache but still count. The counter resets at midnight (UTC).

When you reach it, calls return 429 with error "daily_limit_reached" and a resets_at time. We never return a guessed verdict.

POST /verify

Check one address.

curl -X POST https://email-verifier.nilede.tech/api/v1/verify \
  -H "Authorization: Bearer YOUR_API_KEY" -H "Accept: application/json" \
  -d email=jane@example.com

Parameters: email (required). sender (optional) overrides the probe sender and must be on a domain this service owns.

{
  "email": "jane@example.com",
  "status": "verified",
  "reason": "Mail server confirmed this mailbox and refused a made-up one",
  "safe_to_send": true,
  "did_you_mean": null,
  "flags": {
    "is_free_provider": false,
    "is_role_account": false,
    "is_disposable": false,
    "is_catch_all": false,
    "is_security_gateway": false,
    "has_mail_server": true
  },
  "provider": "google",
  "mx_host": "aspmx.l.google.com",
  "checked_at": "2026-11-02T10:15:00+00:00",
  "cached": false,
  "retry_scheduled_at": null,
  "steps": [
    { "step": "syntax", "status": "pass", "detail": "Address is well formed" },
    { "step": "dns", "status": "pass", "detail": "Domain exists" },
    { "step": "smtp", "status": "pass", "detail": "Server replied: 250 2.1.5 OK" },
    { "step": "catch_all", "status": "pass", "detail": "Server refused a made-up address" }
  ]
}
Flags and suggestions

flags gives quick yes/no facts you can filter on: is_free_provider (Gmail, Yahoo...), is_role_account (info@, sales@), is_disposable, is_catch_all (null when not tested), is_security_gateway and has_mail_server. did_you_mean suggests a corrected address when the domain looks like a typo of a common provider (never shown for verified addresses).

Statuses
status
Meaning
safe_to_send
verified
The server confirmed this mailbox and refused a made-up one. true
risky
May exist but cannot be proven: catch-all domain, role account (info@, sales@), or a security gateway. false
invalid
Will bounce: bad format, dead domain, no mail server, mailbox refused, or disposable provider. false
unknown
Could not decide: server refused us, greylisting (we retry once), timeout, or DNS trouble. Try again later. false
POST /find

Work out the most likely address for a person at a company domain (tests up to four common formats). Counts as one check.

curl -X POST https://email-verifier.nilede.tech/api/v1/find \
  -H "Authorization: Bearer YOUR_API_KEY" -H "Accept: application/json" \
  -d first_name=Jane -d last_name=Doe -d domain=example.com
{
  "email": "jane.doe@example.com",
  "status": "verified",
  "reason": "Confirmed format \"first.last\" at example.com",
  "format": "first.last",
  "probes": 1,
  "tried": [ { "email": "jane.doe@example.com", "status": "verified" } ]
}

On a catch-all domain nothing can be confirmed, so the most common format is returned with status "risky".

POST /batches

Check a list in the background (up to 500 addresses). The whole batch must fit in your remaining daily allowance, otherwise nothing starts and you get 429 daily_limit_reached.

curl -X POST https://email-verifier.nilede.tech/api/v1/batches \
  -H "Authorization: Bearer YOUR_API_KEY" -H "Accept: application/json" \
  -d "emails[]=jane@example.com" -d "emails[]=bob@example.org"
202 { "id": "01k...", "status": "queued", "total": 2, "status_url": "https://email-verifier.nilede.tech/api/v1/batches/01k..." }
GET /batches/{id}

Poll until status is "finished". Results appear as they are checked.

{
  "id": "01k...", "status": "running", "total": 2, "processed": 1,
  "summary": { "verified": 1, "risky": 0, "invalid": 0, "unknown": 0, "pending": 1 },
  "results": [ { "email": "jane@example.com", "status": "verified", "reason": "...", "safe_to_send": true } ]
}
GET /usage

Free. Shows your allowance.

{ "used": 12, "limit": 100, "remaining": 88, "resets_at": "2026-11-03T00:00:00+00:00" }
GET /health

Free. Tells you whether mailbox checks can run right now, plus your usage.

{ "status": "ok", "can_check_mailboxes": true, "message": null, "usage": { "used": 12, "limit": 100, "remaining": 88, "resets_at": "..." } }
Errors
HTTP
error
Meaning
401 unauthorized Missing, wrong or revoked credentials.
422 (validation) / invalid_sender A required field is missing, or the sender is not on a domain we own.
429 daily_limit_reached You used all your checks today. See resets_at.
429 find_limit_reached You used all your name searches today. See resets_at.
429 (throttle) More than 120 requests a minute. Slow down.
503 service_busy The service is at capacity for live mailbox checks today. No verdict was produced.
OAuth (client credentials)

Create an OAuth app on the API keys page, then exchange its client ID and secret for a token (valid 12 hours). Use the token exactly like an API key.

curl -X POST https://email-verifier.nilede.tech/api/oauth/token \
  -d grant_type=client_credentials -d scope=verify \
  -d client_id=CLIENT_ID -d client_secret=CLIENT_SECRET
MCP for AI agents

Connect any MCP-capable agent to https://email-verifier.nilede.tech/mcp with an API key as the Bearer token. Tools: verify-email, verify-emails (up to 25), find-email, service-health.

claude mcp add --transport http email-verifier https://email-verifier.nilede.tech/mcp \
  --header "Authorization: Bearer YOUR_API_KEY"