Email Verifier REST API Reference

Base URL (production):

text
https://email-verifier-v61-production-gateway.emaily.workers.dev

All /v1/* endpoints require authentication with an API key:

text
Authorization: Bearer ev_live_<your-api-key>
Auth before routing: requests under /v1/* are authenticated before path matching, so an invalid or missing key yields 401 even for unknown or malformed paths (e.g. /v1// returns 401, not 404).

Response conventions

  • Every response carries tracing headers:
  • X-Request-Id — correlates a request with its structured log events.
  • X-Response-Time — request duration in milliseconds.
  • Paid endpoints include a billing object and quota headers.
  • Errors return JSON with an error code and message. Client code should branch on the error code, not the HTTP status alone.
  • Reaching a rate limit or monthly quota returns HTTP 429 with a Retry-After header (and retry_after_seconds in the body).

Common error codes

HTTPerrorMeaning
400invalid_jsonRequest body is not valid JSON.
400invalid_requestRequest body is not a JSON object.
400invalid_emailemail is not a string in the expected length range.
400invalid_dkim_selectorsToo many / too long DKIM selectors (max 8, each ≤ 63 chars).
400invalid_query_parameterA boolean query param was not true/false/1/0/yes/no.
400invalid_domainInvalid domain (too short/long or bad encoding).
401unauthorizedMissing/invalid Authorization header.
404not_foundUnknown REST endpoint.
405method_not_allowedWrong HTTP method for the path (Allow header set).
429rate_limit_exceededPer-key rate limit (scope: minute, day, credits_minute, credits_day).
429monthly_quota_exceededMonthly credit quota exhausted (upgrade_required: true).
409batch_not_cancellableBatch already in a terminal state.
409export_not_readyExport not yet assembled.
500service_misconfiguredA required service component is missing or misconfigured.
500internal_errorUnhandled failure.

Endpoints

GET /health — service status (no auth)

bash
curl https://email-verifier-v61-production-gateway.emaily.workers.dev/health
json
{
  "status": "ok",
  "version": "6.1.0",
  "environment": "production",
  "checks": { "core": "ok" }
}

Returns 503 with status: "degraded" if a required core dependency is unavailable.


GET /v1/capabilities — capability declaration (free)

bash
curl -H "Authorization: Bearer ev_live_..." \
  https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/capabilities

Returns the service version, the list of MCP tools, REST endpoints, the available plan mapping, and explicit can_check / cannot_check_without_smtp_or_external_reputation_data lists. Use this at runtime to discover what the service can and cannot do.


GET /v1/usage — quota status (free)

bash
curl -H "Authorization: Bearer ev_live_..." \
  https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/usage
json
{
  "account": "you@example.com",
  "plan": "developer",
  "period": "2026-08",
  "used": 0,
  "limit": 10000,
  "remaining": 10000,
  "reserved": 0
}

POST /v1/syntax — syntax only (free)

Walks no network; pure local parse + normalization.

bash
curl -X POST https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/syntax \
  -H "Authorization: Bearer ev_live_..." -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com"}'

Body:

  • email (string, 1–254 chars). Required.

Returns { email, valid, normalized, local, domain, ...flags, billing }.


POST /v1/verify — verify one email (1 credit)

bash
curl -X POST https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/verify \
  -H "Authorization: Bearer ev_live_..." -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com","include_policy_checks":true}'

Body:

  • email (string, 3–254 chars). Required.
  • include_policy_checks (boolean, optional, default true). Also query SPF and DMARC. Disable for fewer DNS requests (false).

Returns the full verification result (see Verification result schema below) plus a billing object.


POST /v1/verify-batch — verify up to 10 (N credits)

bash
curl -X POST https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/verify-batch \
  -H "Authorization: Bearer ev_live_..." -H "Content-Type: application/json" \
  -d '{"emails":["alice@example.com","admin@example.org"],"include_policy_checks":false}'

Body:

  • emails (array of strings, 1–10 items, each 3–254 chars). Required.
  • include_policy_checks (boolean, optional, default false).

Policy checks are limited to 3 addresses per batch for Workers-Free subrequest safety. Returns { summary, results, billing }.


GET /v1/domain/:domain — deep domain inspection (1 credit)

bash
curl "https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/domain/example.com?try_common_dkim_selectors=true&fetch_mta_sts_policy=true" \
  -H "Authorization: Bearer ev_live_..."

Query parameters (all optional):

  • dkim_selectors — comma-separated selectors (max 8, each ≤ 63 chars).
  • try_common_dkim_selectors — boolean (true/false/1/0/yes/no).
  • fetch_mta_sts_policy — boolean; fetch the standards-defined MTA-STS policy file.

Returns MX/SPF/DMARC/MTA-STS/TLS-RPT/DANE/DKIM/BIMI analysis plus a billing object.


Async batches

POST /v1/batches — submit a batch (N credits)

bash
curl -X POST https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/batches \
  -H "Authorization: Bearer ev_live_..." -H "Content-Type: application/json" \
  -d '{"emails":["alice@example.com","bob@example.org"]}'

Body:

  • emails (array of strings, 3–254 chars each). Required.
  • include_policy_checks (boolean, optional, default false).

Optional header:

  • Idempotency-Key — replaying the same key returns the same batch_id; concurrent replays are safe (exactly one submission wins; losers get 503 with retryable: true and no batch_id).

Returns 202 with:

  • batch_id
  • email_count, total_credits
  • chunk_size (dynamic chunking, bounded for Workers-Free subrequest safety)
  • billing (credits reserved, plan usage).

GET /v1/batches?limit=N — list batches (free)

bash
curl -H "Authorization: Bearer ev_live_..." \
  "https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/batches?limit=20"

limit 1–100, default 20. Returns the account's recent batches, newest first, each with status, chunk progress, email count, charged credits, and creation time.

GET /v1/batches/:id — batch status (free)

bash
curl -H "Authorization: Bearer ev_live_..." \
  https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/batches/<batch_id>

Includes status, progress (total_chunks, completed_chunks), counts, billing (reserved_credits, charged_credits), and results.export_ready.

GET /v1/batches/:id/results — stream results

bash
curl -H "Authorization: Bearer ev_live_..." \
  https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/batches/<batch_id>/results

Streams unique results once the batch is terminal.

GET /v1/batches/:id/export — combined export file

bash
curl -OJ -H "Authorization: Bearer ev_live_..." \
  https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/batches/<batch_id>/export

Streams the assembled export.json (all unique results in one file) once results.export_ready is true. Returns 409 export_not_ready while assembly is still in progress.

POST /v1/batches/:id/cancel — cancel a running batch

bash
curl -X POST -H "Authorization: Bearer ev_live_..." \
  https://email-verifier-v61-production-gateway.emaily.workers.dev/v1/batches/<batch_id>/cancel

Marks unfinished chunks dead_letter (CANCELLED_BY_CUSTOMER), sets the job to cancelled (terminal), settles consumed credits, releases the rest, and deletes the batch input data from storage. Finished chunks stay readable until expiry. Returns 409 batch_not_cancellable for terminal batches.

Batch terminal states: completed, partially_completed, failed, cancelled, expired.


Verification result schema

The verify_email / verify_emails endpoints and the equivalent MCP tools share this shape:

FieldTypeNotes
emailstringAddress as supplied.
normalized_emailstring | nullLocal-part normalized + punycode domain.
verdictstringdomain_deliverable | risky | invalid | unknown.
confidencestringhigh | medium | low.
scorenumber0–1 heuristic score.
risk_flagsstring[]e.g. disposable, role_account, no_reply, free_provider, typo_domain.
checksobjectsyntax_valid, domain, domain_dns_exists, mx_found, mx_count, null_mx, implicit_mx_fallback, spf_found, spf_valid, dmarc_found, dmarc_valid, dmarc_policy, disposable, role_account, no_reply_account, …
suggested_correctionstring | nullWhen a common domain typo is detected.
billingobjectplan, credits_charged, period, used, reserved, remaining.

Verdict meanings:

  • domain_deliverable — syntax pass + MX (or implicit A/AAAA) present; the domain accepts mail.
  • risky — deliverable at the domain level but with risk flags (disposable, role, free provider, weak/no auth, typo suspicion).
  • invalid — syntax failure, no MX, null MX, or a hard disqualifier.
  • unknown — verdict could not be determined (always the case for mailbox existence and catch-all behavior, which cannot be verified without SMTP).

Plans & limits

Credits and request limits are enforced per API key.

PlanMonthly creditsRequests/minRequests/dayCredits/minCredits/day
free50030256050
developer10,000300300600700
pro50,0001,5001,2002,5003,000
agency250,00015,0006,0005,00012,000

Monthly credit usage resets on a calendar month (UTC) boundary. All limits surface as HTTP 429 — always read the error code and scope from the body to tell them apart.