# Email Checker: MX, disposable and role check with a reason (`bepolabs/email-dns-check`) Actor

Paste addresses and get valid, risky or invalid for each, in plain words: throwaway domains, shared inboxes and webmail flagged.

- **URL**: https://apify.com/bepolabs/email-dns-check.md
- **Developed by:** [BEPO Labs](https://apify.com/bepolabs) (community)
- **Categories:** Lead generation, Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.80 / 1,000 email addresses

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 📧 What is Email Checker?

Built for sign-up forms, outreach sheets and newsletter audiences, this email checker gives each entry a status and a short explanation, from a broken format or a nonexistent host to a temporary service or a team alias like info@ or sales@. It reads only public DNS and never opens an SMTP connection, so your sender reputation and IP stay out of it.

- **Lead list cleanup**: drop dead domains and throwaway inboxes from scraped or bought lists before outreach
- **Bounce protection**: remove `invalid` rows before a campaign so your sending domain keeps its reputation
- **B2B filtering**: keep company addresses: `freeProvider` marks Gmail, Outlook, GMX and other webmail
- **Sign-up hygiene**: check exported sign-ups once a day from a schedule and flag throwaway accounts
- **AI agents**: let Claude or ChatGPT check addresses through MCP

![Email Checker: Bulk email validation over DNS: valid, risky or invalid per address, with the reason, MX host, throwaway and shared-inbox flags.](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/email-dns-check-hero.png)

#### ✨ Why use this Actor?

- ✅ **✅**:
- ✅ **✅**:
- ✅ **✅**:
- ✅ **✅**:
- ✅ **✅**:
- ✅ **✅**:

### 📦 What data can you get with Email Checker?

| | | |
|---|---|---|
| ✅ Valid, risky or invalid | 💬 Reason in plain words | 📮 Main MX host and count |
| 🗑️ Throwaway domain | 👥 Shared inbox (role) | 🌐 Webmail provider |
| 🛡️ SPF record | 🔒 DMARC policy |  |

### 🚀 How to use Email Checker

Email Checker works in a few clicks, no coding needed:

1. [Create a free Apify account](https://console.apify.com/sign-up) (the free plan includes 5 USD of monthly credit).
2. Open [Email Checker](https://apify.com/bepolabs/email-dns-check) and click **Try for free**.
3. Paste your addresses, one per line or comma separated.
4. Click **Start** and wait for the run to finish (most runs take seconds).
5. Download your data as JSON, CSV, Excel, XML or HTML, or send it straight to Google Sheets, Make, Zapier or your AI agent.

![How Email Checker works](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/email-dns-check-workflow.png)

### ⬇️ Input

Give `emails` in any common form: one per line, comma or space separated, with or without `mailto:`. Duplicates are checked once.

##### Only valid addresses

`onlyValid` saves and charges only valid rows; off by default, so every address gets its reason.

##### SPF and DMARC

`dnsAuth` adds the domain's mail security records; turn it off for a slightly quicker run.

##### Large lists

Each domain is looked up once, so 100,000 addresses on a few thousand domains finish in minutes.

| Field | Type | What it does | Default |
|---|---|---|---|
| **Emails** (`emails`) | array | Email addresses, one per line (commas, spaces and mailto: are fine). | `["hello@apify.com","info@example.com","t` |
| **Only valid emails** (`onlyValid`) | boolean | Off: every address gets a row with its status and reason. | `false` |
| **SPF and DMARC** (`dnsAuth`) | boolean | Add whether the domain publishes SPF and its DMARC policy (none, quarantine, reject). | `true` |

![Email Checker input form](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/email-dns-check-input.png)

#### Input example

```json
{
    "emails": [
        "hello@apify.com",
        "support@github.com",
        "jane.doe@gmail.com"
    ]
}
```

### ⬆️ Output

One row per address. `status` is valid, risky or invalid; `unknown` (free) when DNS did not answer in time. `valid` means the syntax is right and the domain takes mail; whether the mailbox itself exists only the receiving server knows, and this Actor does not ask it.

![Email Checker output table](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/email-dns-check-output.png)

#### Output example

Download as JSON, CSV, Excel, XML or HTML.

```json
{
    "email": "sales@stripe.com",
    "status": "risky",
    "reason": "role address: a shared inbox, not a person",
    "syntaxValid": true,
    "domain": "stripe.com",
    "mx": "aspmx.l.google.com",
    "mxCount": 5,
    "disposable": false,
    "role": true,
    "freeProvider": false,
    "spf": true,
    "dmarc": "reject"
}
```

View the results as a table or JSON in the Output tab and download them as JSON, CSV, Excel, XML, HTML or RSS, all fields or only those you pick.

### 💰 How much does Email Checker cost?

Email Checker is priced **per event**: **0.8 USD per 1,000 emails** (0.0008 USD per email), with no monthly rental. Rows with status unknown are free.

| You get | You pay |
|---|---|
| 100 emails | 0.08 USD |
| 1,000 emails | 0.8 USD |
| 10,000 emails | 8 USD |
| 100,000 emails | 80 USD |

💡 Apify's free plan gives you 5 USD of credit every month, enough for about **6,250 emails** at no cost. Set a spending limit per run and the Actor stops there.

### ⚖️ Email Checker vs. the alternatives

| | Email Checker | SMTP verifiers | Regex in a spreadsheet |
|---|---|---|---|
| **Syntax and mail server check** | ✅ | ✅ | syntax only |
| **Throwaway and shared inboxes** | ✅ | ✅ | ❌ |
| **Reason in plain words** | ✅ | sometimes | ❌ |
| **Safe for your IP and domain** | ✅ | depends on the provider | ✅ |
| **Proves a mailbox exists** | ❌ | partly (catch-all domains hide it) | ❌ |

### 🔌 Integrations, API and MCP

#### Connect Email Checker to your AI agent (MCP)

Give Claude, ChatGPT, Cursor or any MCP client direct access to Email Checker through the [Apify MCP server](https://mcp.apify.com). Add this URL to its settings:

```text
https://mcp.apify.com/?actors=bepolabs/email-dns-check
```

For Claude Desktop, add it under `mcpServers` in `claude_desktop_config.json`:

```json
{
    "mcpServers": {
        "email-dns-check": {
            "command": "npx",
            "args": [
                "-y",
                "@apify/actors-mcp-server",
                "--actors",
                "bepolabs/email-dns-check"
            ],
            "env": {
                "APIFY_TOKEN": "<your Apify API token>"
            }
        }
    }
}
```

Then ask: *"Check these 200 lead emails and list the invalid and throwaway ones with the reason."*

#### Run it from your code

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("bepolabs/email-dns-check").call(run_input={"emails":["hello@apify.com","support@github.com","jane.doe@gmail.com"]})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

JavaScript (`npm install apify-client`):

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('bepolabs/email-dns-check').call({"emails":["hello@apify.com","support@github.com","jane.doe@gmail.com"]});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### No-code integrations

Send results to **Google Sheets, Slack, Airtable, HubSpot, Make, Zapier, n8n** and more from the Integrations tab, start runs on a **schedule**, or trigger your own endpoint with a **webhook** when a run finishes. The [Apify API](https://docs.apify.com/api/v2) gives you full control over runs and datasets.

### ❓ FAQ

##### Does it prove a mailbox exists?

No. It proves the address is well formed and its domain accepts messages. Only the receiving mail server knows whether `jane@` exists, and many domains accept everything (catch-all), so even SMTP checks guess there. Use `valid` as "safe to try", and keep bounce handling on.

##### Why is info@ risky and not invalid?

Shared inboxes usually work, but they reach a team, not a person, and are often filtered for cold outreach. The row keeps `role: true` so you decide.

##### Where does the throwaway list come from?

From the open-source disposable-email-domains list (MIT licence), about 120,000 domains plus wildcard suffixes.

##### What does unknown mean?

DNS did not answer for that domain in time. These rows are free; run them again later.

##### How long does a run take?

Each domain is looked up once with 20 lookups in parallel: a few seconds for hundreds of addresses, minutes for 100,000.

##### Is it legal to use Email Checker?

Email Checker reads only public DNS records of the domains in your list and sends no email. You are responsible for having a lawful basis (for example under GDPR or CAN-SPAM) to process and contact the addresses you check.

##### What if something is missing or does not work?

Open an issue on the **Issues** tab; we read each one and reply. Feature requests are welcome too.

### 💬 Your feedback

Tell us what Email Checker should add on the **Issues** tab or leave a review; your notes decide what we work on next.

### 🔗 Related Actors

| Actor | What it does |
|---|---|
| 📞 [Phone Number Validator](https://apify.com/bepolabs/phone-validator) | Bulk phone number validation offline: valid or not, E.164 format, country and line type (mobile, fixed line, VoIP) for every number. |
| 🏛️ [SAM.gov Contract Opportunities](https://apify.com/bepolabs/sam-gov) | US federal contract opportunities by keyword, NAICS, set-aside or agency, with deadlines, contacts and attachments. |
| 🇬🇧 [UK Tenders](https://apify.com/bepolabs/uk-tenders) | UK public contracts from Contracts Finder and Find a Tender by keyword, CPV, value, region and deadline, with daily alerts. |
| 💼 [ATS Jobs](https://apify.com/bepolabs/ats-jobs) | Every open job from company career boards on Greenhouse, Lever, Ashby, Workable, SmartRecruiters and Recruitee in one deduped feed. |
| 🌐 [Domain RDAP and DNS](https://apify.com/bepolabs/domain-rdap) | Domains to registrar, creation and expiry dates, age, status, nameservers, DNSSEC and DNS records from official RDAP, in bulk. |
| 📊 [Google Sheets Import and Export](https://apify.com/bepolabs/google-sheets) | Send any Apify dataset or JSON to a Google Sheet (append, replace or upsert by key), or read a sheet back as clean rows. |
| 🩺 [NPI Registry Lookup](https://apify.com/bepolabs/npi-registry) | US doctors, nurses, clinics and pharmacies from the official CMS NPI Registry, by specialty, name, NPI or place. |
| 📍 [OpenStreetMap Places](https://apify.com/bepolabs/osm-pois) | Shops, restaurants and offices in any city or area, with address, phone, website, opening hours and coordinates. |

# Changelog

This Actor's version history is a separate document: https://apify.com/bepolabs/email-dns-check/changelog.md

# Actor input Schema

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

Email addresses, one per line (commas, spaces and mailto: are fine). Duplicates are checked once. Up to 100,000.

## `onlyValid` (type: `boolean`):

Off: every address gets a row with its status and reason. On: only valid addresses are saved and charged.

## `dnsAuth` (type: `boolean`):

Add whether the domain publishes SPF and its DMARC policy (none, quarantine, reject).

## Actor input object example

```json
{
  "emails": [
    "hello@apify.com",
    "info@example.com",
    "test@mailinator.com"
  ],
  "onlyValid": false,
  "dnsAuth": true
}
```

# Actor output Schema

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

Dataset items, one row per result, in the overview table view.

# 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": [
        "hello@apify.com",
        "info@example.com",
        "test@mailinator.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bepolabs/email-dns-check").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": [
        "hello@apify.com",
        "info@example.com",
        "test@mailinator.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("bepolabs/email-dns-check").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": [
    "hello@apify.com",
    "info@example.com",
    "test@mailinator.com"
  ]
}' |
apify call bepolabs/email-dns-check --silent --output-dataset

```

## MCP server setup

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

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/gOc3rAU2wuKMC6kGY/builds/3Z5SulaQlfNVLDgJS/openapi.json
