# Email Verifier - Bulk Email Validation & List Cleaning API (`appdata-labs/email-verifier`) Actor

Verify and clean bulk email lists: syntax, domain and MX checks, 8,700+ disposable providers, role accounts, free-mailbox detection and typo correction that recovers gmial.com as gmail.com. Every row says exactly what was checked and what was not.

- **URL**: https://apify.com/appdata-labs/email-verifier.md
- **Developed by:** [Kobkoon Janngam](https://apify.com/appdata-labs) (community)
- **Categories:** Agents, MCP servers, Lead generation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 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.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Email Verifier — bulk validation that tells you what it actually checked

**Clean an email list before you send to it.** Syntax, domain, MX records, 8,700+ disposable providers, role accounts, free mailboxes — and typo correction that turns `user@gmial.com` back into a reachable person instead of a rejection.

**Quick start:** press **Start** with no configuration at all. It ships with a demo list that reaches every verdict the Actor can produce, so one run shows you the whole output shape.

### Sample output

| normalizedEmail | status | confidence | isDisposable | isRoleAccount | didYouMean | reason |
|---|---|---|---|---|---|---|
| jane@vercel.com | risky | 65 | false | false | | Domain accepts mail via mx.vercel.com. The mailbox itself was not checked. |
| sales@stripe.com | risky | 50 | false | true | | Domain accepts mail via aspmx.l.google.com (role account). |
| test@mailinator.com | undeliverable | 5 | true | false | | Disposable or temporary address provider. |
| user@gmial.com | undeliverable | 5 | true | false | gmail.com | Disposable provider. Did you mean user@gmail.com? |
| nobody@nosuchdomain-xyz.com | undeliverable | 2 | false | false | | Domain does not exist. |

Every row also carries `email`, `local`, `domain`, `isValidSyntax`, `isFreeProvider`, `domainExists`, `acceptsMail`, `mxHost`, `mxCount`, `smtpChecked`, `smtpReason` and `mailboxExists`.

### Why this one

**It does not pretend to have checked things it did not check.** Every verifier on this Store advertises live SMTP validation. Outbound port 25 is blocked by default on most cloud hosts, so a hosted verifier either is not doing it or is not saying where from. This Actor treats that as a field, not a footnote: `smtpChecked` says whether the mail server was actually asked, `smtpReason` says what stopped it, and **a mailbox that was never confirmed is never labelled deliverable**. It comes back `risky`, with the reason spelled out.

That sounds like a weaker claim than the competition makes. It is a more useful one. A list marked "95% deliverable" that then bounces costs you your sending reputation; a list that tells you which 60% is proven and which 35% is merely plausible lets you decide.

**Typos are recovered, not just rejected.** `gmial.com`, `hotmial.com`, `yahooo.com` — a bounded edit-distance match against the twenty domains people actually mistype. A typo'd address is a real person you can still reach, and every other verifier throws them away. Suggestions are only offered for domains that do not accept mail, so a legitimate company domain is never "corrected" into Gmail.

**Duplicates are removed before you are charged.** A list pasted out of a CRM is routinely a third duplicates, and case and whitespace variants of the same address are the same address.

### What you can do with it

- **Clean a scraped lead list.** Point it at the output of any contact scraper and turn `onlyDeliverable` on — you are charged per row returned, so filtering is genuinely cheaper, not just tidier.
- **Protect a sending domain.** `excludeRoleAccounts` removes the `info@` and `abuse@` addresses that get senders blocklisted.
- **Sharpen a B2B list.** `excludeFreeProviders` drops Gmail and Outlook signups, which tell you nothing about where someone works.
- **Catch form typos.** Run it on signups and use `didYouMean` to ask the user rather than losing the account.
- **Feed an AI agent.** Rows are under 600 bytes and always the same shape, and every verdict carries a plain-language `reason` a model can quote back.

### Input

| Field | Default | Notes |
|---|---|---|
| `emails` | 13 demo addresses | Plain addresses or pasted `Name <a@b.com>` form. Deduplicated before charging. |
| `checkMailbox` | `false` | Opens an SMTP conversation and asks whether the mailbox exists. Honest about whether it worked. |
| `onlyDeliverable` | `false` | Drops undeliverable rows before charging. |
| `excludeRoleAccounts` | `false` | Drops `info@`, `sales@`, `support@` and ~40 others. |
| `excludeFreeProviders` | `false` | Drops Gmail, Yahoo, Outlook and similar. |
| `concurrency` | `10` | Parallel lookups. DNS resolvers start refusing above about thirty. |

### How the verdict is reached

| status | means |
|---|---|
| `deliverable` | The mail server accepted the address. Only reachable with `checkMailbox` on and port 25 open. |
| `risky` | The domain exists and accepts mail; this mailbox is unproven. |
| `undeliverable` | Bad syntax, dead domain, no MX record, disposable provider, or the server rejected it. |

`confidence` is a 0–100 companion to `status`, so you can set your own threshold rather than trusting ours.

### Limits worth knowing before you buy

**Without `checkMailbox`, nothing can be `deliverable`** — that is the design, not a gap. With it on, the result depends on whether the run's host can reach port 25 and whether the receiving server answers honestly; many large providers greylist or accept everything, and a server that accepts everything is reported as unproven rather than as a pass.

The disposable-domain list is a dated snapshot, recorded in every run's summary. New throwaway providers appear constantly and no list is ever complete.

This checks whether an address can receive mail. It does not tell you whether the person still works there, and it is not a substitute for permission to contact them.

### Pricing

Pay per address returned, after filtering. Nothing is charged for duplicates or for rows your filters removed.

### Disclaimer

This Actor performs standard DNS lookups and, when asked, a standard SMTP
conversation — both public internet protocols, used exactly as specified. It
scrapes no website, calls no third-party API, and stores no address after the
run. There is no `robots.txt` to respect because no website is involved.

The disposable-domain list is derived from the public
`disposable-email-domains` project, released under CC0 1.0 (public domain).

Verifying an address tells you it can receive mail. It says nothing about
whether you are permitted to contact the person behind it — that is your
responsibility under GDPR, CAN-SPAM and the equivalent rules in your market.

# Actor input Schema

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

The addresses to check. Pasted forms such as "Jane Doe <jane@acme.com>" are accepted and unwrapped, and duplicates are removed before anything is charged.

## `checkMailbox` (type: `boolean`):

Off by default. When on, the Actor opens an SMTP conversation with the domain’s mail server and asks whether it would accept mail for the address. Cloud hosts commonly block outbound port 25 — when that happens the run says so in smtpChecked and smtpReason rather than guessing.

## `onlyDeliverable` (type: `boolean`):

Drops anything judged undeliverable — bad syntax, dead domains, no MX, disposable providers. You are only charged for rows returned, so this is also the cheapest way to clean a large list.

## `excludeRoleAccounts` (type: `boolean`):

Removes info@, sales@, support@ and about forty other function addresses. They rarely bounce and rarely reply, and cold outreach to them is what gets a sending domain blocklisted.

## `excludeFreeProviders` (type: `boolean`):

Removes Gmail, Yahoo, Outlook and similar. Useful for B2B lists, where a personal mailbox tells you nothing about where someone works.

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

How many lookups run in parallel. Higher is faster on large lists; DNS resolvers start refusing above about thirty.

## Actor input object example

```json
{
  "emails": [
    "jane@acme.com",
    "Jane Doe <jane@acme.com>"
  ],
  "checkMailbox": false,
  "onlyDeliverable": false,
  "excludeRoleAccounts": false,
  "excludeFreeProviders": false,
  "concurrency": 10
}
```

# Actor output Schema

## `rows` (type: `string`):

One row per address: status, confidence, the reason behind the verdict, and every individual check that produced it.

## `summary` (type: `string`):

Counts by status, how many were removed by each filter, and whether the SMTP check was actually possible.

# 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": [
        "someone@gmail.com",
        "sales@stripe.com",
        "info@apify.com",
        "jane.doe@shopify.com",
        "hello@notion.so",
        "support@github.com",
        "test@mailinator.com",
        "temp@guerrillamail.com",
        "user@gmial.com",
        "someone@hotmial.com",
        "nobody@nosuchdomain-xyz-98765.com",
        "not-an-email",
        "Jane Doe <jane@vercel.com>"
    ],
    "checkMailbox": false,
    "onlyDeliverable": false,
    "excludeRoleAccounts": false,
    "excludeFreeProviders": false,
    "concurrency": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("appdata-labs/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": [
        "someone@gmail.com",
        "sales@stripe.com",
        "info@apify.com",
        "jane.doe@shopify.com",
        "hello@notion.so",
        "support@github.com",
        "test@mailinator.com",
        "temp@guerrillamail.com",
        "user@gmial.com",
        "someone@hotmial.com",
        "nobody@nosuchdomain-xyz-98765.com",
        "not-an-email",
        "Jane Doe <jane@vercel.com>",
    ],
    "checkMailbox": False,
    "onlyDeliverable": False,
    "excludeRoleAccounts": False,
    "excludeFreeProviders": False,
    "concurrency": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("appdata-labs/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": [
    "someone@gmail.com",
    "sales@stripe.com",
    "info@apify.com",
    "jane.doe@shopify.com",
    "hello@notion.so",
    "support@github.com",
    "test@mailinator.com",
    "temp@guerrillamail.com",
    "user@gmial.com",
    "someone@hotmial.com",
    "nobody@nosuchdomain-xyz-98765.com",
    "not-an-email",
    "Jane Doe <jane@vercel.com>"
  ],
  "checkMailbox": false,
  "onlyDeliverable": false,
  "excludeRoleAccounts": false,
  "excludeFreeProviders": false,
  "concurrency": 10
}' |
apify call appdata-labs/email-verifier --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,appdata-labs/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/zkC0518OflqRQj9Vk/builds/Nj7SlhsHzxaYsEYeM/openapi.json
