Mailvett
Free API + MCP server · paid keys from $5

Catch bad email addresses before you send

Paste addresses and get a clear verdict for each: syntax, domain and mail server (MX), mail provider, disposable, role (info@, sales@), free provider and likely typos (gmial.com → gmail.com), plus domain age, SPF and DMARC.

Manage your subscription

Opens Stripe's billing portal: invoices, payment method, cancel.

Who it's for

Anyone who needs this answer fast, from a person to an AI agent.

Sign-up forms and SaaS

Stop disposable and mistyped addresses at sign-up, with a "did you mean" suggestion.

Sales and marketing

Clean a small list before a send: drop dead domains, flag role and free addresses.

AI agents and CRMs

One tool call answers "is this email real enough to use?" with reasons.

Developers

Consistent JSON with machine-readable reason codes you can branch on.

Try it

Up to 10 addresses, one per line or comma separated.

Prefilled with a real example. Press Validate.

Real sample output

Captured from a live call to this API (trimmed for length).

{
  "results": [
    {
      "input": "jane.doe@gmial.com",
      "email": "jane.doe@gmial.com",
      "verdict": "risky",
      "score": 1,
      "reasons": [
        "mail_server_from_a_record",
        "disposable_domain",
        "possible_typo_of:gmail.com",
        "no_spf",
        "no_dmarc",
        "domain_age_years:23"
      ],
      "summary": "jane.doe@gmial.com: risky (score 1) - Implicit (A record), disposable domain, did you mean jane.doe@gmail.com?, domain 23y old.",
      "localPart": "jane.doe",
      "domain": "gmial.com",
      "syntax": {
        "valid": true,
        "error": null
      },
      "domainExists": true,
      "mx": {
        "present": true,
        "hosts": [],
        "provider": "Implicit (A record)",
        "implicit": true,
        "nullMx": false
      },
      "flags": {
        "disposable": true,
        "role": false,
        "roleType": null,
        "freeProvider": false,
        "typoSuggestion": "gmail.com",
        "parkedDomain": false
      },
      "suggestion": "jane.doe@gmail.com",
      "domainHealth": {
        "spf": null,
        "dmarc": null,
        "createdAt": "2003-05-12T18:26:31Z",
        "ageDays": 8537,
        "registrar": "GoDaddy.com, LLC",
        "parkedEvidence": null
      },
      "catchAll": "not_checked",
      "mailbox": "not_checked",
      "errors": [],
      "ms": 748,
      "checkedAt": "2026-09-25T23:03:27.011Z"
    },
    {
      "input": "info@stripe.com",
      "email": "info@stripe.com",
      "verdict": "deliverable_likely",
      "score": 78,
      "reasons": [
        "mx_present",
        "role_account:general",
        "spf_present",
        "dmarc:reject",
        "domain_age_years:31"
      ],
      "summary": "info@stripe.com: deliverable_likely (score 78) - Google Workspace, role account (general), domain 31y old.",
      "localPart": "info",
      "domain": "stripe.com",
      "syntax": {
        "valid": true,
        "error": null
      },
      "domainExists": true,
      "mx": {
        "present": true,
        "hosts": [
          "aspmx.l.google.com",
          "alt1.aspmx.l.google.com",
          "alt2.aspmx.l.google.com",
          "aspmx2.googlemail.com",
          "aspmx3.googlemail.com"
        ],
        "provider": "Google Workspace",
        "implicit": false,
        "nullMx": false
      },
      "flags": {
        "disposable": false,
        "role": true,
        "roleType": "general",
        "freeProvider": false,
        "typoSuggestion": null,
        "parkedDomain": false
      },
      "suggestion": null,
      "domainHealth": {
        "spf": "softfail",
        "dmarc": "reject",
        "createdAt": "1995-09-12T04:00:00Z",
        "ageDays": 11336,
        "registrar": "SafeNames Ltd.",
        "parkedEvidence": null
      },
      "catchAll": "not_checked",
      "mailbox": "not_checked",
      "errors": [],
      "ms": 107,
      "checkedAt": "2026-09-25T23:03:26.370Z"
    }
  ],
  "count": 4,
  "verdicts": {
    "deliverable_likely": 1,
    "risky": 2,
    "undeliverable": 1,
    "invalid": 0
  },
  "checks": {
    "domainAge": true,
    "parkedWebsite": true,
    "mailbox": "never probed (no SMTP)"
  }
}

Limits, plainly

Free and rate limited so it stays fast for everyone. A bulk and scheduled version for big lists is coming to the Apify Store.

  • 20 calls per minute per IP address.
  • Up to 10 emails per call.
  • Domain age and parked-site checks run in full for up to 5 different domains per call.
  • Mailboxes are never probed (no SMTP), so the top score is 90.
  • Free, no key.

Get an API key

Validate up to 10 email addresses per call: syntax, MX and mail provider, disposable, role and free-provider flags, typo fixes (gmial.com to gmail.com), domain age, SPF and DMARC, with a verdict and a 0-100 score. Keys work on the REST API and the MCP server.

14-day money-back promise: if it doesn't work as described, email us within 14 days and we fix it or refund you in full. Refund terms.

Free
$0

50 calls a day per IP · 20 per minute · no key, no sign-up

Try it now
Pay as you go
$5

1,000 calls to use whenever (no expiry) · 60 per minute

Buy the pack
Cleaner
$19/month

5,000 calls a month · 60 per minute

Get Cleaner keyor $190/year, 2 months free
Growth recommended
$49/month

20,000 calls a month · 120 per minute

Get Growth keyor $490/year, 2 months free
Agency
$99/month

60,000 calls a month · 240 per minute

Get Agency keyor $990/year, 2 months free

Pay with card, Apple Pay, Google Pay or Link through Stripe Checkout (sales tax/VAT handled by Stripe). Your key appears on the page you return to right after checkout: save it. Manage or cancel any time at mailvett.cybermax-tools.workers.dev/manage. Send it as x-api-key: YOUR_KEY (or Authorization: Bearer YOUR_KEY, which MCP clients support). Check usage at /key. Failed calls are not counted. Email validation APIs charge per email: MailboxValidator $29.95 for 3,000, Emailable $38 for 5,000, ZeroBounce $39 minimum for 2,000 (rival median about $10 per 1,000, checked 27 Sep 2026). Those also probe the mailbox by SMTP; Mailvett checks syntax, MX, disposable, role, typos, SPF and DMARC without touching the mailbox, so it is priced below them: Cleaner $19/month for 5,000 calls of up to 10 emails, or $5 pay-as-you-go for 1,000 calls that never expire.

Using several CyberMax APIs? CyberMax API All-Access: one key for all 10 APIs (this one included, 5,000 calls a month here) for $119/month. See All-Access

With your key
curl -s "https://mailvett.cybermax-tools.workers.dev/api/validate?..." -H "x-api-key: YOUR_KEY"

# MCP (Claude Desktop, Cursor, VS Code)
{ "mcpServers": { "mailvett": { "type": "http", "url": "https://mailvett.cybermax-tools.workers.dev/mcp",
  "headers": { "Authorization": "Bearer YOUR_KEY" } } } }

# Usage so far
curl -s https://mailvett.cybermax-tools.workers.dev/key -H "x-api-key: YOUR_KEY"

Use the API

JSON over HTTPS, CORS enabled, no key. GET for quick calls, POST a JSON body for lists. Spec: openapi.json · llms.txt

cURL
curl -s "https://mailvett.cybermax-tools.workers.dev/api/validate?email=jane.doe%40gmial.com%0Ainfo%40stripe.com%0Atest%40mailinator.com%0Asales%40this-domain-does-not-exist-9x7q.com"

# lists: POST a JSON body
curl -s -X POST https://mailvett.cybermax-tools.workers.dev/api/validate \
  -H "content-type: application/json" \
  -d '{"emails":["jane.doe@gmial.com","info@stripe.com","test@mailinator.com"]}'
Python
import requests

r = requests.post("https://mailvett.cybermax-tools.workers.dev/api/validate",
                  json={"emails":["jane.doe@gmial.com","info@stripe.com","test@mailinator.com"]}, timeout=30)
r.raise_for_status()
for row in r.json()["results"]:
    print(row)

Endpoints: /api/validate validate up to 10 email addresses

Add it to your AI agent (MCP)

A remote MCP server at https://mailvett.cybermax-tools.workers.dev/mcp (streamable HTTP, no auth). Read-only tools with JSON schemas, so agents know exactly what to send.

MCP config
// Claude Desktop, Cursor, VS Code, any MCP client (remote, no key)
{
  "mcpServers": {
    "mailvett": { "type": "http", "url": "https://mailvett.cybermax-tools.workers.dev/mcp" }
  }
}

# Claude Code
claude mcp add --transport http mailvett https://mailvett.cybermax-tools.workers.dev/mcp

# Tools: validate_emails
# e.g. validate_emails({"emails":["jane.doe@gmial.com"]})
  • validate_emails
    Check up to 10 email addresses: syntax, whether the domain exists and has mail servers (MX), mail provider, disposable, role account (info@, sales@), free provider, likely typo with a suggested fix, domain age, SPF and DMARC. Returns verdict (deliverable_likely/risky/undeliverable/invalid), score 0-100 and reason codes per address. Does not verify that the mailbox itself exists.

FAQ

Why not an SMTP "mailbox exists" check?

Probing mail servers is slow, often blocked or answered with fake "OK"s (catch-all servers), and can hurt the reputation of the IP doing it. Mailvett never probes mailboxes and says so (mailbox: "not_checked"); it tells you everything that can be known safely.

What do the verdicts mean?

deliverable_likely: real domain with mail servers and no warning signs. risky: works but disposable, parked, very new, a likely typo or unusual. undeliverable: the domain does not exist or accepts no mail. invalid: bad syntax.

Where does the disposable list come from?

The community-maintained disposable-email-domains list (CC0), plus our own role, free-provider and typo rules.

Do you store the addresses?

No. Addresses are checked live and not saved. Only DNS, RDAP and the domain's homepage are queried, never the mailbox.

Can I clean a big list?

The free API takes 10 addresses per call. A bulk version for large lists is coming to the Apify Store.