Every email verification returns a quality score from 0-100. This score provides a nuanced view of email quality beyond a simple valid/invalid binary.
Score Ranges
| Score | Deliverability | Recommendation |
|---|---|---|
| 80-100 | High | Safe to send |
| 50-79 | Medium | Proceed with caution |
| 25-49 | Low | High risk |
| 0-24 | Risky | Do not send |
How Scores Are Calculated
The score is calculated using a proprietary algorithm that evaluates multiple factors:
Positive Factors
- Valid email syntax (+10)
- Domain has valid MX records (+15)
- Mailbox verified to exist (+55)
- Known reputable email provider (+10)
- Not using disposable email service (+5)
- SPF record present (+5)
- DMARC record present (+5)
Negative Factors
- Disposable/temporary email domain (-20)
- Catch-all domain (-15)
- Role account (info@, support@, etc.) (-10)
Score Examples
High Score (95)
{
"email": "[email protected]",
"valid": true,
"score": 95,
"deliverability": "high",
"disposable": false,
"role_account": false,
"catch_all": false,
"free_email": false,
"syntax_valid": true,
"domain_valid": true,
"mailbox_valid": true,
"provider": "google",
"mx_host": "aspmx.l.google.com.",
"suggestion": null,
"dns": null
}
This email has everything going for it: valid syntax, established domain, proper MX records, and a verified mailbox.
Medium Score (65)
{
"email": "[email protected]",
"valid": true,
"score": 65,
"deliverability": "medium",
"disposable": false,
"role_account": true,
"catch_all": true,
"free_email": false,
"syntax_valid": true,
"domain_valid": true,
"mailbox_valid": false,
"provider": null,
"mx_host": "mx1.newstartup.io.",
"suggestion": null,
"dns": {
"has_spf": true,
"has_dmarc": true,
"dmarc_policy": "quarantine"
}
}
The domain is a catch-all (accepts all addresses), so we can't verify the specific mailbox exists. It's also a role account. The email might be valid, but there's uncertainty.
Low Score (20)
{
"email": "[email protected]",
"valid": false,
"score": 20,
"deliverability": "risky",
"disposable": true,
"role_account": false,
"catch_all": false,
"free_email": false,
"syntax_valid": true,
"domain_valid": true,
"mailbox_valid": true,
"provider": null,
"mx_host": "mx.tempmail.net.",
"suggestion": null,
"dns": null
}
Even though domain checks pass, the disposable domain tanks the score and marks it invalid. This is likely a throwaway account.
Using Scores in Your Application
Simple Threshold
const result = await verifyEmail(email);
if (result.score < 50) {
return { error: 'Please use a different email address' };
}
Tiered Approach
const result = await verifyEmail(email);
if (result.score >= 80) {
// Full access, auto-verify
await createAccount(email, { verified: true });
} else if (result.score >= 50) {
// Require email confirmation
await createAccount(email, { verified: false });
await sendVerificationEmail(email);
} else {
// Reject signup
return { error: 'Please use a valid email address' };
}
Using Deliverability Rating
const result = await verifyEmail(email);
switch (result.deliverability) {
case 'high':
// Safe to proceed
break;
case 'medium':
// Require confirmation
await sendVerificationEmail(email);
break;
case 'low':
case 'risky':
return { error: 'Please use a valid email address' };
}
Scores vs. Validity
A high score doesn't always mean valid: true, and vice versa:
| Scenario | valid | Score | Reason |
|---|---|---|---|
| Gmail address, verified | true | 95 | Everything checks out |
| Disposable, verified | false | 20 | Works but risky |
| Catch-all domain | true | 60 | Can't confirm mailbox |
| Typo in domain | false | 0 | Invalid domain |
Best Practices
- Don't rely solely on
valid- Use the score for nuanced decisions - Set appropriate thresholds - Different use cases need different standards
- Monitor score distributions - Track average scores to detect trends
- Combine with other signals - IP reputation, behavior patterns, etc.