Remove invalid, disposable, and risky addresses with real-time SMTP verification
Email lists decay at roughly 22% per year as people change jobs and providers. Our API checks each address via live SMTP, MX records, and disposable-domain databases so you send only to inboxes that exist — reducing bounce rates, protecting sender reputation, and cutting ESP costs.
One email per line — add your API key below to verify more addresses
Six-layer verification catches every category of bad address before it reaches your ESP
A live SMTP handshake confirms the specific inbox exists on the recipient's mail server — not just that the domain accepts email. Catches invalid addresses that pass MX checks alone.
Checks DNS mail exchange records to confirm the domain is properly configured to receive email. Removes addresses on domains with no mail infrastructure.
Matches against a continuously updated database of 10,000+ temporary and throwaway email providers (Mailinator, Guerrilla Mail, etc.) updated every 12 hours.
Flags addresses like admin@, noreply@, support@, and info@ that belong to teams rather than individuals. These rarely convert and often generate spam complaints.
Identifies domains configured to accept all incoming email regardless of whether the specific mailbox exists. Catch-all addresses look valid but produce unpredictable delivery results.
Detects common domain misspellings (gmial.com, yhaoo.com, hotmial.com) and returns the likely intended address so you can correct signup data at source.
Three steps from dirty list to deliverable list — via API or CSV in minutes
Send a JSON array or upload a CSV file to the batch endpoint. Up to 100 addresses per request, up to 300,000 per month on the Enterprise plan. The first column of your CSV is used automatically; headers are detected and skipped.
Each address is checked in parallel: syntax rules, MX record lookup, live SMTP handshake, disposable-domain match, role-account pattern, and catch-all probe. Addresses are processed concurrently — a 100-email batch typically completes in under 60 seconds.
The API returns a JSON object with per-address results including reachable, smtp.deliverable, disposable, role_account, and smtp.catch_all flags. Filter to reachable: "yes" and disposable: false to get your clean list. The tool above generates a ready-to-download CSV.
Every invalid address you send to is a wasted cost, a bounce event, and a signal to ISPs that your sending practices need scrutiny
Major ESPs including Mailchimp and SendGrid flag accounts when hard bounce rates exceed 2%. Once flagged, deliverability suffers for all subsequent sends — including to your valid subscribers. Regular list cleaning keeps your bounce rate well below that threshold.
Most ESPs charge by list size or email volume. B2B email lists typically contain 15–25% invalid addresses within six months of collection. Removing those addresses before your next send directly reduces the quantity you're billed for — with no impact on reach.
ISPs and spam filters use bounce rates, complaint rates, and engagement signals to score your sender domain and IP. Consistently sending to stale or invalid addresses trains filters to treat your emails as low-quality, causing inbox placement to decline over time.
Sending to a smaller, verified list produces higher open rates — which in turn improves inbox placement in subsequent sends, creating a positive feedback loop. Cleaned lists consistently outperform uncleaned ones on engagement metrics.
Clean lists before campaign sends to maximise deliverability and reduce ESP overage charges
Validate imported contact exports from LinkedIn, trade show scans, and form submissions
Scrub prospect lists before sequences to stay below bounce thresholds and protect domain reputation
Validate email at signup with the single-address endpoint, then re-verify dormant accounts in bulk
Subscribe to verify up to 300,000 addresses per month via API or CSV upload.
Two batch endpoints — JSON array for programmatic integration, CSV multipart upload for file-based workflows. Both return per-address SMTP results in one synchronous response.
The batch endpoint accepts up to 100 addresses per request. Results include reachability, SMTP status, disposable flag, role account flag, and catch-all detection for every address.
# Clean a list of email addresses via JSON batch
curl -X POST "https://ip-api.io/api/v1/email/advanced/batch" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{"emails": ["alice@example.com", "bob@company.org", "noreply@acme.io"]}'
# Upload a CSV file — first column is used, headers auto-detected
curl -X POST "https://ip-api.io/api/v1/email/advanced/batch/csv" \
-H "X-Api-Key: YOUR_API_KEY" \
-F "file=@email_list.csv"
import requests, csv, io
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://ip-api.io/api/v1/email/advanced"
def clean_email_list(emails):
"""Verify a list of emails and return only deliverable addresses."""
response = requests.post(
f"{BASE_URL}/batch",
headers={"X-Api-Key": API_KEY},
json={"emails": emails}
)
response.raise_for_status()
results = response.json()
clean, risky, invalid = [], [], []
for email, data in results.items():
if data.get("reachable") == "yes" and not data.get("disposable"):
clean.append(email)
elif data.get("reachable") == "unknown" or data.get("smtp", {}).get("catch_all"):
risky.append(email)
else:
invalid.append(email)
return {"clean": clean, "risky": risky, "invalid": invalid}
# Example: clean a list in batches of 100
emails = ["alice@example.com", "test@mailinator.com", "bob@company.org"]
result = clean_email_list(emails)
print(f"Clean: {len(result['clean'])}, Risky: {len(result['risky'])}, Invalid: {len(result['invalid'])}")
const API_KEY = "YOUR_API_KEY";
async function cleanEmailList(emails) {
const response = await fetch(
"https://ip-api.io/api/v1/email/advanced/batch",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": API_KEY
},
body: JSON.stringify({ emails })
}
);
if (!response.ok) throw new Error(`API error: ${response.status}`);
const results = await response.json();
return Object.entries(results).reduce(
(acc, [email, data]) => {
if (data.reachable === "yes" && !data.disposable) {
acc.clean.push(email);
} else if (data.reachable === "unknown" || data.smtp?.catch_all) {
acc.risky.push(email);
} else {
acc.invalid.push(email);
}
return acc;
},
{ clean: [], risky: [], invalid: [] }
);
}
// Usage
cleanEmailList(["alice@example.com", "test@mailinator.com"])
.then(({ clean, risky, invalid }) => {
console.log(`Clean: ${clean.length}, Risky: ${risky.length}, Invalid: ${invalid.length}`);
});
<?php
$apiKey = "YOUR_API_KEY";
$emails = ["alice@example.com", "test@mailinator.com", "bob@company.org"];
$response = file_get_contents(
"https://ip-api.io/api/v1/email/advanced/batch",
false,
stream_context_create([
"http" => [
"method" => "POST",
"header" => "Content-Type: application/json\r\nX-Api-Key: $apiKey",
"content" => json_encode(["emails" => $emails])
]
])
);
$results = json_decode($response, true);
$clean = array_filter($results, fn($d) => $d["reachable"] === "yes" && !$d["disposable"]);
echo count($clean) . " deliverable addresses";
JSON body: {"emails": ["addr1@...", "addr2@..."]} — up to 100 addresses
Multipart form with file field — CSV/TXT, first column, ≤1MB per request
"yes", "no", or "unknown"Each batch request processes up to 100 addresses concurrently. A full 100-address batch typically completes in 15–60 seconds. For lists larger than 100, split into sequential requests and merge the results — or use the code pattern above. Quota is only deducted on successful completion; a failed batch costs nothing.
Start using IP-API.io to make your website safer and more user-friendly. Keep out unwanted bots, show visitors content that's relevant to where they are, and spot risky IP addresses quickly. It's perfect for making online shopping more personal and keeping your site secure. Get started today with one of the plans!
Everything you need to know about email hygiene, list scrubbing, and SMTP verification
Email list cleaning — also called email list scrubbing or email hygiene — is the
process of removing invalid, undeliverable, and risky addresses from a mailing list before sending. This includes
addresses that bounce (invalid syntax, no MX records, non-existent inboxes), disposable or temporary email addresses,
role-based accounts like admin@ and noreply@, and catch-all domains that accept any address
regardless of whether it exists.
Each address is checked in a series of steps: (1) syntax validation against RFC 5321/5322 rules, (2) MX record lookup to confirm the domain has mail infrastructure, (3) a live SMTP handshake with the recipient's mail server to verify the specific inbox exists, (4) matching against a database of known disposable and temporary email providers, and (5) pattern matching for role-based accounts. The result is a deliverability verdict — typically reachable, not reachable, or unknown — plus individual flags for each check.
Most email marketers clean their lists every 3–6 months, or before any large campaign send. B2B lists decay faster than B2C — roughly 22% of business email addresses become invalid each year as people change jobs. As a practical rule: clean before any send to a list that hasn't been mailed in 90 days, and clean monthly if you're importing new contacts from trade shows, LinkedIn exports, or lead generation forms.
Email validation typically refers to checking a single address in real time — for example, at signup to reject typos and disposable addresses before they enter your database. Email list cleaning refers to batch-processing an existing list to remove accumulated invalid contacts. The underlying SMTP checks are the same, but the workflow differs: validation is a real-time gate at data entry, while list cleaning is periodic maintenance applied to stored contacts. See our Advanced Email Validation API for single-address real-time checking.
Yes. The POST /api/v1/email/advanced/batch/csv endpoint accepts a multipart form with a CSV or plain text
file up to 1MB per request. The first column is used as the email address; header rows are detected and skipped automatically.
For files larger than 1MB, split them and send multiple requests, then merge the results.
A catch-all domain is configured to accept all incoming email regardless of whether a specific mailbox exists — so SMTP verification cannot confirm the individual inbox. They're common in enterprise and government domains (where the address is often real), but also used to capture harvested emails. A conservative approach is to treat them as risky: keep them in a separate segment and monitor bounce rates before sending at full volume.
Email hygiene is the ongoing practice of maintaining a high-quality list by regularly removing invalid and unresponsive contacts, monitoring bounce and complaint rates, and keeping data current. Good hygiene includes: removing hard bounces immediately after each send, cleaning the full list every 3–6 months with SMTP verification, suppressing contacts who haven't opened any email in 12+ months, and validating new addresses at the point of collection.
SMTP verification is the most accurate method available for confirming inbox existence, with accuracy typically cited at 95%+ for non-catch-all domains. The main limitation is catch-all servers, which always accept SMTP connections, and greylisting — temporary rejections that look like failures. For non-catch-all domains, SMTP reliably distinguishes between existing and non-existing inboxes.
Explore how IP-API.io can enhance your security, provide robust bot protection, and improve IP geolocation accuracy for your applications.
Contact SupportCustomize your experience with tailored plans that fit your IP security and geolocation needs.
Email Us