Bulk Email Verifier & Validator - MX, Disposable, No API Key avatar

Bulk Email Verifier & Validator - MX, Disposable, No API Key

Pricing

from $3.00 / 1,000 results

Go to Apify Store
Bulk Email Verifier & Validator - MX, Disposable, No API Key

Bulk Email Verifier & Validator - MX, Disposable, No API Key

Email deliverability checker and bulk verifier. No API key, never sends email. Checks syntax, MX records, 7,900+ disposable domains, role accounts and free webmail; detects Google Workspace/Microsoft 365, flags typos, scores 0-100 (A-F). Clean email lists before a cold campaign. CSV, JSON, Excel.

Pricing

from $3.00 / 1,000 results

Rating

5.0

(1)

Developer

Flash Scrape

Flash Scrape

Maintained by Community

Actor stats

0

Bookmarked

5

Total users

0

Monthly active users

6 days ago

Last modified

Share

Bulk email verifier and email list cleaning tool for cold-email senders, lead-gen agencies and CRM owners. Every address comes back with a deliverable / risky / undeliverable status, a reason code, a 0–100 deliverability score and an A–F gradeno API key, no subscription, and it never sends a single email. $3 per 1,000 verified emails; a run that verifies nothing bills nothing.

Copy-paste input to start:

{
"emails": ["john@apify.com", "info@stripe.com", "jane@gmial.com", "test@mailinator.com"]
}

Only emails is required — an array, one address per line, or a single comma/space/newline-separated string.

What does it check?

For every email address in your list, the actor runs a fast, read-only verification pipeline:

  • Syntax validation — RFC-style format check (local part, domain shape, and the RFC 5321 length limits: local part ≤ 64, whole address ≤ 254, each domain label ≤ 63 characters)
  • MX record lookup — resolves the domain's mail servers over DNS-over-HTTPS (Google and Cloudflare resolvers), so it works from any network without port-25 access. A lookup that does not complete is retried once within the run before the address is marked mx_lookup_failed (time permitting - if the run's timeout arrives first, the status message says how many were not retried)
  • Disposable domain detection — a bundled blocklist of 7,900+ temporary-inbox domains (mailinator, yopmail, guerrillamail, temp-mail and thousands more)
  • Role account detection — flags generic mailboxes like info@, sales@, support@, noreply@, admin@ that convert poorly and bounce often
  • Typo detectionjane@gmial.com gets did_you_mean: "jane@gmail.com" (a common-provider typo map plus a single-edit-distance check against gmail, outlook, yahoo, icloud and other major domains)
  • Mailbox provider detection — identifies Google Workspace, Microsoft 365, Zoho Mail, Proofpoint, Fastmail and others from the MX hosts
  • Free webmail detection — labels gmail, outlook, yahoo, icloud, proton and other consumer providers so you can separate B2B from personal addresses
  • Normalization + deduping — trims, lowercases, and (optionally) drops case-insensitive duplicates before verifying

Verification runs in parallel (configurable concurrency) with per-domain MX caching and one in-flight lookup per domain, so large lists that share domains finish especially fast — 1,000 addresses on 50 domains cost 50 lookups, not 1,000. Rows are delivered to the dataset in batches of up to 500 while the run is still verifying, so a run that hits its timeout keeps everything verified so far.

Input

FieldTypeDefaultDescription
emailsarray(required)List of email addresses to verify. You can paste them one per line, or pass an array. Also accepts a single comma/space/newline-separated string.
concurrencyinteger20How many emails to verify in parallel (1–100).
dedupebooleantrueDrop duplicate addresses (case-insensitive) before verifying.
includeInvalidbooleantrueKeep malformed addresses in the results (flagged undeliverable) instead of dropping them.

Output columns

One dataset row per verified address. Export to CSV, JSON, or Excel, or pull results via the Apify API.

ColumnWhat it holds
emailThe address exactly as you provided it
normalizedTrimmed, lowercased form that was verified
statusdeliverable, risky, or undeliverable
score / deliverability_score0–100 deliverability score (score is the same value, kept for back-compat)
gradeLetter grade: A ≥ 85, B 70–84, C 50–69, D 20–49, F < 20
business_classgood / risky / bad — outreach-value view of the same result
technical_statedeliverable / undeliverable / unknown (unknown = the DNS lookup itself failed)
reasonMachine code: ok, role_address, mx_lookup_failed, no_mx_record, disposable_domain, invalid_syntax
syntax_validtrue if the address passed the syntax gate
domainThe part after @
is_freeConsumer webmail (gmail, outlook, yahoo, ...)
is_roleShared alias (info@, sales@, ...)
is_disposableDomain is on the throwaway blocklist
mx_foundDomain has working mail servers
mx_hostHighest-priority MX hostname (null when no MX resolved)
providerMailbox provider from the MX hosts: Google Workspace, Microsoft 365, Proofpoint, Mimecast, Zoho Mail, Fastmail, GoDaddy, or Other / self-hosted when the MX hosts are not recognized; null only when no MX resolved
did_you_meanTypo-corrected suggestion (null unless the domain looks like a typo of a major provider)

A real row:

{
"email": "john@apify.com",
"normalized": "john@apify.com",
"status": "deliverable",
"score": 95,
"deliverability_score": 95,
"grade": "A",
"business_class": "good",
"technical_state": "deliverable",
"reason": "ok",
"syntax_valid": true,
"domain": "apify.com",
"is_free": false,
"is_role": false,
"is_disposable": false,
"mx_found": true,
"mx_host": "aspmx.l.google.com",
"provider": "Google Workspace",
"did_you_mean": null
}

How the status, score and grade are decided

Status and score map to a fixed, transparent rubric:

statusreasonscoregrademeaning
deliverableok95 on Google Workspace / Microsoft 365, else 85AValid syntax, domain has working mail servers, no risk flags
deliverableok + did_you_mean setcapped at 60CThe domain resolves but looks like a typo of a major provider — double-check before sending
riskyrole_address60CGeneric mailbox (info@, sales@, ...) — deliverable but low-value for outreach
riskymx_lookup_failed20DThe DNS lookup did not complete even after the run's one retry (or the run's timeout arrived before the retry could start — the status message says which) — unknown, not a confirmed failure. Re-run these rather than discarding them. The status message tells you how many rows ended this way. If the resolvers never answered for any domain in the run, these rows are held back instead of delivered (see below) and you are not charged for them.
undeliverableno_mx_record15FDomain has no mail servers — mail cannot be delivered
undeliverabledisposable_domain5FTemporary/throwaway domain
undeliverableinvalid_syntax0FMalformed address

Example output

Real rows from a run of the verification engine (2026-08-23):

emailstatusscoregradereasondid_you_mean
john@apify.comdeliverable95Aok
info@stripe.comrisky60Crole_address
jane@gmial.comundeliverable5Fdisposable_domainjane@gmail.com
test@mailinator.comundeliverable5Fdisposable_domain
invalid@@bademailundeliverable0Finvalid_syntax

(gmial.com is both on the disposable blocklist and an obvious gmail typo, so it gets flagged twice over.)

Pricing — what does it cost to verify 1,000 emails?

$3 per 1,000 verified emails (Apify pay-per-event: one result event per row in the dataset). No subscription, no minimums, and no charge for runs that deliver nothing. A free Apify plan is enough to try it — the plan's monthly platform credit covers cleaning a real list before you pay anything. Note that every row pushed to the dataset is a charged result, including rows kept by includeInvalid.

What you get back when a run cannot finish cleanly

The status message on the run always names what happened, in plain words, and a run that delivered nothing ends with "You were not charged.":

  • Run timeout — the actor reads the run's own timeout and stops starting new addresses about 30 seconds before it; everything verified so far is already in the dataset (delivered in batches of ≤ 500 rows) and billed. The message says how many addresses were left unverified so you can re-run just those, or raise the run's timeout.
  • DNS resolvers down — a lookup that does not complete is retried once. If some lookups still fail, those rows are delivered as risky / mx_lookup_failed and the message tells you how many. If the resolvers never answered for any domain in the whole run, the unverified rows are held back, not delivered and not charged — "risky" is never used as a euphemism for "unchecked"; the rows that need no DNS (malformed, disposable) are still delivered.
  • Charge limit — with a maxTotalChargeUsd on the run, the actor asks the platform how many rows still fit before each batch and delivers exactly the rows you are billed for, never more. The message says how many were left out.
  • Nothing to verify — an empty emails list, or a list where every address is malformed while includeInvalid is off, exits SUCCEEDED with a message telling you what to change.

Every run comes with a report

Every run that delivers at least one row also writes a REPORT record to the run's key-value store (Output tab → REPORT, or follow the "Report:" link in the status message). It is a single self-contained HTML page — the verdict split, reason codes, mailbox providers, the first 100 rows and the same notes the status message carries — safe to forward or screenshot for a client. The dataset remains the source of truth; the report is a view of exactly the rows that were delivered and billed.

Run summary for API and scheduled callers

Every run — including zero-row runs — writes a RUN_SUMMARY record (key-value store) with the counts an integration needs: supplied, unique, duplicates_removed, verified, delivered, charged, by_status, by_reason, malformed_dropped, dns_unknown_delivered, dns_withheld, dns_retried, skipped_timeout, left_out_budget, cause (null on a normal run, otherwise the same reason the status message names), report_url and status_message. delivered and charged are equal on a normal run; if they differ, the run log carries a charge warning or MISMATCH line - please report that run. dns_retried counts the lookups the retry pass actually started (the run's timeout can cut the retry short; the status message then says how many rows were not retried).

Verifying at volume? (agencies, lead-gen teams)

This is built for bulk: paste 50,000 addresses and it verifies the lot in one run, priced per result at a fraction of the mainstream verifiers (many charge $8-$100 per 1,000 at their entry tier; the big SaaS tools charge $30-80 per 1,000). No subscription, no monthly minimum, no API key - and a run that verifies nothing bills nothing. If you maintain client lists and re-verify monthly, this is the cheapest way on the platform to do it. Open an issue if you need a custom volume arrangement.

Use cases

  • Cold outreach list cleaning — run every scraped or purchased list through the verifier and keep only deliverable rows; bounces above ~2–3% get your domain flagged by Google and Microsoft.
  • Sales prospecting pipelines — chain it after a lead scraper so every contact you hand to sales already has a verified, scored email.
  • Lead-gen agencies — deliver client lists with a status and score column attached; verified lists command higher prices than raw scrapes.
  • CRM hygiene — export your CRM's email column quarterly, verify it, and archive contacts whose domains no longer accept mail.
  • Form-signup filtering — batch-check new signups and quarantine disposable domains before they hit your product analytics or drip campaigns.

FAQ

How can I verify an email address without sending an email?

This is exactly that: the actor confirms an address's syntax is valid and its domain runs real mail servers using DNS lookups only. Nothing is ever sent, no mailbox is ever contacted, and the address owner never knows a check happened — safe to run on scraped or purchased lists.

Can it check an email list for bounces before I send?

That's the core use case. Run the list, keep status = "deliverable" rows, and you remove the addresses that are guaranteed to hard-bounce (dead domains, throwaway inboxes, malformed entries) before your ESP ever sees them. Bounces above ~2–3% get your sending domain flagged by Google and Microsoft, so cleaning first protects the domain itself.

Does it do a full SMTP handshake with the mail server?

No — and the README won't pretend otherwise. This verifier checks syntax and MX/DNS only (plus disposable/role/free classification). It confirms the domain accepts mail, not that the specific mailbox exists. That's why a clean pass caps at a score of 95, not 100. The upside: it's read-only, sends nothing, needs no proxies or port 25, and never risks your IP reputation. For high-stakes sends, treat deliverable as "safe to include", and let your email tool's soft-bounce handling catch the remaining mailbox-level misses.

Can a deliverable email still bounce?

Yes, occasionally. A domain can have valid MX records while the individual mailbox is full, disabled, or never existed (catch-all domains are the usual culprit). MX-level verification typically removes the large majority of bounces from a scraped list, but it can't guarantee zero.

Why are role accounts marked risky rather than undeliverable?

info@ and sales@ mailboxes usually work — they're flagged because they're shared inboxes with low reply rates, and some ESPs penalize campaigns heavy on role addresses. Filter them out with the is_role column if your tooling dislikes them, or keep them for local-business outreach where they're often the only address available.

How big a list can I verify in one run?

There's no hard input cap. Verification is parallel (up to concurrency: 100) and MX lookups are cached per domain, so lists that share domains verify especially fast. Rows reach the dataset in batches of up to 500 while the run is still working, and the actor watches the run's own timeout: it stops taking new addresses shortly before the platform would kill the run, delivers and bills what it verified, and tells you in the status message how many addresses were left unverified. For very large jobs, splitting into runs of a few tens of thousands (or raising the run's timeout) keeps datasets easy to export.

What happens to malformed addresses?

With includeInvalid: true (the default) they stay in the output flagged undeliverable / invalid_syntax with a score of 0 — useful for auditing what was wrong with a source list. Set it to false to drop them silently. Note that every row pushed to the dataset is a charged result.

Does it need proxies or an API key?

No. MX resolution goes over DNS-over-HTTPS to Google and Cloudflare, which works from any IP, including datacenter IPs, with nothing to configure.

What this actor does NOT do

  • No SMTP / mailbox-level verification — it cannot confirm an individual inbox exists or detect catch-all domains (see the FAQ above for why that trade-off is deliberate)
  • It never sends email — no test messages, no pings, nothing lands in anyone's inbox
  • It doesn't find or guess addresses — for that, use Email Pattern Finder and verify its guesses here
  • It doesn't validate phone numbers — the phone column of the same list goes to Phone Number Validator
  • Phone Number Validator — the phone counterpart from the same publisher: validate and E.164-format the phone column of the same lead list, offline
  • Email Pattern Finder — discover a company's email format when you have names but no addresses, then verify the guesses here
  • Local Business Leads — scrape local business leads with MX-verified emails, a natural upstream source for this verifier

Found a bug or need a feature? Open an issue on the actor's Issues tab — typical response within 1 business day.