Bulk Email Verifier & MX Record Checker (DNS, $0.70/1K) avatar

Bulk Email Verifier & MX Record Checker (DNS, $0.70/1K)

Pricing

$0.70 / 1,000 email verifieds

Go to Apify Store
Bulk Email Verifier & MX Record Checker (DNS, $0.70/1K)

Bulk Email Verifier & MX Record Checker (DNS, $0.70/1K)

Email validator and bulk verifier: syntax, MX record lookup, disposable and role detection, typo fixes, 0-100 score. DNS only, no SMTP probing. $0.70 per 1,000 emails.

Pricing

$0.70 / 1,000 email verifieds

Rating

0.0

(0)

Developer

Winters Works

Winters Works

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

14 hours ago

Last modified

Share

Bulk Email Verifier (DNS/MX, no SMTP ping)

Email validator and bulk email verifier for cleaning your own lists fast and cheaply. Paste emails, point to a CSV/text URL or an Apify dataset, and get one flat record per address with a status (valid / invalid / risky / unknown), a 0-100 score and a plain-English reason.

Keywords: email validator, bulk email verifier, email validation API, email list cleaner, MX record checker, disposable email detector, bounce reduction, typo fix. A low-cost alternative to per-seat email validation tools for list hygiene.

It checks syntax, whether the domain exists, MX records, disposable domains, role-based addresses, free providers and common typos. It uses DNS only. It never connects to mail servers or sends RCPT probes, so it is safe, fast and cheap, and it is aimed at people cleaning lists they already own (signup forms, newsletter exports, CRM).

What each check does

CheckDetail
Syntax and normalizationRFC 5322 dot-atom rules, length limits, internationalized domains converted to punycode, domain lowercased, whitespace and mailto:/Name <a@b.com> wrappers stripped
Domain and MXMX lookup with RFC 5321 implicit-MX fallback to A/AAAA; detects null MX (RFC 7505) and non-existent domains
DisposableMatched against the open-source disposable-email-domains list (100k+ domains, wildcard subdomains included)
Role-basedinfo@, admin@, sales@, support@, noreply@ and ~50 more
Free providerGmail, Yahoo, Outlook, iCloud, Proton and thousands of others
Typo suggestiongmial.com to gmail.com, hotmial.com to hotmail.com, .con to .com, etc.
SPF / DMARC (optional)Whether the domain publishes SPF and DMARC records

Statuses

  • valid: syntax OK and the domain accepts mail (score 90-100; a missing MX record lowers the score to 90).
  • risky: probably deliverable but a problem is flagged: disposable domain, role-based address, or likely typo.
  • invalid: bad syntax, domain does not exist, null MX, or no mail records at all.
  • unknown: DNS lookup failed or timed out, or DNS checking was turned off.

Output example

{
"input": "bob@gmial.com",
"email": "bob@gmial.com",
"status": "risky",
"score": 35,
"reason": "Possible typo, did you mean bob@gmail.com?",
"suggestion": "bob@gmail.com",
"domain": "gmial.com",
"domainExists": true,
"hasMx": true,
"mxRecords": ["mx.example.net"],
"isDisposable": false,
"isRoleBased": false,
"isFreeProvider": false,
"hasSpf": null,
"hasDmarc": null
}

Output fields

FieldMeaning
inputThe string you submitted, unchanged
emailNormalized address (domain lowercased, punycode), or null if the syntax is invalid
statusvalid, risky, invalid or unknown (see Statuses)
score0-100, higher is cleaner
reasonPlain-English explanation of the status
riskTypelow, medium, high or unknown (mapping below)
syntaxValidtrue if the address parses. isValidSyntax holds the same value and is kept for older integrations
hasPlusTagtrue if the local part has a plus tag, like jane+news@example.com
verifiedAtISO 8601 UTC timestamp of the check
localPart, domainThe two halves of the address
domainExists, hasMx, nullMx, mxRecordsDNS results (null when DNS was off or failed)
isDisposable, isRoleBased, isFreeProviderFlags from the optional checks
suggestionCorrected address when a typo is likely
hasSpf, hasDmarcOnly filled when checkSpfDmarc is on

How riskType is set. It is derived only from the checks above, in this order:

  • high: invalid syntax, domain does not exist, null MX or no mail records, or a disposable domain.
  • unknown: the DNS lookup failed, or DNS checking is turned off.
  • medium: role-based address, likely typo, no MX record (mail would fall back to the A/AAAA record), or neither SPF nor DMARC published (when that check is on).
  • low: valid syntax, the domain accepts mail, and none of the flags above.

riskType is a summary of domain-level signals. It says nothing about whether the individual mailbox exists.

Input

{
"emails": ["jane@company.com", "info@acme.io", "bob@gmial.com"],
"sourceUrl": "https://example.com/my-export.csv",
"checkSpfDmarc": true,
"maxResults": 5000
}

You can combine emails, datasetId (with emailField) and sourceUrl. Duplicates are removed (case-insensitive) and are never charged. An empty-input run uses a small sample set so you can see the output format in seconds.

Use cases

  • Remove dead and typo'd addresses from a signup list before importing to your ESP, lowering bounce rates.
  • Block or flag disposable signups in a CRM export.
  • Separate personal from role-based addresses for B2B outreach to your own contacts.
  • Pre-screen your own contact list before spending on an SMTP-level verifier.
  • Chain after another Actor: pass its dataset ID and the email field name.

What DNS-only verification can and cannot tell you

Honest version: this Actor tells you whether an address could receive mail, not whether the specific mailbox exists.

  • It can catch: malformed addresses, dead or misspelled domains, domains that accept no mail, throwaway domains, shared inboxes and common typos. In typical signup lists this removes a large share of hard bounces.
  • It cannot catch: nobody123@gmail.com where the domain is real but the mailbox is not, full mailboxes, catch-all behaviour, or spam traps. Only an SMTP handshake can sometimes answer that, and many providers (including Gmail and Microsoft) hide the answer anyway. We deliberately do not do SMTP probing: it is blocked on Apify (port 25), unreliable, and abusive at scale.
  • A "valid" result means "no problem found at the domain level". Treat it as list hygiene, not a delivery guarantee.

DNS layer vs SMTP verifiers

This Actor is a DNS layer, not an SMTP verifier.

  • What we check: syntax, domain and MX records, disposable domains, role-based addresses, free providers, typos, and optionally SPF and DMARC.
  • What we do not check: whether a specific mailbox exists, and whether a domain is catch-all. Both need an SMTP conversation with the recipient's mail server, which we never start.
  • When to use us: first-pass cleaning of big lists at a low price, before you send, or before you pay for an SMTP verifier on the addresses that are left.
  • No SMTP probing means nothing here touches the recipient's mail server. Only public DNS is queried.

FAQ

Is this allowed? It only performs public DNS lookups and local list matching. Use it on lists you have the right to process.

Do you store my emails? No. Emails are processed only inside your run and written to your own run dataset. We do not store, sell or reuse them. Delete your dataset any time.

How fast is it? About 20 emails verified in parallel by default (up to 100), with DNS cached per domain, so a list with repeated domains finishes in seconds. 200 emails take about a second.

How much does it cost? Pay per event: $0.70 per 1,000 verified emails, with no charge for duplicates or for rows where the DNS lookup failed. See the Pricing table.

Why is a Gmail address "valid" when the mailbox may not exist? See the section above: DNS cannot see individual mailboxes.

Is the disposable list up to date? It is bundled at build time from the open list and refreshed when the Actor is rebuilt.

Are the results estimates from a model? No. They come from deterministic rule-based checks and DNS lookups.

Built by Winters Works. Feedback and feature requests are welcome via the Issues tab.

Disposable domain data: disposable-email-domains (CC0/MIT). Free provider data: free-email-domains (MIT).

Pricing

Pay per event: $0.70 per 1,000 emails, flat, no seats and no subscription.

EmailsCost
1,000$0.70
10,000$7
100,000$70
1,000,000$700

Duplicate addresses (case-insensitive) are dropped before verification and are never charged. Rows where the DNS lookup failed or timed out (status unknown) are returned so you can retry them, but they are not charged. You're never charged for failed or empty lookups, and the run's status message tells you why any input came back short (duplicates, DNS failures, maxResults). Apify's free plan includes $5 of monthly platform credit, which covers roughly 7,000 emails; platform compute usage also draws from that credit, so treat it as an estimate. Set a maximum cost per run and the Actor stops cleanly when it is reached.

Yes, in the sense that it only reads public or official data: public DNS records only (no mailbox contact). It does not log in, bypass paywalls or access private data. You remain responsible for how you use the results, including privacy, copyright and marketing laws. Not affiliated with or endorsed by the data sources.

Quick start and cost

Run it with the prefilled input to see sample output in seconds; the default run costs only a few cents at most. Then adjust the input and schedule it.

Integrations and AI agents (MCP)

Chain from a scraper. Pass the dataset ID of any other Actor run in datasetId, and the field that holds the address in emailField (default email). If that field is missing, the first value containing an @ is used.

Apify platform integrations. Like every Actor on Apify, this one can be started from webhooks, Make, n8n and Zapier, or through the Apify API and the official JavaScript and Python clients. These are Apify platform features, not separate integrations built by us.

MCP for AI agents. Apify's hosted MCP server at https://mcp.apify.com can expose this Actor as a tool. Use this URL:

https://mcp.apify.com?actors=wintersworks/bulk-email-verifier-dns

Example config for Claude Desktop, Cursor or Claude Code (an MCP client that supports remote servers with headers):

{
"mcpServers": {
"email-verifier": {
"url": "https://mcp.apify.com?actors=wintersworks/bulk-email-verifier-dns",
"headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
}
}
}

Two prompts to try:

  • "Check these 200 addresses with the email verifier and give me only the ones with riskType low."
  • "Verify the emails in dataset abc123 and list every disposable or role-based address."

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("wintersworks/bulk-email-verifier-dns").call(
run_input={"emails": ["jane@company.com", "info@acme.io"]}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["email"], item["status"], item["riskType"])

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('wintersworks/bulk-email-verifier-dns').call({
emails: ['jane@company.com', 'info@acme.io'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((i) => [i.email, i.status, i.riskType]));

Results land in the run's dataset (JSON, CSV, Excel).

About

Built and maintained by Winters Works. Questions or feature requests: open an issue on the Actor page or email wintersworks.shop@gmail.com.

More from Winters Works