Bulk Email Verifier & Validator โ Automation-Ready Results
Pricing
from $1.20 / 1,000 email verification results
Bulk Email Verifier & Validator โ Automation-Ready Results
Verify email addresses in bulk with clear, automation-ready results. Get valid/invalid/inconclusive outcomes, proceed/hold/suppress recommendations, reason codes, risk flags, deduplication, and optional in-place enrichment for lead records and Apify Datasets.
Pricing
from $1.20 / 1,000 email verification results
Rating
0.0
(0)
Developer
Emiliano Mastragostino
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Verify email addresses in bulk and get clear, automation-ready results.
Bulk Email Verifier & Validator checks email syntax, domain mail infrastructure, and mailbox-level signals to classify addresses before they enter outreach, a CRM, or another automation.
Provide one email or a bulk list and get structured results with a technical verdict, a proceed / hold / suppress recommendation, stable reason codes, retryability, and explicit risk flags.
Already have leads in Apify? You can also verify emails directly inside lead records or an Apify Dataset. The Actor preserves every original field and appends an emailVerification result โ no extracting emails, correlating responses, or joining data back together.
โ๏ธ What can Bulk Email Verifier & Validator do?
- Verify one or thousands of email addresses using the same simple
emailsinput. - Check syntax and domain mail infrastructure before mailbox verification.
- Perform mailbox-level verification when an address passes local checks.
- Return a clear technical result:
valid,invalid,inconclusive, ornot_performed. - Return an automation-ready recommendation:
proceed,hold, orsuppress. - Explain every result with a stable, machine-readable
primaryReason. - Flag catch-all, disposable, role-based, and free-provider addresses.
- Distinguish uncertainty from errors instead of forcing every address into valid/invalid.
- Deduplicate emails within a run so repeated addresses are verified and billed only once.
- Write results incrementally during bulk runs.
- Verify emails inside inline lead records or Apify Datasets while preserving the original row context.
- Use results through the Apify API, webhooks, schedules, Make, Zapier, n8n, Google Sheets, and other integrations.
๐ฏ Why use this bulk email verifier?
Automation-ready results
A simple valid or invalid flag is often not enough for automated workflows.
Every processed address gets both a technical result and a practical recommendation:
| Verification result | Recommendation | Typical meaning |
|---|---|---|
valid | proceed | Evidence supports using the address |
invalid | suppress | Do not use the address |
inconclusive | hold | Available evidence cannot safely confirm or reject it |
not_performed | hold or suppress | Verification could not or should not be performed |
Your workflow can branch directly on recommendation, while primaryReason, retryable, risk flags, and diagnostics remain available when you need more detail.
Conservative handling of uncertainty
The Actor does not turn ambiguous evidence into false certainty.
For example, a catch-all domain may accept mail for addresses that do not actually exist. In that case, the individual mailbox cannot be confirmed, so the result is reported as:
{"verificationResult": "inconclusive","recommendation": "hold","primaryReason": "catch_all"}
Similarly, provider failures are reported as errors rather than disguised as verification uncertainty.
Predictable bulk verification
Bulk runs are designed to behave safely in automation:
- the same normalized email is verified once per run;
- duplicate occurrences reuse that result;
- internal retries do not create additional verification charges;
- results are written continuously rather than only at the end;
- completed results survive interrupted or aborted runs;
RUN_SUMMARYrecords what was processed, reused, billed, or left unfinished.
Built for Apify workflows
Running the verifier as an Apify Actor gives you scheduling, webhooks, API access, integrations, monitoring, and Dataset storage.
You can use it as a standalone bulk email checker or as a verification step inside a larger Apify workflow.
๐ How to verify email addresses in bulk
The simplest way to use the Actor is the emails input.
1. Add the email addresses
{"emails": ["ada@acme.com", "grace@example.com", "invalid-email"]}
One address is fine; large lists use the same input.
2. Start the Actor
Click Start. Results appear in the Output dataset incrementally while the run is still processing.
3. Use the result in your workflow
A result contains the original address plus its verification data:
{"email": "ada@acme.com","emailVerification": {"recommendation": "proceed","retryable": false,"verificationResult": "valid","primaryReason": "mailbox_verified","risk": {"catchAll": false,"disposable": false,"roleBased": false,"freeProvider": false}}}
For most automated workflows:
- use
recommendationto decide what to do; - use
verificationResultfor the technical classification; - use
primaryReasonto understand or report why; - use
retryableto decide whether trying again later could help.
๐ How email verification works
The Actor progressively verifies each address.
1. Syntax check
Malformed addresses are rejected locally.
2. Domain and mail infrastructure check
The Actor checks whether the domain exists and whether it has usable MX or other mail-routing records.
Addresses that can already be resolved at this stage do not require mailbox verification.
3. Mailbox-level verification
Addresses that survive the local checks are sent to the current mailbox-verification backend.
The Actor maps backend responses into its own stable result contract rather than exposing provider-specific statuses.
4. Automation decision
The available evidence becomes:
- a
verificationResult; - a
recommendation; - a
primaryReason; - a
retryableflag; - risk flags and diagnostics.
๐งฉ Verify emails inside lead records and Apify Datasets
If your leads are already structured records, you do not need to extract their email addresses first.
Pass the records directly:
{"records": [{"firstName": "Ada","company": "Acme","contact": {"email": "ada@acme.com"}},{"firstName": "Grace","company": "Hopper Inc","contact": {"email": "grace@hopper.test"}}],"emailField": "contact.email"}
The Actor returns each original record with an emailVerification field appended:
{"firstName": "Ada","company": "Acme","contact": {"email": "ada@acme.com"},"emailVerification": {"recommendation": "proceed","retryable": false,"verificationResult": "valid","primaryReason": "mailbox_verified"}}
The same workflow works with an existing Apify Dataset by providing its datasetId.
This avoids the usual:
extract emails โ verify emails โ correlate responses โ join results back to leads
workflow.
For the first release, record mode supports one email address per record.
๐ฅ Input
At least one input source must be supplied.
| Field | Type | Description |
|---|---|---|
emails | string[] | One or more email addresses to verify. |
records | object[] | Inline records whose email should be verified while preserving the original record. |
datasetId | string | Apify Dataset containing records to verify. Read lazily, page by page. |
emailField | string | Field containing the email in records or Dataset items. Dot paths and array indexes are supported, e.g. contact.email or contacts.0.email. |
You can combine multiple input sources in one run. They share the same deduplication scope.
Email field detection
When using records or datasetId, you can set emailField explicitly.
For example:
{"datasetId": "YOUR_DATASET_ID","emailField": "contact.email"}
If emailField is omitted, the Actor tries:
emailemailAddressemails
and uses the first value that is a plain string.
A field containing an array of emails is not guessed automatically. Record mode currently supports one address per record; split multi-email records upstream or use the emails input instead.
Invalid or missing record values
A missing, empty, or non-string email value does not cause the row to disappear.
It is emitted with an appropriate input_invalid result and is not charged.
If the supplied datasetId cannot be read, the run fails before verification or billing begins rather than silently processing an incomplete Dataset.
Very large inputs are also protected by a safety ceiling. If the limit is reached, ingestion stops explicitly and the condition is reported in the run log, run summary, and status message.
๐ค Email verification output
For the emails input, each dataset item has this structure:
{"email": "ada@acme.com","emailVerification": {"schemaVersion": 1,"recommendation": "proceed","retryable": false,"verificationResult": "valid","primaryReason": "mailbox_verified","processingState": "processed","email": {"original": "ada@acme.com","normalized": "ada@acme.com","domain": "acme.com"},"risk": {"catchAll": false,"disposable": false,"roleBased": false,"freeProvider": false},"diagnostics": {"syntaxValid": true,"domainStatus": "mx_found","mailboxSignal": "accepted","mailProvider": "aspmx.l.google.com","verificationTier": "mailbox"},"processing": {"verifiedAt": "2026-08-16T09:04:11.482Z","resultReused": false,"verificationAttempts": 1,"error": null},"source": {"type": "emails","index": 0,"occurrenceId": "emails:0"}}}
For record and Dataset inputs, the same emailVerification object is appended to the original record.
Results can be downloaded from Apify in formats including JSON, CSV, Excel, and HTML.
๐ง Understanding the verification results
Core fields
| Field | Meaning |
|---|---|
emailVerification.recommendation | proceed, hold, or suppress โ default decision for downstream automation. |
emailVerification.verificationResult | valid, invalid, inconclusive, or not_performed. |
emailVerification.primaryReason | Stable machine-readable reason explaining the result. |
emailVerification.retryable | Whether another attempt later could reasonably produce a better result. |
emailVerification.processingState | processed, input_invalid, unprocessed, or error. |
Risk flags
| Field | Meaning |
|---|---|
risk.catchAll | Domain accepts addresses broadly, preventing confirmation of the individual mailbox. |
risk.disposable | Disposable or temporary email address. |
risk.roleBased | Role address such as info@, sales@, or support@. |
risk.freeProvider | Consumer email provider. |
A null risk flag means not evaluated, not false.
For example, if an address fails syntax validation, mailbox-level risk checks are unnecessary and the corresponding flags remain null.
Diagnostics
| Field | Meaning |
|---|---|
diagnostics.syntaxValid | Local syntax validation result. |
diagnostics.domainStatus | Domain/mail-routing result. |
diagnostics.mailboxSignal | Mailbox verification signal. |
diagnostics.mailProvider | Primary MX host derived from DNS. |
diagnostics.verificationTier | Deepest verification tier that produced evidence: none, syntax, domain, or mailbox. |
Possible domainStatus values include:
mx_foundimplicit_mxnull_mxno_mail_recordsdomain_not_foundtemporary_failurenot_checked
Possible mailboxSignal values include:
acceptedrejectedambiguousnot_establishednot_checked
๐ท๏ธ Stable email verification reason codes
primaryReason is intended to be safe for downstream automation.
The Actor currently emits these reason codes:
| Code | Meaning | Result | Recommendation | Retryable | Billed |
|---|---|---|---|---|---|
mailbox_verified | Mailbox-level evidence supports validity. | valid | proceed | No | Yes |
disposable_address | Technically reachable, but disposable. | valid | suppress | No | Yes |
mailbox_rejected | Mail server permanently rejected the recipient. | invalid | suppress | No | Yes |
domain_not_found | Domain does not resolve well enough to receive mail. | invalid | suppress | No | Yes |
no_mail_infrastructure | Domain publishes no usable mail routing. | invalid | suppress | No | Yes |
invalid_syntax | Address has invalid email syntax. | invalid | suppress | No | No |
catch_all | Domain accepts broadly, so the mailbox cannot be confirmed. | inconclusive | hold | No | No |
verification_inconclusive | Evidence does not justify valid or invalid. | inconclusive | hold | No | No |
missing_email | No usable email was present. | not_performed | suppress | No | No |
invalid_email_value | Email field contained a non-string value. | not_performed | suppress | No | No |
provider_error | Verification backend failed before producing a result. | not_performed | hold | Usually yes | No |
internal_error | Actor failed while processing this item. | not_performed | hold | Yes | No |
trial_limit_reached | Free-plan mailbox-verification allowance was exhausted. | not_performed | hold | Yes | No |
Existing reason-code meanings will not change silently. New codes may be added in future schema versions.
What does inconclusive mean?
The current verification backend cannot reliably distinguish every case of greylisting, temporary SMTP behavior, or providers that deliberately prevent mailbox enumeration.
These situations are conservatively mapped to:
{"verificationResult": "inconclusive","primaryReason": "verification_inconclusive","recommendation": "hold","retryable": false}
The Actor does not claim that re-running such an address is likely to improve the result.
โป๏ธ Bulk deduplication
The same normalized email address is verified once per run.
If it occurs multiple times:
- every input occurrence still receives its own output;
- later occurrences reuse the original verification;
processing.resultReusedistrue;- the original
verifiedAttimestamp is preserved; - the verification is billed only once.
Deduplication is intentionally conservative.
Domains are normalized by lower-casing and punycoding, but local parts are not merged case-insensitively.
Therefore:
John@example.comjohn@example.com
are treated as different addresses.
Plus tags are also preserved:
ada@acme.comada+newsletter@acme.com
are distinct verification identities.
Deduplication applies within one run, not across separate runs.
๐ Correlating bulk results with input
Output order is not guaranteed.
Some addresses can be resolved locally in milliseconds while mailbox checks take longer, so results may arrive in a different order from the input.
For emails, records, and Dataset input, every occurrence receives a stable:
emailVerification.source.occurrenceId
that is unique within the run.
For structured records, you can also correlate using your own preserved fields.
๐งฑ Lossless lead-record enrichment
When using record or Dataset mode, the Actor preserves the original record.
- Original top-level fields are copied without renaming, flattening, pruning, or type coercion.
- Nested objects and arrays remain unchanged.
- The original email field is not modified.
- The new verification result is added under
emailVerification.
If your input already contains an emailVerification field, it is preserved by moving it to:
emailVerification__source
then, if necessary:
emailVerification__source_2emailVerification__source_3...
The collision is recorded in the generated verification metadata.
If an element in records is not an object, it is preserved under sourceValue alongside the corresponding explanation.
undefined values follow normal JSON serialization behavior and are dropped; null values remain null.
๐ก๏ธ Bulk run reliability
Results are written to the output Dataset as soon as they are available.
This means an interrupted, migrated, or aborted run retains work that has already completed.
The Actor does not need to wait until the entire batch finishes before producing usable output.
๐ Run summary
Every run continuously maintains a RUN_SUMMARY record in the run's key-value store.
You can find it under:
Storage โ Key-value store โ RUN_SUMMARY
It summarizes:
- source items discovered and reached;
- unique email addresses;
- duplicate results reused;
- verification results by category;
- recommendations;
- processing and provider errors;
- billable results;
- known unprocessed items;
- reasons work was left unfinished.
This is useful for monitoring large automated runs and deciding whether anything needs attention afterward.
๐ณ Bulk email verification pricing
The Actor uses Apify pay-per-event pricing:
- a small run-start event;
- one verification event for each unique email address that produces a substantive definitive result.
Current event prices are available in the Actor's Pricing tab.
You are not charged for
- duplicate occurrences of the same address within a run;
- internal verification retries;
- syntactically invalid email addresses;
- missing, empty, or non-string email values;
- catch-all results;
- other inconclusive results;
- provider errors;
- Actor processing errors;
- rows that were never reached;
- mailbox verification declined because the free trial allowance was exhausted.
You are charged for definitive verification results
Billable outcomes currently include:
- verified mailbox;
- permanently rejected mailbox;
- domain not found;
- domain with no usable mail infrastructure.
In other words, repeated input and failed processing do not multiply verification charges.
๐ Free-plan mailbox verification trial
Mailbox-level verification has a real third-party cost.
For this reason, non-paying Apify accounts receive a capped mailbox-verification trial rather than unlimited developer-funded verification.
Local syntax and domain checks remain available regardless of the mailbox allowance.
When the allowance has been exhausted, mailbox verification is not partially performed for the remainder of the run. Affected items are returned as:
{"processingState": "unprocessed","primaryReason": "trial_limit_reached","recommendation": "hold"}
They are not charged.
Any information established by the local verification tiers is still returned.
Upgrade to a paid Apify plan to use mailbox verification at normal scale.
The trial counter stores only an Apify account identifier and aggregate counts; it does not store email addresses or domains.
๐ก Tips for email verification workflows
- Use
recommendationfor automation. It is the simplest field for branching downstream workflows. - Use
primaryReasonfor analytics and reporting. It explains why the recommendation was made. - Do not automatically treat
inconclusiveas invalid. Some real mailboxes cannot be safely verified remotely. - Verify records directly when you already have structured leads. It avoids an unnecessary extraction and join step.
- Run deduplication is automatic. You do not need to remove repeated addresses beforehand just to avoid duplicate verification charges.
- Check
RUN_SUMMARYfor large jobs. In particular, inspect known unprocessed items after interrupted or bounded runs. - Remember that deduplication is per run. Starting another run is a new verification request.
๐ Third-party email processing and privacy
Addresses that pass local syntax and domain checks are currently sent to ValidatedMails, a third-party email-verification service, for mailbox-level verification.
ValidatedMails is the Actor's current backend, not part of the public result contract.
Provider-specific status names, reason strings, scores, and identifiers are not exposed in the output. They are mapped into the backend-independent emailVerification schema documented above.
This means the verification backend can be replaced or supplemented without requiring downstream workflows to depend on provider-specific semantics.
Addresses resolved locally are never sent to the mailbox-verification provider. This includes:
- invalid syntax;
- domains that do not exist;
- domains with no usable mail infrastructure.
Input and output data are stored in your own Apify storage under normal Actor operation.
The Actor's operational logs do not contain complete email addresses.
โ FAQ
Does valid guarantee email delivery?
No.
valid means the available technical verification evidence supports treating the address as usable under this Actor's verification model.
It does not guarantee:
- future delivery;
- inbox placement;
- avoidance of a spam folder;
- sender reputation;
- ownership of the mailbox by a particular person.
Why can a real email be inconclusive?
Some email providers deliberately prevent external systems from reliably determining whether an individual mailbox exists.
This is a limitation of remote email verification itself.
The Actor represents that state as inconclusive rather than converting it to valid, invalid, or an internal error.
Can I verify an Apify Dataset directly?
Yes.
Provide its datasetId and, if necessary, the field containing the email.
The Actor reads the Dataset and returns every record with an emailVerification block appended.
๐ ๏ธ Support
Found a bug or a result that looks wrong? Please open an issue from the Actor's Issues tab.
You can also contact the developer directly at emiliano.mastra@gmail.com.