Bulk Email Validator: MX, Disposable, Typo and Role Check
Pricing
from $1.00 / 1,000 emails
Bulk Email Validator: MX, Disposable, Typo and Role Check
Cut bounces before you send: bulk email validation with syntax, MX and null MX, dead domains, disposable and role addresses, free providers, typos (gmial.com) with fixes, SPF and DMARC. Status valid, risky, invalid or unknown with reasons. DNS only, no SMTP, so mailboxes are not confirmed.
Pricing
from $1.00 / 1,000 emails
Rating
0.0
(0)
Developer
Joe Simo
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Email Validator: Bulk MX, Disposable and Role Check
Clean an email list before you send to it, and cut bounces from dead domains, typos and throwaway addresses. Paste addresses, upload a list or point the Actor at a dataset column, and get one row per address with a clear status (valid, risky, invalid or unknown), the exact reasons, and the DNS facts behind them.
Every address gets checked for:
- Syntax: RFC 5321/5322 rules that matter in practice, with plain reasons such as
missing_at_signorinvalid_dots. HandlesJane Doe <jane@acme.com>,mailto:links, stray quotes and punctuation, and international domains (IDN). - Domain and mail servers: does the domain exist (NXDOMAIN), does it have MX records, a null MX (RFC 7505, "this domain takes no email"), or only an A record fallback. Optionally checks that the listed mail server host names actually resolve.
- Disposable domains: about 10,000 throwaway domains (mailinator.com, yopmail.com, 10minutemail.com ...), including their subdomains.
- Role accounts: info@, sales@, support@, admin@, noreply@ and about 140 more shared mailboxes.
- Free providers: Gmail, Outlook, Yahoo, iCloud, Proton, GMX, Mail.ru, QQ and about 160 more.
- Typos:
gmial.com,hotmial.com,gmail.conand similar, with a suggested fix (jane@gmail.com). - SPF and DMARC: whether the domain publishes them, and the DMARC policy (
none,quarantine,reject). - Mail provider: Google Workspace, Microsoft 365, Yahoo, Proofpoint, Mimecast, Zoho and others, detected from MX records.
Important and honest: this Actor works at the DNS level only. It never connects to mail servers (no SMTP probing), so it cannot confirm that a specific mailbox exists and cannot detect catch-all domains. valid means "the address is well formed and its domain is set up to receive email", not "this person will get your message". Every row says so with mailboxChecked: false and catchAll: null. In exchange it is fast, cheap, does not touch anyone's mail server, and cannot get your IP blocklisted.
Quick start
- Click Try for free, paste your addresses into Emails and press Start.
- Or call the API with an empty input
{}. That checks these 6 demo addresses:
{"emails": ["john.doe@gmail.com", "info@apify.com", "someone@mailinator.com", "jane@gmial.com", "bad.address@", "user@example.com"]}
On Nov 1, 2026 this run checked 6 addresses in about 1 second for 6 x $0.001 = $0.006: 1 valid (john.doe@gmail.com), 3 risky (info@apify.com role account, someone@mailinator.com disposable, jane@gmial.com typo) and 2 invalid (bad.address@ missing domain, user@example.com null MX). The typo row, shortened:
{"email": "jane@gmial.com","status": "risky","reasons": ["disposable_domain", "no_mx_a_fallback", "possible_typo"],"suggestion": "jane@gmail.com","domain": "gmial.com","syntaxValid": true,"domainExists": true,"hasMx": false,"isDisposable": true,"mailboxChecked": false,"catchAll": null}
What you can use it for
- Clean signup forms and CRM exports: drop dead domains, typos and throwaway addresses before they hurt deliverability.
- Pre-filter before a paid SMTP verifier: remove the obvious invalid and disposable rows first, so you pay the expensive per-mailbox check only for what is left.
- Lead list hygiene: flag role accounts and free mailboxes in B2B lists, and see which companies run Google Workspace or Microsoft 365.
- Fraud and abuse screening: spot disposable domains and domains with no mail setup on new accounts.
- Enrich datasets from other Actors: point it at any Apify dataset and the field that holds the email.
Why this Actor
- $1 per 1,000 emails, pay only for what is checked. Duplicates are removed before charging.
- Fast: domains are looked up once and cached, with parallel DNS queries, timeouts, retries and a DNS over HTTPS second opinion for flaky domains.
- Clear output: one status, machine readable reason codes, and a plain English
reasonTextfor every row. - Your rules: decide whether role accounts, free providers and disposable domains count as risky or invalid.
- No proxy, no browser, no SMTP: nothing that can get blocked or blocklisted.
Input
Give addresses in any combination of three ways: a list, a pasted block of text, or a dataset.
{"emails": ["john.doe@gmail.com", "info@apify.com", "someone@mailinator.com", "jane@gmial.com", "bad.address@", "user@example.com"],"emailsText": "Jane Doe <jane@acme.com>, bob@yahoo.com\nsales@shop.example","roleAsRisky": true,"disposableStatus": "risky","freeAsRisky": false}
| Field | Default | What it does |
|---|---|---|
emails | List of addresses, one per entry. | |
emailsText | Paste a whole column or text block. Split on new lines, commas, semicolons and tabs. Tokens without an @ (like a CSV header) are skipped and counted. | |
datasetId | Read addresses from an existing Apify dataset (ID or name), for example the output of another Actor. | |
datasetField | email | Field that holds the address. Dot paths work (contact.email) and array values are expanded. |
maxItems | 0 (no limit) | Check at most this many addresses (after removing duplicates). |
dedupe | true | Remove duplicates (case insensitive) before checking, so you never pay twice for the same address. |
roleAsRisky | true | Role accounts (info@, sales@ ...) get status risky. Off: they can be valid, the flag stays. |
disposableStatus | risky | Status for disposable domains: risky or invalid. |
freeAsRisky | false | Free consumer providers (gmail.com ...) get status risky. Useful for B2B lists. |
checkMxHosts | true | Also check that the listed mail server host names resolve. |
checkSpfDmarc | true | Look up SPF and DMARC records (informational, does not change status). |
includeSpfRecord | false | Add the raw SPF record text to each row. |
dnsMode | udp | udp uses plain DNS (fastest). doh uses DNS over HTTPS (Cloudflare and Google). |
dnsServers | 1.1.1.1, 8.8.8.8 | Resolvers for plain DNS. Leave empty to use the system resolver. |
dohFallback | true | When a plain DNS lookup still fails after all retries, ask Google DNS over HTTPS once before returning unknown. |
dnsConcurrency | 50 | Parallel DNS queries. |
dnsTimeoutSecs | 4 | Timeout per DNS query. |
dnsRetries | 2 | Retries on timeouts and server failures, rotating resolvers. |
Before checking anything, the Actor runs a DNS self test (gmail.com must return Google mail servers). If the configured resolver is blocked it falls back to the system resolver, then to DNS over HTTPS. If nothing works, the run fails before anything is charged.
Output
One dataset row per checked address, in input order:
{"email": "info@apify.com","normalizedEmail": "info@apify.com","status": "risky","reasons": ["role_account"],"reasonText": "Role or shared mailbox (info@, sales@, support@ ...), often a group inbox with low engagement.","suggestion": null,"localPart": "info","domain": "apify.com","syntaxValid": true,"domainExists": true,"hasMx": true,"nullMx": false,"mxFallbackToA": false,"mxRecords": [{ "exchange": "aspmx.l.google.com", "priority": 1 }, { "exchange": "alt1.aspmx.l.google.com", "priority": 5 }],"mailProvider": "Google","isDisposable": false,"isRoleAccount": true,"isFreeProvider": false,"plusTag": null,"hasSpf": true,"hasDmarc": true,"dmarcPolicy": "reject","mailboxChecked": false,"catchAll": null,"dnsErrorCode": null,"checkedAt": "2026-10-29T12:18:39.013Z"}
A typo row looks like "email": "jane@gmial.com", "status": "risky", "reasons": ["disposable_domain", "no_mx_a_fallback", "possible_typo"], "suggestion": "jane@gmail.com".
Statuses
| Status | Meaning | Typical action |
|---|---|---|
valid | Well formed, the domain exists and is set up to receive mail, no risk flags. | Keep. |
risky | Deliverable domain, but something is off: disposable, role account, typo suspect, no MX (A record fallback), quoted or non-ASCII local part, or free provider if you turned that on. | Review, or segment. |
invalid | Bad syntax, the domain does not exist, has a null MX, has no mail server at all, or its mail servers do not resolve. | Remove. |
unknown | DNS failed after retries (timeout or SERVFAIL). Usually a broken or temporarily unreachable domain. | Retry later. |
Reason codes
| Code | Status | Meaning |
|---|---|---|
empty, contains_whitespace, missing_at_sign, multiple_at_signs, missing_local_part, missing_domain, invalid_dots, invalid_characters, invalid_local_part, local_part_too_long, address_too_long | invalid | Syntax problems in the address. |
ip_address_domain, invalid_domain, domain_missing_tld, domain_too_long, invalid_tld, reserved_domain | invalid | Domain part is malformed or reserved (.test, .local, .invalid, localhost ...). |
domain_not_found | invalid | The domain does not exist (NXDOMAIN). |
null_mx | invalid | The domain publishes a null MX (RFC 7505): it accepts no email. |
no_mail_server | invalid | No MX and no A/AAAA record. |
mx_host_not_found | invalid | None of the listed mail servers resolve. |
mx_localhost | invalid | Mail servers point to localhost or an unroutable address. |
disposable_domain_invalid | invalid | Disposable domain, when disposableStatus is invalid. |
disposable_domain | risky | Disposable (throwaway) domain. |
role_account | risky | Role or shared mailbox. |
possible_typo | risky | Domain looks like a typo of a popular provider; see suggestion. |
no_mx_a_fallback | risky | No MX record; mail would go to the domain A record. Often not a real mail setup. |
quoted_local_part, non_ascii_local_part | risky | Technically allowed but rejected by many systems. |
free_provider | risky | Only when freeAsRisky is on. |
dns_error, mx_host_dns_error | unknown | DNS lookups failed after retries. |
Field reference
| Field | Description |
|---|---|
email | The value as supplied. |
normalizedEmail | Cleaned address with a lowercase, ASCII (punycode) domain. The local part keeps its case. |
status, reasons, reasonText | Verdict, reason codes, and plain English explanation. |
suggestion | Corrected address when the domain looks like a typo, else null. |
localPart, domain | The two halves of the address. |
syntaxValid | Passed the syntax checks. |
domainExists | The domain resolves in DNS. Null if not checked or DNS failed. |
hasMx, nullMx, mxFallbackToA | MX record found, null MX found, or no MX but an A/AAAA record. |
mxRecords | Up to 5 mail servers, best priority first. |
mailProvider | Detected mail host (Google, Microsoft, Yahoo, Proofpoint ...), or null. |
isDisposable, isRoleAccount, isFreeProvider | Flags, independent of how you set the status rules. |
plusTag | Sub-address tag, for example promo in sales+promo@acme.com. |
hasSpf, hasDmarc, dmarcPolicy | Email authentication records of the domain. spfRecord is added when includeSpfRecord is on. |
mailboxChecked, catchAll | Always false and null: this Actor does not open SMTP connections. |
dnsErrorCode | DNS error code when status is unknown. |
checkedAt | ISO time of the check. |
Run summary
The key value store record OUTPUT holds a summary: emails supplied, duplicates removed, emails checked, counts per status and per reason, unique domains, DNS statistics (resolver used, queries, cache hits, retries, timeouts) and run time. The dataset also has an Overview view and a DNS details view in Console.
Pricing
Pay per event, no subscription:
| Event | Price |
|---|---|
| Email checked (one dataset row) | $0.001 ($1 per 1,000) |
| Actor start | $0.00005 per run (Apify default) |
Duplicates removed by dedupe are not charged. If you set a maximum cost per run, the Actor checks only as many addresses as fit, stops cleanly, and reports how many were left in notCheckedBecauseOfChargeLimit.
Rough cost: 10,000 addresses cost about $10. In our cloud test, 10,000 addresses across about 1,000 different domains finished in under a minute at the default 256 MB memory. Lists with fewer distinct domains are faster.
Limits and good to know
- No mailbox check. DNS cannot tell whether
john@acme.comexists. If you need that, run the cleaned list through an SMTP verifier; this Actor makes that list shorter and cheaper. - No catch-all detection for the same reason.
- Disposable lists are never complete. New throwaway domains appear every day. The list is updated with new Actor versions.
- Role and free provider lists cover the common cases, not every one in the world.
unknownis rare and usually means the domain's own DNS is broken. Rerun those rows later.- Domains are cached within a run, so lists with many addresses at the same company are very fast.
FAQ
Is a valid address guaranteed to be deliverable?
No. It means the address is well formed and its domain accepts mail according to DNS. The mailbox may still not exist, be full, or bounce. Anyone who promises more without SMTP access is guessing.
Why not do SMTP checks? SMTP probing is slow, often blocked or misleading (many providers accept every address), and can get the probing IP blocklisted. This Actor stays at the DNS level on purpose and is priced accordingly.
Why is jane@gmial.com marked disposable?
Some typo domains of big providers are registered by third parties and collect mail, so the open source disposable list includes them. The possible_typo reason and suggestion tell you what was probably meant.
Can I use my own DNS servers?
Yes, set dnsServers, or switch dnsMode to doh for DNS over HTTPS.
Does it find or collect email addresses? No. It only checks the addresses you give it. It does not scrape, search for or store addresses anywhere other than your own run's dataset.
Data sources and licenses
- Disposable domains: disposable-email-domains, released under CC0 1.0 (public domain dedication), snapshot of 2026-10-27. Some extra checks for subdomains are added by this Actor.
- Role account, free provider, typo and mail provider rules are maintained in this Actor.
Legal and privacy
Email addresses are personal data in many jurisdictions (GDPR, CCPA and others). Only submit addresses you are allowed to process, for example your own customers or contacts with a lawful basis. The Actor processes them only inside your run, sends only domain names to DNS resolvers, and keeps results in your own Apify storage, which you control and can delete.
Support
Questions, bugs or feature requests: open an issue on the Actor's Issues tab, or email joesimo@mail.grokbot.com.
More examples and the docs for all 6 of our Actors: github.com/Joe-Simo/apify-actors. Store page: https://apify.com/joesimo/email-validator