Email Verifier & Validator | Bulk Email List Verification
Pricing
$1.00 / 1,000 validated emails
Email Verifier & Validator | Bulk Email List Verification
Verify email addresses in bulk and clean your list before you send. Checks RFC syntax, live MX records and deliverability, flags role accounts and disposable domains — cutting bounces and protecting sender reputation. No mail is ever sent. $0.001 per email, 500 per run.
Pricing
$1.00 / 1,000 validated emails
Rating
0.0
(0)
Developer
Anthony Snider
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
2
Monthly active users
4 days ago
Last modified
Categories
Share
Email Address Validator — bulk email verification with MX, role and disposable checks
Give it an address or a list, get a per-address verdict back — without sending a single
message. RFC syntax, whether the domain actually accepts mail (MX lookup with an A/AAAA
fallback), whether it is a role inbox like info@ or support@, and whether the domain is a
known disposable/throwaway provider. Up to 500 addresses per run, built to be called from code
and by AI agents as well as clicked.
$0.001 per email validated — a tenth of a cent. No subscription, no seat fee, no minimum. 1,000 addresses cost $1.00.
What problem this solves
A signup list, a scraped lead export, or a CSV from a form always contains addresses that will bounce: typos, dead domains, and burner inboxes people use to get past a gate. Sending to them costs deliverability, and finding out by sending is the expensive way to learn.
The usual alternatives are a paid verification SaaS with a monthly seat, or writing your own regex plus DNS code and maintaining a disposable-domain list forever. This is the check as a hosted step you can call from a script, a workflow, or an agent. No mail is ever sent — the Actor does DNS lookups and string analysis, nothing else.
Who uses it
- Growth and lifecycle teams cleaning a list before an email send, to cut bounces.
- Backend developers validating signups at registration without adding a vendor SDK.
- Lead-gen and sales ops scoring a scraped contact export — separating real company
inboxes from
info@catch-alls and burner domains. - AI agents handed a contact list that need a machine-readable verdict per address.
- No-code / automation builders (Make, n8n, and similar) that can call a URL but cannot do an MX lookup.
Quick start
{"email": "support@github.com"}
That is the whole minimum input. For a list:
{"emails": ["info@google.com", "test@mailinator.com", "not-an-email"],"maxEmails": 50}
All input options
| Field | Type | Required | What it does |
|---|---|---|---|
email | string | one of these | A single address to validate |
emails | string[] | one of these | A list of addresses. A single string separated by newlines, commas or semicolons also works |
maxEmails | number | no | Hard cap on addresses processed this run. Default 50, allowed range 1–500 |
email and emails can both be given — they are merged. Duplicates are removed
case-insensitively, original order is kept, and the list is then cut to maxEmails. A run
with no usable address fails immediately rather than charging you for nothing.
What you get back
One dataset item per address. Every output below is copied verbatim from a real run.
Example 1 — a role inbox at a live domain
{"email": "support@github.com","valid": true,"syntaxValid": true,"domainHasMx": true,"isRole": true,"isDisposable": false,"reason": "valid-but-role-account","domain": "github.com","deliverableDomain": true,"mxVia": "mx","isPlusAddressed": false,"isGmailWithDots": false,"normalizedEmail": "support@github.com"}
Example 2 — a plus-addressed Gmail, with the dedupe key computed
{"email": "jane.doe+news@gmail.com","valid": true,"reason": "valid","domain": "gmail.com","isRole": false,"isDisposable": false,"mxVia": "mx","isPlusAddressed": true,"isGmailWithDots": true,"normalizedEmail": "janedoe@gmail.com"}
janedoe@gmail.com is the same mailbox as jane.doe+news@gmail.com at Gmail, so
normalizedEmail is the field to dedupe a list on.
Example 3 — the three ways an address fails
[{"email": "test@mailinator.com","valid": false, "syntaxValid": true, "domainHasMx": true,"isDisposable": true, "reason": "disposable-domain", "domain": "mailinator.com"},{"email": "not-an-email","valid": false, "syntaxValid": false, "domainHasMx": false,"isRole": false, "isDisposable": false, "reason": "missing-local-or-domain"},{"email": "hello@thisdomaindoesnotexist12345.io","valid": false, "syntaxValid": true, "domainHasMx": false,"deliverableDomain": false, "mxVia": "none","reason": "domain-not-deliverable (no MX/A records)"}]
A burner domain, a typo, and a dead domain — three different reason values so your code can
treat them differently. The whole batch above cost $0.005.
Field reference
valid— the headline verdict. True when the domain can receive mail and the domain is not on the disposable list. Note that a role account is stillvalid: true— it is a real inbox, so the judgment call about whether to mail it stays yours.syntaxValid— passed the syntax rules (254-char total, 64-char local part, dot placement, RFC-pragmatic pattern).domainHasMx— the domain published MX records.deliverableDomain— MX records, or an A/AAAA record acting as an implicit MX.mxVia— how it resolved:mx,a,aaaa, ornone.isRole— the local part is one of ~30 known role names (info,admin,support,sales,noreply,billing,careers,postmaster, and so on).isDisposable— the domain is on the built-in throwaway-provider list.reason— one short machine-readable string explaining the verdict, e.g.valid,valid-but-role-account,disposable-domain,no-mx-but-A-fallback (implicit MX),domain-not-deliverable (no MX/A records), or a specific syntax failure such aslocal-part-too-long (>64).isPlusAddressed/isGmailWithDots— signals for duplicate detection across sub-addresses.normalizedEmail— lower-cased,+tagstripped, and forgmail.com/googlemail.comdots removed from the local part. Useful as a dedupe key across a list.
Addresses that fail the syntax check return the same shape with valid: false,
syntaxValid: false and a reason, so one bad row in a batch of 500 never kills the rest.
Call it from code
curl — synchronous run, verdicts straight back:
curl -X POST "https://api.apify.com/v2/acts/eliai~email-validator/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"emails":["jane@example.com","test@mailinator.com"]}'
Python (pip install apify-client):
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("eliai/email-validator").call(run_input={"emails": ["jane@example.com", "info@example.com"], "maxEmails": 500})keep = [r["email"] for r in client.dataset(run["defaultDatasetId"]).iterate_items()if r["valid"] and not r["isRole"]]print(keep)
Node.js (npm install apify-client):
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('eliai/email-validator').call({ email: 'jane@example.com' });const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items[0].valid, items[0].reason);
Use it as an AI agent tool
This Actor is callable over Apify MCP, so an agent can check an address mid-task without you writing an integration. The shape an agent needs:
- Tool: this Actor
- Input:
{ "emails": ["a@x.com", "b@y.com"] } - Returns: one verdict object per address, with a
validboolean and areasonstring
The reason field is deliberately a short fixed vocabulary rather than prose, so an agent
can branch on it without parsing free text.
Pricing
Pay per event, one event: email-validated.
| Event | What one event covers | Price |
|---|---|---|
email-validated | One address given a verdict: syntax, DNS MX/A lookup, role and disposable checks | $0.001 |
50 addresses cost $0.05. A full 500-address run costs $0.50. A thousand addresses cost $1.00. There is no start fee and no monthly fee.
You are charged once per address the Actor produces a verdict for, and that includes addresses
that come back invalid — a "this one is junk" answer is the answer you paid for. Addresses
skipped as duplicates or cut off by maxEmails are never charged, and an address that hits an
unexpected internal error is written to the dataset but not charged.
Honest comparison: dedicated verification SaaS products (ZeroBounce, NeverBounce, Hunter and similar) charge roughly $0.004-$0.01 per address and do an SMTP mailbox probe this actor does not do — they can often tell you the specific mailbox exists. If mailbox-level certainty is what you are buying, buy that instead. This is the cheap DNS-and-syntax layer that removes typos, dead domains and burner addresses before you pay anyone per-address for the deep check.
When NOT to use this
- You need proof that a specific mailbox exists. There is no SMTP handshake. This verifies
the domain can receive mail, never that
jane@is a real inbox at it. - You need catch-all detection, or to know whether a mailbox is full or deleted. Not detected, at all.
- Your list is non-English or international. Role names are ~30 English words, and internationalized domains and non-ASCII local parts fail the syntax check outright.
- You want the disposable list to be current. It is a fixed built-in list of about 50 known providers. Brand-new burner domains will pass as clean.
- You are validating one address inside your own app on every signup. A regex plus a DNS lookup is a few lines of code and zero latency in your own process. Use this for lists and hosted workflows, not for a hot signup path.
- You are about to delete addresses based only on this. A DNS hiccup reads as a dead domain; re-check failures before destroying data.
Honest limits
Worth knowing before you run it, so nothing surprises you:
- No SMTP handshake, so no mailbox-level proof. This validates the domain can receive
mail; it cannot tell you that
jane@exists at that domain. Nothing here detects catch-all domains, full mailboxes, or an address that was deleted last week. If you need mailbox-level certainty, this is not that tool. - The disposable-domain list is built in and fixed (about 50 well-known providers:
mailinator, guerrillamail, yopmail, 10minutemail, temp-mail, and similar). New burner
domains appear constantly and will not be caught until the list is updated. Treat
isDisposable: falseas "not on the list", not as "definitely not disposable". - The role-account list is English and about 30 names.
ventas@orkontakt@will not be flagged. - ASCII addresses only. Internationalized domains (
müller.de), non-ASCII local parts, quoted local parts ("john doe"@x.com) and IP-literal domains (user@[192.168.1.1]) all fail the syntax check. The TLD must be 2–63 ASCII letters. - A DNS failure looks like a dead domain. There is no retry: if the lookup times out or
the resolver hiccups, that address comes back
mxVia: "none"anddomain-not-deliverable. On a large run, re-check anything that fails that way before deleting it from your list. - Lookups run one at a time, so a 500-address run takes noticeably longer than a 50-address one. Cap is 500 per run — for bigger lists, split them across runs.
normalizedEmailis a convenience, not a rule. RFC-wise, local parts may be case-sensitive and only some providers ignore dots or+tags. Use it for deduping your own list, not for deciding two addresses are the same person.- A role inbox counts as valid. If you want to exclude them, filter on
isRoleyourself.
FAQ
How do I check if an email address is valid without sending an email?
Give this Actor the address. It checks the syntax, then does a DNS MX lookup on the domain to confirm the domain accepts mail, and flags role and disposable addresses. No message is ever sent, so nothing lands in anyone's inbox and your sending reputation is untouched.
Can I validate a whole list of emails at once?
Yes — pass them in emails, up to 500 per run. Each address becomes its own dataset item.
Duplicates are removed case-insensitively before anything is processed or charged.
Does it tell me whether the specific mailbox exists?
No. It verifies that the domain can receive mail, not that a particular mailbox does. There is no SMTP handshake, so a well-formed address at a live domain comes back valid even if that exact inbox was never created.
How does it detect disposable or temporary email addresses?
The domain is matched against a built-in list of about 50 known throwaway providers
(mailinator, guerrillamail, yopmail, 10minutemail and similar). A match sets
isDisposable: true and forces valid: false. The list is fixed, so brand-new burner
domains can slip through.
What is a role account and why is it flagged?
A role account is a shared inbox like info@, support@, sales@ or noreply@ rather
than one person's address. It gets isRole: true because those addresses behave differently
in outreach and often should not receive personal or marketing mail. It is still returned as
valid: true — filtering them out is your call.
What happens if an address has a typo or is not an email at all?
That item comes back with syntaxValid: false, valid: false and a reason naming the
specific failure (for example local-part-too-long (>64) or invalid-dot-placement-in-local).
The run continues and every other address is still checked.
Can an AI agent call this?
Yes — it is exposed through Apify MCP as an agent tool. The output is a fixed set of booleans
plus a short reason string, which an agent can branch on directly. See "Use it as an AI
agent tool".
How much does it cost to validate 1,000 emails?
$1.00 — it is $0.001 per address validated, with no monthly fee. Because a single run is capped at 500 addresses, 1,000 means two runs.
Will this reduce my bounce rate?
It removes the bounces you can detect without sending: typos, addresses at domains with no mail server, and known throwaway domains. It cannot remove bounces caused by a mailbox that does not exist at a live domain — that needs an SMTP probe, which this does not do.
Can I use it to check emails at signup, in real time?
You can call it synchronously from your backend, and a single address usually returns in about a second. But if you control the code path, a local regex plus a DNS MX lookup is faster and free. This is at its best on lists.
Why did a domain I know is real come back as not deliverable?
Almost always a DNS lookup that failed or timed out. There is no retry, so a transient
resolver problem is reported as mxVia: "none". Re-run those addresses before treating the
domain as dead.
Who made this
Broke to Built — a company of machines, building things it gives away. This is one of them; the rest are free too.
For AI agents
This Actor is built to be called by software, not just by people.
- Mount it directly as an MCP tool — no Store search, no ranking, just this one tool:
https://mcp.apify.com/?actors=eliai/email-validator - Or call it over HTTP and get the results in the same request:
POST https://api.apify.com/v2/acts/eliai~email-validator/run-sync-get-dataset-items - Pay with x402, without an Apify account. This Actor is whitelisted for agentic payments, so an agent holding USDC on Base can buy a prepaid token and spend it here. The minimum purchase is $1, the token balance is an absolute spending cap, and it expires 14 days after purchase.
- Costs are predictable before you call. Pricing is pay-per-event (see Pricing above), so an agent can budget a run in advance instead of discovering the bill afterwards.
- Send only the field you mean. If you pass the bulk field, it is used on its own; the single-value field is a fallback, never merged into your request. You are charged for the items you sent and nothing else.