Compare email verification APIs side-by-side. SMTP checks, disposable email detection, MX validation, catch-all detection. Find the best email validation API for your signup forms, CRM, and marketing automation.
Most email validation APIs perform these checks in sequence. Each layer catches different types of invalid addresses.
Feature matrix across all 7 email validation APIs. Scroll horizontally on mobile.
| Provider | Free Tier | SMTP Check | Disposable Detection | Catch-All | Role Detection | Quality Score | Signup Required |
|---|---|---|---|---|---|---|---|
| ZeroBounce FREEMIUM | 100 free/mo | Yes | Yes | Yes | Yes | Yes | Email + phone |
| Hunter.io FREEMIUM | 25 free/mo | Yes | Yes | Yes | Yes | Yes | Email signup |
| Abstract API FREEMIUM | 100 free/mo | Yes | Yes | Yes | Yes | Yes (0-1) | Email signup |
| Emailable FREEMIUM | 250 credits | Yes | Yes | Yes | Yes | Yes | Email signup |
| Reacher OPEN SOURCE | Unlimited (self-hosted) | Yes | Yes | Yes | Yes | No | No (self-hosted) |
| NeverBounce FREEMIUM | 1,000 free | Yes | Yes | Yes | Yes | No | Email signup |
| Frostbyte DNS 200 FREE CREDITS | 200 credits | No (MX only) | Yes (via MX patterns) | No | No | No | No signup form |
Detailed analysis of each email validation API with strengths and weaknesses.
Not every project needs full SMTP verification. Choose the right level of validation for your use case.
ZeroBounce, Hunter, Abstract, Emailable, Reacher, NeverBounce
Frostbyte DNS API
Enter an email address or domain to check if it has valid MX records. Uses the Frostbyte DNS API.
Copy-paste examples for popular email validation APIs.
curl "https://api.zerobounce.net/v2/validate?api_key=YOUR_KEY&email=test@example.com"
const res = await fetch(
'https://api.zerobounce.net/v2/validate?api_key=YOUR_KEY&email=test@example.com'
);
const data = await res.json();
console.log(data.status); // "valid", "invalid", "catch-all", "unknown"
console.log(data.sub_status); // "mailbox_not_found", "disposable", etc.
import requests
r = requests.get('https://api.zerobounce.net/v2/validate',
params={'api_key': 'YOUR_KEY', 'email': 'test@example.com'})
data = r.json()
print(data['status']) # valid, invalid, catch-all, unknown
print(data['sub_status']) # mailbox_not_found, disposable, etc.curl "https://emailvalidation.abstractapi.com/v1/?api_key=YOUR_KEY&email=test@example.com"
const res = await fetch(
'https://emailvalidation.abstractapi.com/v1/?api_key=YOUR_KEY&email=test@example.com'
);
const data = await res.json();
console.log(data.deliverability); // "DELIVERABLE" or "UNDELIVERABLE"
console.log(data.quality_score); // 0.0 to 1.0
console.log(data.is_disposable_email.value); // true/false
import requests
r = requests.get('https://emailvalidation.abstractapi.com/v1/',
params={'api_key': 'YOUR_KEY', 'email': 'test@example.com'})
data = r.json()
print(data['deliverability']) # DELIVERABLE / UNDELIVERABLE
print(data['quality_score']) # 0.0 to 1.0
print(data['is_disposable_email']) # {"value": true/false}# Check MX records for email domain validation
curl "https://agent-gateway-kappa.vercel.app/v1/agent-dns/all/gmail.com" \
-H "x-api-key: YOUR_KEY"
# Response includes MX, TXT (SPF/DKIM/DMARC), and more
# If MX records exist -> domain can receive email
# Check TXT for SPF/DMARC -> domain has email authentication
async function validateEmailDomain(email, apiKey) {
const domain = email.split('@')[1];
const res = await fetch(
`https://agent-gateway-kappa.vercel.app/v1/agent-dns/all/${domain}`,
{ headers: { 'x-api-key': apiKey } }
);
const data = await res.json();
const mx = data.records?.MX || [];
const txt = data.records?.TXT || [];
// Check if domain has mail servers
const canReceiveEmail = mx.length > 0;
// Check for SPF record (email authentication)
const hasSPF = txt.some(r =>
(r.entries || [r.data || '']).join('').includes('v=spf1')
);
// Check for DMARC
// (query _dmarc.domain separately for full check)
return { domain, canReceiveEmail, mailServers: mx.length, hasSPF };
}
const result = await validateEmailDomain('user@gmail.com', 'YOUR_KEY');
console.log(result);
// { domain: 'gmail.com', canReceiveEmail: true, mailServers: 5, hasSPF: true }import requests
def validate_email_domain(email, api_key):
domain = email.split('@')[1]
r = requests.get(
f'https://agent-gateway-kappa.vercel.app/v1/agent-dns/all/{domain}',
headers={'x-api-key': api_key}
)
data = r.json()
records = data.get('records', {})
mx = records.get('MX', [])
txt = records.get('TXT', [])
can_receive = len(mx) > 0
has_spf = any('v=spf1' in str(t) for t in txt)
return {
'domain': domain,
'can_receive_email': can_receive,
'mail_servers': len(mx),
'has_spf': has_spf
}
result = validate_email_domain('user@gmail.com', 'YOUR_KEY')
print(result)
# {'domain': 'gmail.com', 'can_receive_email': True, 'mail_servers': 5, 'has_spf': True}package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
)
func validateEmailDomain(email, apiKey string) map[string]interface{} {
parts := strings.Split(email, "@")
domain := parts[len(parts)-1]
req, _ := http.NewRequest("GET",
"https://agent-gateway-kappa.vercel.app/v1/agent-dns/all/"+domain, nil)
req.Header.Set("x-api-key", apiKey)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var data map[string]interface{}
json.Unmarshal(body, &data)
records := data["records"].(map[string]interface{})
mx, _ := records["MX"].([]interface{})
return map[string]interface{}{
"domain": domain,
"can_receive_email": len(mx) > 0,
"mail_servers": len(mx),
}
}
func main() {
result := validateEmailDomain("user@gmail.com", "YOUR_KEY")
fmt.Println(result)
}What each email validation API costs when you outgrow the free tier.
Choose based on your specific use case and requirements.
Use Abstract API or ZeroBounce. Real-time SMTP checks with quality scoring catch invalid emails before they enter your database. Both have generous free tiers for testing.
Use NeverBounce or Emailable. Bulk validation APIs with high accuracy. Emailable credits never expire, which is great for periodic list cleaning.
Use Hunter.io. Combines email finding with verification. Search by company domain to find professional email addresses and verify them in one workflow.
Use Frostbyte DNS or Abstract API. Frostbyte checks MX records to identify disposable email service patterns. Abstract has a dedicated is_disposable flag in the response.
Use Reacher. Open-source, Rust-based, deploy on your own infrastructure. No email data leaves your servers. Combine with Frostbyte DNS for MX pre-validation.
Use Frostbyte DNS. Check if a domain has MX records and email authentication (SPF/DMARC) in a single API call. Fast (~50ms), no signup forms, no SMTP probing needed.