Email List Cleaner & Validator (Syntax, MX, Disposable) avatar

Email List Cleaner & Validator (Syntax, MX, Disposable)

Pricing

from $0.56 / 1,000 email checkeds

Go to Apify Store
Email List Cleaner & Validator (Syntax, MX, Disposable)

Email List Cleaner & Validator (Syntax, MX, Disposable)

Clean and validate email lists in bulk: syntax, MX records, disposable domains, role addresses, typo fixes and duplicates. No SMTP probing, privacy-friendly.

Pricing

from $0.56 / 1,000 email checkeds

Rating

0.0

(0)

Developer

James Brown

James Brown

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Email Validator & List Cleaner (MX, Disposable, Typos)

This email validator and list cleaner checks an email list before you send to it. For every address you get syntax validation, a DNS MX check (with the RFC 5321 A-record fallback), disposable-domain detection, role-address detection (info@, sales@, admin@, enquiries@, kontakt@…), domain typo suggestions (gmial.com → gmail.com), duplicate flags and a plain verdict: deliverable-likely, risky or invalid with the reasons. A ready-made clean CSV of the addresses worth keeping is saved next to the results.

No SMTP probing, no mailbox verification. The actor never connects to a mail server and never sends a message, so it cannot get your IP blocklisted, trigger greylisting or tip anyone off that an address is being tested. The only network traffic about your addresses is DNS lookups of their domains (the part after the @). The part before the @ never leaves the run. That makes it fast, cheap and privacy-friendly: $0.80 per 1,000 addresses.

What the email validator can and cannot tell you

This actor
Is the address well-formed?Yes
Does the domain exist and can it receive mail (MX, or A/AAAA fallback, null-MX)?Yes
Is the domain a known disposable / throwaway service?Yes (bundled list, CC0)
Is it a shared role mailbox (info@, sales@…)?Yes
Did the user mistype a popular domain (gmial.com)?Yes, with a suggested fix
Does this particular mailbox exist?No (that needs SMTP probing, which this actor deliberately does not do)
Is the domain a catch-all?No

A deliverable-likely verdict means "well-formed, the domain accepts mail, and nothing suspicious was found". It is not a guarantee the mailbox exists. Use it to remove the obviously dead, mistyped and throwaway addresses before a send, not as proof of delivery.

What the email list cleaner returns per address

FieldMeaning
row1-based position among non-blank inputs
originalThe input, trimmed
normalizedTrimmed, domain lowercased (IDN domains in punycode), Name <addr> and mailto: unwrapped. null if the syntax is invalid
syntaxValidRFC 5321/5322 dot-atom syntax check (quoted local parts and IP-literal domains are rejected)
domainLowercase domain
hasMxtrue if the domain has MX records, or none but an A/AAAA record (implicit MX per RFC 5321 §5.1; see mxSource); false if it cannot receive mail; null if the lookup failed
mxSourcemx, a-fallback or null
dnsStatusok, nxdomain, null-mx (RFC 7505: domain refuses mail), no-records, or error (timeout / SERVFAIL after one retry)
isDisposableDomain, or a parent domain, is on the disposable list
isRoleAddressLocal part is a role mailbox (info, sales, admin, no-reply, enquiries, bookings, accounts, reception, kontakt, ventas, accueil…; dots, hyphens, underscores and +tags ignored)
typoSuggestionLikelier domain, e.g. gmail.com for gmial.com
suggestedEmailThe address with the domain fixed
duplicateOf, duplicateOfRowSet on repeats (compared case-insensitively on the normalized address; inputs that are not valid addresses are compared by their trimmed text); duplicateOfRow is the first occurrence
recoveredAfterRestartOnly present (true) on a row pushed again after a restart; it was not charged a second time
verdictdeliverable-likely, risky, invalid (null on duplicates, whose first occurrence carries the verdict)
reasonsWhy: see below

Verdict rules. invalid: bad syntax (syntax:…), domain-not-found, null-mx, no-mail-records. Otherwise risky if any of disposable-domain, role-address, possible-typo, no-mx-a-record-fallback (the domain has a web server record but no MX), dns-unavailable (the lookup failed, so the domain is unknown), internationalised-local-part (valid, but many systems cannot handle it). Otherwise deliverable-likely.

Input

FieldDescription
emailsList of addresses
textBlob: one per line, or separated by commas / semicolons / tabs. Name <a@b.com> and mailto: forms are understood
csvUrl + csvColumnPublic CSV URL, read as a stream (up to 200 MB). Column by header name or 1-based index; auto-detects headers containing "mail"
csvHeaderauto / yes / no: whether the first CSV row is a header
includeRiskyInCleanCsvAlso put risky addresses in the clean CSV. Default off

Run it with no input and you get an 11-row sample.

Example input

{
"emails": ["jane.doe@gmail.com", "Jane.Doe@GMAIL.com", "sam@hotmial.co.uk", "info@gmail.com", "promo@mailinator.com", "user@@broken"]
}

Example output (one record shown)

{
"row": 3,
"original": "sam@hotmial.co.uk",
"normalized": "sam@hotmial.co.uk",
"syntaxValid": true,
"domain": "hotmial.co.uk",
"hasMx": true,
"mxSource": "mx",
"dnsStatus": "ok",
"isDisposable": false,
"isRoleAddress": false,
"typoSuggestion": "hotmail.co.uk",
"suggestedEmail": "sam@hotmail.co.uk",
"duplicateOf": null,
"duplicateOfRow": null,
"verdict": "risky",
"reasons": ["possible-typo"]
}

Clean-CSV export

When the run ends, two files are saved in the run's key-value store:

  • clean-emails.csv: one email column with the first occurrence of every deliverable-likely address (plus risky ones if you switched that on). Invalid addresses are never in it. Addresses starting with =, +, - or @ are left out (spreadsheet formula risk) and listed in the review file instead.
  • review-emails.csv: every risky and invalid address with its reasons and suggestedEmail, for fixing by hand. Text beginning with = + - @ is prefixed with ' so spreadsheets do not execute it.

Both are built from the run's dataset when the run finishes, so they are complete even after a restart.

Pricing (pay per event)

EventPriceWhen it is charged
Actor start$0.005Once per run
Email checked$0.0008Per unique address checked (duplicates, blank rows and failed DNS lookups are free)
AddressesApproximate cost
1,000$0.805
10,000$8.005
100,000$80.005
  • Actor start: $0.005 per run (Apify's apify-actor-start event). Maximum run memory is capped at 1,024 MB so the start event is never multiplied.
  • Email checked: $0.0008 per address (email-checked event), charged after the result is saved to the dataset. Syntax-invalid addresses are charged too (first occurrence only): they are a completed check with an invalid verdict.
  • Free: duplicates (including repeated invalid inputs such as N/A), blank rows, and addresses whose DNS lookup failed with a timeout/SERVFAIL (dnsStatus: "error"; those are returned as risky / dns-unavailable; re-run them later).

Example: 50,000 unique addresses = $40.00 + $0.005. If you set a maximum cost per run, the actor stops cleanly when it is reached.

Performance

Addresses are processed in batches of 500, with up to 50 DNS lookups in flight and one lookup per distinct domain per run (cached). Measured locally (Windows dev machine, Python 3.11, real DNS from a home connection, local file storage, no pricing configured): 403 addresses over 10 domains took about 7 seconds; 5,000 addresses over about 300 distinct domains took about 70 seconds with a peak of about 84 MB resident memory (much of that time is local per-item dataset writes, as with the other actors in this portfolio). Lists with many distinct domains are limited by DNS latency, not CPU; memory is dominated by the interpreter and the bundled disposable list (about 10,000 domains), and the duplicate index holds one short entry per distinct address. These figures were measured locally, not on the Apify platform.

Restarts

Progress is saved to the key-value store (PROGRESS, counters only, never addresses), so a restart or migration continues without re-pushing or re-charging addresses already delivered, and without repeating their DNS lookups. Results are never lost and never double-charged: the few addresses that were in flight when the run was interrupted are pushed again, without a charge, and carry recoveredAfterRestart: true. In rare cases that means a result row appears twice in the dataset (the first copy has no flag); the two CSV exports are built with each row number once, so they contain no repeats.

Data sources, licences and compliance

  • Disposable domains: disposable-email-domains disposable_email_blocklist.conf, CC0 1.0 Universal (public-domain dedication; verified 2026-10-21 against the repository's LICENSE.txt). Bundled unmodified in data/disposable_domains.txt (upstream commit and licence copy in data/SOURCE.md and data/LICENSE-disposable-email-domains.txt). The list is as of the actor's build and is refreshed by releasing a new version. It also contains some typo-squatting domains (e.g. gmial.com), which therefore get both disposable-domain and possible-typo.
  • Role-address and typo lists: written for this actor (no third-party data).
  • Dependencies: dnspython (ISC licence), httpx (BSD-3-Clause), the Apify SDK (Apache-2.0). No GPL/AGPL code.
  • ToS / robots.txt: nothing is scraped. DNS is queried through the platform's resolver. The only HTTP access is when you supply a csvUrl: the actor then fetches that file, identifies itself with a User-Agent, honours the host's robots.txt (RFC 9309; it refuses if disallowed, and also if robots.txt cannot be fetched or returns 5xx/429), re-checks every redirect target, blocks private/internal addresses, and spaces requests about 1 second apart. This cannot be switched off.
  • Credentials in URLs (user:pass@host) are not sent: the actor never makes authenticated requests, so use a URL that needs no login.
  • What is stored: the results go to the run's default dataset and the two CSV files plus PROGRESS to the run's default key-value store, with standard Apify storage retention for your account/plan. You control and can delete them. The actor keeps nothing outside your run. Addresses are never written to the run log; error messages contain neither addresses nor full URLs. Apart from the domain DNS lookups described above, the addresses are not sent anywhere.
  • Personal data: email addresses are personal data. You are responsible for having a lawful basis (e.g. UK GDPR / PECR) for processing and mailing the addresses you submit.

Limitations

  • No mailbox-level verification. Cannot detect non-existent mailboxes on a working domain, full inboxes or catch-all servers.
  • Disposable detection is list-based and only as current as the bundled list; new throwaway domains will be missed. The list can also contain domains you consider legitimate.
  • Typo suggestions are advisory: exact for a curated set of common mistakes, plus a conservative one-edit fuzzy match against about 50 popular providers. A real but unusual domain one letter away from a big provider can be flagged.
  • Role detection is a word list; unusual role names are not recognised, and a few personal addresses may share a role word.
  • Duplicates compare the full normalized address case-insensitively; Gmail dots and +tags are not collapsed.
  • DNS answers reflect the moment of the run, as seen from the platform's resolver. A dns-unavailable row means "unknown": re-run it.
  • Quoted local parts ("a b"@x.com), comments and IP-literal domains are treated as invalid.
  • CSV input: quoted multi-line fields are parsed as one record. csvColumn takes a header name or a 1-based number. If the file changes between a restart and the original run, row numbers may shift.
  • The platform's dataset retention applies; download your results in time.

FAQ

How do I clean an email list? Add the addresses to emails, paste them into text, or give a public csvUrl. Download clean-emails.csv from the run's key-value store for the addresses worth keeping, and review-emails.csv for the ones to fix.

Does it verify that a mailbox exists? No. It checks syntax, whether the domain can receive mail (MX), disposable domains, role addresses and likely typos. It never connects to a mail server, so it cannot confirm a specific mailbox.

Can it find disposable email addresses? Yes, against a bundled list of about 10,000 disposable domains. New throwaway domains may be missed until the list is refreshed.

Can it fix typos such as gmial.com? It suggests the likelier domain in typoSuggestion and suggestedEmail; it does not change your data.