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.



Who it's for
Anyone who needs this answer fast, from a person to an AI agent.
Stop disposable and mistyped addresses at sign-up, with a "did you mean" suggestion.
Clean a small list before a send: drop dead domains, flag role and free addresses.
One tool call answers "is this email real enough to use?" with reasons.
Consistent JSON with machine-readable reason codes you can branch on.
Try it
Up to 10 addresses, one per line or comma separated.
Raw JSON response
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.
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 -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"]}'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.
// 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.