Email Validator API: Syntax, MX and Disposable Check avatar

Email Validator API: Syntax, MX and Disposable Check

Pricing

$0.80 / 1,000 email checkeds

Go to Apify Store
Email Validator API: Syntax, MX and Disposable Check

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

The Sjöstrand Project

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

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 codes
  • domain_found, accepts_mail, mx_hosts: what DNS says about the domain's mail
  • is_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

  1. 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.
  2. 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.
  3. Open the Output tab, look at the verdicts and reasons, then paste in your own addresses, one per line.

Input

FieldWhat it doesDefault
Email addressesThe 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.

CodeMeaningVerdict
syntax_invalidThe line is not one address.invalid
domain_not_foundThe domain does not exist in DNS.invalid
null_mxThe domain says it takes no mail (a null MX record).invalid
no_mail_hostThe domain exists but has no MX, A or AAAA record.invalid
dns_errorThe DNS lookup failed, so nothing can be said. The row is not charged.unknown
implicit_mxNo MX record, but an A or AAAA record that mail may fall back to.risky
disposable_domainThe domain is on the disposable-address list.risky
role_addressThe part before the @ is a role name such as info or support.no change
reserved_domainA 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_version on 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.