Email Validation
3 min read
Email validation catches invalid addresses before you send, protecting your sender reputation and reducing bounces.
Why validate emails
Every bounced email hurts your reputation:
- High bounce rates trigger spam filters
- ISPs may block your domain
- You waste money on undeliverable messages
- Engagement metrics become unreliable
Validation prevents this by checking addresses before sending.
Validation checks
Our validation performs multiple checks:
| Check | What it catches |
|---|---|
| Syntax | Missing @, invalid characters |
| DNS | Domain doesn’t exist |
| MX records | Domain can’t receive email |
| Disposable | Temporary/throwaway addresses |
| Role-based | info@, support@, admin@ |
| Catch-all | Domain accepts any address |
| SMTP | Mailbox doesn’t exist |
Single email validation
Via API
curl -X POST https://api.mailingapi.com/v1/validate/single \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'
Response:
{
"email": "user@example.com",
"valid": true,
"result": "deliverable",
"checks": {
"syntax": "valid",
"dns": "valid",
"mx": "valid",
"disposable": false,
"role": false,
"catch_all": false,
"smtp": "valid"
},
"suggestion": null
}
Result types
| Result | Meaning | Action |
|---|---|---|
deliverable |
Mailbox exists and accepts mail | Safe to send |
undeliverable |
Mailbox doesn’t exist | Don’t send |
risky |
May bounce (catch-all, etc.) | Send with caution |
unknown |
Couldn’t verify | Consider manual review |
Batch validation
Validate multiple emails in one request. Results are returned synchronously.
curl -X POST https://api.mailingapi.com/v1/validate/batch \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emails": [
"user1@example.com",
"user2@example.com",
"invalid@nonexistent.domain"
]
}'
Response:
{
"results": [
{
"email": "user1@example.com",
"valid": true,
"result": "deliverable",
"checks": {
"syntax": "valid",
"dns": "valid",
"mx": "valid",
"disposable": false,
"role": false
}
},
{
"email": "invalid@nonexistent.domain",
"valid": false,
"result": "undeliverable",
"checks": {
"syntax": "valid",
"dns": "invalid",
"mx": "invalid",
"disposable": false,
"role": false
}
}
],
"summary": {
"total": 3,
"deliverable": 2,
"undeliverable": 1,
"risky": 0,
"unknown": 0
}
}
Limits:
- Maximum 10,000 emails per request
Real-time validation
Validate during user signup:
JavaScript example
async function validateEmail(email) {
const response = await fetch('https://api.mailingapi.com/v1/validate/single', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ email })
});
const result = await response.json();
if (result.result === 'undeliverable') {
return { valid: false, message: 'This email address appears to be invalid' };
}
if (result.checks.disposable) {
return { valid: false, message: 'Disposable email addresses are not allowed' };
}
if (result.suggestion) {
return { valid: true, suggestion: `Did you mean ${result.suggestion}?` };
}
return { valid: true };
}
Form integration
<input type="email" id="email" onblur="checkEmail(this.value)">
<span id="email-status"></span>
<script>
async function checkEmail(email) {
const status = document.getElementById('email-status');
const result = await validateEmail(email);
if (result.valid) {
status.textContent = result.suggestion || '✓ Valid';
status.className = 'valid';
} else {
status.textContent = result.message;
status.className = 'invalid';
}
}
</script>
Typo suggestions
We detect common typos and suggest corrections:
{
"email": "user@gmial.com",
"valid": false,
"result": "undeliverable",
"suggestion": "user@gmail.com"
}
Common corrections:
-
gmial.com→gmail.com -
gamil.com→gmail.com -
outloo.com→outlook.com -
yahooo.com→yahoo.com
Disposable email detection
Block temporary email addresses:
{
"email": "temp123@10minutemail.com",
"valid": true,
"result": "risky",
"checks": {
"disposable": true
}
}
We maintain a database of 100,000+ disposable domains including:
- 10minutemail.com
- guerrillamail.com
- tempmail.org
- throwaway.email
Role-based email detection
Identify generic addresses:
{
"email": "info@company.com",
"valid": true,
"result": "risky",
"checks": {
"role": true
}
}
Role-based addresses often have:
- Multiple recipients
- Higher complaint rates
- Lower engagement
Common role addresses:
- info@, support@, sales@
- admin@, webmaster@, postmaster@
- contact@, help@, no-reply@
Catch-all detection
Identify domains that accept all addresses:
{
"email": "anything@catch-all-domain.com",
"valid": true,
"result": "risky",
"checks": {
"catch_all": true
}
}
Catch-all domains accept any address, so we can’t verify if the specific mailbox exists. Higher risk of bounces.
Best practices
- Validate at signup — Catch bad addresses immediately
- Re-validate old lists — Emails go bad over time
- Remove undeliverable — Don’t send to known-bad addresses
- Consider risky emails — Decide your tolerance level
- Use suggestions — Help users fix typos
- Block disposables — If appropriate for your use case
- Monitor bounce rates — Validation isn’t 100% accurate
Validation strategies
Conservative (recommended for transactional)
Send only to deliverable:
if (result.result === 'deliverable') {
sendEmail(email);
}
Moderate (balanced approach)
Send to deliverable and some risky:
if (result.result === 'deliverable' ||
(result.result === 'risky' && !result.checks.disposable)) {
sendEmail(email);
}
Aggressive (maximum reach)
Send unless explicitly undeliverable:
if (result.result !== 'undeliverable') {
sendEmail(email);
}
Pricing
Validation is billed per check:
| Volume | Price per validation |
|---|---|
| First 1,000 | Free |
| 1,001 - 10,000 | $0.005 |
| 10,001 - 100,000 | $0.003 |
| 100,001+ | $0.001 |
Bulk validation is more cost-effective than individual checks.
Next steps
- Set up webhooks for delivery notifications
- Create templates for consistent emails
- Monitor deliverability with analytics