Email Verifier: Syntax, MX & Disposable-Domain Score avatar

Email Verifier: Syntax, MX & Disposable-Domain Score

Pricing

Pay per usage

Go to Apify Store
Email Verifier: Syntax, MX & Disposable-Domain Score

Email Verifier: Syntax, MX & Disposable-Domain Score

Validates email addresses without ever sending mail: syntax, live MX record, disposable-domain and role-account checks, rolled into a transparent 0-100 confidence score with a per-check breakdown. Never claims a mailbox was confirmed to exist.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Catalyst

Catalyst

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Email Verifier: Syntax, MX and Disposable-Domain Confidence Score

Validates email addresses without ever sending mail: syntax, live MX record, disposable-domain and role-account checks, rolled into a transparent 0-100 confidence score with a per-check breakdown.

What this checks, and what it does not

This is a validate-without-sending tool. It never opens a connection to any mail server and never attempts to deliver anything. Concretely, it runs four checks per address:

  1. Syntax — does the address have a valid shape (RFC 5322 practical subset)?
  2. MX record — does the domain currently have a live, working mail server, confirmed by a real DNS lookup at run time (not a cached or guessed answer)?
  3. Disposable domain — is the domain a known throwaway/temporary-email provider, checked against a bundled list of 75,000+ domains?
  4. Role account — does the local part (before the @) look like a team inbox (info@, support@, noreply@, etc.) rather than one person's mailbox?

What it cannot and does not claim: whether that specific mailbox actually exists. Confirming a mailbox requires an SMTP handshake with the destination mail server (an RCPT TO probe), which this Actor deliberately does not do. No field in this Actor's output should ever be read as "we confirmed this inbox is real." mxFound: true means the domain is set up to receive mail in general, nothing more specific than that.

Why not go further and check the mailbox too

Most competing "email verifier" Actors advertise SMTP/mailbox verification. We tested it directly: outbound port 25 (the port SMTP mail delivery uses) is blocked at the platform level, against four independent mail providers (Gmail, Outlook, Yahoo, Fastmail). Every connection attempt times out identically, with no response from the destination at all. Rather than claim something that can't actually be verified this way, this Actor is honest about the boundary: syntax, MX, disposable-domain and role-account are the four things that are genuinely checkable, and that is exactly what it reports, nothing more.

Input

Give it one or more email addresses via emails (a JSON array, a single string, or a comma/newline separated list). emailAddresses works the same way, as an alias.

FieldTypeDefaultDescription
emailsarray of stringsnoneEmail addresses to check. Supply this or the alias below.
emailAddressesarraynoneAlias of emails.
timeoutSecondsinteger15Per-address DNS lookup timeout, clamped to 3-60.

Output

One dataset item per input email address:

{
"email": "person@example.com",
"syntaxValid": true,
"mxFound": true,
"mxHosts": ["aspmx.l.google.com", "alt1.aspmx.l.google.com"],
"isDisposableDomain": false,
"isRoleAccount": false,
"confidenceScore": 100,
"checksRun": ["syntax", "mx", "disposable", "role"],
"charged": false
}

Real, unmodified output from a local run against a small mixed batch:

{"email":"not-an-email","syntaxValid":false,"mxFound":false,"mxHosts":[],"isDisposableDomain":false,"isRoleAccount":false,"confidenceScore":0,"checksRun":["syntax"],"charged":false}
{"email":"info@microsoft.com","syntaxValid":true,"mxFound":true,"mxHosts":["microsoft-com.mail.protection.outlook.com"],"isDisposableDomain":false,"isRoleAccount":true,"confidenceScore":90,"checksRun":["syntax","mx","disposable","role"],"charged":false}
{"email":"someone@mailinator.com","syntaxValid":true,"mxFound":true,"mxHosts":["mail2.mailinator.com","mail.mailinator.com"],"isDisposableDomain":true,"isRoleAccount":false,"confidenceScore":80,"checksRun":["syntax","mx","disposable","role"],"charged":false}
{"email":"user@example.com","syntaxValid":true,"mxFound":false,"mxHosts":[],"isDisposableDomain":false,"isRoleAccount":false,"confidenceScore":60,"checksRun":["syntax","mx","disposable","role"],"charged":false}

The last row, user@example.com, resolves against a domain with a DNS "null MX" record, the domain's own explicit declaration that it accepts no mail at all. That is a confirmed, real answer (mxFound: false), not a lookup failure.

error is set only when the DNS lookup itself fails for reasons unrelated to the domain (a transient resolver problem). It stays empty on a syntax-invalid row: that is a complete answer, not a failure.

Scoring

confidenceScore is additive out of 100: syntax (30) + live MX (40) + not disposable (20) + not a role account (10). Invalid syntax scores 0 outright. This is deliberately a graded score with a visible checksRun breakdown, not a flat pass/fail boolean: a syntax-only row and a row that passed all four checks both show exactly what was and wasn't checked.

Pricing

Free. This Actor has no price set, so a run costs you only your own Apify platform usage.

The code supports pay-per-event billing on a single email-verify event, priced per processed address, if a price is ever set on the Apify Console. A row is only ever charged when it carries a complete answer: a confirmed syntax-invalid address counts (you were told exactly why it's invalid), a genuine DNS lookup failure does not. Nothing is hardcoded: the Actor reads its own current price from the platform at startup and runs unmetered when there isn't one.

Third-party data bundled in this Actor

The disposable-domain list is disposable/disposable-email-domains (github.com/disposable/disposable-email-domains), MIT licensed, pinned to commit 7011bb4c072d96fbaed9ef96657ec6f873185d9c (2026-09-26), 75,390 domains. Vendored into this Actor's image at build time (data/disposable_domains.txt), never fetched at runtime.

Before publishing this Actor

  • processItem implements syntax, MX, disposable-domain and role-account checks; Result in types.go matches.
  • .actor/dataset_schema.json documents the real output fields, read directly from Result.
  • This README's Input/Output sections match the real code.
  • Charge guard holds: pricing.Charge is only called on a branch with a complete, returnable answer (a confirmed valid/invalid syntax result, or a completed MX lookup), never on a genuine lookup failure.
  • verify_gate.py run against a real Apify platform dataset, PASS.
  • No scraping, no login, no target site at all: nothing to violate any site's terms.
  • Measured memory, seconds, compute units and cost per run on a real platform run.