Email Verifier & Validator - Bulk SMTP Verification
Pricing
from $2.00 / 1,000 results
Email Verifier & Validator - Bulk SMTP Verification
Verify email deliverability in bulk with syntax, MX/A fallback, non-sending SMTP mailbox checks, catch-all detection, disposable/role/free-provider flags, and optional SPF/DKIM/DMARC health. Conservative good/risky/bad scoring with no verifier API key.
Pricing
from $2.00 / 1,000 results
Rating
0.0
(0)
Developer
Thirdwatch
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
11 hours ago
Last modified
Categories
Share
Email Verifier & Validator — Bulk SMTP Verification
Verify email lists before outreach with syntax, DNS, non-sending SMTP mailbox checks, catch-all detection, disposable/role/free-provider classification, and a stable deliverability score.
What this Actor verifies
Each input address produces one dataset row with:
- practical email syntax validation;
- MX lookup with RFC-compatible A-record fallback;
- a non-sending SMTP
RCPT TOmailbox check; - catch-all detection with a random-address control probe;
- disposable-domain detection from a vendored blocklist;
- role-address, free-provider, and plus-tag classification;
- optional SPF, DKIM, and DMARC domain-health checks;
good/risky/badbusiness status;valid/invalid/unknown/catch_all/disposable/errortechnical status;- a transparent 0–100 score, reason code, and full verification evidence.
The SMTP conversation stops before DATA. No email is sent. No external API key or verifier subscription is required.
Important accuracy note
SMTP verification is evidence, not a delivery guarantee. Some providers reject recipient probes, temporarily defer requests, accept every recipient, or deliberately hide whether an inbox exists. This Actor handles those cases conservatively:
- a definitive
250/251/252recipient response can confirm acceptance; 551/553, or a550response that explicitly says the recipient does not exist (for example5.1.0,5.1.1,user unknown, ormailbox not found), marks the mailbox rejected;- quota, policy, reputation, authentication, and other ambiguous 5xx responses stay
unknowninstead of becoming false invalids; - if a random address is also accepted, the domain is
catch_alland the individual mailbox stays unknown; - timeouts, greylisting, blocks, and ambiguous responses return
unknownrather than being guessed.
Actual delivery can still fail later because a mailbox becomes full, is disabled after verification, or a provider rejects the message based on content or sender reputation.
Input
{"emails": ["hello@openai.com","person@gmail.com","sales@company.com","hello@mailinator.com","not-an-email"],"smtpCheck": true,"detectCatchAll": true,"checkDomainHealth": false,"maxConcurrency": 10,"smtpTimeoutSecs": 4,"useApifyProxy": true}
| Field | Required | Default | Description |
|---|---|---|---|
emails | Yes | [] | Email addresses. Comma/newline-separated values inside an entry are also accepted. |
smtpCheck | No | true | Run the non-sending SMTP mailbox probe. |
detectCatchAll | No | true | Check whether the domain accepts a random recipient too. |
checkDomainHealth | No | false | Add SPF, best-effort DKIM, and DMARC checks. |
maxConcurrency | No | 10 | Global concurrency, 1–50. Requests to the same domain remain serialized. |
smtpTimeoutSecs | No | 4 | SMTP connection/response timeout, 2–20 seconds. |
useApifyProxy | No | true | Tunnel SMTP through the run's authenticated Apify proxy. Keep enabled on Apify. |
deep | No | false | Legacy v1 input name retained for migration. In v2, true enables SMTP checks; unlike v1, it is no longer a no-op. Use smtpCheck for new integrations. |
Output
{"email": "person+campaign@example.com","domain": "example.com","status": "good","technical_status": "valid","score": 95,"reason": "ok","free": false,"role": false,"disposable": false,"catch_all": false,"has_tag": true,"mailInfrastructureFound": true,"mailInfrastructureStatus": "available","domainHealthChecked": false,"error": "none","verification_details": {"normalized_email": "person+campaign@example.com","verdict": {"is_valid": true,"status": "valid","state": "Deliverable","confidence_score": 95,"primary_reason": "OK","reasons": ["syntax_ok", "mail_infrastructure_ok", "smtp_accepted"]},"classification": {"is_free_provider": false,"is_role_based": false,"is_disposable": false,"has_tag": true},"checks": {"syntax_valid": true,"mx_records_valid": true,"mail_infrastructure_found": true,"mail_infrastructure_status": "available","a_record_fallback": false,"smtp_reachable": true,"mailbox_exists": true,"catch_all_domain": false,"mx_hosts": ["mx.example.com"]},"smtp": {"status": "accepted","mx_host": "mx.example.com","response_code": 250,"response_message": "250 2.1.5 recipient accepted","latency_ms": 184},"domain_health": {"spf": false, "dkim": false, "dmarc": false},"domain_health_checked": false}}
mailInfrastructureFound reports whether the domain can receive mail through MX or the RFC A-record fallback. mailInfrastructureStatus is available, unavailable, or unknown; usingARecordFallback distinguishes fallback delivery from literal MX. mxFound now means that an actual MX record was found.
domainHealthChecked tells consumers whether SPF/DKIM/DMARC lookup was requested. Because checkDomainHealth defaults to false, a false value inside domainHealth must not be interpreted as a failed authentication audit unless domainHealthChecked is true.
Status and reason semantics
| Business status | Meaning |
|---|---|
good | Mailbox was accepted and no high-risk classification was found. |
risky | Provider response was ambiguous, the address is role-based, or the domain is catch-all. |
bad | Syntax/infrastructure is invalid, the address is disposable, or SMTP definitively rejected it. |
| Technical status | Meaning |
|---|---|
valid | SMTP accepted the recipient; catch-all control did not invalidate the individual signal. |
invalid | Invalid syntax/infrastructure or a definitive SMTP rejection. |
unknown | Provider did not expose a decisive mailbox signal. |
catch_all | Domain accepted both the requested and randomized recipients. |
disposable | Address uses a known temporary-email domain. |
error | The row could not be processed. |
Machine-readable reasons include ok, invalid_syntax, no_mail_infrastructure, mail_infrastructure_unknown, smtp_rejected, smtp_unreachable, smtp_not_checked, catch_all_domain, disposable_email, role_address, and request_failed.
Performance and cost controls
- DNS answers are cached per domain for the run.
- Up to 100 rows are scheduled at a time, with configurable global concurrency.
- SMTP probes to the same domain are serialized to avoid recipient-server rate limits.
- Once a domain is confirmed catch-all, that result is reused for later addresses at the same domain.
- An unreachable provider is probed once per run and then reused as
unknownfor that domain. - No browser is used; the Actor runs at 256 MB.
- SMTP uses the run's Apify HTTP proxy as an authenticated
CONNECTtunnel; no separate verifier API is required. Known provider-controlled MX zones use hostname routing for proxy compatibility, while other MX destinations are pinned to a locally validated public IP to block private-network probes. - Pay per result with volume tiers, from $0.60 per 1,000 results at GOLD.
Compared with michael.g/email-verifier-validator
| Capability | Thirdwatch | michael.g |
|---|---|---|
| Syntax, MX, SMTP reachability | Yes | Yes |
| Catch-all, disposable, role, free-provider, plus-tag | Yes | Yes |
good/risky/bad + technical status + score | Yes | Yes |
| Full normalized verification payload | Yes | Yes |
| A-record mail fallback | Yes | Documented in detailed output |
| SPF / DKIM / DMARC health | Optional, included | Not surfaced in public schema |
| Raw SMTP response code, host, and latency | Included | Not surfaced in public schema |
| No external API key | Yes | Yes |
| Lowest paid tier | $0.50/1K | $0.60/1K |
The output's top-level parity fields intentionally match the established integration contract, while the nested evidence and retained v1 field names make results easier to audit and migrate.
Common workflows
- clean Apollo, Clay, CRM, or scraped lead lists before outreach;
- reject malformed and disposable signup addresses;
- route
riskycatch-all/role addresses to manual review; - suppress definitive SMTP rejections before a campaign;
- monitor stored contacts for dead domains or disabled mailboxes;
- audit SPF, DKIM, and DMARC across a partner or vendor list;
- call the Actor from Make, Zapier, n8n, Airbyte, Google Sheets, or an MCP client.
Migration from v1
Version 2 changes the primary status values from valid/invalid/risky/unknown to the competitor-compatible business values good/risky/bad. Use technical_status for the technical result. This is a contract migration, not a drop-in backward-compatible change.
The v1 camelCase field names remain present: syntaxValid, mxFound, mxHost, isDisposable, isRole, isFreeProvider, domainHealth, smtpCheck, mailboxExists, and confidence. Their SMTP-informed semantics or types can differ from v1: smtpCheck now contains a probe state instead of always blocked; mailboxExists can be a boolean or the string unknown; confidence aliases the new score; and mxFound is restricted to literal MX presence. Prefer mailInfrastructureFound, mailInfrastructureStatus, domainHealthChecked, and the new parity fields in new integrations.
For workflows that need the old deterministic behavior, set smtpCheck to false; such mail-capable addresses return status: risky, technical_status: unknown, and reason: smtp_not_checked because mailbox existence was not tested.
Responsible use
Verify addresses you are legally permitted to process. Follow applicable privacy and anti-spam law, keep retention proportionate, and do not interpret verification as consent to send. The Actor performs only an SMTP envelope check and never transmits message content.
Support
For questions or edge cases, open an issue on the Actor page or contact Thirdwatch at thirdwatch.dev.
Last verified: 2026-08