HowtoCheckEmailValidity:CompleteGuidetoEmailVerification
How email validity checking works, what each verdict means, how to pick a service, and how to wire real-time and bulk verification into your product. Node.js and Python code included.
Robby Frank
CEO & Founder

How to check email validity: complete guide to email verification
Email lists rot on their own. People change jobs, abandon inboxes, and mistype addresses at signup, and every dead address on your list costs you twice: once for the send, and again in sender reputation when it bounces. Mailbox providers watch your bounce rate, and a sender who keeps mailing dead addresses looks like a spammer to them.
Checking email validity before you send is the cheapest fix available. This guide covers how validation actually works, what each result means, how to pick a tool, and how to wire it into your product without annoying real users. To check one address right now, paste it into our free email checker.
What is email validity checking?
Email validity checking verifies that an address exists, can receive mail, and is worth sending to. Format checking only tells you an address looks right. Validity checking tells you whether it works.
A full check runs several layers. Syntax validation confirms the address follows RFC rules. Domain verification confirms the domain exists and has MX records, meaning it can receive mail at all. Mailbox verification asks the receiving server whether that specific inbox exists. On top of those, risk checks flag disposable addresses, known spam traps, and role accounts like info@ or sales@, and roll everything into a deliverability score.
The distinction matters because "looks right" and "works" are different claims. name@compayn.com passes every syntax check ever written. It will still bounce.
Validation versus verification
The two words get used interchangeably, and vendors are not consistent about them, but there is a real distinction worth knowing when you read a pricing page.
Validation usually means the cheap, fast layers: syntax, DNS, MX records, domain reputation. It runs in milliseconds and never touches the receiving mail server. Verification usually means the expensive layer: an actual SMTP conversation with the receiving server to ask whether the mailbox exists. It is slower and it is the part that can come back "unknown."
Most vendors sell both under one product and price them differently, so check what a given plan actually performs rather than trusting the label. If you want the real per-check cost for your mix, run a sample through a trial and divide.
How email validity checking works
A validation service runs an address through a sequence of checks, each deeper than the last. Every verification service runs the same four, in the same order, because each one is cheaper than the next. We call the sequence the Email Verification Ladder.
Syntax comes first: RFC 5322 compliance, character rules, length limits, proper local-part and domain structure. This is deterministic and instant.
Domain checks come next. The service resolves the domain in DNS, verifies MX records exist so the domain can accept mail, and often inspects SPF, DKIM, and DMARC records along with domain age and reputation. In 1Lookup's September 2026 email authentication census, 29.5% of the 5,000 most-visited domains publish no MX record at all; mail to an address at one of those bounces before a mailbox is ever consulted.
Then the mailbox check. The service opens an SMTP conversation with the receiving mail server and asks whether the specific mailbox exists, stopping short of sending a message. This step also detects catch-all domains and identifies role-based addresses. It is the expensive rung.
Finally, risk assessment: matching the address against databases of disposable email providers and known spam traps, checking domain and IP reputation, and looking at historical bounce behavior. The result comes back as a score plus individual flags, fast enough that a full check can run inline on a signup form. Syntax-only checks are effectively instant.
Most hard bounces fail on the domain and mailbox rungs. Most fake signups pass those and fail on the risk rung. Knowing which rung an address failed tells you what to do with it: fix the typo, drop the domain, hold the catch-all for a lower-risk channel, or block the disposable at signup. The share of addresses verified on the 1Lookup platform that come back undeliverable, disposable or role-based is published on the contact data quality page.
The SMTP conversation, step by step
The mailbox check is the step that separates real verification from format checking, because it asks the receiving server directly. The exchange looks like this:
Connection: Establish SMTP session with mail server
Commands:
HELO/EHLO → Server greeting
MAIL FROM → Sender identification
RCPT TO → Recipient validation
QUIT → Clean disconnection
Output: Mailbox existence + delivery capability
No message is ever sent. The verifier reads the server's response to RCPT TO and disconnects. That response is the whole answer, which is also why the answer is only as honest as the receiving server chooses to be.
What the verdicts mean
The individual checks matter less than the category they roll up into. Most services return something close to these four:
- Valid. A working mailbox was confirmed. Safe to send.
- Invalid. The domain or mailbox does not exist. Do not send; these are your hard bounces.
- Risky. The address resolves but something is off: a catch-all domain, a role account, a disposable provider, or a poor reputation signal. Send with care, or hold these out of your biggest campaigns.
- Unknown. The server timed out, greylisted the probe, or refused to answer. This is not a synonym for invalid. Retry later before you act on it.
Designing for four states instead of two is the single most common thing teams get wrong. "Unknown" is a real answer and needs its own handling.
Validation accuracy and what to trust
Different checks deserve different levels of trust, and it is worth knowing which is which.
Syntax validation is exact about the one thing it measures: whether the format is legal. It says nothing about whether the mailbox exists. Domain and MX checks are also reliable, since DNS either resolves or it does not.
Mailbox verification is where certainty ends. Catch-all domains accept mail for any address, so the check cannot distinguish a real inbox from a fake one there. Some providers block or throttle verification probes. Greylisting delays answers. Disposable detection is only as good as the blocklist behind it, and new burner domains appear daily.
Accuracy also shifts with context. Business domains tend to verify more cleanly than consumer ones, big providers like Gmail and Outlook each behave differently under verification, and a mail server having a bad afternoon can turn a valid address into an "unknown."
Vendor accuracy claims all cluster in the high nineties and there is no independent referee, so treat published benchmarks as marketing. The practical takeaway: treat validation results as strong signals, not ground truth, and measure any vendor on your own list. Any vendor promising certainty on mailbox existence is promising something SMTP does not allow.
How to measure a provider on your own data
The test that settles it takes an afternoon. Pull a sample of a few thousand addresses from your own list, run it through two or three finalists, and inspect the addresses they disagree on. Then send to a held-back slice and compare each provider's verdicts against the bounces you actually get.
Two numbers come out of that, and they are the only two that matter:
- False positive rate: good addresses flagged bad. This silently costs you subscribers and nobody complains, because the people affected never hear from you.
- False negative rate: bad addresses waved through. These show up as bounces, so you notice them, which is why teams over-index on this one.
Most buyers only measure the second. The first is usually the more expensive mistake.
Technical limitations and challenges
The hard limits worth knowing before you build on validation: catch-all domains accept everything regardless of mailbox existence; some providers block or rate-limit verification attempts; mail server downtime produces temporary false negatives; international providers behave inconsistently; and validation traffic itself can be throttled if you hammer one provider.
A few input shapes break naive validators too. Internationalized domain names need punycode conversion before they are checked, unusual but legal characters in the local part get rejected by over-strict regexes, and very long domains trip length assumptions. If you are writing your own pre-check in front of a validation API, handle those explicitly rather than dropping the address.
Validation also touches personal data, so it needs to respect user privacy and comply with data protection rules wherever your users are.
Business applications of email validity checking
Email marketing
This is the most common use. Cleaning a list before a campaign removes the addresses that would bounce, which protects your sender reputation and stops you paying to mail nobody. Ongoing hygiene keeps the list clean as it ages. For the mechanics of a full cleaning pass, see our email list cleaning guide.
User onboarding and registration
Real-time validation at signup catches bad addresses without a confirmation-email round trip. It also verifies recovery addresses, keeps two-factor delivery reliable, and surfaces suspicious patterns like burner domains during registration.
Customer communication
Transactional email has to land. Validating the addresses behind order confirmations, receipts, support replies, and billing or security alerts means those messages reach the customer instead of a dead inbox that generates a support ticket.
Lead generation and sales
Validation earns its keep in the pipeline too: scoring leads partly on whether their email works, checking addresses bought from third-party data sources before anyone wastes outreach on them, and keeping CRM contact data clean enough to trust.
Real-time or bulk: when to use which
Both, in most production setups, for different jobs.
Real-time validation runs inline at signup, checkout, contact forms, and lead capture. Its advantage is that the user is still on the page, so you can reject a typo or suggest a correction while it is still free to fix. It needs to be fast and it needs a fallback.
Bulk validation runs against lists you already have: a quarterly sweep of the database, a pass before a large campaign, and any list you import from an outside source. It is cheaper per address, it tolerates latency, and it belongs in a background worker rather than a request cycle.
The setup that works for most companies is all three: validate every new address on entry, re-validate the whole database a few times a year, and gate large sends behind a pre-campaign check.
Choosing the right email validity checking solution
Essential features for business applications
Performance first: responses fast enough to run inline on a form, throughput high enough for your bulk jobs, coverage for the international domains your users actually have, and honest error handling for the "unknown" cases.
Depth second: multiple verification methods rather than syntax-plus-marketing, disposable and spam-trap databases that get updated continuously, and risk scoring you can tune to your own tolerance.
Integration last but not least: a clean REST API with JSON responses, SDKs for your stack, bulk upload for CSV files, and documentation you can build from without a support ticket.
Beyond that, the checklist worth scoring vendors against: false positive and false negative rates on your own sample, catch-all detection, disposable coverage and how fast the blocklist updates, latency if you validate inside signup flows, batch throughput if you clean lists, and integrations with your ESP or CRM.
Pricing models and cost management
Most vendors price per email checked, with the rate depending on verification depth: syntax and domain checks cost less than full mailbox verification and risk scoring. Volume discounts kick in as monthly usage grows, and some vendors sell subscriptions with a monthly allowance instead of pure pay-per-check.
To keep the bill sensible, tier your validation so cheap checks run everywhere and expensive ones run only where the contact is worth it, batch bulk jobs to hit volume discounts, and cache results so you never pay to validate the same address twice. For a side-by-side of what the main vendors charge, see our email validation service pricing comparison.
Popular email validity checking tools compared
A quick qualitative pass over the well-known options. Pricing and accuracy claims change constantly, so verify current numbers on each vendor's site and, better, with your own trial data. Our ranking of the 10 best email verification tools compares nine of them with 1Lookup, with prices read from each vendor's own page.
1Lookup, our product, covers email, phone, and IP validation through one API and one credit pool, with no monthly minimums. Email checks include SMTP mailbox verification, disposable and role detection, and risk scoring. It is built for teams that want one vendor for all contact validation rather than a separate tool per channel.
NeverBounce leads with a friendly interface and solid bulk cleaning, which makes it a comfortable fit for marketing teams working through lists rather than code.
ZeroBounce is known for spam-trap detection and detailed bounce categorization, useful when reputational risk is the main worry. Its best pricing sits behind committed tiers, which suits high-volume senders more than small ones.
Clearout specializes in bulk list processing. Emailable is a developer-oriented API with straightforward docs. Mailgun bundles validation with its sending infrastructure, which is convenient if your transactional email already runs through them.
One thing to weigh that vendor pages will not raise: if you collect phone numbers and IP addresses as well as emails, separate vendors for each means three integrations, three bills, and three dashboards.
Implementation best practices
Real-time email validation
Validate at signup, synchronously, with a fallback for when the service is unreachable:
// Example: User registration with email validation
async function validateUserEmail(email, options = {}) {
try {
// Comprehensive email validation
const validation = await emailValidationAPI.validate(email);
// Check validation results
if (!validation.isValid) {
return { success: false, error: 'Invalid email address' };
}
if (validation.isDisposable) {
return { success: false, error: 'Disposable email addresses not allowed' };
}
if (validation.riskScore > 70) {
return { success: false, error: 'Email address appears to be high risk' };
}
// Proceed with user registration
return { success: true, validation: validation };
} catch (error) {
// Fallback to basic validation
const basicCheck = basicEmailValidation(email);
if (!basicCheck.isValid) {
return { success: false, error: 'Invalid email format' };
}
// Allow registration with warning for comprehensive validation failure
return { success: true, warning: 'Email validation service unavailable' };
}
}
A reusable API client
If you are calling a validation API from more than one place, wrap it once. Here is a Node.js client with single and batched validation:
const axios = require("axios");
class EmailValidator {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = "https://app.1lookup.io/api/v1";
}
async validateEmail(email) {
try {
const response = await axios.post(
`${this.baseUrl}/email`,
{
email: email,
},
{
timeout: 10000, // 10 second timeout
headers: {
Authorization: `Bearer ${this.apiKey}`,
"Content-Type": "application/json",
"User-Agent": "1Lookup-Email-Validator/1.0",
},
}
);
return this.parseValidationResult(response.data);
} catch (error) {
console.error("Email validation error:", error.message);
return { valid: false, error: error.message };
}
}
parseValidationResult(body) {
const { classification, insights, risk_assessment } = body.data;
return {
valid: ["DELIVERABLE", "RISKY"].includes(
classification.deliverability_status
),
deliverability_status: classification.deliverability_status,
email_type: classification.email_type,
fraud_score: risk_assessment.fraud_score,
risk_level: risk_assessment.risk_level,
catch_all: insights.deliverability.factors.catch_all,
quality_score: insights.quality.score,
};
}
async validateBulk(emails) {
const results = [];
const batchSize = 100; // Process in batches to avoid rate limits
for (let i = 0; i < emails.length; i += batchSize) {
const batch = emails.slice(i, i + batchSize);
const batchPromises = batch.map((email) => this.validateEmail(email));
try {
const batchResults = await Promise.allSettled(batchPromises);
results.push(
...batchResults.map((result) =>
result.status === "fulfilled"
? result.value
: { error: result.reason }
)
);
} catch (error) {
console.error("Batch validation error:", error);
}
// Rate limiting: wait 1 second between batches
await new Promise((resolve) => setTimeout(resolve, 1000));
}
return results;
}
}
The same pattern in Python, using a session so connections get reused:
import requests
import time
from typing import List
from dataclasses import dataclass
@dataclass
class ValidationResult:
valid: bool
deliverability_status: str
email_type: str
fraud_score: int
risk_level: str
error: str = None
class EmailValidatorAPI:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = 'https://app.1lookup.io/api/v1'
self.session = requests.Session()
self.session.headers.update({
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json',
'User-Agent': '1Lookup-Email-Validator-Python/1.0'
})
def validate_email(self, email: str) -> ValidationResult:
"""Validate a single email address"""
payload = {'email': email}
try:
response = self.session.post(
f'{self.base_url}/email',
json=payload,
timeout=10
)
response.raise_for_status()
data = response.json()['data']
status = data['classification']['deliverability_status']
return ValidationResult(
valid=status in ['DELIVERABLE', 'RISKY'],
deliverability_status=status,
email_type=data['classification']['email_type'],
fraud_score=data['risk_assessment']['fraud_score'],
risk_level=data['risk_assessment']['risk_level']
)
except requests.RequestException as e:
return ValidationResult(
valid=False,
deliverability_status='UNKNOWN',
email_type='UNKNOWN',
fraud_score=0,
risk_level='UNKNOWN',
error=str(e)
)
def validate_bulk(self, emails: List[str], batch_size: int = 100) -> List[ValidationResult]:
"""Validate multiple addresses in batches, pausing between them"""
results = []
for i in range(0, len(emails), batch_size):
batch = emails[i:i + batch_size]
results.extend(self.validate_email(email) for email in batch)
if i + batch_size < len(emails):
time.sleep(1)
return results
Bulk list processing
For marketing lists, validate in batches and sort the results into keep, watch, and drop piles:
// Example: Marketing list cleaning
async function cleanEmailList(emailList, options = {}) {
const batchSize = options.batchSize || 1000;
const batches = chunkArray(emailList, batchSize);
const validEmails = [];
const invalidEmails = [];
const riskyEmails = [];
for (const batch of batches) {
try {
const validationResults = await emailValidationAPI.validateBatch(batch);
for (let i = 0; i < batch.length; i++) {
const email = batch[i];
const result = validationResults[i];
if (result.isValid && result.riskScore < 30) {
validEmails.push({ email, ...result });
} else if (result.isValid && result.riskScore < 70) {
riskyEmails.push({ email, ...result });
} else {
invalidEmails.push({ email, ...result });
}
}
} catch (error) {
console.error('Batch validation error:', error);
// Continue with next batch
}
// Rate limiting between batches
await delay(1000);
}
return { validEmails, riskyEmails, invalidEmails };
}
Error handling and fallback strategies
Production code has to survive a validation outage. Retries with backoff, a timeout, and a conservative default cover most failure modes:
async function safeEmailValidation(email, options = {}) {
const maxRetries = options.maxRetries || 2;
const timeoutMs = options.timeout || 5000;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const result = await Promise.race([
emailValidationAPI.validate(email),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), timeoutMs)
)
]);
return result;
} catch (error) {
if (attempt === maxRetries - 1) {
// Final attempt failed, return conservative validation
return {
isValid: false,
riskScore: 75,
error: 'Validation service unavailable',
fallback: true
};
}
// Exponential backoff between retries
await delay(Math.pow(2, attempt) * 1000);
}
}
}
Whatever you do on failure, do not let a validation outage become a signup outage. Degrade to a basic syntax check, let the user through, and flag the record for re-validation later.
Performance, caching, and cost control
Four habits keep validation fast and the bill small:
- Cache verdicts. Key on a normalized (trimmed, lowercased) address and hold results for a day or two. Most APIs bill per check, so re-validating the same address is money for nothing.
- Batch anything that does not need an instant answer, and push large list jobs to background workers rather than request handlers.
- Reuse connections instead of opening a new one per request, and go async for anything in a user-facing path.
- Throttle your own callers so one runaway loop cannot burn a month of quota, and add a circuit breaker so an upstream outage fails fast instead of hanging every signup.
Set timeouts you can live with, usually five to ten seconds for a single inline check, and monitor your own API usage as a first-class metric.
Security and compliance
Treat email addresses as personal data: encrypt them in transit and at rest, keep audit logs of validation activity, restrict who can see results, and follow GDPR and CCPA rules on retention. Do not keep validation data longer than you need it, and confirm your provider's own retention policy before you send them your list.
Integration with email marketing platforms
List hygiene can run automatically against your email platform. Here is the pattern with Mailchimp:
// Example: Mailchimp integration for list cleaning
async function cleanMailchimpList(apiKey, listId, options = {}) {
const mailchimp = new MailchimpAPI(apiKey);
// Get subscribers from Mailchimp
const subscribers = await mailchimp.getListMembers(listId);
// Extract emails for validation
const emails = subscribers.members.map(member => member.email_address);
// Bulk validate emails
const validationResults = await emailValidationAPI.validateBatch(emails);
// Prepare updates for Mailchimp
const updates = subscribers.members.map((member, index) => {
const validation = validationResults[index];
return {
email_address: member.email_address,
status: validation.isValid ? 'subscribed' : 'unsubscribed',
merge_fields: {
...member.merge_fields,
EMAIL_VALID: validation.isValid ? 'Yes' : 'No',
EMAIL_RISK: validation.riskScore,
VALIDATION_DATE: new Date().toISOString()
}
};
});
// Update Mailchimp list
await mailchimp.batchUpdateMembers(listId, updates);
return {
totalProcessed: emails.length,
validEmails: validationResults.filter(r => r.isValid).length,
invalidEmails: validationResults.filter(r => !r.isValid).length
};
}
Common implementation pitfalls
Over-validating creates friction. Running your deepest, slowest check on every interaction punishes real users; graduate the depth instead, with format checks for low-stakes actions and full verification for signups that matter.
Relying on syntax checks alone leaves most of the problem in place. A perfectly formatted address can still point to a mailbox that does not exist, and only the domain and SMTP layers can tell you.
Treating temporary failures as permanent throws away good addresses. A mail server timeout is not an invalid mailbox. Retry with backoff, and store "unknown" as its own state.
Treating catch-all acceptance as proof is a quieter version of the same error. A catch-all domain says yes to everything, so acceptance there tells you almost nothing. Our catch-all email detection guide covers how to handle those addresses.
Running a stale disposable blocklist lets burner domains through. New ones appear daily, so this is a subscription to a maintained list, not a file you ship once.
Treating validation as a project rather than a schedule. Lists decay continuously, so a one-time clean buys you a few months at best.
Ignoring privacy creates legal exposure. Validation practices need to hold up under GDPR, CAN-SPAM, and whatever else governs your users.
Cost-benefit analysis
Skip the vendor ROI calculators and run your own numbers; the math is short. On the cost side: the per-check price at your volume, plus the engineering time to integrate.
On the benefit side, three inputs from your own data. First, run a trial batch through a validator to learn what share of your list is actually invalid. Second, price what those invalid addresses cost you now in wasted sends and the deliverability drag of bounces. Third, count the downstream costs a bad address creates in your business, whether that is support tickets from users who never got a confirmation email or sales time burned on dead leads.
Then weigh the ongoing costs honestly: integration is a one-time expense, but list hygiene and deliverability monitoring are recurring work. For most senders with a meaningfully dirty list, validation pays for itself quickly, but your list and your send costs decide that, not a blog post.
A 30-day rollout plan
Week 1: measure. Export your lists, pull your current bounce rate from your ESP, and write down every place an email address enters your system: signup, checkout, imports, forms, integrations. You cannot validate an entry point you have not found.
Weeks 2 and 3: implement. Bulk-validate the existing database and remove the invalid addresses. Add real-time validation to signup and lead capture. Add a pre-send validation step to your campaign process. Test the error paths deliberately, especially what happens when the API is unreachable.
Week 4: confirm it worked. Compare bounce rates before and after, check inbox placement on your next campaign, and put quarterly re-validation on the calendar.
Track four numbers from then on: bounce rate, spam complaint rate, inbox placement, and cost per delivered email. If those are moving the right way, the system is doing its job. If they are not, the problem is upstream of validation and worth finding before you spend more.
Advanced applications and use cases
Validation data is useful beyond the initial check. Marketing teams segment on it, comparing campaign performance between validated and unvalidated cohorts and using risk flags to decide who gets which content.
Security teams use it for fraud work: flagging suspicious email changes on existing accounts, blocking burner-domain patterns at registration, and verifying an address before it can be used for password recovery. Our guide to detecting disposable email addresses via API covers that path in detail.
Data teams fold it into customer platforms, using validated emails as a key for identity resolution across systems and tracking validity changes over a contact's lifecycle.
And compliance teams lean on it for GDPR and CAN-SPAM work: confirming the addresses attached to consent records are real, making sure unsubscribes process against working addresses, and running periodic validity sweeps for audits.
Industry-specific implementation guides
E-commerce and retail should prioritize transactional deliverability first, marketing hygiene second. Order confirmations and shipping updates that bounce turn directly into support tickets, so validate at checkout and before cart-recovery and promotional campaigns.
SaaS companies need real-time validation at signup most of all, since the address collected there carries product updates, billing, and account recovery for the life of the customer. See our email verification best practices for SaaS onboarding for a reference signup flow.
Financial services carry the strictest requirements. Security alerts and regulatory disclosures have to reach customers, and email validation slots into KYC and fraud prevention alongside its deliverability role.
Healthcare adds privacy on top: appointment reminders, results delivery, and emergency contact verification all depend on valid addresses, and every check has to happen inside HIPAA-compliant handling.
Future of email validity checking
Expect the machine-learning share of validation to grow: providers are moving from static checks toward prediction, using bounce history to estimate deliverability rather than only reporting whether a mailbox exists right now. Alongside that, better spam-trap detection, risk models that update as burner domains rotate, and reputation monitoring that runs continuously instead of at check time.
The other visible shift is toward privacy-first validation, with consent-aware processing, data minimization, and clearer disclosure of what a validation check actually does with an address. The core loop does not change: verify on entry, clean on a schedule, check before big sends.
Get started with email validity checking
Every invalid address on your list is money spent to reach nobody and a small dent in your sender reputation. Validation, done with the right depth in the right places, removes that waste at the source.
Start with your riskiest surface: the signup form if you are a product, the oldest list segment if you are a sender. Run a trial batch, look at what share comes back invalid, and let that number tell you how urgent the rest is.
Check a single address free with our email verifier tool, or read the email validation API docs if you are ready to wire it into your own stack. To find out who owns an address rather than whether it works, use the free reverse email lookup.
If you want to run that test with us, try 1Lookup's email validation with your own addresses.
Questions about implementation? Contact our deliverability team and we will help you design the validation strategy for your stack.
Meet the Expert Behind the Insights
Real-world experience from building and scaling B2B SaaS companies

Robby Frank
Head of Growth at 1Lookup
"Calm down, it's just life"
About Robby
Self-taught entrepreneur and technical leader with 12+ years building profitable B2B SaaS companies. Specializes in rapid product development and growth marketing with 1,000+ outreach campaigns executed across industries.
Author of "Evolution of a Maniac" and advocate for practical, results-driven business strategies that prioritize shipping over perfection.