Email Verifier — Bulk SMTP & MX Validation, Catch-all
Pricing
from $0.87 / 1,000 email-verifications
Email Verifier — Bulk SMTP & MX Validation, Catch-all
Verify email addresses you provide with syntax, disposable, role, MX, and optional SMTP checks. Get status, score, and verification fields. Run in your Apify account using emails. Pricing: $0.0009 per dataset item + $0.00005 per Actor Start event on Free.
Pricing
from $0.87 / 1,000 email-verifications
Rating
0.0
(0)
Developer
Vitalii Bondarev
Maintained by CommunityActor stats
0
Bookmarked
48
Total users
26
Monthly active users
3 days ago
Last modified
Categories
Features
Share
Email Verifier for Bulk Email Validation
Email Verifier checks the addresses you provide with syntax, disposable and role-account lists, DNS MX records, and an SMTP probe, and returns a status, score, and verification fields. Outbound port 25 is normally closed on Apify, so most runs rely on the non-SMTP checks (see Limits).
- Verify addresses in bulk without sending a message or issuing a
DATAcommand - Clean B2B lead lists and outreach databases with status, confidence scores, and MX details
- Validate signup addresses and flag disposable or generic role accounts
- Catch-all detection when an SMTP probe completes
What you get
Each address goes through syntax, disposable-domain, role-account, DNS MX, optional SMTP, and catch-all checks.
| Field | Type | Description |
|---|---|---|
email | string | Normalized, lowercased address; not null or empty in a returned record |
status | string | deliverable, undeliverable, risky, or unknown; not null |
score | integer | Confidence from 0 to 100; not null |
syntax_valid | boolean | Passes syntax validation; not null |
is_disposable | boolean | Domain is on the built-in temporary-mail hotlist; not null |
is_role | boolean | Generic role local part such as info, support, or admin; not null |
mx_found | boolean | Result of the DNS MX check; not null |
mx_host | string | Highest-priority MX hostname; null when no MX is found |
smtp_code | integer | Raw SMTP response; null if SMTP is unreachable, skipped, or does not complete |
smtp_message | string | SMTP response text, or a reason such as the port-25-blocked note; null when SMTP is skipped |
is_catch_all | boolean | Domain accepts arbitrary local parts; null when SMTP is skipped, unreachable, or catch-all status cannot be determined |
checked_at | ISO 8601 string | UTC timestamp for the check; not null |
A field is null when the source does not provide the value.
Disposable domains are checked against a built-in hotlist of known temporary-mail providers. It is deliberately not exhaustive, so a disposable domain missing from it is not flagged. Generic role local parts such as info, support and admin are flagged in is_role.
If DNS returns no MX record, the Actor checks for an A-record fallback. A DNS timeout or other DNS failure counts as no MX (undeliverable, score 0).
SMTP connects to the highest-priority MX host on port 25 and uses HELO, MAIL FROM, and RCPT TO. It reads the RCPT TO response and closes the connection without delivering a message. After a 250 response, a random non-existent address is checked to identify catch-all domains.
Before the first address, the Actor tests whether port 25 is reachable. If it is closed, every address skips SMTP. If a run starts with port 25 open but 5 probes in a row are unreachable and none has connected, the Actor stops probing for the rest of the run.
Sample output
A record from a real run on Apify for a public throwaway address on the disposable mailinator.com domain, where port 25 was blocked: smtp_code and is_catch_all are null, and smtp_message carries the blocked-port note. Score 5 is what a disposable domain gets when an MX is found and the SMTP probe is unreachable. A role address on a non-disposable domain in the same situation returns unknown, score 60 instead.
{"email": "user@mailinator.com","syntax_valid": true,"is_disposable": true,"is_role": false,"mx_found": true,"mx_host": "mail.mailinator.com","smtp_code": null,"smtp_message": "connection_failed: outbound port 25 is blocked in this environment (detected once per run; SMTP probe skipped, MX/DNS result only)","is_catch_all": null,"status": "undeliverable","score": 5,"checked_at": "2026-10-30T01:29:09Z"}
Pricing
The Actor uses pay-per-event pricing: a start charge per run (one event per GB of run memory, minimum one) and a charge per dataset item.
You pay only for the events listed below. This Actor does not use the Pay per event + usage option, so the platform usage of your runs (compute, proxy traffic and storage) is not billed to you separately.
| Plan | Actor Start | Dataset item |
|---|---|---|
| Free | $0.00005 per event on Free plan | $0.0009 per event on Free plan |
The email-verification event name has no price of its own in the price list; each returned record is billed as the priced dataset item in the table above.
For one Actor Start event:
1,000 dataset events: $0.00005 + (1,000 × $0.0009) = $0.90005 on the Free plan
10,000 dataset events: $0.00005 + (10,000 × $0.0009) = $9.00005 on the Free plan
The Apify Free plan includes $5 of monthly platform usage credit; the $5 credit covers 5,555 priced dataset events after one Free-plan Actor Start event.
How to use
- Prepare an
emailslist of plain strings or objects with anemailkey. - Choose concurrency, SMTP timeout, and SMTP mode. Use
skipSmtp: trueto skip the SMTP step and avoid waiting on a closed port. - Run the Actor with an input such as the one below (start it with Start in Apify Console, or through the Apify API; the Console prefill already holds three runnable addresses):
{"emails": ["user@mailinator.com"],"concurrency": 10,"smtpTimeoutSecs": 10,"skipSmtp": false}
- Inspect returned records for status, score, flags, and MX/SMTP values.
- Filter records according to your workflow, reviewing
risky, disposable, and role-account results separately. - Schedule the run through Apify Schedules as a starting point, such as weekly for lead-list verification.
Export the dataset as JSON or CSV, or read it through the Apify dataset API.
Input parameters
| Parameter | What it does | Default |
|---|---|---|
emails | Required plain strings or objects with an email key; maximum 10,000 entries per run | Required |
concurrency | Emails verified in parallel; range 1–50, with 5–20 recommended | 10 |
smtpTimeoutSecs | Timeout for each SMTP attempt; range 3–30 seconds | 10 |
skipSmtp | Skips SMTP and uses MX-only mode | false |
disableUsageStats | Set to true to turn off the run summary described in Usage statistics. | false |
Limits and edge cases
Output rows reach the dataset as each address finishes, before its charge is attempted. If a run is aborted, times out, or fails after rows are pushed, those rows remain and addresses not yet pushed have no rows.
The Actor writes an OUTPUT record with emails_verified and a reason to the run's default key-value store when it:
- fails on unusable input;
- stops early on the cost-efficiency check;
- finishes with port 25 blocked.
A run you abort yourself, or one that times out, does not write it.
| Condition | What you see | What to do |
|---|---|---|
| More than 10,000 entries | The run uses the first 10,000 | Split the list |
emails is empty, or has no usable strings or email values | The run fails with an input-needed message and emails_verified: 0 | Add addresses as strings or objects with an email key |
| Syntax is invalid | undeliverable, score 0; no network round-trip | Correct the address |
| No MX record, no A-record fallback, or a DNS timeout | undeliverable, score 0 | Check the domain; re-run if DNS was flaky |
| Port 25 is blocked or SMTP times out (the usual case on Apify) | smtp_code is null. Known providers (Gmail, Outlook, Yahoo, iCloud, Proton, AOL, Zoho and similar) return deliverable, score 80, a domain-name heuristic with no mailbox check. Domains on the disposable hotlist return undeliverable, score 5. Other domains return unknown, score 60 | Treat 80 and 60 as unconfirmed |
skipSmtp is true | No SMTP probe; the same MX-only rules apply | Use it to avoid the port-25 preflight |
SMTP returns 250 and the random address is rejected | deliverable, score 100 | Highest-confidence result |
SMTP returns 250 but the catch-all check does not complete | deliverable, score 100, is_catch_all null | Catch-all status is unknown; review separately |
SMTP returns 250 for the random address too | risky, is_catch_all: true, score 40 | Review the mailbox separately |
| SMTP returns a 4xx response | risky, score 35 | Re-verify later or review it |
| SMTP returns a 5xx response | undeliverable, score 0 | Remove or correct the address |
| SMTP returns any other code | unknown, score 50 | Re-verify or review it |
A server accepts an address with 250 | Acceptance does not guarantee that a later message will not bounce silently | Treat the score as a verification signal |
| High concurrency is used against one domain | Mail servers may return more 4xx responses from rate-limiting | Reduce concurrency; the default of 10 is conservative |
| The cost-efficiency stop occurs before the first row | The run fails with emails_verified: 0 | Run again with a smaller list |
| The cost-efficiency stop occurs after rows are written | A partial run reports emails_verified and emails_not_processed | Run the remaining addresses later with a smaller list |
To see whether SMTP worked, check smtp_code: null means the SMTP step did not complete.
FAQ
How much does it cost to scrape email addresses?
This Actor verifies addresses rather than finding them. Actor Start costs $0.00005 per event on the Free plan and each dataset item costs $0.0009 per event on the Free plan; see Pricing for the worked calculation.
Why can a result be unknown or risky?
unknown generally means an MX result was found but SMTP could not be reached (score 60), or an unexpected SMTP code came back (score 50). risky means the domain is catch-all or the SMTP server returned a temporary 4xx response.
What happens if the run returns no results or does not work?
An empty emails list or a list without usable entries fails with an input-needed message. If SMTP is unavailable, the Actor still returns records from the other checks.
Is it legal to verify email addresses using public data?
The Actor works with the addresses you provide, DNS records and mail-server responses. Whether verifying them is lawful depends on your use case and local law, so check that before use.
Related actors
- Bulk Email Verifier — validates emails with MX, disposable, and role checks.
- Email Finder — finds a work email from a name and domain before verification.
- Email Finder Bulk — finds emails from lists of domains or people before verification.
Usage statistics
This Actor creates a small, content-free summary at the end of each run, used only to monitor reliability and improve this Actor. No input values, credentials or scraped data are sent.
A copy of the exact record for your run is saved as USAGE_STATS in your own Apify key-value store.
To opt out, set disableUsageStats to true in the input. Nothing is sent then.