# Bulk Email Verifier - MX, Disposable, Role & Deliverability (`scrapesage/bulk-email-verifier`) Actor

Clean an email list before you send. Get MX deliverability, disposable and role flags, provider ID, typo fixes and an optional SMTP check as a status and 0-100 score.

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

## Pricing

from $1.10 / 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 - MX, Disposable, Role & Deliverability

Clean an email list before you send. Paste or upload addresses and get, for each one, whether the
format is valid, whether the domain can actually receive mail (MX), whether it is a disposable or
role-based address, which mail provider runs it, and a likely-typo suggestion - plus a single
`status` and a 0-100 confidence `score` you can sort and filter on.

No browser, no proxy, no anti-bot target: every check is DNS plus local logic, so runs finish in
seconds and cost a fraction of a cent per address.

### What each check means (read this - it is honest about the limits)

| Field | What it tells you |
|---|---|
| `status` | `deliverable` · `risky` · `undeliverable` · `unknown` - the headline verdict |
| `score` | 0-100 confidence, combining every signal below |
| `formatValid` | The address passes RFC-shaped syntax and length rules |
| `mxFound` / `mxHost` | The domain publishes an MX (or A) record, so it **can receive mail**, and the primary mail host |
| `mailProvider` | Who runs the mail: Google Workspace, Microsoft 365, Zoho, Proton, Proofpoint, and more |
| `isDisposable` | The domain (or its MX operator) is a throwaway/temporary-mail service |
| `isRoleBased` | A shared address like `info@`, `support@`, `sales@` - not a specific person |
| `isFreeProvider` | A consumer mailbox (gmail, outlook, yahoo, ...) |
| `didYouMean` | A likely typo fix, e.g. `user@gmial.com` -> `user@gmail.com` |
| `normalizedEmail` | Canonical form for de-duping (gmail dots and `+tags` removed) |
| `smtpChecked` / `smtpAccepted` | Optional: the result of a live mailbox handshake (see below) |

**About mailbox-level verification.** Confirming that a *specific mailbox* exists needs a live SMTP
handshake on port 25, which most cloud platforms (Apify included) block to prevent abuse. So by
default this actor verifies **domain-level deliverability and address hygiene** - a `deliverable`
result means the address is well-formed and its domain accepts mail and is not disposable or
role-based, which is exactly what you need to cut bounces from a list. Turn on **Attempt SMTP mailbox
check** to try the handshake anyway: where the platform allows it, results are upgraded to a confirmed
mailbox; where it does not, they degrade silently to the DNS verdict and nothing fails.

### Input

```json
{
  "emails": ["jane.doe@gmail.com", "info@acme.com", "hello@mailinator.com"],
  "smtpCheck": false,
  "maxItems": 1000
}
```

- **Emails** - one per line. Or leave empty to get a small free sample.
- **Import emails from a file** - paste a whole list, or link a public `.txt`/`.csv`, a Google
  Sheet/Drive share link, or an Apify key-value-store record. Blank lines, `#` comments, quotes and
  extra CSV columns all parse.
- **Output fields** - tick only the fields you want for a lean CSV/Sheets export.

### Output (one row per address)

```json
{
  "email": "info@acme.com",
  "status": "risky",
  "score": 70,
  "formatValid": true,
  "mxFound": true,
  "mxHost": "aspmx.l.google.com",
  "mailProvider": "Google Workspace",
  "isDisposable": false,
  "isRoleBased": true,
  "isFreeProvider": false,
  "didYouMean": null,
  "reason": "role-based address (not a specific person)"
}
```

### Use with AI assistants (MCP)

This actor is available through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp),
so an AI assistant or agent can call it as a tool - hand it a list of addresses and get back a clean,
scored dataset it can act on (drop the undeliverables, flag the disposables, keep the deliverables).

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** - AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** - an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) - no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** - agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### Notes

- Verification is based on public DNS and address structure; a `deliverable` result reduces bounce
  risk but is not a guarantee that a person reads the mailbox.
- Disposable and role lists are maintained inside the actor and matched against the live MX host, so
  vanity domains that resolve to a throwaway provider are still caught.

# Actor input Schema

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

Email addresses to verify, one per line. Duplicates are collapsed and addresses are lower-cased. <b>Leave empty and the run returns a small free sample</b> so you can see the output shape at no cost.

## `emailsFromFile` (type: `string`):

Bulk-load addresses. Either <b>paste the whole list</b> (one per line or comma-separated), or give <b>a single link</b> to a public <code>.txt</code>/<code>.csv</code>, a Google Sheet or Drive share link, or an Apify key-value-store record. Blank lines, <code>#</code> comments, CRLF, a UTF-8 BOM, quotes and extra CSV columns all parse. A file that cannot be read stops the run with a clear message and charges nothing.

## `smtpCheck` (type: `boolean`):

Additionally try a live SMTP handshake to confirm the specific mailbox exists. <b>Most cloud platforms block outbound SMTP (port 25)</b>, so this is best-effort: when it is available it upgrades a result to a confirmed mailbox, and when it is not it degrades silently to the DNS/MX verdict. It never fails a row. Leave off for the fastest run.

## `concurrency` (type: `integer`):

How many addresses to check in parallel. DNS checks are light, so 20 is a good default; lower it only if you enable the SMTP check against a strict mail host.

## `outputFields` (type: `array`):

Pick the fields you want and every record is trimmed to exactly those - handy for lean CSV/Sheets exports. <b>Nothing to memorise:</b> open the dropdown and tick, or start typing (<code>status</code>, <code>mx</code>, <code>disposable</code>) to filter.

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

Maximum number of addresses to verify in one run (after de-duplication).

## Actor input object example

```json
{
  "emails": [
    "support@apify.com",
    "jane.doe@gmail.com",
    "hello@mailinator.com"
  ],
  "smtpCheck": false,
  "concurrency": 20,
  "maxItems": 1000
}
```

# Actor output Schema

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

Each scraped record - email addresses verified (DNS/MX + syntax) - as a JSON item in the default dataset.

# 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": [
        "support@apify.com",
        "jane.doe@gmail.com",
        "hello@mailinator.com"
    ],
    "emailsFromFile": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/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": [
        "support@apify.com",
        "jane.doe@gmail.com",
        "hello@mailinator.com",
    ],
    "emailsFromFile": "",
}

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

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).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": [
    "support@apify.com",
    "jane.doe@gmail.com",
    "hello@mailinator.com"
  ],
  "emailsFromFile": ""
}' |
apify call scrapesage/bulk-email-verifier --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapesage/bulk-email-verifier"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/mmhEofF5FvJ6b7vie/builds/hJnoEEDh9PrXB8nDA/openapi.json
