# Bulk Email Verifier - MX, Disposable & Typo Detection (`nonstop-greed/bulk-email-verifier`) Actor

Clean email lists at scale: syntax, MX/DNS deliverability, disposable domains, role accounts and typo correction. Honest confidence scoring.

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

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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 & Typo Detection

Clean an email list before you send to it. Paste addresses or point the Actor at a file, and get back a per-address verdict: which are safe to send to, which will bounce, which are throwaway signups, and which are simple typos you can fix instead of discard.

Built for lead lists exported from Apollo, LinkedIn, Hunter, a CRM, or a signup form.

### What it checks

| Check | What you get |
|---|---|
| **Syntax** | Malformed addresses caught before they cost you a bounce |
| **Domain / MX** | Live DNS lookup. Domains that cannot receive mail at all are flagged `undeliverable` |
| **Disposable** | 8,000+ throwaway providers (mailinator, 10minutemail, …), from a maintained public blocklist, updated with each release |
| **Typos** | `gmial.com` → `gmail.com`, `yahoo.co` → `yahoo.com`. Returns a corrected address so you can **recover** the lead instead of deleting it |
| **Role accounts** | `info@`, `sales@`, `support@` — deliverable, but not a person. Flagged separately so you can decide |
| **Free providers** | Gmail/Yahoo/Outlook marked, useful when you only want business addresses |

Every address gets a `safe_to_send` boolean and a `confidence` score. Duplicates are removed automatically, and Gmail's dot/plus aliases (`john.doe+news@gmail.com`) are folded so you don't pay twice for the same mailbox.

### What it does *not* do — read this before you buy

**This Actor does not open an SMTP connection to confirm an individual mailbox exists.** Neither does any other Actor on Apify: the platform blocks outbound port 25, which is what an SMTP probe requires.

So when a tool here reports an address as "verified" or "deliverable" with 99% certainty, that number did not come from checking the mailbox. We would rather tell you exactly what we proved:

- `undeliverable`, `disposable`, `invalid_syntax`, `typo_suspected` — **high confidence.** These are decided by DNS and syntax, which are authoritative. This is the bulk of what is actually wrong with a real list.
- `deliverable_domain` — the domain accepts mail; whether that specific mailbox exists is **unknown**. The field `mailbox_verified` is always `false`, because it never was.

For most lists the difference doesn't matter: typos, dead domains and disposables are the overwhelming majority of bad addresses. And for Gmail, Outlook and Yahoo an SMTP probe wouldn't help anyway — they accept-all at the RCPT stage and reveal nothing.

If you need per-mailbox confirmation, use a service that operates its own mail infrastructure. If you need a list cleaned of everything that is provably bad, this is faster and far cheaper.

### Input

Any one of these:

- **Paste** addresses into the text box — one per line, or separated by commas/semicolons/spaces
- **JSON array** via `emails`, when calling from the API
- **File URL** via `fileUrl` — a public `.txt` or single-column `.csv` link (a header row named `email` is skipped)

```json
{
  "emailsText": "john.doe@gmail.com\ninfo@apify.com\nsomeone@gmial.com",
  "concurrency": 50
}
```

### Output

One row per input address, in the order you supplied them:

```json
{
  "email": "someone@gmial.com",
  "normalized": "someone@gmial.com",
  "domain": "gmial.com",
  "status": "typo_suspected",
  "reason": "domain looks like a misspelling of gmail.com",
  "suggestion": "someone@gmail.com",
  "confidence": 88,
  "safe_to_send": false,
  "disposable": false,
  "role_account": false,
  "free_provider": false,
  "mailbox_verified": false
}
```

Statuses: `deliverable_domain`, `role_account`, `undeliverable`, `disposable`, `typo_suspected`, `invalid_syntax`, `unknown`.

`unknown` means the DNS lookup timed out — the address is not condemned, just unresolved. Re-run those, or raise **DNS timeout** in the input.

### Pricing

**Free.** There is no per-address fee and no markup on top of it — you pay only the Apify platform compute your own run consumes, which for this Actor is a fraction of a cent per thousand addresses.

For comparison, verifying 100,000 addresses costs roughly two cents of compute here. Paid alternatives on this Store charge between $0.00089 and $0.10 per address for the same category of checks.

Duplicates are removed before any work is done, so you never pay compute for the same mailbox twice.

### Speed

Roughly 300 addresses/second on a list of entirely distinct domains, and over 1,000/second on typical lead lists, where many contacts share the same company domain — results are cached per domain within a run, so a 5,000-contact export from one company costs one DNS lookup, not 5,000.

### Common uses

- Cleaning a cold-outreach list before import, to protect sender reputation
- Filtering disposable signups out of a product's user table
- Recovering mistyped addresses from a webform instead of losing the lead
- Splitting business addresses from personal ones for B2B campaigns

### FAQ

**Will this stop my emails bouncing?**
It removes the addresses that are provably undeliverable, which is where most bounces come from. It cannot promise a zero bounce rate — nothing that doesn't own mail infrastructure can.

**Why is `confidence` 70 for a good address?**
Because the domain was confirmed and the mailbox was not. We don't inflate that number.

**Do you keep my list?**
Results go to your own dataset on your account. The Actor sends your addresses to no third party; the only outbound traffic is DNS queries for the domains.

# Actor input Schema

## `emailsText` (type: `string`):

Paste addresses here - one per line, or separated by commas/semicolons/spaces.

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

Same as above, as a JSON array. Useful when calling this Actor from the API.

## `fileUrl` (type: `string`):

Public link to a plain-text or single-column CSV file of addresses. Rows are read as text; a header row named 'email' is skipped automatically.

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

Raise for very large lists, lower if your DNS resolver rate-limits you.

## `dnsTimeoutSecs` (type: `integer`):

Per-nameserver timeout. Lower values finish faster but mark more slow domains as 'unknown'.

## Actor input object example

```json
{
  "emailsText": "john.doe@gmail.com\ninfo@apify.com\ntest@mailinator.com\nsomeone@gmial.com",
  "concurrency": 50,
  "dnsTimeoutSecs": 2
}
```

# 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 = {
    "emailsText": `john.doe@gmail.com
info@apify.com
test@mailinator.com
someone@gmial.com`
};

// Run the Actor and wait for it to finish
const run = await client.actor("nonstop-greed/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 = { "emailsText": """john.doe@gmail.com
info@apify.com
test@mailinator.com
someone@gmial.com""" }

# Run the Actor and wait for it to finish
run = client.actor("nonstop-greed/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 '{
  "emailsText": "john.doe@gmail.com\\ninfo@apify.com\\ntest@mailinator.com\\nsomeone@gmial.com"
}' |
apify call nonstop-greed/bulk-email-verifier --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/783ASClvsLqFVr52S/builds/svVwgUwcO5fEjXV9H/openapi.json
