Bulk Email Verifier (syntax, MX, disposable, catch-all, SMTP)
Pricing
from $0.30 / 1,000 results
Bulk Email Verifier (syntax, MX, disposable, catch-all, SMTP)
Verify email lists in bulk: RFC syntax, typo suggestions, MX records, disposable and free provider detection, role accounts, catch-all detection and SMTP mailbox check without sending mail.
Pricing
from $0.30 / 1,000 results
Rating
0.0
(0)
Developer
Rod Services
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
What does Bulk Email Verifier do?
Bulk Email Verifier checks email lists in bulk and tells you which addresses are valid, invalid, risky or unknown. It runs RFC syntax validation, typo suggestions (gmial.com to gmail.com), domain and MX record lookups, disposable email detection, free provider and role account flags. With your own SOCKS5 proxy it also runs a catch-all check and an SMTP mailbox check that talks to the mail server without sending any email.
What
validmeans. Without the SMTP check,validmeans the address is well formed and its domain can receive mail (verificationLevel: "dns"). The mailbox itself is not confirmed. Only rows withverificationLevel: "smtp"were confirmed by the recipient mail server. SMTP needs your own SOCKS5 proxy, because Apify blocks port 25.
Paste addresses or give a CSV URL, click Start, and download clean results as JSON, CSV or Excel. As an Apify Actor you also get an API, scheduling, webhooks, integrations with Make, Zapier and Google Sheets, and run monitoring.
Why use Bulk Email Verifier?
- Protect sender reputation. Remove hard bounces before a campaign. High bounce rates get domains blocked.
- Clean signup forms and CRMs. Catch typos like
john@gmail.conand throwaway inboxes from Mailinator or 10MinuteMail. - Keep B2B lists useful. Flag role accounts such as
info@orsales@that rarely reach a decision maker. - Cheap and fast. 1,000 addresses finish in about 4 seconds in DNS mode. Domains are looked up once and cached.
- No lock-in. Plain dataset output, API access, no monthly plan.
How to verify an email list
- Open the Input tab.
- Paste addresses into Email addresses, or put a CSV or text file link into CSV or text file URL.
- Leave SMTP mailbox check off unless you have a SOCKS5 proxy. See below.
- Click Start. The prefilled 5 address example finishes in a few seconds.
- Open the Output tab. Filter by
statusor download the dataset.
Input
All fields are in the Input tab. JSON example:
{"emails": ["info@apify.com", "example.user@gmial.com", "test@mailinator.com"],"emailsFileUrl": "https://example.com/contacts.csv","smtpCheck": false,"socksProxyUrl": "socks5://user:pass@proxy.example.com:1080","heloHost": "verify.yourdomain.com","fromAddress": "bounce@yourdomain.com","checkCatchAll": true,"timeoutSecs": 10,"maxConcurrency": 10,"maxConnectionsPerMx": 2,"greylistRetrySecs": 60}
| Field | Meaning |
|---|---|
emails | Addresses to verify. Blocks separated by new lines, commas or semicolons also work. |
emailsFileUrl | CSV or text file. Every cell with an @ is used, so headers and other columns are ignored. Max 50 MB. |
smtpCheck | Turn on the SMTP mailbox and catch-all check. Needs socksProxyUrl on Apify. |
socksProxyUrl | Your SOCKS5 proxy that can reach port 25. Stored encrypted. |
heloHost, fromAddress | Identity used in EHLO and MAIL FROM. Use a domain you control. |
checkCatchAll | One extra RCPT per domain with a random address. |
greylistRetrySecs | Wait time before one retry after 4xx answers. 0 disables it. |
timeoutSecs | Timeout per DNS query and per SMTP step. |
maxConcurrency | Domains processed in parallel. |
maxConnectionsPerMx | Parallel SMTP sessions to one mail server. |
Duplicates are verified and billed once. Addresses count as duplicates after trimming, removing mailto: or Name <...> wrappers and lowercasing, so INFO@Example.com and info@example.com are one result. Plus tags are kept: jane+news@gmail.com and jane@gmail.com are two results.
Output
One item per unique address. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.
{"email": "example.user@gmial.com","normalized": "example.user@gmial.com","domain": "gmial.com","status": "risky","reason": "possible_typo","verificationLevel": "dns","isSyntaxValid": true,"hasMx": false,"mxHosts": ["gmial.com"],"isDisposable": true,"isFreeProvider": false,"isRole": false,"isCatchAll": null,"smtpChecked": false,"smtpCode": null,"smtpMessage": null,"didYouMean": "example.user@gmail.com","checkedAt": "2026-09-27T10:32:25.005Z"}
A run summary with counts per status and per verification level is saved as SUMMARY in the key-value store. It also shows smtpMode: off, socks, direct or unavailable.
Data fields
| Field | Description |
|---|---|
email | Address as given |
normalized | Trimmed, lowercased, punycode domain |
status | valid, invalid, risky or unknown |
reason | Why. See the table below |
verificationLevel | dns: domain accepts mail, mailbox not confirmed. smtp: mail server answered for this mailbox. syntax: rejected before any lookup |
isSyntaxValid | Passes RFC 5321/5322 addr-spec rules |
hasMx | Domain has MX records |
mxHosts | Mail hosts by priority. Domain itself when only an A record exists |
isDisposable | Domain is on the disposable list |
isFreeProvider | Gmail, Yahoo, Outlook, GMX and about 110 more |
isRole | info@, admin@, support@, noreply@ and similar |
isCatchAll | Server accepts any address. null when not tested |
smtpChecked | Mail server gave a definitive answer for this mailbox |
smtpCode, smtpMessage | Raw RCPT TO reply |
didYouMean | Suggested fix for a likely domain typo |
checkedAt | ISO timestamp |
Status and reason
| Status | Reasons | What to do |
|---|---|---|
valid | mailbox_exists: mailbox confirmed by SMTP, verificationLevel smtp | Safe to keep |
valid | mx_found, a_record_only: domain accepts mail, mailbox not checked, verificationLevel dns | Keep, but expect some bounces |
invalid | invalid_syntax, domain_not_found, null_mx, no_mail_server, mailbox_not_found | Remove |
risky | disposable, catch_all, possible_typo, mailbox_full | Review or remove |
unknown | dns_error, smtp_blocked, greylisted, smtp_temporary_error, smtp_unreachable, smtp_error | Retry later |
Without the SMTP check, valid means syntax, domain and mail server are fine and the domain is not disposable. The mailbox itself is not confirmed, so an address like nobody-12345@gmail.com is still valid at DNS level. Filter on verificationLevel = smtp when you need confirmed mailboxes. a_record_only means the domain has no MX record and mail would go to its A record, per RFC 5321. Many such domains do not accept mail in practice.
How much does email verification cost?
Pay per event, no subscription:
- $0.30 per 1,000 addresses for syntax, DNS, MX, disposable, role and typo checks.
- +$0.40 per 1,000 only for addresses where the SMTP check got a definitive answer. That is $0.70 per 1,000 in total.
- A small start fee of $0.0005 per run, per GB of memory. The default 256 MB run pays it once.
Blocked, greylisted or unreachable SMTP answers are not charged as SMTP checks. The Apify free plan monthly credit covers tens of thousands of DNS level checks. Set Maximum cost per run in run options to cap spend. The Actor stops when it is reached. Addresses past the cap are not written and not charged.
SMTP mailbox check and port 25
The mailbox check needs outbound TCP port 25. Apify blocks port 25, like most cloud providers. The Apify Proxy does not tunnel it either. So on Apify the SMTP step needs your own SOCKS5 proxy:
- Rent a small VPS where port 25 is open. Many hosts open it on request.
- Set reverse DNS of its IP to a hostname you own, e.g.
verify.yourdomain.com. - Run a SOCKS5 server such as Dante with username and password.
- Fill
socksProxyUrl,heloHostandfromAddress, then turn onsmtpCheck.
The Actor tests port 25 before it starts. If it fails, you get a warning, the run continues at DNS level, and no SMTP events are charged. The run summary shows smtpMode.
The SMTP step sends only EHLO, MAIL FROM, RCPT TO and QUIT. It never sends DATA, so no email is delivered.
Tips and advanced options
- Rate limits. Keep
maxConnectionsPerMxat 1 or 2. Domains on Google Workspace or Microsoft 365 share MX hosts, and the limit applies per host. - Greylisting. Some servers answer 450 or 451 on first contact. The Actor waits
greylistRetrySecsand retries once with the same probe addresses. - Big providers. Yahoo and some Microsoft servers accept every RCPT or block probes. Expect
catch_allorsmtp_blockedthere. - Speed. DNS mode uses at least 20 parallel domains. 256 MB memory is enough for lists of 100,000+ addresses.
Acceptable use
- Only verify lists you have a lawful basis to process, for example your own customers or signups under GDPR or similar law. You are the data controller for the addresses you upload.
- No spam. Do not use this Actor to build or clean lists for unsolicited email, or to guess addresses for harvesting.
- Respect mail server limits. Do not raise concurrency to hammer servers.
- The Actor stores results only in your own Apify storage. Delete datasets you no longer need.
FAQ and support
Is the result 100% accurate? No verifier is. Catch-all servers, greylisting and anti-probe policies limit what SMTP can prove. risky and unknown exist for that reason.
Where does the disposable list come from? A pinned snapshot of disposable-email-domains, CC0 licensed, 9,185 domains, commit 0655284. Details in data/disposable-source.json.
Does it send emails? No. There is no DATA command.
What happens if my input is invalid? The run still ends SUCCEEDED and you pay only the small start fee. No address is charged and the dataset stays empty. The run status message explains the problem and the fix, and the same help record is saved in the key-value store under INPUT_ERROR:
{"error": true,"errorCode": "EMPTY_INPUT","message": "No email addresses in input.","howToFix": "Add addresses to \"emails\" ..."}
Codes: EMPTY_INPUT (no addresses), NO_EMAILS_FOUND (the file has no address), FILE_UNREADABLE (emailsFileUrl cannot be downloaded) and INVALID_INPUT (a wrong socksProxyUrl). Addresses with bad syntax are not an input error: they are verified and returned with status invalid.
Found a bug or need a feature? Open the Issues tab. Custom verification pipelines are available on request.