Email Verifier: Syntax, MX & Disposable-Domain Score
Pricing
Pay per usage
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
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:
- Syntax — does the address have a valid shape (RFC 5322 practical subset)?
- 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)?
- Disposable domain — is the domain a known throwaway/temporary-email provider, checked against a bundled list of 75,000+ domains?
- 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.
| Field | Type | Default | Description |
|---|---|---|---|
emails | array of strings | none | Email addresses to check. Supply this or the alias below. |
emailAddresses | array | none | Alias of emails. |
timeoutSeconds | integer | 15 | Per-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
-
processItemimplements syntax, MX, disposable-domain and role-account checks;Resultintypes.gomatches. -
.actor/dataset_schema.jsondocuments the real output fields, read directly fromResult. - This README's Input/Output sections match the real code.
- Charge guard holds:
pricing.Chargeis 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.pyrun 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.