Email Verifier - Bulk List Cleaning, MX & Disposable Checks
Pricing
from $0.48 / 1,000 emails
Email Verifier - Bulk List Cleaning, MX & Disposable Checks
Clean a bulk email list before you send: paste it, or read a dataset from another run or a CSV, Excel or Google Sheets file. Each address is checked for syntax and a working MX record, and flagged if disposable, a role inbox like info@ or a free provider. It never sends mail. $0.49 per 1,000.
Pricing
from $0.48 / 1,000 emails
Rating
5.0
(2)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
168
Total users
1
Monthly active users
21 hours ago
Last modified
Categories
Share
Verify a bulk email list before you send: syntax, MX records, disposable and role checks: paste
a list of addresses, pick a dataset from an earlier run, or hand it a CSV, Excel or Google Sheets
file, and each address comes back as a row with a status, a 0 to 100 score, and the reason behind
it. Whether the domain can actually receive mail, whether it is a throwaway, whether
the address is a shared inbox like info@, and whether the domain is a free consumer provider.
Here is the part that decides whether this is the right tool. It never sends mail, and from
Apify's cloud it cannot ask the mail server about a mailbox either, so it cannot prove a mailbox
exists. valid here means the syntax passed
and the domain accepts mail, which is the check you run before a send so bounces do not wreck your
sender reputation. It is not a deliverability guarantee.
| Input | A list of email addresses, a dataset from another run, or a CSV, Excel or Google Sheets file |
| Output | One row per address: status, score, reason, MX records, and disposable, role and free-provider flags |
| Ceiling | No fixed size for a pasted list; a dataset or a file adds up to 100,000 addresses. The run's own time limit, 5 minutes by default, is the real one |
| Account needed | None, no API key and no mailbox |
| Price | $0.49 per 1,000 addresses checked on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 10,200 |
🔍 What Email Verifier does
Each address goes through the same passes. The syntax is checked. The domain is looked up in public DNS for MX records. The domain is matched against a built-in list of disposable providers, the local part against a list of role names, and the domain against the free consumer providers.
A domain that can receive mail says so in public DNS with an MX record, and a domain that has sworn off mail says that too, with a null MX. Both answers are useful, and both are in the row.
Duplicate addresses are lowercased and collapsed before anything is checked, so the same address in your list twice is one row and one charge.
There is also a bounded SMTP probe you can switch on. Read the limits before you rely on it.
📋 What data you get from each email address
| What you get | Field |
|---|---|
| The verdict and a 0 to 100 score behind it | status, confidence |
| The reason for the verdict, in one word | reason |
| Whether the address is written correctly | syntaxValid |
| Whether the domain has mail servers, and the list of them | mxFound, mxRecords |
| Throwaway domain, shared inbox, free consumer provider | isDisposable, isRoleAccount, isFreeProvider |
| Whether a mail server confirmed this exact recipient | mailboxVerified |
| The SMTP probe's answer, when you switch it on | smtp, smtpNote |
| The address as checked, lowercased, and its domain | email, domain |
▶️ How to verify an email list before you send
- Open Email Verifier and click Try for free.
- Paste your addresses into Email addresses, one per line. Or pick a dataset under Addresses from a dataset, or upload a file under Addresses from a CSV or Excel file.
- Leave Attempt bounded SMTP probe off for a first run.
- Click Start.
- Download the dataset as JSON, CSV or Excel, or read it from the Apify API.
Start it with the list empty and you get one free sample row showing the output shape.
💰 How much does it cost to verify email addresses?
$0.49 per 1,000 addresses checked on the Free plan. Paid plans pay a little less: $0.485 on Starter, $0.48 on Scale and $0.475 on Business. On the free plan, the $5 Apify gives you each month covers about 10,200 addresses.
One charge per completed check. The sample row, per-address failure rows and diagnostic rows are not
billed, and a duplicate address collapsed into one row is billed once. An address that fails on
syntax still gets its row, free. One case is billed although it tells you little: an unknown row
where DNS gave no answer.
📥 What you give it
{"emails": ["person@example.com", "info@example.com", "bad@@example.com"],"checkSmtp": false,"smtpTimeoutMs": 5000,"maxConcurrency": 10}
| Field | Default | What it is |
|---|---|---|
emails | none | The list. The form starts with two example addresses in it. Duplicates are collapsed. Leave it empty and you get one free sample row showing the output shape. |
checkSmtp | false | Try a short SMTP probe against the domain's first mail host. It never sends a message body. See the limits for what it can and cannot tell you. |
smtpTimeoutMs | 5000 | Deadline per connection, capped at 8000, so one dead mail host cannot hold up a run. |
maxConcurrency | 10 | How many addresses are checked at once, 1 to 25. Lower it if you want gentler DNS traffic. |
inputDatasetId | none | A dataset from an earlier run. It is read a page at a time and its addresses join the list. |
fileUrl | none | A CSV or .xlsx file, uploaded or linked, or a Google Sheets link shared as "Anyone with the link can view". First sheet only, 5 MB at most. |
emailField | none | The dataset field (email, or contact.email for a nested one) or the file's column heading. Empty means the fields or columns with "mail" in their name; a file without one is searched cell by cell. |
maxItems | none | Stop after this many different addresses, across all three sources. Empty means the whole pasted list, plus up to 100,000 from a dataset or a file. |
Checking another run's results looks like this:
{"inputDatasetId": "your-dataset-id","emailField": "email","maxItems": 5000}
📤 What you get back
A real row from a recent run. example.com publishes a null MX, which is a domain stating in public
that it accepts no mail, so the address is invalid with high confidence:
{"ok": true,"email": "person@example.com","status": "invalid","confidence": 98,"mailboxVerified": false,"syntaxValid": true,"domain": "example.com","mxFound": false,"mxRecords": [],"isDisposable": false,"isRoleAccount": false,"isFreeProvider": false,"smtp": null,"smtpNote": null,"reason": "no_mx_record"}
| Field | How to read it |
|---|---|
status | valid, risky, invalid or unknown. |
mailboxVerified | true only when a mail server accepted this exact recipient, false when one permanently refused it or the domain cannot receive mail at all, null when nobody could ask. |
reason | mx_valid, no_mx_record, invalid_syntax, disposable_domain, role_account, smtp_recipient_accepted, smtp_recipient_rejected, dns_inconclusive or sample_only. |
mxRecords | The mail servers as {priority, exchange}, sorted by priority. mxFound is null when DNS itself gave no answer. |
smtp | null unless you switch the probe on. Otherwise its status, code, stage and reason. |
🧾 Reading the output
| Row | How to spot it | Charged |
|---|---|---|
| A completed check | ok: true and a status | yes |
| An address with broken syntax | status: "invalid" and reason: "invalid_syntax" | no |
| The sample row | _sample: true and reason: "sample_only" | no |
| A per-address failure | ok: false with an error | no |
| A diagnostic | errorCode of NO_RESULTS or INTERNAL_ERROR | no |
| A source that could not be read | errorCode of BAD_INPUT, SOURCE_ERROR or NO_ADDRESSES, with source set to dataset or file and the reason in error. If nothing else was given, the run ends as failed | no |
| A time-limit notice | errorCode of TIME_LIMIT: the run got close to its time limit and stopped on its own. The emails checked before that are delivered and charged, the rest have no row and no charge. Give the run more time, or send fewer emails. The run ends as failed only when this stopped it before any email was checked | no |
What each status means:
| Status | Meaning |
|---|---|
valid | Syntax passed and the domain accepts mail. Keep it in the list. |
risky | The domain is fine but something about the address is not. A shared inbox or a disposable provider. |
invalid | Bad syntax, or the domain publishes no MX and says it takes no mail. |
unknown | The check ran but DNS gave no usable answer, so reason is dns_inconclusive. This is a completed check and it is billed like any other. |
The Console's overview table leaves out reason, mailboxVerified and isFreeProvider, which
is exactly what you need to tell one unknown from another. Read the JSON for those.
💡 What people use it for
- Cleaning a list before a send, so hard bounces do not damage the sending domain.
- Splitting a signup list into personal and shared inboxes, using
isRoleAccount. - Dropping throwaway signups, using
isDisposable.
From a list of company websites to a checked contact sheet, in three runs:
- Run Contact Details Scraper on the websites.
- Paste the addresses from its
emailslists into Email addresses here and keep thevalidrows. - Paste the
e164numbers from itsphoneslists into Phone numbers on Phone Number Validator.
🚧 What it does not do
- It never sends mail, and without a mail server to ask it cannot confirm a mailbox exists or predict a bounce.
- The SMTP probe does not connect from here. Apify's runners block outbound port 25, measured
across eight mail hosts, so in the cloud
mailboxVerifiedcomes backnullon every row. Run the actor on your own machine and the probe behaves normally. Big providers refuse to confirm or deny a recipient anyway. - Catch-all domains look the same as working mailboxes. Telling them apart means asking the mail server, which the cloud probe cannot reach.
- The disposable list is built in and holds 16 domains. It catches the common services, not every throwaway on the internet.
- A run stops at its time limit, 5 minutes by default. Addresses checked by then are delivered and charged; the rest get no row and no charge. For a long list, raise the limit, or set Maximum addresses and run the rest later.
- Old .xls files, password-protected sheets and other sheets than the first are not read.
- 25 concurrent checks is the ceiling.
- It is a list-cleaning signal, not consent. Only run addresses you are allowed to process.
- It is not an official tool of any platform or company named on this page. Dami's Studio is independent and is not affiliated with or endorsed by any of them.
🧭 Which lead tool do you need?
| If you want | Use |
|---|---|
| To clean a list of addresses you already have | This one |
| Emails, phones and socials pulled off a list of websites | Contact Details Scraper |
| The same kind of check for phone numbers | Phone Number Validator |
| Businesses with phone, website and address | Google Maps Scraper |
❓ Questions people ask
Does it prove the person's inbox exists?
No. From Apify's cloud it cannot reach the mail server to ask, so valid means the domain accepts
mail and the address is worth keeping.
Why is mailboxVerified always null?
Outbound port 25 is blocked on Apify's runners, so the probe never connects in the cloud.
Why is a good address marked risky?
Usually because it is a role account. info@ and sales@ are real addresses, but a team shares them
and mail sent there often goes unread.
Am I billed for an address with a typo in it?
No. A malformed address still gets its row, marked invalid_syntax, and is not charged. Duplicates
are collapsed before anything is checked and billed once.
Can I call it from code or connect it to an AI assistant?
Yes. The API tab has ready-made code
for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP client, connect
https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/email-verification. Either way the
run happens on your Apify account at the same price.
Is verifying email addresses legal?
Verifying addresses you hold is ordinary list hygiene, but an email address is personal data and data-protection law covers it, so have a reason for holding the list. Apify's write-up on scraping and the law is a good start, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the run ID and one address that behaved oddly. The
reason field usually explains the verdict on its own.