# Bulk Email Verifier — Validate Emails, MX, Disposable & Role (`bovi/bulk-email-verifier`) Actor

Validate a list of emails fast. Per address: syntax, MX/DNS check, disposable & role detection, free-provider flag, and a typo suggestion (gmial.com -> gmail.com). One clean record per email, de-duplicated. Pay per email.

- **URL**: https://apify.com/bovi/bulk-email-verifier.md
- **Developed by:** [Vitalii Bondarev](https://apify.com/bovi) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.87 / 1,000 email-verifieds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Bulk Email Verifier

Clean and validate a list of email addresses in bulk. For every address you get one
structured record: is the syntax valid, does the domain actually accept mail (MX/DNS),
is it a disposable or free-provider address, is it a role account (`info@`, `support@`…),
and — if the address has an obvious typo — a suggested correction
(`john@gmial.com` → did you mean `gmail.com`).

Built for lead-list hygiene: drop the junk before you import into your CRM or send a
campaign, so you protect your sender reputation and stop paying to email dead addresses.

### What you get per email

| Field | Meaning |
|-------|---------|
| `email` | The normalised address (trimmed, lower-cased domain). |
| `result` | Overall verdict: `valid`, `invalid`, `risky`, or `unknown`. |
| `reason` | Short machine-readable reason behind the verdict. |
| `isValid` | `true` when syntax is correct **and** the domain has mail records. |
| `syntaxValid` | Address passes RFC-style syntax checks. |
| `domain` | The domain part of the address. |
| `mxFound` | The domain publishes MX (or fallback A) records — it can receive mail. |
| `mxRecord` | The primary mail host found for the domain. |
| `isFreeProvider` | Address is on a free webmail provider (gmail, yahoo, outlook…). |
| `isDisposable` | Address is on a throwaway / temporary-mail provider. |
| `isRoleAccount` | Local part is a role address (`info`, `admin`, `support`, `sales`…). |
| `didYouMean` | Suggested domain correction when a likely typo is detected. |
| `smtpCheck` | Optional best-effort mailbox check: `deliverable`, `undeliverable`, `unknown`, or `skipped` (when not requested). |

### Input

```json
{
  "emails": [
    "ceo@stripe.com",
    "info@gmail.com",
    "john@gmial.com",
    "user@mailinator.com"
  ],
  "checkSmtp": false,
  "timeout": 8,
  "maxItems": 0
}
```

- **emails** *(required)* — the addresses to verify. Duplicates are removed automatically,
  so you are never charged twice for the same address.
- **checkSmtp** *(default `false`)* — also attempt a live SMTP mailbox probe. This is
  best-effort only: many mail hosts and networks block this kind of check, in which case
  the address keeps its syntax/MX/heuristic verdict and `smtpCheck` is `unknown`. Slower.
- **timeout** *(default `8`)* — seconds to wait for DNS (and SMTP, if enabled) per email.
- **maxItems** *(default `0`)* — cap on emails verified in one run; `0` means no cap.

### Pricing

Pay per verified email. Deduplication means repeated addresses in your list are charged
once. Syntax and heuristic checks are instant; MX/DNS lookups add a fraction of a second
per unique domain.

### Notes

- The verifier does **not** send any email and does not require a proxy — it only reads
  public DNS records (and, when enabled, performs a standard SMTP handshake without
  delivering a message).
- A `risky` result flags addresses that are technically deliverable but lower quality
  (role accounts, disposable domains) so you can decide whether to keep them.

# Actor input Schema

## `emails` (type: `array`):

The email addresses to verify. Duplicates are removed automatically (you are not charged twice for the same address).

## `checkSmtp` (type: `boolean`):

Also attempt a live SMTP mailbox check. Best-effort only — many mail servers and networks block this, in which case the address keeps its syntax/MX/heuristic verdict and smtpCheck is 'unknown'. Slower when enabled.

## `timeout` (type: `integer`):

Max seconds to wait for DNS (and SMTP, if enabled) per email.

## `maxItems` (type: `integer`):

Cap on emails verified in one run. 0 = no cap (verify all).

## Actor input object example

```json
{
  "emails": [
    "ceo@stripe.com",
    "info@gmail.com",
    "john@gmial.com",
    "user@mailinator.com"
  ],
  "checkSmtp": false,
  "timeout": 8,
  "maxItems": 0
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset of email records (email, result, reason, isValid, syntaxValid, domain, mxFound, mxRecord, isFreeProvider, isDisposable, isRoleAccount, didYouMean, smtpCheck).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "emails": [
        "ceo@stripe.com",
        "info@gmail.com",
        "john@gmial.com",
        "user@mailinator.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bovi/bulk-email-verifier").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "emails": [
        "ceo@stripe.com",
        "info@gmail.com",
        "john@gmial.com",
        "user@mailinator.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("bovi/bulk-email-verifier").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "emails": [
    "ceo@stripe.com",
    "info@gmail.com",
    "john@gmial.com",
    "user@mailinator.com"
  ]
}' |
apify call bovi/bulk-email-verifier --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=bovi/bulk-email-verifier",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/PJvZolGOy5bniuria/builds/MNEX2C0Vc2MaWH6wl/openapi.json
