How to clean an email list before a campaign: bulk MX, disposable and typo check
Updated 2026-10-28 ยท Tool used: Bulk Email Validator - MX, Disposable, Role & Typo Check on Apify ยท Price: $0.30 per 1,000 emails; bad syntax, duplicates and DNS errors are free
Old CRM exports, scraped lead lists and signup forms all collect dead domains, typos like gmial.com and throwaway inboxes. Sending to them causes bounces that hurt your sender reputation, and most verification services charge several dollars per 1,000 addresses.
This guide shows how to run a cheap first pass over thousands of addresses using DNS only: syntax, whether the domain exists and accepts mail (MX, null MX, A fallback), about 10,000 disposable domains, role inboxes such as info@, free webmail and typo suggestions, plus the domain's SPF and DMARC. It does not probe mailboxes over SMTP, which keeps it fast and safe for your list.
Steps
- Paste addresses into
emails(a column copied from Excel or a CRM export works), or setdatasetIdto pull every email from another run, such as a contact extractor. - Run it. Each unique address that gets a DNS verdict is one charge; duplicates and bad syntax are free.
- Filter by
statusand flags such asisRoleBasedorisDisposable, then export only thevalidrows as CSV.
Example input
{
"input": "jane@gmial.com",
"email": "jane@gmial.com",
"status": "risky",
"reason": "typo-trap domain on the disposable list, did you mean jane@gmail.com?",
"syntaxValid": true,
"domain": "gmial.com",
"localPart": "jane",
"isRoleBased": false,
"isFreeProvider": false,
"isDisposable": true,
"didYouMean": "jane@gmail.com",
"domainExists": true,
"hasMx": false,
"mxRecords": [],
"nullMx": false,
"acceptsMailViaA": true,
"hasSpf": false,
"hasDmarc": false,
"smtpChecked": false,
"charged": true,
"checkedAt": "2026-10-18T07:03:28.104Z"
}
Example output (one item, shortened)
{
"input": "jane@gmial.com",
"status": "risky",
"reason": "typo-trap domain on the disposable list, did you mean jane@gmail.com?",
"syntaxValid": true,
"domain": "gmial.com",
"localPart": "jane",
"isRoleBased": false,
"isFreeProvider": false,
"isDisposable": true,
"didYouMean": "jane@gmail.com",
"domainExists": true,
"hasMx": false,
"mxRecords": [],
"nullMx": false,
"acceptsMailViaA": true,
"hasSpf": false,
"hasDmarc": false,
"smtpChecked": false,
"charged": true,
"checkedAt": "2026-10-18T07:03:28.104Z"
}
Every run's dataset can be downloaded as JSON, CSV, Excel, XML or HTML from the Apify Console, or via https://api.apify.com/v2/datasets/<datasetId>/items?format=csv.
Run it from code
Python
from apify_client import ApifyClient # pip install apify-client
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run_input = {
"input": "jane@gmial.com",
"email": "jane@gmial.com",
"status": "risky",
"reason": "typo-trap domain on the disposable list, did you mean jane@gmail.com?",
"syntaxValid": true,
"domain": "gmial.com",
"localPart": "jane",
"isRoleBased": false,
"isFreeProvider": false,
"isDisposable": true,
"didYouMean": "jane@gmail.com",
"domainExists": true,
"hasMx": false,
"mxRecords": [],
"nullMx": false,
"acceptsMailViaA": true,
"hasSpf": false,
"hasDmarc": false,
"smtpChecked": false,
"charged": true,
"checkedAt": "2026-10-18T07:03:28.104Z"
}
run = client.actor("tinyrex/bulk-email-validator").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)JavaScript / Node.js
import { ApifyClient } from 'apify-client'; // npm i apify-client
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('tinyrex/bulk-email-validator').call({
"input": "jane@gmial.com",
"email": "jane@gmial.com",
"status": "risky",
"reason": "typo-trap domain on the disposable list, did you mean jane@gmail.com?",
"syntaxValid": true,
"domain": "gmial.com",
"localPart": "jane",
"isRoleBased": false,
"isFreeProvider": false,
"isDisposable": true,
"didYouMean": "jane@gmail.com",
"domainExists": true,
"hasMx": false,
"mxRecords": [],
"nullMx": false,
"acceptsMailViaA": true,
"hasSpf": false,
"hasDmarc": false,
"smtpChecked": false,
"charged": true,
"checkedAt": "2026-10-18T07:03:28.104Z"
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);curl (no SDK)
# Runs the actor and returns the results directly (CSV here; use format=json for JSON)
curl -X POST "https://api.apify.com/v2/acts/tinyrex~bulk-email-validator/run-sync-get-dataset-items?format=csv" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"input": "jane@gmial.com", "email": "jane@gmial.com", "status": "risky", "reason": "typo-trap domain on the disposable list, did you mean jane@gmail.com?", "syntaxValid": true, "domain": "gmial.com", "localPart": "jane", "isRoleBased": false, "isFreeProvider": false, "isDisposable": true, "didYouMean": "jane@gmail.com", "domainExists": true, "hasMx": false, "mxRecords": [], "nullMx": false, "acceptsMailViaA": true, "hasSpf": false, "hasDmarc": false, "smtpChecked": false, "charged": true, "checkedAt": "2026-10-18T07:03:28.104Z"}' > results.csv
Get your API token in Apify Console โ Settings โ API & Integrations. The free Apify plan includes monthly credit that is enough to try this.
Use it from an AI agent (MCP)
The Apify MCP server exposes this actor as a tool for Claude, Cursor, VS Code, n8n and other MCP clients. Add this to your client's MCP config (or use the OAuth flow at mcp.apify.com instead of a token):
{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=tinyrex/bulk-email-validator",
"headers": {
"Authorization": "Bearer <YOUR_APIFY_TOKEN>"
}
}
}
}
Then ask in plain language, e.g. "Bulk email validator for this list and give me a table".
Pricing
Pay per result: $0.30 per 1,000 emails; bad syntax, duplicates and DNS errors are free. You can cap the cost of every run in the run options.
FAQ
How do I check if an email is valid without sending an email?
The actor checks the syntax and asks DNS whether the domain exists and has a mail server. If either fails, the address cannot receive mail and is marked invalid.
Does it check whether the mailbox exists?
No. There is no SMTP handshake, so it cannot confirm that a specific person's mailbox exists on a domain that accepts mail. Use it to remove dead domains, disposables and typos first, then send the rest to an SMTP verifier if you need mailbox-level certainty.
Should I remove role-based emails like info@?
For cold outreach to people, often yes; for B2B lead lists they are usually fine. They stay valid and are flagged with isRoleBased so you can decide.
Is my list stored or shared?
The emails stay in your own Apify run storage. Lookups go to public DNS over HTTPS, which only sees domain names, never full addresses.
Try it on Apify โMore guides
- Bulk tech stack lookup: a Wappalyzer / BuiltWith alternative for thousands of domains
- How to scrape Greenhouse, Lever and Ashby jobs (plus Personio, Teamtailor, Recruitee)
- How to export all products from any Shopify store to CSV or JSON
- How to scrape jobs from Workday career sites (myworkdayjobs.com)
- How to export products from any WooCommerce store to CSV or JSON
- How to export EU public tenders from TED (Tenders Electronic Daily) to CSV or JSON
- How to scrape remote jobs from Himalayas, Remote OK, We Work Remotely and more in one run
- How to export open EU funding calls (Horizon Europe, Digital Europe, cascade funding) to CSV or JSON
- How to turn any RSS or Atom feed into JSON or CSV (bulk, with monitoring)
- How to extract emails, phone numbers and social links from a list of company domains
- How to take bulk website screenshots from a URL list and save them to CSV or Google Drive
- How to export US federal (SAM.gov) and UK (Contracts Finder) tenders to CSV or JSON
- How to look up French companies by SIREN or SIRET and build a B2B list from Sirene
- How to look up Norwegian companies by organisation number and build lead lists from Brreg
- How to download SEC filings (10-K, 10-Q, 8-K, Form 4) by ticker and search EDGAR full text
- How to validate NPI numbers in bulk and build US healthcare provider lists from NPPES
- How to look up hundreds of UK companies on Companies House at once (profile, officers, PSC)
- How to look up Finnish companies by Y-tunnus and build B2B lead lists from the YTJ register
- How to extract all URLs from a website's sitemap (and find broken links)
- How to transcribe hundreds of audio and video files to text and subtitles with Whisper
- How to extract text from hundreds of PDFs, including scanned ones, in one run
- How to get Dutch public tenders from TenderNed into a spreadsheet, with daily alerts
- How to audit titles, meta descriptions, H1s and canonicals for hundreds of pages at once
- How to find every broken link and redirect on a website, with the pages to fix
- How to validate LEI codes and find the LEI for a list of companies in bulk
- How to run Lighthouse on hundreds of URLs and get Core Web Vitals in one table