Email Validator & List Cleaner
Pricing
from $0.40 / 1,000 email checkeds
Email Validator & List Cleaner
Sorts an email list into valid, invalid, risky and unknown addresses, with the reason for each, for marketers, sales teams and developers. Checks syntax, the domain's mail server, disposable and role addresses, and typos. It checks the address and its domain, not the individual mailbox.
Pricing
from $0.40 / 1,000 email checkeds
Rating
0.0
(0)
Developer
Enis Bodlli
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Clean an email list before you send to it. This email validator checks every address you give
it for correct syntax, looks up whether its domain is set up to receive mail, flags
disposable, role and free-provider addresses, names the mail provider behind the
domain, and suggests a fix for typos such as gmial.com. Paste the list, upload a CSV or TXT
file, or point it at an Apify dataset. To try it, leave the five sample addresses in the input and
click Start: you get one result per address, as a table you can export.
It checks the address and its domain, not the individual mailbox. The Actor does not contact the
mail server to ask whether a particular inbox exists, so valid means "correctly formed, and the
domain is set up to receive mail". It does not mean "this person's inbox exists".
Nothing is scraped and no email is sent. You supply the addresses, and the only outside information the Actor uses is the public DNS record of each domain.
What you can do with this email list cleaner
- Clean a mailing list before a campaign. Remove malformed addresses and addresses on domains that no longer exist or take no mail. These bounce every time.
- Catch typos.
user@gmial.comcomes back with the suggestionuser@gmail.com, so you can correct the address and keep the contact. - Filter out throwaway sign-ups. Addresses from disposable email services are flagged.
- Sort a lead list. Tell shared mailboxes such as
info@orsales@from personal ones, and free-provider addresses from company addresses. - See which mail service a company uses.
mailProvidertells you whether a domain's mail goes to Google, Microsoft, Zoho, Proofpoint or another known service. - Clean the output of another Actor. Give the dataset of a contact scraper as input and get its addresses checked.
- Validate emails from your own code or an AI agent. Start the Actor through the Apify API and read the results as JSON.
Is a list cleaner enough, or do you need a mailbox verifier?
A list cleaner is enough when the question is "which of these addresses are certainly bad?". This Actor finds:
- addresses that are not correctly formed,
- domains that do not exist,
- domains that take no mail,
- throwaway addresses from disposable email services,
- mistyped domains of well-known mailbox providers.
These answers come from the address itself and from public DNS records, so they are dependable. For a list of your own subscribers or customers, collected through a sign-up form, this removes the failures you can know about in advance.
You need a mailbox verifier when the question is "does this exact inbox exist?". That is the case
for an old list where people have since left their companies, for a list of guessed addresses such
as first.last@company.com, or when your sending service demands a bounce rate close to zero. A
mailbox verifier asks the mail server of each domain about each address. This Actor does not, so an
address like nobody.by.this.name@gmail.com is valid here: it is correctly formed and
gmail.com receives mail. For the same reason there is no numeric score: without a mailbox check a
score would be an invented number.
How to validate email addresses in bulk
- Give the list in one of three ways, or in several at once:
- paste the addresses under Email addresses, one per line;
- upload a CSV or TXT file, or paste a link to one;
- pick an Apify Dataset that holds the addresses.
- Click Start. Results are saved while the run is going, so a run you stop keeps what it finished.
- Open the Output tab and export the table as JSON, CSV or Excel, or read it through the API.
- Remove the
invalidaddresses, decide what to do with theriskyones, and run theunknownones again later. Then look atdidYouMeanfor addresses you can correct.
Pricing
You pay per email that gets an answer, plus $0.00005 per run start. Addresses the check could not answer are returned free. Platform usage is included, so there is nothing else to pay.
| Apify plan | Price per 1,000 emails | Per email |
|---|---|---|
| Free and Bronze | $0.50 | $0.0005 |
| Silver | $0.45 | $0.00045 |
| Gold | $0.40 | $0.0004 |
- 10,000 addresses cost at most $5.00 on the Free and Bronze plans and $4.00 on Gold.
- 500 addresses cost at most $0.25.
Repeated addresses are removed before the check, so you pay for each address once. An address is
charged when the check answered it: valid, invalid or risky. An address it could not answer
(unknown: the DNS lookup failed on all three attempts, or the check itself stopped with an error)
is still in the results, so you can run it again later, and costs nothing.
You can set a maximum charge per run. The Actor then checks only as many addresses as that limit
covers, from the top of the list, and reports how many it left out. unknown addresses do not
count against the limit.
You pay only for results that are stored. A run that is aborted, fails or times out keeps the results it stored and charges those and nothing else. When Apify moves a run to another server, or you resurrect a run, it continues after the results that are already stored instead of starting over. Starting a new run with the same list checks and charges the whole list again.
Input
| Field | What it does |
|---|---|
Email addresses (emails) | The addresses to check, as a list. Up to 200,000 per run. |
CSV or TXT file (fileUrl) | A file with the addresses: upload it in the input form, or give a link that opens without a login. Up to 50 MB. |
Dataset (datasetId) | An Apify dataset that holds the addresses. The Actor only reads it. |
Column or field with the addresses (emailColumn) | The CSV column or dataset field to read. Only needed when it is not called email. |
At least one of the first three is needed. Addresses from all of them are checked together. Blank entries and repeats are removed; upper and lower case count as the same address, and the first spelling is kept. One run takes up to 200,000 different addresses; split a longer list into several runs.
CSV and TXT files. A TXT file has one address per line. In a CSV file the separator may be a
comma, a semicolon or a tab, and cells may be quoted. The Actor reads one column: the one named in
emailColumn; otherwise the one whose header is email (or contains "email" or "e-mail");
otherwise the first column that holds an address. A first line without an @ is taken as a header
and is not checked. Excel workbooks (.xlsx) are not read; save the sheet as CSV first.
Datasets. Addresses are read from the field email, or from the field named in emailColumn.
A field that holds a list of addresses gives one result per address. Rows without the field are
skipped.
Example with a pasted list:
{"emails": ["info@apify.com", "support@github.com", "user@gmial.com", "someone@mailinator.com", "not-an-email"]}
Example with a file whose addresses are in the column "Work email":
{"fileUrl": "https://example.com/leads.csv","emailColumn": "Work email"}
Output
One item per address, in the order of your list. Below are three results from a run of the sample input: a valid address, an invalid one and a risky one.
[{"email": "info@apify.com","normalized": "info@apify.com","status": "valid","reason": "mx_found","isValidSyntax": true,"domain": "apify.com","hasMx": true,"mxHost": "aspmx.l.google.com","mailProvider": "Google","isDisposable": false,"isRoleAddress": true,"isFreeProvider": false,"didYouMean": null,"checkedAt": "2026-10-04T14:43:25.249Z"},{"email": "not-an-email","normalized": null,"status": "invalid","reason": "invalid_syntax","isValidSyntax": false,"domain": null,"hasMx": null,"mxHost": null,"mailProvider": null,"isDisposable": null,"isRoleAddress": null,"isFreeProvider": null,"didYouMean": null,"checkedAt": "2026-10-04T14:43:25.234Z"},{"email": "someone@mailinator.com","normalized": "someone@mailinator.com","status": "risky","reason": "disposable","isValidSyntax": true,"domain": "mailinator.com","hasMx": true,"mxHost": "mail2.mailinator.com","mailProvider": null,"isDisposable": true,"isRoleAddress": false,"isFreeProvider": false,"didYouMean": null,"checkedAt": "2026-10-04T14:43:25.254Z"}]
In the same run, user@gmial.com comes back with "didYouMean": "user@gmail.com", and
support@github.com with "mailProvider": "Microsoft".
| Field | Meaning |
|---|---|
email | The address as you entered it, with surrounding spaces removed. An entry longer than 320 characters is cut there. |
normalized | The address with its domain in lower case. null when the syntax is invalid. |
status | valid, invalid, risky or unknown. |
reason | Short code for why the address got its status. |
isValidSyntax | Whether the address is correctly formed. |
domain | The domain of the address, in lower case. |
hasMx | true when the domain has an MX record, the DNS entry that names its mail server, and that server exists. false when it has none. |
mxHost | The server that takes mail for the domain. null when there is none. |
mailProvider | The mail service that server belongs to, such as Google or Microsoft. null when it is not one the Actor knows. |
isDisposable | The domain belongs to a disposable (temporary) email service. |
isRoleAddress | A shared address such as info@, support@ or sales@, not a person. |
isFreeProvider | The domain is a free mailbox provider such as gmail.com or yahoo.com. |
didYouMean | A corrected address when the domain looks like a typo of a well-known provider. |
checkedAt | When the address was checked, in UTC. |
A field is null when it could not be determined, for example every domain field of an address
with invalid syntax. The role, free-provider, mail-provider and typo fields are there for you to
filter on; they do not change the status.
Each run also stores a summary record, RUN_SUMMARY, in its key-value store: how many addresses
the list had, how many were checked and not checked, the count per status, and whether the run was
complete, ended by the charge limit, or aborted.
Mail providers
mailProvider is read from the MX host, never guessed from the domain name. The Actor names these
services: Google (Gmail and Google Workspace), Microsoft (Outlook.com and Microsoft 365), Yahoo
(with AOL), iCloud, Zoho, Proton, Fastmail, Amazon (WorkMail or SES), GMX, Tuta, Yandex, Mail.ru,
Tencent QQ, NetEase, Rackspace, GoDaddy, IONOS, Namecheap, OVHcloud, Titan and Migadu, and the mail
security gateways Proofpoint, Mimecast, Barracuda and Cloudflare. When a domain's mail passes
through a gateway, the gateway is what is named; the mailbox service behind it is not visible from
outside. Every other mail host gives null.
What each email validation status and reason means
| Status | Meaning | What to do |
|---|---|---|
valid | The address is correctly formed, its domain is set up to receive mail, and the domain is not a known disposable service. The mailbox itself is not checked. | Keep it. |
invalid | The address cannot receive mail: it is malformed, or its domain does not exist or takes no mail. | Remove it. |
risky | The domain belongs to a disposable email service. | Usually remove it. Your decision. |
unknown | The check gave no answer at the time of the run. | Run it again later. |
| Reason | Status | Meaning |
|---|---|---|
mx_found | valid | The domain is set up to receive mail. |
invalid_syntax | invalid | Not a correctly formed email address. |
domain_not_found | invalid | The domain does not exist. |
no_mail_server | invalid | The domain exists, but nothing takes mail for it: it declares that it takes none, it has neither a mail record nor an address, or its mail record points to a server that does not exist. |
disposable | risky | The domain belongs to a disposable email service, whose addresses are made to be thrown away. |
dns_error | unknown | The DNS lookup for the domain failed or timed out on each of three attempts, so nothing could be established. |
check_failed | unknown | The check stopped with an internal error. This should not happen; please report it. |
Limits
- The individual mailbox is not checked. A
validaddress can still bounce, because the mailbox was closed or the name before the@is misspelled. - A result describes the moment of the check. Domains expire and change.
- A domain without an MX record still counts as set up for mail when it has an address record,
because that is where mail for it is sent. Many such domains are only websites. They come back
validwithhasMx: false. For a stricter list, keep only addresses withhasMx: true. - The disposable-domain check uses a list of about 9,000 known domains that ships with the Actor. A service that appeared last week may be missing.
- Typo suggestions cover well-known mailbox providers only. A suggestion does not change the status,
so look at
didYouMeanas well asstatus. - International domain names are supported and are shown in their ASCII form (
xn--...) indomainandnormalized. The part before the@must be plain, unquoted ASCII; addresses with accented or non-Latin characters there are reported asinvalid_syntax. - One run takes up to 200,000 different addresses, and a file of up to 50 MB.
- A list of 10,000 addresses on 9,200 different domains took about one minute in a test. A list with many domains whose name servers no longer answer takes longer, about 10 seconds for each such domain, shared between 50 lookups at a time.
FAQ
Can it check if an email address exists?
Not the individual mailbox. It checks that the address is correctly formed and that its domain exists and is set up to receive mail. Whether a mailbox with that name exists on the domain is something only the mail server knows, and this Actor does not ask it. See "Is a list cleaner enough, or do you need a mailbox verifier?" above.
Does this email checker send any emails?
No. It sends nothing and does not connect to any mail server. It reads the address and looks up the domain, and the mail host the domain names, in DNS. Nobody on your list is contacted.
Can I upload a CSV file?
Yes. Upload it under CSV or TXT file, or paste a link to it. The addresses must be in one
column; the Actor finds the column named email, or you name the column in emailColumn. The
other columns are ignored and do not appear in the output, so match the results to your file on
the email field.
What happens to my email list?
It is processed inside your own run on the Apify platform, and the results go only to the dataset of
that run, in your account. When the list comes from a file or a dataset, the run also keeps a
working copy of it in its own key-value store, so that a restarted run checks the same list; it is
stored with the run and deleted with it. The Actor passes the list to no other service. The only
requests it makes to the outside are DNS lookups for each domain, which do not include the part
before the @, and the download of the file you linked. The developer of this Actor cannot see
your input or your results. The one exception is yours to control: the Apify account setting Share
run data with developers, which is off unless you turn it on.
How accurate is email validation?
What the Actor reports is dependable, because it comes from the address itself and from the public
DNS record of its domain: a malformed address is malformed, and a domain that takes no mail cannot
receive yours. What it cannot tell you is whether the mailbox exists, so valid is not a promise
that a message will arrive. The disposable flag depends on a list of known services and can miss a
new one.
Why is a mistyped address "valid"?
A mistyped domain can be a real domain that someone else owns. The address is then correctly formed
and its domain can receive mail, and the status reports that. The typo is reported separately: when the
domain is one or two characters away from a well-known mailbox provider, didYouMean holds the
corrected address.
Why is an address "unknown"?
The DNS lookup for its domain failed or timed out three times in a row, so the Actor could not tell
whether the domain receives mail. This is usually temporary. Run those addresses again later;
unknown addresses are not charged.
What happens when a run is stopped or restarted?
The results that are stored stay, and you pay for those only. If you resurrect the run, or Apify moves it to another server, it continues after the last stored result. The run's status message shows the progress while it runs, and the final message says how many addresses were checked and how many were left out.
Is a role address such as info@ invalid?
No, it can receive mail like any other address. isRoleAddress tells you that it is a shared
mailbox and not a person. Some senders leave shared mailboxes out of their lists, so the flag lets
you filter them. Whether to keep them is your decision.
Where do I report a problem?
Open an issue on the Issues tab of this Actor. Say which status and reason you got and what you expected, and name the domain of the address. Issues are answered there.
More Actors from this developer
Contacts and lists:
Jobs:
- Company Jobs Search
- ATS Job Postings: Workday, Greenhouse, Lever & Ashby
- Workday Jobs Scraper
- Greenhouse Jobs Scraper
- Lever Jobs Scraper
- Ashby Jobs Scraper
Company registers: