# APIddress > APIddress is a developer-first email validation API. One HTTP request tells you whether an email address is deliverable, malformed, disposable, or risky — with syntax, DNS, MX, SMTP, and reputation checks behind it. Designed for signup forms, onboarding flows, CRM hygiene, and outbound list cleaning. Base URL: https://api.apiddress.com Docs: https://apiddress.com/docs OpenAPI spec: https://api.apiddress.com/api/v1/openapi.yaml Status: Private beta — free API keys available at https://apiddress.com Support: support@apiddress.com ## Authentication Every endpoint requires an API key in the `x-api-key` request header. Keys are shaped `ak_live_` followed by 32 hex characters. There is no OAuth, no token refresh, no request signing — a single static header on every call. During the private beta, keys are issued through single-use claim links. Join the wishlist at https://apiddress.com, receive a claim email, and open the link to generate your key. The raw key is shown exactly once and is never stored or emailed — only a hash is kept. The only unauthenticated endpoint is `GET /api/v1/health`. ## Validate a single email `POST /api/v1/validate-email` Validates one email address and returns a normalized, structured result. Use for signup forms, onboarding flows, lead capture, and CRM hygiene. Request body (JSON): - `email` (string, required) — the address to validate - `check_smtp` (boolean, default false) — attempt an SMTP-level deliverability probe; slower, but fills in `checks.smtp` and `checks.catch_all` - `allow_role_based` (boolean, default true) — when false, role-based addresses such as support@ or info@ are returned as `risky` Response fields: - `email` — the address as submitted - `normalized_email` — lower-cased, trimmed canonical form; store and dedupe on this - `status` — overall verdict: `valid`, `invalid`, `risky`, `disposable`, or `unknown` - `valid` — convenience boolean; true only when status is `valid` - `score` — confidence between 0 and 1; higher means more deliverable - `reason` — machine-readable verdict explanation: `accepted_email`, `disposable_provider`, `invalid_syntax`, `no_mx_record`, `likely_typo` - `suggestion` — suggested correction for typo-like addresses (e.g. `ada@gmail.com` for `ada@gmial.com`); null otherwise - `checks` — per-signal breakdown (see below) - `provider` — mailbox provider when identifiable (e.g. `google.com`); null when unknown - `created_at` — ISO 8601 timestamp The `checks` object signals: - `syntax` — address is syntactically well-formed - `domain_exists` — domain resolves in DNS - `mx` — domain publishes MX records and can receive mail - `smtp` — result of the SMTP mailbox probe; null when probe was not run - `disposable` — domain belongs to a disposable/throwaway provider - `role_based` — local part is a role address (support@, admin@, info@) - `free_provider` — uses a free mailbox provider (Gmail, Outlook, Yahoo) - `catch_all` — domain accepts mail for any local part; null when SMTP probe was not run - `typo` — domain looks like a misspelling of a popular provider - `spam_trap_risk` — `low`, `medium`, `high`, or null Status values: - `valid` — deliverable with high confidence; safe to accept and send - `invalid` — undeliverable: bad syntax, non-existent domain, no MX records, or mailbox rejected by SMTP probe - `risky` — technically deliverable but flagged: catch-all domain, likely typo, or disallowed role-based address - `disposable` — throwaway address from a disposable provider; conclusive regardless of DNS - `unknown` — verdict could not be established (e.g. DNS timed out); retry later or apply your own risk tolerance The `score` refines the status: a `valid` corporate mailbox confirmed over SMTP scores higher than a `valid` free-provider address. Many teams accept >= 0.7 and review the rest. Example request: ``` curl https://api.apiddress.com/api/v1/validate-email \ -H "x-api-key: YOUR_API_KEY" \ -H "content-type: application/json" \ -d '{"email": "ada@stripe.com", "check_smtp": true}' ``` ## Bulk validation (up to 100 addresses) `POST /api/v1/validate-emails` Validates 1–100 email addresses synchronously in a single request. Best for lightweight imports or admin tooling. Request body: `{ "emails": ["..."], "check_smtp": false }` Response: `{ "count": N, "results": [...] }` — one full validation result per address in submission order, same shape as the single-address endpoint. Each address consumes one quota unit individually. Capped at 100 addresses. For lists up to 5,000 use the async batch endpoint. ## Async batch jobs (up to 5,000 addresses) `POST /api/v1/batches` — create a batch job `GET /api/v1/batches/{batch_id}` — poll for status and results Creates an asynchronous job for larger email lists. Quota is reserved up front — a 5,000-address batch requires 5,000 remaining validations or the request fails with `429 quota_exceeded`. Create request body: - `emails` (string[], required) — 1 to 5,000 addresses - `callback_url` (string, optional) — HTTPS URL to POST the finished results to; omit to rely on polling - `check_smtp` (boolean, default false) Create response (202 Accepted): - `batch_id` — job identifier (`bat_…`) - `status` — always `pending` at creation - `submitted_count` — addresses accepted Status lifecycle: `pending` → `processing` → `completed` (or `failed`). Poll `GET /api/v1/batches/{batch_id}` until `status` is `completed`. The `results` array and `completed_at` are null until the job finishes. Webhooks: if `callback_url` was supplied, the completed job payload is POSTed to it when done. Delivery is attempted twice; failed deliveries are not retried further — results remain available via polling. Respond with any 2xx quickly and process out of band. ## Account and usage `GET /api/v1/me` — returns plan, limits, and metadata for the current API key Fields: `id`, `email`, `plan` (`free`/`paid`/`enterprise`), `is_active`, `requests_limit`, `requests_used`, `created_at` Plan quotas: - free: 2,000 validations/month - paid: 50,000 validations/month - enterprise: 250,000 validations/month `GET /api/v1/usage?month=YYYY-MM` — usage for one month (defaults to current) Fields: `month`, `requests_used`, `requests_limit`, `remaining`. Check `remaining` before large imports to fail gracefully instead of mid-way through. `GET /api/v1/usage/history?months=N` — last N calendar months (default 12, max 24), oldest first, zero-filled: `{ "months": [{ "month": "2026-06", "requests_used": 1240, "requests_limit": 2000 }] }`. Powers the beta dashboard usage chart. ## Errors and rate limits Every non-2xx response uses one envelope: `{ "error": { "code": "...", "message": "...", "details": {} } }`. Branch on `error.code`; messages may be reworded, codes will not. Error codes: - `400 invalid_request` — request body or parameters failed validation; `details.field` names the problem - `401 unauthorized` — missing, malformed, revoked, or unknown API key - `404 not_found` — unknown route or a batch ID that does not exist or belongs to another key - `404 claim_invalid` — claim link is invalid, expired, or already used (all three cases are indistinguishable by design) - `429 quota_exceeded` — monthly validation quota exhausted; quota check runs before the work, so a request that would overshoot is rejected whole; counter resets at the start of each calendar month - `429 rate_limited` — per-minute limit on public keyless endpoints (e.g. claim redemption); wait one minute and retry - `500 internal_error` — unexpected server-side failure; safe to retry with backoff Handling guidance: - Treat `400` as a bug in your request — fix, do not retry - Treat `401` as a configuration problem — check the key, do not retry - On `429 quota_exceeded`, pause until next month or upgrade; retrying sooner cannot succeed - On `429 rate_limited` and `500`, retry with exponential backoff ## Optional pages - https://apiddress.com/docs — full documentation (React SPA; also see llms.txt for machine-readable content) - https://apiddress.com/docs/authentication - https://apiddress.com/docs/validate-email - https://apiddress.com/docs/validate-emails - https://apiddress.com/docs/batches - https://apiddress.com/docs/account - https://apiddress.com/docs/errors - https://apiddress.com/terms - https://apiddress.com/privacy