# EmailVerify Pro — complete documentation Email verification API, CLI, SDKs and MCP server. Base URL: https://emailverifypro.com API version 6.0.0. 152 endpoints. This file concatenates every documentation page so it can be ingested in a single fetch. Individual pages are available as Markdown at https://emailverifypro.com/docs/.md --- # Quickstart Source: https://emailverifypro.com/docs/quickstart EmailVerify Pro checks whether an email address can actually receive mail, before you send to it. It runs 152 endpoints covering SMTP probing, DNS and MX intelligence, catch-all resolution, disposable and role detection, and a deliverability score that combines all of them. There are four ways to use it. Pick one: | | Best for | Start here | |---|---|---| | **REST API** | Any language, any platform | [API guide](https://emailverifypro.com/docs/api) | | **CLI** | Terminal, scripts, CI, one-off checks | [CLI guide](https://emailverifypro.com/docs/cli) | | **SDK** | Python or TypeScript applications | [SDK guide](https://emailverifypro.com/docs/sdk) | | **MCP server** | Claude and other AI assistants | [MCP guide](https://emailverifypro.com/docs/mcp) | ## Verify one address in 10 seconds No signup, no key. The API answers unauthenticated requests, rate limited by IP: ```bash curl "https://emailverifypro.com/validate?email=someone@example.com" ``` The same thing from the terminal, if you'd rather not read raw JSON: ```bash pipx install emailverify emailverify verify someone@example.com ``` ``` VALID someone@example.com (mailbox_verified) score=96 A+ can_send=yes ``` ## Reading the result ```json { "email": "someone@example.com", "status": "valid", "sub_status": "mailbox_verified", "deliverability_score": { "score": 96, "grade": "A+", "can_send": true, "recommendation": "Send", "primary_risk": null }, "mx_found": true, "smtp_provider": "google", "is_disposable": false, "is_role": false, "catch_all": false } ``` **The one field that matters is `deliverability_score.can_send`.** It is a boolean that already accounts for catch-all domains, greylisting, provider quirks and role addresses. If you only read one field, read that one. `status` is the raw SMTP verdict and is more nuanced: | `status` | Meaning | Should you send? | |---|---|---| | `valid` | The mailbox was confirmed to exist | Yes | | `invalid` | The mail server explicitly rejected it | No | | `accept_all` | Catch-all domain — accepts every address, so existence cannot be proven over SMTP | Judge by `can_send` | | `unknown` | No definitive answer (greylisting, timeout, provider blocking) | Judge by `can_send` | > A `status` of `unknown` is common and often still scores well above the send threshold, > because dozens of non-SMTP signals agree the address is real. Do not treat `unknown` as > a failure. ## Verify a list ```bash curl -X POST https://emailverifypro.com/validate/bulk \ -H "Content-Type: application/json" \ -d '{"emails":["a@example.com","b@example.com"],"deduplicate":true}' ``` Up to 100 addresses per call. For more, use the async job API: ```bash curl -X POST https://emailverifypro.com/validate/bulk/async \ -H "X-API-Key: evp_your_key" \ -H "Content-Type: application/json" \ -d '{"emails":["..."]}' # -> {"job_id": "job_abc123"} curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/jobs/job_abc123 ``` Or let the CLI handle files, batching and polling: ```bash emailverify bulk --file leads.csv --out results.json ``` ## Get an API key You don't need one to try the API, but a key raises your limits and attributes usage to your account. ```bash curl -X POST https://emailverifypro.com/keys \ -H "Content-Type: application/json" \ -d '{"name":"my-laptop","tier":"free","owner_email":"you@company.com"}' ``` The secret is shown **once**. Full details in the [API keys guide](https://emailverifypro.com/docs/api-keys). ## How long does it take? A single verification typically takes **1–5 seconds**, and can legitimately take **30 seconds or more** when the destination server greylists or stalls. Set a client timeout of at least 60 seconds, and use the async bulk API for large lists rather than holding a connection open. ## Where to go next - [API guide](https://emailverifypro.com/docs/api) — authentication, every core endpoint, full request and response shapes - [API keys](https://emailverifypro.com/docs/api-keys) — create, scope, rotate, revoke - [CLI](https://emailverifypro.com/docs/cli) — all 152 endpoints as shell commands - [SDKs](https://emailverifypro.com/docs/sdk) — Python and TypeScript - [MCP server](https://emailverifypro.com/docs/mcp) — connect Claude or another AI assistant - [Recipes](https://emailverifypro.com/docs/recipes) — clean a CRM export, gate a signup form, verify before a campaign - [Endpoint reference](https://emailverifypro.com/docs/endpoints) — all 152, searchable - [Errors and limits](https://emailverifypro.com/docs/errors) — status codes, rate limits, timeouts --- # REST API Source: https://emailverifypro.com/docs/api The REST API is the foundation — the CLI, the SDKs and the MCP server are all thin wrappers over it. Base URL: ``` https://emailverifypro.com ``` All responses are JSON. All requests that send a body use `Content-Type: application/json`. There are 152 endpoints; this page covers the ones almost everybody uses. The [full reference](https://emailverifypro.com/docs/endpoints) lists the rest, and [`https://emailverifypro.com/openapi.json`](https://emailverifypro.com/openapi.json) is the machine-readable spec. ## Authentication Pass your key in the `X-API-Key` header: ```bash curl -H "X-API-Key: evp_your_key" "https://emailverifypro.com/validate?email=a@example.com" ``` Or as a query parameter, where headers are awkward: ```bash curl "https://emailverifypro.com/validate?email=a@example.com&api_key=evp_your_key" ``` > **Warning.** A key in a query string ends up in browser history, proxy logs and server > access logs. Prefer the header. Requests without a key still work and are rate limited by IP. A key raises your limits and attributes usage to your account. See [API keys](https://emailverifypro.com/docs/api-keys). ## Verify a single address ### `GET /validate` The workhorse. Every signal layer, one address. ```bash curl -H "X-API-Key: evp_your_key" \ "https://emailverifypro.com/validate?email=someone@example.com" ``` | Parameter | Type | Default | Purpose | |---|---|---|---| | `email` | string | *required* | The address to verify | | `smtp` | bool | `true` | Perform the live SMTP probe. Turning this off is much faster but far less accurate | | `rbl` | bool | `true` | Check the MX IP against blacklists | | `gravatar` | bool | `true` | Look for a Gravatar as a signal the address is real | | `breach` | bool | `false` | Check breach databases — strong evidence an address existed | | `web_presence` | bool | `true` | Look for the address on the domain's website | | `domain_age` | bool | `true` | Domain registration age; very new domains are riskier | | `enrich` | bool | `false` | Add the ML prediction and an activity score | | `suppression` | bool | `true` | Check your suppression list first | ### `POST /validate` Same thing with a JSON body — use it when the address may contain characters awkward in a URL. ```bash curl -X POST https://emailverifypro.com/validate \ -H "X-API-Key: evp_your_key" \ -H "Content-Type: application/json" \ -d '{"email":"someone@example.com","breach":true,"enrich":true}' ``` ### The response ```json { "email": "someone@example.com", "status": "valid", "sub_status": "mailbox_verified", "confidence_score": 99, "deliverability": "deliverable", "deliverability_score": { "score": 96, "grade": "A+", "band": "excellent", "can_send": true, "recommendation": "Send", "primary_risk": null, "email_type": "personal", "breakdown": { "mx_found": 10, "smtp_valid": 25, "corporate_domain": 5, "name_pattern": 5 } }, "account": "someone", "domain": "example.com", "mx_found": true, "mx_records": ["aspmx.l.google.com"], "smtp_provider": "google", "smtp_response_code": "250", "catch_all": false, "is_disposable": false, "is_role": false, "is_free": false, "did_you_mean": null } ``` | Field | Why you care | |---|---| | `deliverability_score.can_send` | **The decision.** Boolean, already weighs every signal | | `deliverability_score.score` | 0–100, if you want your own threshold | | `status` | Raw SMTP verdict: `valid`, `invalid`, `accept_all`, `unknown` | | `sub_status` | Why — e.g. `mailbox_verified`, `mailbox_not_found`, `catch_all_address` | | `catch_all` | The domain accepts everything; per-address proof is impossible | | `is_disposable` | Temporary/burner provider | | `is_role` | `support@`, `info@`, `sales@` — real, but not a person | | `did_you_mean` | Typo suggestion, e.g. `gmial.com` → `gmail.com` | ## Verify many addresses ### `POST /validate/bulk` — synchronous, up to 100 ```bash curl -X POST https://emailverifypro.com/validate/bulk \ -H "X-API-Key: evp_your_key" \ -H "Content-Type: application/json" \ -d '{ "emails": ["a@example.com", "b@example.com"], "deduplicate": true, "check_suppression": true, "max_concurrent": 10 }' ``` ```json { "total": 2, "processing_time_ms": 8652, "summary": {"valid": 1, "invalid": 1}, "results": [ {"email": "a@example.com", "status": "valid", "confidence_score": 95}, {"email": "b@example.com", "status": "invalid", "sub_status": "mailbox_not_found"} ] } ``` > The whole call blocks until every address finishes, so it takes as long as the slowest > one. For more than about 25 addresses, prefer the async endpoint. ### `POST /validate/bulk/async` — a job you poll ```bash curl -X POST https://emailverifypro.com/validate/bulk/async \ -H "X-API-Key: evp_your_key" \ -H "Content-Type: application/json" \ -d '{"emails": ["a@example.com", "b@example.com"]}' ``` ```json {"job_id": "job_a1b2c3", "status": "queued", "total": 2} ``` ```bash curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/jobs/job_a1b2c3 ``` Poll every few seconds until `status` is `completed`, then read `results`. `GET /jobs/{job_id}/dead-letter` lists addresses that failed permanently, and `POST /jobs/{job_id}/retry-dead-letter` re-queues them. ### `POST /validate/bulk/turbo` Same shape as `/validate/bulk`, tuned for throughput over per-address depth. Use it when you are cleaning a very large list and can accept slightly lower confidence. ## Faster, cheaper checks | Endpoint | Cost | Use when | |---|---|---| | `GET /validate/syntax` | free, instant | Form validation — is it even a well-formed address? | | `GET /validate/quick` | fast | DNS and MX only, no SMTP probe | | `GET /validate/fast` | fast | Cached result if present, otherwise a shallow check | | `GET /validate` | full | You are about to send mail to this address | ```bash curl "https://emailverifypro.com/validate/syntax?email=not-an-email" ``` ```json {"email": "not-an-email", "valid": false, "normalized": "", "did_you_mean": null} ``` ## Catch-all domains A catch-all domain accepts mail for *every* address, so no verifier on earth can prove a specific mailbox exists there over SMTP. When `status` is `accept_all`, resolve it with additional signals: ```bash curl -X POST https://emailverifypro.com/resolve-catchall \ -H "X-API-Key: evp_your_key" \ -H "Content-Type: application/json" \ -d '{"email":"jane@catchall-example.com"}' ``` This runs a nine-signal pipeline — Microsoft credential probing, LinkedIn presence, breach records, Gravatar, domain cohort behaviour and more — and returns a resolved verdict where it can. > **Warning.** Treat `accept_all` as its own risk tier, not as a pass or a fail. Roughly > a quarter of business domains are catch-all. ## Finding an address ```bash curl -X POST https://emailverifypro.com/find-email \ -H "X-API-Key: evp_your_key" \ -H "Content-Type: application/json" \ -d '{"domain":"example.com","first_name":"Jane","last_name":"Doe"}' ``` Detects the domain's naming convention (`first.last@`, `flast@`, `first@`) from known addresses, then constructs and verifies the most likely candidates. Related: `GET /domain-formats/{domain}` returns the learned pattern on its own. ## Suppression list Stop sending to addresses that bounced, complained or unsubscribed. ```bash curl -X POST https://emailverifypro.com/suppression/add \ -H "X-API-Key: evp_your_key" \ -H "Content-Type: application/json" \ -d '{"email":"unsubscribed@example.com","reason":"unsubscribe"}' curl -H "X-API-Key: evp_your_key" \ "https://emailverifypro.com/suppression/check?email=unsubscribed@example.com" ``` With `check_suppression: true` (the default), bulk verification skips suppressed addresses automatically. ## Feedback improves accuracy Report real outcomes and the model learns from them: ```bash curl -X POST https://emailverifypro.com/bounce \ -H "Content-Type: application/json" \ -d '{"email":"bounced@example.com","bounce_type":"hard"}' curl -X POST https://emailverifypro.com/delivered \ -H "Content-Type: application/json" \ -d '{"email":"delivered@example.com"}' ``` Your ESP can post these directly — there are ready-made receivers at `/webhooks/sendgrid`, `/webhooks/ses`, `/webhooks/postmark` and `/webhooks/mailchimp`. ## Account and usage ```bash curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/me/usage # quota remaining curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/me/stats # verification statistics curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/me/recent-verifications ``` ## Errors ```json {"detail": "Invalid or revoked API key"} ``` | Code | Meaning | Do this | |---|---|---| | `200` | Success | — | | `401` | Key missing, invalid or revoked | Check the key. If you just created it, wait up to 2 minutes | | `404` | No such resource, or it belongs to another account | — | | `422` | Invalid parameters | The body names the offending field | | `429` | Rate limited | Back off and retry; the SDKs do this automatically | | `500` | Server error | Retry once | Full detail in [errors and limits](https://emailverifypro.com/docs/errors). ## Machine-readable specs | | | |---|---| | OpenAPI 3.1 | [`https://emailverifypro.com/openapi.json`](https://emailverifypro.com/openapi.json) | | Interactive explorer | [`https://emailverifypro.com/docs`](https://emailverifypro.com/docs) | | Tooling manifest | [`https://emailverifypro.com/tooling`](https://emailverifypro.com/tooling) | | These docs as Markdown | [`https://emailverifypro.com/llms-full.txt`](https://emailverifypro.com/llms-full.txt) | Generate a client for any language straight from the spec: ```bash npx @openapitools/openapi-generator-cli generate \ -i https://emailverifypro.com/openapi.json -g go -o ./emailverify-go ``` --- # API keys Source: https://emailverifypro.com/docs/api-keys Every key belongs to exactly one account, identified by `owner_email`. That ownership is what lets you list, inspect, rotate and revoke it — and what stops anyone else doing the same to your keys. ## Create a key ```bash curl -X POST https://emailverifypro.com/keys \ -H "Content-Type: application/json" \ -d '{"name":"my-laptop","tier":"free","owner_email":"you@company.com"}' ``` ```json { "key_id": "kid_a1b2c3d4e5f60718", "api_key": "evp_xxxxxxxxxxxxxxxxxxxxxxxx", "tier": "free", "monthly_limit": 100, "rate_per_min": 10, "owner_email": "you@company.com", "warning": "Save this key now — it cannot be retrieved again." } ``` | Field | Required | Notes | |---|---|---| | `name` | yes | A label you'll recognise later — `ci`, `laptop`, `production` | | `owner_email` | yes | Scopes the key to you. Must be a valid address | | `tier` | no | `free`, `starter`, `pro`, `enterprise`. Defaults to `free` | > **Warning.** `api_key` is returned once and never again. No endpoint will show it to > you later — only metadata. If you lose it, rotate the key. > A new key takes up to 2 minutes to replicate to every verification worker. Until then > it can return `401 Invalid or revoked API key`. Wait and retry. Anonymous creation is capped at **5 keys per IP per hour**. Authenticated callers are not capped, and their new keys are always bound to their own account regardless of what `owner_email` says. ## Use a key ```bash curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/me/usage ``` ```bash curl "https://emailverifypro.com/me/usage?api_key=evp_your_key" ``` > **Warning.** A key in a query string ends up in browser history, proxy logs and server > access logs. Use the header wherever you can. With the CLI, store it once: ```bash emailverify login ``` ## List your keys Authenticate with any active key you own. The response is scoped to that key's `owner_email` and never contains secrets. ```bash curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/keys ``` ```json { "owner_email": "you@company.com", "keys": [ { "key_id": "kid_a1b2c3d4e5f60718", "name": "my-laptop", "tier": "free", "is_active": 1, "monthly_limit": 100, "rate_per_min": 10, "verifications_this_month": 12, "verifications_total": 480, "created_at": 1785680898.94, "last_used": 1785690000.11 } ] } ``` ## Inspect one key ```bash curl -H "X-API-Key: evp_your_key" \ https://emailverifypro.com/keys/kid_a1b2c3d4e5f60718/usage ``` Another account's `key_id` returns `404`, not `403` — the API will not confirm that an id it doesn't own even exists. ## Rotate a key Issues a fresh secret with the same name and tier, and revokes the old one. ```bash curl -X POST -H "X-API-Key: evp_your_key" \ https://emailverifypro.com/keys/kid_a1b2c3d4e5f60718/rotate ``` ```json { "key_id": "kid_9f8e7d6c5b4a3021", "api_key": "evp_yyyyyyyyyyyyyyyyyyyyyyyy", "rotated_from": "kid_a1b2c3d4e5f60718", "revoked": "kid_a1b2c3d4e5f60718" } ``` > **Warning.** The old key stops working immediately. Deploy the new one first, or accept > a gap. Rotate whenever a key may have been exposed — in a commit, a log, a screenshot > or a support ticket. ## Revoke a key ```bash curl -X DELETE -H "X-API-Key: evp_your_key" \ https://emailverifypro.com/keys/kid_a1b2c3d4e5f60718 ``` Irreversible. You cannot revoke a key you do not own. ## Who can do what | Endpoint | Auth | Scope | |---|---|---| | `POST /keys` | optional | Anonymous self-serve, 5 per IP per hour. Authenticated callers get a key bound to their own account | | `GET /keys` | **required** | Only your keys | | `GET /keys/{key_id}/usage` | **required** | Yours only; another account's id returns 404 | | `POST /keys/{key_id}/rotate` | **required** | Yours only | | `DELETE /keys/{key_id}` | **required** | Yours only | ## Tiers and limits | Tier | Verifications / month | Requests / minute | |---|---|---| | `free` | 100 | 10 | | `starter` | 1,000 | 30 | | `pro` | 10,000 | 100 | | `enterprise` | unlimited | 500 | Check what's left: ```bash curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/me/usage ``` Exceeding a limit returns `429`. The SDKs back off and retry automatically. ## Keeping keys safe - Put keys in environment variables or a secret manager, never in source control. - Use a **separate key per environment** — laptop, CI, staging, production — so you can revoke one without disrupting the others. - The CLI stores its key at `~/.config/emailverify/config.json` with mode `600`. - Rotate on any suspicion of exposure. Rotation is instant and free. - Prefer the `X-API-Key` header over the `api_key` query parameter. ## With the CLI ```bash emailverify login # store a key emailverify keys # list yours emailverify create-key --name ci --owner-email you@co.com emailverify raw POST /keys/kid_abc123/rotate # rotate emailverify raw DELETE /keys/kid_abc123 # revoke emailverify config # which key is in use emailverify logout # forget it ``` --- # Command line interface Source: https://emailverifypro.com/docs/cli A command for every one of the 152 API endpoints, generated from the OpenAPI spec — so the moment an endpoint ships, it has a command. The common operations also get short aliases. ## Install ```bash pipx install emailverify ``` ```bash npm install -g @emailverifypro/mcp ``` Both packages install the same `emailverify` command with the same behaviour. Pick whichever matches your stack. The Python build has **no runtime dependencies**; the Node build needs Node 18 or newer. Run it without installing anything: ```bash uvx --from emailverify emailverify verify someone@example.com ``` ```bash npx -y @emailverifypro/mcp emailverify verify someone@example.com ``` ## Authenticate once ```bash emailverify login ``` Prompts for your key and writes `~/.config/emailverify/config.json` with mode `600`. Precedence, highest first: 1. `--api-key` on the command line 2. `EMAILVERIFY_API_KEY` in the environment 3. the config file ```bash emailverify config # show which key and base URL are in effect emailverify logout # forget the stored key ``` ## Verify ```bash emailverify verify someone@example.com ``` ``` VALID someone@example.com (mailbox_verified) score=96 A+ can_send=yes ``` The summary line is colourised by status: green `VALID`, red `INVALID`, amber `ACCEPT_ALL`, grey `UNKNOWN`. Add `--json` for the full response: ```bash emailverify verify someone@example.com --json ``` Pipe it straight into `jq`: ```bash emailverify verify someone@example.com --json | jq -r '.deliverability_score.can_send' ``` Turn signals on and off: ```bash emailverify verify someone@example.com --smtp false --breach true --enrich true ``` ## Verify a file ```bash emailverify bulk --file leads.csv --out results.json ``` `--file` accepts: - one address per line - a JSON array — `["a@x.com", "b@y.com"]` - a CSV — it picks the column containing an `@` - `-` to read standard input ```bash cut -d, -f3 crm-export.csv | emailverify bulk --file - --out results.json ``` Bulk calls take as long as their slowest address, so raise the timeout for big batches: ```bash emailverify bulk --file big-list.txt --timeout 600 --out results.json ``` ## Discover commands ```bash emailverify list # everything, grouped by category emailverify list --tag Verification # one category emailverify list --search catchall # search paths, names and descriptions emailverify describe validate:bulk # parameters for one command ``` `describe` prints the method, path, every parameter with its type and default, and whether the command is destructive. ## Call anything Named commands cover every endpoint, but `raw` bypasses them entirely: ```bash emailverify raw GET /db/stats emailverify raw GET /validate --query email=a@b.com --query smtp=false emailverify raw POST /bounce --body '{"email":"a@b.com","bounce_type":"hard"}' ``` ## Aliases | Command | Endpoint | What it does | |---|---|---| | `emailverify verify` | `GET /validate` | Validate Get | | `emailverify bulk` | `POST /validate/bulk` | Validate Bulk | | `emailverify bulk-async` | `POST /validate/bulk/async` | Validate Bulk Async | | `emailverify quick` | `GET /validate/quick` | Validate Quick | | `emailverify syntax` | `GET /validate/syntax` | Validate Syntax Only | | `emailverify score` | `GET /score` | Get Deliverability Score | | `emailverify find-email` | `POST /find-email` | Find Email Endpoint | | `emailverify domain` | `GET /domain-intel/{domain}` | Get Domain Intel | | `emailverify usage` | `GET /me/usage` | Me Usage | | `emailverify stats` | `GET /me/stats` | Me Stats | | `emailverify recent` | `GET /me/recent-verifications` | Me Recent Verifications | | `emailverify keys` | `GET /keys` | List Keys | | `emailverify create-key` | `POST /keys` | Create Key | | `emailverify health` | `GET /health` | Health | | `emailverify plans` | `GET /plans` | Get Plans | | `emailverify suppress` | `POST /suppression/add` | Suppression Add | | `emailverify suppressed` | `GET /suppression/check` | Suppression Check | | `emailverify dedup` | `POST /utils/dedup` | Dedup Emails | | `emailverify catchall` | `POST /resolve-catchall` | Resolve Catchall Endpoint | | `emailverify job` | `GET /jobs/{job_id}` | Get Job | Everything else follows the endpoint path — `/validate/bulk/async` becomes `validate:bulk:async`, `/jobs/{job_id}` becomes `jobs:job-id`. ## Destructive commands Deletes and admin operations prompt before running, and refuse outright when not attached to a terminal: ```bash emailverify gdpr:erase someone@example.com ``` ``` About to call DELETE /gdpr/erase — this is destructive. Type 'yes' to continue: ``` Pass `--yes` in scripts. Without a terminal and without `--yes`, the command exits `2` rather than guessing. ## Scripting Exit codes are stable, so you can branch on them: | Code | Meaning | |---|---| | `0` | Success | | `1` | Unknown command, or the user declined a confirmation | | `2` | Bad arguments — a required parameter is missing | | `3` | Authentication failed | | `4` | API or transport error | ```bash #!/usr/bin/env bash set -euo pipefail if emailverify verify "$1" --json | jq -e '.deliverability_score.can_send' >/dev/null; then echo "safe to send" else echo "do not send"; exit 1 fi ``` Verify a list and keep only the good ones: ```bash emailverify bulk --file leads.txt --json \ | jq -r '.results[] | select(.status=="valid") | .email' \ > clean.txt ``` Set `NO_COLOR=1` to strip ANSI codes when writing to a log. ## Global flags | Flag | Purpose | |---|---| | `--json` | Full JSON instead of the summary line | | `--out PATH` | Write the JSON response to a file | | `--file PATH` | Read a list argument from a file (`-` for stdin) | | `--yes`, `-y` | Skip the confirmation on destructive commands | | `--api-key KEY` | Override the stored key | | `--base-url URL` | Point at staging or a self-hosted instance | | `--timeout SECONDS` | Per-request timeout, default 60 | | `--verbose`, `-v` | Log the request line to stderr | ## Environment | Variable | Purpose | |---|---| | `EMAILVERIFY_API_KEY` | Your key; overrides the config file | | `EMAILVERIFY_BASE_URL` | Staging or self-hosted instance | | `EMAILVERIFY_CONFIG` | Alternative config file path | | `EMAILVERIFY_CA_BUNDLE` | CA bundle, if your Python has none | | `NO_COLOR` | Disable colour | ## Troubleshooting **`CERTIFICATE_VERIFY_FAILED`** — your Python has no CA bundle, common on python.org macOS builds. Run *Install Certificates.command*, or `pip install certifi`, or set `EMAILVERIFY_CA_BUNDLE=/etc/ssl/cert.pem`. **`error: unknown command 'verifyy'`** — the CLI suggests the nearest matches. Run `emailverify list` to see everything. **A command hangs** — some verifications take 30 seconds or more. Raise `--timeout`, or use `emailverify bulk-async` and poll with `emailverify job `. **`401` on a key you just created** — keys take up to 2 minutes to replicate to every verification worker. Wait and retry. --- # MCP server Source: https://emailverifypro.com/docs/mcp The Model Context Protocol lets an AI assistant call real tools instead of guessing. This server exposes **144 tools** — every endpoint except the 8 inbound ESP webhooks, which exist for SendGrid, SES, Postmark and Stripe to call *you*. Once connected, an assistant can verify addresses, clean lists, resolve catch-all domains and check your quota, all without you writing any code. ## Install Node — nothing to install ahead of time: ```json { "mcpServers": { "emailverify": { "command": "npx", "args": ["-y", "@emailverifypro/mcp"], "env": { "EMAILVERIFY_API_KEY": "evp_your_key" } } } } ``` Python: ```json { "mcpServers": { "emailverify": { "command": "uvx", "args": ["--from", "emailverify[mcp]", "emailverify-mcp"], "env": { "EMAILVERIFY_API_KEY": "evp_your_key" } } } } ``` ### Where that config goes | Client | Location | |---|---| | Claude Desktop (macOS) | `~/Library/Application Support/Claude/claude_desktop_config.json` | | Claude Desktop (Windows) | `%APPDATA%\Claude\claude_desktop_config.json` | | Claude Code | `claude mcp add emailverify -- npx -y @emailverifypro/mcp` | | Cursor | Settings → MCP → Add new server | | Windsurf | `~/.codeium/windsurf/mcp_config.json` | | Zed | `~/.config/zed/settings.json` under `context_servers` | In Claude Desktop the file is reachable via Settings → Developer → Edit Config. Restart the app after editing. ## Try it Ask in plain language: - *“Verify brandon@seamlessai.com and tell me whether it will bounce.”* - *“Here are 40 addresses — which are safe to email?”* - *“Is acme.com a catch-all domain?”* - *“What email format does stripe.com use? Then work out Jane Doe's address.”* - *“How much of my verification quota is left this month?”* - *“Add these five addresses to my suppression list.”* - *“This address came back unknown — dig into why.”* ## What the assistant sees Each tool carries the endpoint's summary, its method and path, and an annotation saying how dangerous it is. | Annotation | Tools | Meaning | |---|---|---| | `readOnlyHint` | 90 | `GET` — no side effects, safe to call freely | | `destructiveHint` | 20 | Deletes or overwrites. Well-behaved clients confirm first | | `idempotentHint` | — | Repeating the call is safe | Tools are named after the endpoint: `get_validate`, `post_validate_bulk`, `post_find_email`, `delete_gdpr_erase`. ### Coverage by category | Category | Tools | |---|---| | Verification | 15 | | Signals | 14 | | Infrastructure | 9 | | Admin | 8 | | Feedback | 8 | | Integrations | 8 | | Auth | 6 | | Account | 6 | | Bulk | 5 | | GDPR / CCPA | 5 | | System | 5 | | API Keys | 5 | | Billing | 4 | | Database | 4 | ## Narrowing the tool list 144 tools is a large surface, and most clients choose more accurately from a smaller set. Two environment variables trim it: ```bash EMAILVERIFY_MCP_READONLY=1 ``` Publishes only the 90 read-only tools — nothing can delete or overwrite. This is the safest setting for a shared or autonomous assistant. ```bash EMAILVERIFY_MCP_TAGS="Verification,Bulk,Account" ``` Publishes only those categories. Combine both for a minimal, read-only verification surface. ## Configuration | Variable | Default | Purpose | |---|---|---| | `EMAILVERIFY_API_KEY` | — | Your key. Without it, only public endpoints work | | `EMAILVERIFY_BASE_URL` | `https://emailverifypro.com` | Staging or self-hosted instance | | `EMAILVERIFY_MCP_READONLY` | off | `1` publishes only read-only tools | | `EMAILVERIFY_MCP_TAGS` | all | Comma-separated category allowlist | | `EMAILVERIFY_TIMEOUT` | `60` | Per-request timeout in seconds | A read-only, verification-only setup: ```json { "mcpServers": { "emailverify": { "command": "npx", "args": ["-y", "@emailverifypro/mcp"], "env": { "EMAILVERIFY_API_KEY": "evp_your_key", "EMAILVERIFY_MCP_READONLY": "1", "EMAILVERIFY_MCP_TAGS": "Verification,Bulk" } } } } ``` ## Checking it works Run the server by hand. It speaks JSON-RPC over stdio and prints a banner to stderr: ```bash EMAILVERIFY_API_KEY=evp_your_key npx -y @emailverifypro/mcp ``` ``` emailverify MCP server v1.0.0 — 144 tools (API v6.0.0) ``` If you see that line, the server is healthy and the problem is in your client config. ## Troubleshooting **The server doesn't appear.** JSON config files are unforgiving — a trailing comma or a missing brace silently breaks the whole file. Validate it, then fully restart the client. **Tools appear but every call fails with 401.** `EMAILVERIFY_API_KEY` is missing or wrong. It must sit in the `env` block of the server entry, not in your shell — MCP servers do not inherit your interactive environment. **Calls time out.** Some verifications legitimately take 30 seconds or more while SMTP probes run. Raise `EMAILVERIFY_TIMEOUT`, or ask the assistant to use the async bulk endpoint and poll the job. **`npx` is slow the first time.** It downloads the package on first run. Install it globally (`npm i -g @emailverifypro/mcp`) and use `emailverify-mcp` as the command to avoid the delay. **The assistant picks the wrong tool.** Narrow the surface with `EMAILVERIFY_MCP_TAGS`, and name the operation you want in your prompt. --- # Python & TypeScript SDKs Source: https://emailverifypro.com/docs/sdk Official clients for Python and TypeScript. Neither has a hand-written method per endpoint — both read a registry generated from the OpenAPI spec, so every endpoint is reachable the moment it ships. ## Python ```bash pip install emailverify ``` No runtime dependencies — standard library only. Python 3.10 or newer. ### Get started ```python from emailverify import Client client = Client.from_env() # EMAILVERIFY_API_KEY, or ~/.config/emailverify result = client.verify("someone@example.com") print(result["status"]) # "valid" print(result["deliverability_score"]["can_send"]) # True ``` ### Configure explicitly ```python client = Client( api_key="evp_your_key", base_url="https://emailverifypro.com", timeout=120, # seconds; raise for slow domains max_retries=3, # 429 and 5xx are retried with exponential backoff verbose=False, # log request lines to stderr ) ``` ### Built-in helpers ```python client.verify("a@example.com") # GET /validate client.bulk(["a@example.com", "b@example.com"]) # POST /validate/bulk client.score("a@example.com") # GET /score client.usage() # GET /me/usage ``` ### Any endpoint by name ```python client.call("db:stats") client.call("suppression:check", email="a@example.com") client.call("domain-intel:domain", domain="stripe.com") client.call("find-email", domain="example.com", first_name="Jane", last_name="Doe") ``` Names are the CLI command names — `emailverify list` prints them all, and [the endpoint reference](https://emailverifypro.com/docs/endpoints) shows each one. ### Raw requests ```python client.request("GET", "/validate", query={"email": "a@example.com"}) client.request("POST", "/validate/bulk", body={"emails": ["a@example.com"]}) ``` ### Errors ```python from emailverify import Client, AuthError, EmailVerifyError try: client.verify("someone@example.com") except AuthError: ... # 401/403 — key missing, invalid or unauthorised except EmailVerifyError as e: print(e.status, e.body, e.url) # everything else, with the server's own detail ``` `429` and `5xx` are retried automatically. `401` and `403` are not — retrying a bad key never helps. ### Introspection ```python from emailverify import endpoints, commands, api_version print(api_version()) # "6.0.0" print(len(endpoints())) # every endpoint, as dicts print(commands()[:5]) # every command name ``` ### A complete example ```python import csv from emailverify import Client, EmailVerifyError client = Client.from_env(timeout=300) with open("leads.csv") as fh: emails = [r["email"] for r in csv.DictReader(fh) if r.get("email")] safe = [] for i in range(0, len(emails), 100): # bulk caps at 100 per call try: for r in client.bulk(emails[i:i + 100])["results"]: score = r.get("deliverability_score") or {} if score.get("can_send"): safe.append(r["email"]) except EmailVerifyError as e: print(f"batch {i} failed: {e}") print(f"{len(safe)} of {len(emails)} are safe to send") ``` ## TypeScript and JavaScript ```bash npm install @emailverifypro/mcp ``` Node 18 or newer — it uses the built-in `fetch`. Ships its own type declarations. ### Get started ```typescript import { Client } from "@emailverifypro/mcp"; const client = new Client(); // reads EMAILVERIFY_API_KEY const result = await client.request("GET", "/validate", { email: "someone@example.com", }); console.log(result); ``` ### Configure explicitly ```typescript const client = new Client({ apiKey: "evp_your_key", baseUrl: "https://emailverifypro.com", timeoutMs: 120_000, maxRetries: 3, verbose: false, }); ``` ### Registry-driven calls ```typescript import { Client } from "@emailverifypro/mcp"; import { lookup, endpoints } from "@emailverifypro/mcp/registry"; const client = new Client(); const result = await client.callEndpoint(lookup("verify")!, { email: "someone@example.com", }); const bulk = await client.callEndpoint(lookup("bulk")!, { emails: ["a@example.com", "b@example.com"], deduplicate: true, }); console.log(endpoints.length); ``` ### Errors ```typescript import { Client, AuthError, EmailVerifyError } from "@emailverifypro/mcp"; try { await client.request("GET", "/me/usage"); } catch (e) { if (e instanceof AuthError) { // 401 / 403 } else if (e instanceof EmailVerifyError) { console.log(e.status, e.body, e.url); } } ``` ### In an Express route ```typescript import express from "express"; import { Client } from "@emailverifypro/mcp"; const app = express(); const verifier = new Client(); app.post("/signup", express.json(), async (req, res) => { const check = await verifier.request("GET", "/validate", { email: req.body.email, }) as any; if (check.is_disposable) { return res.status(400).json({ error: "Please use a permanent address." }); } if (check.did_you_mean) { return res.status(400).json({ error: `Did you mean ${check.did_you_mean}?` }); } if (!check.deliverability_score?.can_send) { return res.status(400).json({ error: "We couldn't verify that address." }); } res.json({ ok: true }); }); ``` > Full verification can take seconds. On a request path, prefer `GET /validate/quick` > and follow up properly in a background job. ## Other languages There is no official client for other languages, but the OpenAPI spec drives most generators: ```bash npx @openapitools/openapi-generator-cli generate \ -i https://emailverifypro.com/openapi.json -g go -o ./emailverify-go ``` Substitute `-g` for `java`, `php`, `ruby`, `rust`, `csharp` and so on. Or just call it — it is ordinary REST over HTTPS: ```go req, _ := http.NewRequest("GET", "https://emailverifypro.com/validate?email=someone@example.com", nil) req.Header.Set("X-API-Key", os.Getenv("EMAILVERIFY_API_KEY")) resp, err := http.DefaultClient.Do(req) ``` ```php $ch = curl_init("https://emailverifypro.com/validate?email=someone@example.com"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["X-API-Key: " . getenv("EMAILVERIFY_API_KEY")]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); ``` ```ruby require "net/http" uri = URI("https://emailverifypro.com/validate?email=someone@example.com") req = Net::HTTP::Get.new(uri) req["X-API-Key"] = ENV["EMAILVERIFY_API_KEY"] res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) } ``` --- # Recipes Source: https://emailverifypro.com/docs/recipes Complete, working solutions to the things people actually build. Every snippet runs as-is once you substitute your key. ## Clean a CRM export before a campaign You have a CSV of leads and want only the addresses that will land. ```bash emailverify login emailverify bulk --file leads.csv --out verified.json --timeout 300 ``` `--file` accepts one address per line, a JSON array, or a CSV — for a CSV it picks the column containing an `@`. Then keep only the sendable ones: ```bash jq -r '.results[] | select(.status == "valid" or .status == "accept_all") | .email' \ verified.json > safe-to-send.txt ``` Or in Python, using the deliverability score rather than the raw status: ```python import csv, json from emailverify import Client client = Client.from_env() with open("leads.csv") as fh: emails = [row["email"] for row in csv.DictReader(fh) if row.get("email")] safe, risky = [], [] for i in range(0, len(emails), 100): # bulk caps at 100 per call for r in client.bulk(emails[i:i + 100])["results"]: score = r.get("deliverability_score") or {} target = safe if score.get("can_send") else risky target.append(r["email"]) print(f"{len(safe)} safe, {len(risky)} risky") open("safe-to-send.txt", "w").write("\n".join(safe)) ``` ## Gate a signup form Validate syntax instantly on the client, then verify properly on the server before you create the account. ```javascript // server side — never trust the browser for this const res = await fetch( `https://emailverifypro.com/validate?email=${encodeURIComponent(email)}`, { headers: { "X-API-Key": process.env.EMAILVERIFY_API_KEY } } ); const data = await res.json(); if (data.is_disposable) { return reject("Please use a permanent email address."); } if (data.did_you_mean) { return suggest(`Did you mean ${data.did_you_mean}?`); } if (!data.deliverability_score?.can_send) { return reject("We couldn't verify that address."); } ``` > Keep the full check off the request path where you can — it can take seconds. Either > run it asynchronously after signup, or use `GET /validate/quick` for a fast DNS-only > answer and follow up properly in a background job. ## Catch typos at the point of entry ```bash curl "https://emailverifypro.com/verify/typo?email=someone@gmial.com" ``` ```json {"email": "someone@gmial.com", "did_you_mean": "someone@gmail.com", "confidence": 0.97} ``` ## Block disposable addresses ```python r = client.verify("test@mailinator.com") if r["is_disposable"]: raise ValueError("Disposable addresses are not accepted") ``` ## Find someone's address ```python r = client.call("find-email", domain="example.com", first_name="Jane", last_name="Doe") print(r["email"], r["confidence"]) ``` It learns the domain's convention from addresses it has already seen, builds the likely candidates, and verifies them. ## Keep a suppression list in step with your ESP Point your ESP's webhook at the matching receiver and bounces feed back automatically: | ESP | Webhook URL | |---|---| | SendGrid | `https://emailverifypro.com/webhooks/sendgrid` | | Amazon SES | `https://emailverifypro.com/webhooks/ses` | | Postmark | `https://emailverifypro.com/webhooks/postmark` | | Mailchimp | `https://emailverifypro.com/webhooks/mailchimp` | Or record outcomes yourself: ```python client.call("bounce", email="hard-bounced@example.com", bounce_type="hard") client.call("delivered", email="landed@example.com") ``` Every report improves the model for your future verifications. ## Verify in CI before a send ```yaml # .github/workflows/verify-list.yml name: Verify mailing list on: pull_request: paths: ["lists/**.csv"] jobs: verify: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: pipx install emailverify - name: Verify and fail on undeliverable addresses env: EMAILVERIFY_API_KEY: ${{ secrets.EMAILVERIFY_API_KEY }} run: | emailverify bulk --file lists/campaign.csv --out out.json --json bad=$(jq '[.results[] | select(.status == "invalid")] | length' out.json) echo "$bad undeliverable addresses" test "$bad" -eq 0 ``` ## Re-verify a warm list on a schedule Addresses decay — people leave companies and domains lapse. Re-check anything older than 90 days: ```bash emailverify raw POST /admin/reverify --body '{"older_than_days": 90}' ``` ## Deduplicate before you spend credits Gmail dots, plus-addressing and case differences all hide duplicates: ```bash emailverify dedup --file leads.txt ``` ```json {"original_count": 5000, "unique_count": 4380, "duplicates_removed": 620} ``` ## Ask an AI assistant to do it With the [MCP server](https://emailverifypro.com/docs/mcp) connected, these all work as plain requests: - *“Verify every address in this CSV and tell me which will bounce.”* - *“Is acme.com a catch-all domain?”* - *“Find the email format for stripe.com, then work out Jane Doe's address.”* - *“How much of my monthly quota is left?”* - *“Add these five addresses to my suppression list.”* --- # Errors and limits Source: https://emailverifypro.com/docs/errors ## Status codes | Code | Meaning | What to do | |---|---|---| | `200` | Success | — | | `401` | Key missing, invalid or revoked | Check the key. If you created it in the last two minutes, wait for it to replicate | | `404` | No such resource — or it belongs to another account | Key endpoints return 404 rather than 403 so they never confirm that an id exists | | `422` | Invalid parameters | The response names the offending field | | `429` | Rate limited | Back off and retry. Both SDKs do this for you | | `500` | Server error | Retry once. If it persists, report it | Every error has the same shape: ```json {"detail": "Invalid or revoked API key"} ``` ## Rate limits | Tier | Verifications / month | Requests / minute | |---|---|---| | `free` | 100 | 10 | | `starter` | 1,000 | 30 | | `pro` | 10,000 | 100 | | `enterprise` | unlimited | 500 | Requests without a key are rate limited by IP instead. Check your remaining quota: ```bash curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/me/usage ``` Both SDKs retry `429` and `5xx` with exponential backoff, up to `max_retries` (default 3). `401` and `403` are never retried — a bad key does not become good. ## Timeouts > A single verification can legitimately take **30 seconds or more**. SMTP probes wait on > remote mail servers, some of which greylist or stall deliberately. Set a client timeout > of at least 60 seconds. For large lists, don't hold a connection open — use the async job API: ```bash curl -X POST https://emailverifypro.com/validate/bulk/async \ -H "X-API-Key: evp_your_key" \ -H "Content-Type: application/json" \ -d '{"emails": ["a@example.com", "b@example.com"]}' curl -H "X-API-Key: evp_your_key" https://emailverifypro.com/jobs/job_abc123 ``` ## Reading an ambiguous result | `status` | Confidence | Send? | |---|---|---| | `valid` | Mailbox confirmed to exist | Yes | | `invalid` | Explicitly rejected by the mail server | No | | `accept_all` | Catch-all domain — cannot be proven either way over SMTP | Judge by `can_send` | | `unknown` | No definitive SMTP answer | Judge by `can_send` | **Always prefer `deliverability_score.can_send` over `status`.** It already weighs catch-all behaviour, greylisting, provider quirks, domain reputation and dozens of other signals. A `status` of `unknown` frequently still scores above the send threshold. > **Warning.** Catch-all domains are genuinely ambiguous. They accept mail for every > address, so no verifier can prove a specific mailbox exists there. Treat `accept_all` > as its own risk tier rather than as a pass or a fail — roughly a quarter of business > domains are catch-all. Resolve one with additional signals: ```bash curl -X POST https://emailverifypro.com/resolve-catchall \ -H "X-API-Key: evp_your_key" \ -H "Content-Type: application/json" \ -d '{"email":"jane@catchall-example.com"}' ``` ## Common `sub_status` values | `sub_status` | Meaning | |---|---| | `mailbox_verified` | The server confirmed the mailbox | | `mailbox_not_found` | The server said no such user | | `catch_all_address` | The domain accepts everything | | `google_workspace_confirmed` | Confirmed via Google Workspace | | `m365_confirmed` | Confirmed via Microsoft 365 | | `greylisted` | Temporarily deferred; retry later | | `connection_failed` | Could not reach the mail server | | `policy_rejection` | The server refused the probe on policy grounds | | `domain_not_found` | The domain has no DNS or no MX | | `invalid_format` | Not a well-formed address | ## Troubleshooting ### `401` on a key that was just created Keys replicate to the verification workers on a short cycle. Wait two minutes and retry. ### `CERTIFICATE_VERIFY_FAILED` from the Python CLI or SDK The interpreter has no CA bundle — common on python.org macOS builds. Any of these fix it: ```bash /Applications/Python\ 3.12/Install\ Certificates.command pip install certifi export EMAILVERIFY_CA_BUNDLE=/etc/ssl/cert.pem ``` The client already falls back to the usual system bundles before giving up. ### Everything comes back `unknown` Usually the destination provider is blocking probes from your region, or the domain greylists aggressively. The deliverability score still combines every other signal, so `can_send` remains meaningful. ### Bulk verification is slow A bulk call takes as long as its slowest address. Above roughly 25 addresses, switch to `POST /validate/bulk/async` and poll the job. ### The MCP server doesn't appear in my client Validate the JSON config — a trailing comma silently breaks the whole file — then fully restart the client. `EMAILVERIFY_API_KEY` must be in the server's `env` block; MCP servers do not inherit your shell environment. ## Reporting a problem Include the `email` you verified, the full JSON response, and the time. If it is reproducible, `emailverify verify
--json --verbose` captures everything needed. --- # Endpoint reference Source: https://emailverifypro.com/docs/endpoints All 152 endpoints. Each is also a CLI command and an MCP tool. ## API Keys | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /keys` | List Keys | `emailverify keys:get` | `get_keys` | | `POST /keys` | Create Key | `emailverify keys:post` | `post_keys` | | `DELETE /keys/{key_id}` | Revoke Key (**destructive**) | `emailverify keys:key-id` | `delete_keys_by_key_id` | | `POST /keys/{key_id}/rotate` | Rotate Key (**destructive**) | `emailverify keys:key-id:rotate` | `post_keys_by_key_id_rotate` | | `GET /keys/{key_id}/usage` | Key Usage | `emailverify keys:key-id:usage` | `get_keys_by_key_id_usage` | ## Account | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /me/recent-verifications` | Me Recent Verifications | `emailverify me:recent-verifications` | `get_me_recent_verifications` | | `GET /me/stats` | Me Stats | `emailverify me:stats` | `get_me_stats` | | `GET /me/usage` | Me Usage | `emailverify me:usage` | `get_me_usage` | | `GET /me/verification/{verification_id}` | Me Verification Detail | `emailverify me:verification:verification-id` | `get_me_verification_by_verification_id` | | `GET /plans` | Get Plans | `emailverify plans` | `get_plans` | | `GET /usage` | Get Usage | `emailverify usage` | `get_usage` | ## Admin | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /admin/disposable-stats` | Disposable Stats | `emailverify admin:disposable-stats` | `get_admin_disposable_stats` | | `GET /admin/domain-intel/stats` | Admin Domain Intel Stats | `emailverify admin:domain-intel:stats` | `get_admin_domain_intel_stats` | | `GET /admin/domain-learning/stats` | Admin Domain Learning Stats | `emailverify admin:domain-learning:stats` | `get_admin_domain_learning_stats` | | `POST /admin/reverify` | Trigger Reverify (**destructive**) | `emailverify admin:reverify` | `post_admin_reverify` | | `POST /admin/update-disposable` | Update Disposable (**destructive**) | `emailverify admin:update-disposable` | `post_admin_update_disposable` | | `POST /admin/update-intelligence` | Update Intelligence (**destructive**) | `emailverify admin:update-intelligence` | `post_admin_update_intelligence` | | `GET /admin/users` | Admin List Users | `emailverify admin:users` | `get_admin_users` | | `POST /admin/users/{email}/upgrade` | Admin Upgrade User (**destructive**) | `emailverify admin:users:email:upgrade` | `post_admin_users_by_email_upgrade` | ## Analytics | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /stats` | Stats | `emailverify stats` | `get_stats` | | `GET /stats/domains` | Domain Stats | `emailverify stats:domains` | `get_stats_domains` | | `GET /stats/store` | Store Stats | `emailverify stats:store` | `get_stats_store` | ## Auth | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /auth/clerk/config` | Clerk Config | `emailverify auth:clerk:config` | `get_auth_clerk_config` | | `GET /auth/clerk/me` | Clerk Me | `emailverify auth:clerk:me` | `get_auth_clerk_me` | | `POST /auth/logout` | Auth Logout | `emailverify auth:logout` | `post_auth_logout` | | `GET /auth/me` | Auth Me | `emailverify auth:me` | `get_auth_me` | | `POST /auth/request` | Auth Request Magic Link | `emailverify auth:request` | `post_auth_request` | | `POST /auth/verify` | Auth Verify Post | `emailverify auth:verify` | `post_auth_verify` | ## Benchmark | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /benchmark/report/{benchmark_id}` | Benchmark Report Md | `emailverify benchmark:report:benchmark-id` | `get_benchmark_report_by_benchmark_id` | | `POST /benchmark/run` | Benchmark Run | `emailverify benchmark:run` | `post_benchmark_run` | ## Billing | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /billing/checkout/{plan}` | Billing Checkout (*billable*) | `emailverify billing:checkout:plan` | `get_billing_checkout_by_plan` | | `GET /billing/plans` | Billing Plans (*billable*) | `emailverify billing:plans` | `get_billing_plans` | | `POST /billing/signup` | Billing Signup (*billable*) | `emailverify billing:signup` | `post_billing_signup` | | `POST /billing/stripe-webhook` | Billing Stripe Webhook (*billable*) | `emailverify billing:stripe-webhook` | `post_billing_stripe_webhook` | | `GET /billing/usage/{customer_id}` | Billing Usage (*billable*) | `emailverify billing:usage:customer-id` | `get_billing_usage_by_customer_id` | ## Bounce Processing | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `POST /bounce/postmark` | Bounce Postmark | `emailverify bounce:postmark` | `post_bounce_postmark` | | `POST /bounce/sendgrid` | Bounce Sendgrid | `emailverify bounce:sendgrid` | `post_bounce_sendgrid` | | `POST /bounce/ses` | Bounce Ses | `emailverify bounce:ses` | `post_bounce_ses` | | `GET /bounce/stats` | Bounce Stats | `emailverify bounce:stats` | `get_bounce_stats` | ## Bulk | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /bulk/download/{job_id}` | Bulk Download | `emailverify bulk:download:job-id` | `get_bulk_download_by_job_id` | | `GET /bulk/jobs` | Bulk List Jobs | `emailverify bulk:jobs` | `get_bulk_jobs` | | `GET /bulk/status/{job_id}` | Bulk Status | `emailverify bulk:status:job-id` | `get_bulk_status_by_job_id` | | `POST /bulk/upload` | Bulk Upload | `emailverify bulk:upload` | `post_bulk_upload` | | `GET /bulk/{job_id}/report` | Bulk Health Report | `emailverify bulk:job-id:report` | `get_bulk_by_job_id_report` | ## Catch-All Resolution | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /catchall-classifier/stats` | Catchall Classifier Stats | `emailverify catchall-classifier:stats` | `get_catchall_classifier_stats` | | `POST /catchall-classifier/train` | Catchall Classifier Train | `emailverify catchall-classifier:train` | `post_catchall_classifier_train` | | `POST /resolve-catchall` | Resolve Catchall Endpoint | `emailverify resolve-catchall` | `post_resolve_catchall` | ## Compliance | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /compliance/audit-trail` | Compliance Audit | `emailverify compliance:audit-trail` | `get_compliance_audit_trail` | | `DELETE /compliance/customer-data/{customer_id}` | Compliance Erase (**destructive**) | `emailverify compliance:customer-data:customer-id` | `delete_compliance_customer_data_by_customer_id` | | `GET /compliance/summary` | Compliance Summary | `emailverify compliance:summary` | `get_compliance_summary` | ## Database | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /db/domain/{domain}` | Db Domain Stats | `emailverify db:domain:domain` | `get_db_domain_by_domain` | | `GET /db/lookup` | Db Lookup | `emailverify db:lookup` | `get_db_lookup` | | `GET /db/search` | Db Search | `emailverify db:search` | `get_db_search` | | `GET /db/stats` | Db Stats | `emailverify db:stats` | `get_db_stats` | ## Deliverability | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /deliverability/domain/{domain}` | Domain Deliverability | `emailverify deliverability:domain:domain` | `get_deliverability_domain_by_domain` | | `GET /score` | Get Deliverability Score | `emailverify score` | `get_score` | ## Domain Cohort | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /cohort` | List Cohorts | `emailverify cohort` | `get_cohort` | | `GET /cohort/{domain}` | Get Domain Cohort | `emailverify cohort:domain` | `get_cohort_by_domain` | ## Domain Intelligence | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /domain-formats` | List Domain Formats | `emailverify domain-formats` | `get_domain_formats` | | `POST /domain-formats/scrape` | Scrape Domain Format | `emailverify domain-formats:scrape` | `post_domain_formats_scrape` | | `GET /domain-formats/{domain}` | Get Domain Format Endpoint | `emailverify domain-formats:domain` | `get_domain_formats_by_domain` | ## ESP Integrations | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `POST /integrations/hubspot/sync` | Hubspot Sync (**destructive**, *billable*) | `emailverify integrations:hubspot:sync` | `post_integrations_hubspot_sync` | | `POST /integrations/salesforce/sync` | Salesforce Sync (**destructive**, *billable*) | `emailverify integrations:salesforce:sync` | `post_integrations_salesforce_sync` | | `GET /integrations/status` | Integrations Status | `emailverify integrations:status` | `get_integrations_status` | | `POST /integrations/zapier/send` | Zapier Send (**destructive**, *billable*) | `emailverify integrations:zapier:send` | `post_integrations_zapier_send` | | `POST /webhooks/mailchimp` | Mailchimp Webhook | `emailverify webhooks:mailchimp` | `post_webhooks_mailchimp` | | `POST /webhooks/postmark` | Postmark Webhook | `emailverify webhooks:postmark` | `post_webhooks_postmark` | | `POST /webhooks/sendgrid` | Sendgrid Webhook | `emailverify webhooks:sendgrid` | `post_webhooks_sendgrid` | | `POST /webhooks/ses` | Ses Webhook | `emailverify webhooks:ses` | `post_webhooks_ses` | ## Email Finder | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `POST /find-email` | Find Email Endpoint | `emailverify find-email` | `post_find_email` | | `POST /find-email/v2` | Find Email V2 Endpoint | `emailverify find-email:v2` | `post_find_email_v2` | ## Enrichment | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /activity` | Activity Profile | `emailverify activity` | `get_activity` | ## Feedback | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `POST /bounce` | Record Bounce | `emailverify bounce` | `post_bounce` | | `POST /delivered` | Record Delivered | `emailverify delivered` | `post_delivered` | | `GET /feedback/accuracy` | Feedback Accuracy | `emailverify feedback:accuracy` | `get_feedback_accuracy` | | `POST /feedback/clicked` | Feedback Clicked | `emailverify feedback:clicked` | `post_feedback_clicked` | | `POST /feedback/opened` | Feedback Opened | `emailverify feedback:opened` | `post_feedback_opened` | | `POST /feedback/report` | Feedback Report | `emailverify feedback:report` | `post_feedback_report` | | `POST /received` | Record Received | `emailverify received` | `post_received` | | `POST /received/batch` | Record Received Batch | `emailverify received:batch` | `post_received_batch` | ## GDPR / CCPA | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `DELETE /gdpr/domain` | Gdpr Erase Domain (**destructive**) | `emailverify gdpr:domain` | `delete_gdpr_domain` | | `DELETE /gdpr/erase` | Gdpr Erase (**destructive**) | `emailverify gdpr:erase` | `delete_gdpr_erase` | | `GET /gdpr/export` | Gdpr Export | `emailverify gdpr:export` | `get_gdpr_export` | | `POST /gdpr/purge` | Gdpr Purge (**destructive**) | `emailverify gdpr:purge` | `post_gdpr_purge` | | `GET /gdpr/status` | Gdpr Status | `emailverify gdpr:status` | `get_gdpr_status` | ## Infrastructure | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /cache/stats` | Cache Stats Endpoint | `emailverify cache:stats` | `get_cache_stats` | | `GET /infra/blacklist-status` | Blacklist Status | `emailverify infra:blacklist-status` | `get_infra_blacklist_status` | | `POST /ip-pool/register` | Ip Pool Register | `emailverify ip-pool:register` | `post_ip_pool_register` | | `GET /ip-pool/status` | Ip Pool Status | `emailverify ip-pool:status` | `get_ip_pool_status` | | `GET /regions` | Regions Config | `emailverify regions` | `get_regions` | | `GET /regions/health` | Regions Health | `emailverify regions:health` | `get_regions_health` | | `GET /regions/route` | Regions Route | `emailverify regions:route` | `get_regions_route` | | `GET /sender-domains` | Sender Domains Status | `emailverify sender-domains` | `get_sender_domains` | | `POST /sender-domains/register` | Sender Domain Register | `emailverify sender-domains:register` | `post_sender_domains_register` | ## Integrations | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /integrations` | List Integrations Ep | `emailverify integrations:get` | `get_integrations` | | `POST /integrations` | Create Integration | `emailverify integrations:post` | `post_integrations` | | `POST /integrations/activecampaign/sync` | Activecampaign Sync (**destructive**, *billable*) | `emailverify integrations:activecampaign:sync` | `post_integrations_activecampaign_sync` | | `POST /integrations/klaviyo/sync` | Klaviyo Sync (**destructive**, *billable*) | `emailverify integrations:klaviyo:sync` | `post_integrations_klaviyo_sync` | | `POST /integrations/make/send` | Make Send (**destructive**, *billable*) | `emailverify integrations:make:send` | `post_integrations_make_send` | | `POST /integrations/test` | Test Integration (**destructive**) | `emailverify integrations:test` | `post_integrations_test` | | `DELETE /integrations/{integration_id}` | Delete Integration (**destructive**) | `emailverify integrations:integration-id` | `delete_integrations_by_integration_id` | | `GET /integrations/{integration_id}/events` | Integration Events | `emailverify integrations:integration-id:events` | `get_integrations_by_integration_id_events` | ## Intelligence | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /domain-intel/{domain}` | Get Domain Intel | `emailverify domain-intel:domain` | `get_domain_intel_by_domain` | ## Jobs | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /jobs/{job_id}` | Get Job | `emailverify jobs:job-id` | `get_jobs_by_job_id` | | `GET /jobs/{job_id}/dead-letter` | Get Dead Letter | `emailverify jobs:job-id:dead-letter` | `get_jobs_by_job_id_dead_letter` | | `POST /jobs/{job_id}/resume` | Resume Failed Emails | `emailverify jobs:job-id:resume` | `post_jobs_by_job_id_resume` | | `POST /jobs/{job_id}/retry-dead-letter` | Retry Dead Letter | `emailverify jobs:job-id:retry-dead-letter` | `post_jobs_by_job_id_retry_dead_letter` | ## ML | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /ml/stats` | Ml Stats | `emailverify ml:stats` | `get_ml_stats` | | `GET /ml/stats/v2` | Ml Stats V2 | `emailverify ml:stats:v2` | `get_ml_stats_v2` | | `POST /ml/train` | Ml Train | `emailverify ml:train` | `post_ml_train` | ## Provider Checks | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /verify/google-workspace` | Verify Google Workspace | `emailverify verify:google-workspace` | `get_verify_google_workspace` | | `GET /verify/microsoft-graph` | Verify Microsoft Graph | `emailverify verify:microsoft-graph` | `get_verify_microsoft_graph` | ## Signals | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /check/activity` | Check Activity | `emailverify check:activity` | `get_check_activity` | | `POST /check/cross-reference` | Check Cross Reference | `emailverify check:cross-reference` | `post_check_cross_reference` | | `GET /check/dkim` | Check Dkim | `emailverify check:dkim` | `get_check_dkim` | | `GET /check/dns` | Check Dns Only | `emailverify check:dns` | `get_check_dns` | | `GET /check/domain-age` | Check Domain Age Endpoint | `emailverify check:domain-age` | `get_check_domain_age` | | `GET /check/format-probability` | Check Format Probability | `emailverify check:format-probability` | `get_check_format_probability` | | `GET /check/linkedin-name` | Linkedin Name Check Endpoint | `emailverify check:linkedin-name` | `get_check_linkedin_name` | | `POST /check/mine-emails` | Mine Emails Endpoint | `emailverify check:mine-emails` | `post_check_mine_emails` | | `GET /check/ms-credential` | Check Ms Credential Endpoint | `emailverify check:ms-credential` | `get_check_ms_credential` | | `GET /check/mx-intel` | Check Mx Intel | `emailverify check:mx-intel` | `get_check_mx_intel` | | `GET /check/name-realism` | Check Name Realism | `emailverify check:name-realism` | `get_check_name_realism` | | `GET /check/pattern` | Check Pattern | `emailverify check:pattern` | `get_check_pattern` | | `GET /check/rbl` | Check Rbl Endpoint | `emailverify check:rbl` | `get_check_rbl` | | `GET /check/scrape-domain` | Scrape Domain Endpoint | `emailverify check:scrape-domain` | `get_check_scrape_domain` | ## Suppression | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `POST /suppression/add` | Suppression Add (**destructive**) | `emailverify suppression:add` | `post_suppression_add` | | `GET /suppression/check` | Suppression Check | `emailverify suppression:check` | `get_suppression_check` | | `GET /suppression/stats` | Suppression Stats | `emailverify suppression:stats` | `get_suppression_stats` | | `DELETE /suppression/{email}` | Suppression Remove (**destructive**) | `emailverify suppression:email` | `delete_suppression_by_email` | ## System | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /greylist` | Greylist | `emailverify greylist` | `get_greylist` | | `GET /health` | Health | `emailverify health` | `get_health` | | `GET /ips` | Ips | `emailverify ips` | `get_ips` | | `GET /senders` | Senders | `emailverify senders` | `get_senders` | | `GET /webhooks/stats` | Webhook Stats | `emailverify webhooks:stats` | `get_webhooks_stats` | ## Utilities | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `POST /utils/dedup` | Dedup Emails | `emailverify utils:dedup` | `post_utils_dedup` | ## Validate | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /validate/with-score` | Validate With Score | `emailverify validate:with-score` | `get_validate_with_score` | ## Verification | Endpoint | Description | CLI | MCP tool | |---|---|---|---| | `GET /validate` | Validate Get | `emailverify validate:get` | `get_validate` | | `POST /validate` | Validate Post | `emailverify validate:post` | `post_validate` | | `POST /validate/bulk` | Validate Bulk | `emailverify validate:bulk` | `post_validate_bulk` | | `POST /validate/bulk/async` | Validate Bulk Async | `emailverify validate:bulk:async` | `post_validate_bulk_async` | | `POST /validate/bulk/turbo` | Validate Bulk Turbo | `emailverify validate:bulk:turbo` | `post_validate_bulk_turbo` | | `GET /validate/checks` | Validate Checks Get | `emailverify validate:checks:get` | `get_validate_checks` | | `POST /validate/checks` | Validate Checks Post | `emailverify validate:checks:post` | `post_validate_checks` | | `GET /validate/fast` | Validate Fast | `emailverify validate:fast` | `get_validate_fast` | | `GET /validate/quick` | Validate Quick | `emailverify validate:quick` | `get_validate_quick` | | `GET /validate/syntax` | Validate Syntax Only | `emailverify validate:syntax` | `get_validate_syntax` | | `GET /verify/breach-intel` | Breach Intelligence Endpoint | `emailverify verify:breach-intel` | `get_verify_breach_intel` | | `POST /verify/catchall-resolve` | Catchall Resolve V2 | `emailverify verify:catchall-resolve` | `post_verify_catchall_resolve` | | `GET /verify/quick` | Verify Quick | `emailverify verify:quick` | `get_verify_quick` | | `GET /verify/status/{verification_id}` | Verify Status | `emailverify verify:status:verification-id` | `get_verify_status_by_verification_id` | | `GET /verify/typo` | Check Typo | `emailverify verify:typo` | `get_verify_typo` | ---