Email Validator API: Syntax, MX and Disposable Check
Pricing
$0.80 / 1,000 email checkeds
Email Validator API: Syntax, MX and Disposable Check
Validate email addresses by syntax, MX record and disposable-domain list and return one row per address with a valid, risky, invalid or unknown verdict. Input: up to 5,000 addresses. Row: verdict, reason codes, MX hosts, disposable, role and typo hint. No SMTP check.
Pricing
$0.80 / 1,000 email checkeds
Rating
0.0
(0)
Developer
The Sjöstrand Project
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
What this Actor returns
Validate email addresses by syntax, MX record and disposable-domain list and return one row per address with a valid, risky, invalid or unknown verdict. You give it a list of up to 5,000 addresses; each row holds the verdict, the reason codes behind it, whether the domain exists and accepts mail, its mail servers, and whether the address is disposable, a role address or one typo away from a large mail provider.
email,verdict,reasons: the address as you gave it, the verdict and its stable reason codesdomain_found,accepts_mail,mx_hosts: what DNS says about the domain's mailis_disposable,is_role,suggested_domain: the disposable flag, the role flag and a typo hint ("possible typo; this domain does not receive mail")list_version,checked_at: the disposable list's date and commit, and when the row was made
No SMTP check: this Actor never connects to a mail server, so "valid" means the domain accepts mail, not that the mailbox exists.
Who it helps
- Anyone cleaning a sign-up or contact list who wants to drop addresses whose domain cannot take mail, flag disposable ones and catch typos such as a misspelt provider, before sending anything.
- Developers and AI agents who need a quick, predictable check inside a form or a pipeline, through the Apify API, with the same fields and codes on every row.
Quick start
- Open the Input tab and leave the default list as it is. It holds four example lines on reserved names, so a first run sends no DNS query at all and returns four rows.
- Press Start. The default run costs about $0.0025: three checked addresses at $0.0008 (the line that is not an address is free), plus Apify's tiny start event.
- Open the Output tab, look at the verdicts and reasons, then paste in your own addresses, one per line.
Input
| Field | What it does | Default |
|---|---|---|
| Email addresses | The addresses to check, one per line, up to 5,000 per run. A line that is not one address gets an invalid row and is not charged; neither is a row whose DNS lookup failed (unknown). Repeated addresses are checked once. | four example lines on reserved names |
Output
One row per unique address, in the order you gave them. The rows below are what the default input returned on 13 October 2026, unchanged.
[{"email": "jane.doe@example.com","verdict": "invalid","reasons": ["null_mx", "reserved_domain"],"domain_found": true,"accepts_mail": false,"mx_hosts": [],"is_disposable": false,"is_role": false,"suggested_domain": null,"list_version": "2026-10-13 d1a9c51","checked_at": "2026-10-13T10:13:35Z"},{"email": "info@example.org","verdict": "invalid","reasons": ["null_mx", "role_address", "reserved_domain"],"domain_found": true,"accepts_mail": false,"mx_hosts": [],"is_disposable": false,"is_role": true,"suggested_domain": null,"list_version": "2026-10-13 d1a9c51","checked_at": "2026-10-13T10:13:35Z"},{"email": "not-an-address","verdict": "invalid","reasons": ["syntax_invalid"],"domain_found": null,"accepts_mail": null,"mx_hosts": [],"is_disposable": false,"is_role": false,"suggested_domain": null,"list_version": "2026-10-13 d1a9c51","checked_at": "2026-10-13T10:13:35Z"},{"email": "someone@nothing.invalid","verdict": "invalid","reasons": ["domain_not_found", "reserved_domain"],"domain_found": false,"accepts_mail": false,"mx_hosts": [],"is_disposable": false,"is_role": false,"suggested_domain": null,"list_version": "2026-10-13 d1a9c51","checked_at": "2026-10-13T10:13:35Z"}]
Verdicts and reason codes
The verdict is the most serious reason on the row: invalid, then unknown, then risky; a row with none of those is valid.
| Code | Meaning | Verdict |
|---|---|---|
syntax_invalid | The line is not one address. | invalid |
domain_not_found | The domain does not exist in DNS. | invalid |
null_mx | The domain says it takes no mail (a null MX record). | invalid |
no_mail_host | The domain exists but has no MX, A or AAAA record. | invalid |
dns_error | The DNS lookup failed, so nothing can be said. The row is not charged. | unknown |
implicit_mx | No MX record, but an A or AAAA record that mail may fall back to. | risky |
disposable_domain | The domain is on the disposable-address list. | risky |
role_address | The part before the @ is a role name such as info or support. | no change |
reserved_domain | A reserved example name, answered without any DNS query. | no change |
What it costs
You pay for one event, Email checked, at $0.0008 per unique address checked. A line that is not an address, or whose DNS lookup failed (an unknown row), still gets its row and is never charged. Repeated addresses are checked and charged once. Apify also adds its standard run-start event; it is the platform's own event, not ours.
For example, a list of 1,000 unique addresses costs $0.80. If your Apify plan includes monthly credit, a small run draws on that credit.
If the run stops early (see below), the rows already returned stand and nothing more is charged.
Limits and honest notes
- No mailbox check. Without SMTP the Actor cannot tell whether a mailbox exists or is full; it tells you whether the domain can take mail at all. Tools that probe mail servers give finer answers and touch the recipient's server; this one never does.
- Up to 5,000 addresses per run, each at most 254 characters. A longer list, or a line that is not text, stops the run before anything is checked and nothing is charged. For more, split the list.
- One lookup per domain. Addresses are grouped by domain, so a list from one company asks DNS once. Lookups go out at most 20 a second, four at a time.
- The resolver's limits are not published. If it keeps answering that it is busy, the run stops with a clear message; the rows already returned stand and the rest are not charged.
- Strict syntax. Quoted local parts and non-ASCII characters before the @ are counted as not an address. An address whose domain ends in a dot (a dot after the last label) is counted as not an address (it is not normalised). International domain names after the @ are fine.
- Typo hints cover about twenty of the largest mail providers, one typing slip away, and appear only when the typed domain does not receive mail (no MX and no A or AAAA record): possible typo; this domain does not receive mail. A domain that resolves is never hinted, so a short real domain is not taken for a provider's.
- Disposable domains come from a bundled copy of the list, refreshed in a new build;
list_versionon each row shows which copy was used.
Privacy
Privacy: we don't keep your inputs. Addresses are used only to produce this run's results, which stay in your Apify storage, and are never written to the run log or status messages.
Only the domain part of each address is sent to Cloudflare's public DNS resolver; the part before the @ never leaves the run.
We open a run's input, log or results only if you share the run with us, for example by attaching it to an issue. Apify's privacy policy applies to the platform itself.
Validate only addresses you have a lawful basis to process. This Actor does not find, extract or guess addresses.
Questions
Why is an address "valid" when mail to it bounces? "Valid" means the domain publishes a mail server. The mailbox itself may not exist; only a mail server could say, and this Actor never asks one.
What does each status message mean?
"Invalid input: the list of addresses is missing or is not a list" means the emails field must be a list of text lines. "every entry in the list must be text" means a line is something else, such as a number; "an entry is longer than one address can be" means a line is over 254 characters; "the list holds more entries than one run accepts" means more than 5,000 lines. Nothing was charged in any of these. "the DNS resolver's request limit was reached" means the resolver kept saying it was busy; wait a few minutes and run the remaining addresses again.
Why is a row "unknown"?
The DNS lookup for its domain failed, for example because the domain's own name servers did not answer. Try that address again later: an unknown row is not charged, so checking it again costs nothing extra.
Why is a role address not marked risky?
Role addresses such as info or support are often real, shared inboxes. The row flags them with is_role and the role_address code so you can decide.
Can I run it on a schedule or from an AI agent? Yes, with the Apify scheduler, the API or an agent integration. Each run is independent and charged per unique address checked.
Data source and AI note
Disposable domains come from the disposable-email-domains list (CC0 1.0).
DNS answers come from Cloudflare's public DNS resolver, asked only about the domain part of each address.
This tool was built with the help of AI coding assistants.
Help
Questions, a verdict that looks wrong, or an idea: please open an issue on the Issues tab. Thank you for the report; every one is read.