If you validate emails with regex, you are checking if a string looks like an email. You are not checking if anyone will receive your message.
I learned this the hard way. 12% bounce rate on a 5,000 email campaign. Sender reputation tanked. Half the "valid" emails were dead mailboxes that regex happily approved.
here is what actually works and why the difference matters.
What regex checks
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
This tells you the string has an @ symbol, a dot, and some characters around them. That is it.
totally.fake.person@nonexistent-domain-12345.com passes regex. Nobody will ever receive that email.
What SMTP verification checks
SMTP verification actually talks to the mail server. It connects on port 25, introduces itself with EHLO, then asks "would you accept mail for this address?" The server responds with a code:
- 250 = yes, this mailbox exists
- 550 = no, user unknown
- 252 = catch all (accepts everything)
This is the same protocol your email client uses to send mail. You are just stopping before actually delivering anything.
The 5 layers of real validation
I built an email validator that runs 5 checks in sequence:
Layer 1: Format check. Yes, regex. But just as a first filter to reject obvious garbage.
Layer 2: Domain check. Does the domain have MX records? If there are no mail servers configured, nobody is receiving email there. dig MX example.com tells you instantly.
Layer 3: Disposable detection. Is this mailinator, guerrillamail, tempmail? I maintain a list of 400+ disposable domains. These addresses work for about 10 minutes then disappear.
Layer 4: Role detection. admin@, info@, support@ are role addresses. They usually go to a shared inbox that nobody monitors for cold outreach.
Layer 5: SMTP handshake. The real check. Connect to the MX server, ask if the mailbox exists. This catches the dead addresses that everything else misses.
What this looks like in practice
Input: hello@stripe.com
{
"email": "hello@stripe.com",
"valid": true,
"format_valid": true,
"mx_found": true,
"smtp_check": "valid",
"is_disposable": false,
"is_free": false,
"is_role_based": false,
"domain": "stripe.com",
"mx_records": [
{"priority": 10, "exchange": "aspmx.l.google.com"}
],
"score": 100
}
Input: test@mailinator.com
{
"email": "test@mailinator.com",
"valid": false,
"format_valid": true,
"mx_found": true,
"smtp_check": null,
"is_disposable": true,
"score": 40,
"reason": "Disposable email address"
}
The disposable check caught it before we even bothered with SMTP.
The bounce rate difference
Before SMTP validation: 12% bounce rate, emails landing in spam, sender score dropping.
After: under 2% bounce rate. Same email copy, same sending infrastructure. The only change was filtering out dead addresses before hitting send.
Cost comparison
| Method | Cost per 1,000 emails | Accuracy |
|---|---|---|
| Regex only | Free | ~60% (misses dead mailboxes) |
| ZeroBounce | $1.60 | ~95% |
| Hunter.io | $3.00 | ~93% |
| NeverBounce | $3.00 | ~96% |
| This API | $2.00 | ~98% (real SMTP) |
Try it
The validator is on Apify Store with a free tier: Email Validator API
Also available on RapidAPI if you prefer REST.
Python quickstart
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("george.the.developer/email-validator-api").call(
run_input={"email": "hello@stripe.com"}
)
result = client.dataset(run["defaultDatasetId"]).list_items().items[0]
print(f"Valid: {result['valid']}, Score: {result['score']}")
curl
curl "https://george-the-developer--email-validator-api.apify.actor/validate?email=hello@stripe.com" \
-H "Authorization: Bearer YOUR_TOKEN"
I build data tools. 57 actors on Apify Store, 869 users. Follow the build log at @ai_in_it on X.
Top comments (0)