# Email Checker & Bulk Email Validator (`goldish_fireplace/email-checker`) Actor

Validate email lists in bulk: syntax, MX records, disposable, role and no-reply addresses, typo fixes. Clear verdict and score per email. DNS-only, never sends email.

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

## Pricing

from $0.70 / 1,000 checked emails

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/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

## Email Checker: Bulk Email Validator & Email List Cleaner (MX, Disposable, Role, Typos)

**Validate and clean an email list in bulk before you send.** This email validator checks syntax, MX records, disposable and throwaway domains, role and no-reply addresses, free providers and common typos, and gives each address a clear verdict (deliverable-likely, risky or invalid) with a 0 to 100 score. It uses DNS only and never sends email or connects to mailboxes. Export the clean list to CSV, Excel or JSON.

**Email Checker** cleans an email list in seconds. For every address it checks the **syntax**, whether the **domain exists and accepts email** (MX records, with the A-record fallback from RFC 5321 and "null MX" detection), whether it's a **disposable/throwaway** address, a **role** address (`info@`, `sales@`), a **free provider** (Gmail, Yahoo, Outlook...), a **no-reply** address, or a **typo** (`gmial.com` → `gmail.com`). Each email gets one clear verdict: **deliverable-likely**, **risky** or **invalid**, with a 0–100 score and a reason in plain English.

> **No SMTP probing.** This Actor **never connects to mail servers and never contacts the mailbox**. It uses DNS lookups (DNS-over-HTTPS) and curated lists only. That makes it fast, cheap, private and safe for your sender reputation, but it **cannot confirm that a specific mailbox exists** or detect catch-all domains. See the FAQ.

### What does it check?

| Check | Result field | What it means |
| --- | --- | --- |
| **Syntax** (RFC 5322 dot-atom, lengths, labels, TLD, IDN → punycode) | `valid_syntax`, `syntax_error` | Catches `john@@acme`, `john@acme`, spaces, double dots and more |
| **Domain exists** | `dns_error`, `reason_code: domain_not_found` | Domain is not registered (NXDOMAIN) |
| **Accepts email** (MX, A fallback, null MX) | `has_mx`, `mx_records`, `a_record_fallback`, `null_mx`, `accepts_mail` | Whether the domain is set up to receive mail at all |
| **Mail provider** | `mx_provider` | Google, Microsoft, Zoho, Proton, Yahoo, Mimecast, Proofpoint and more |
| **Disposable** (10,000+ domains, subdomains included) | `disposable` | Mailinator, 10minutemail, Guerrilla Mail... |
| **Role address** | `role` | `info@`, `sales@`, `support@`, `admin@`... shared inboxes |
| **No-reply** | `no_reply` | `noreply@`, `do-not-reply@`: nobody reads them |
| **Free provider** (~140 domains) | `free_provider` | Gmail, Yahoo, Outlook, GMX, Mail.ru, Yandex... |
| **Typo suggestion** | `did_you_mean` | `gmial.com`, `hotmal.com`, `yahooo.com`, `.con`, `.cmo` |
| **Sender setup** (optional) | `has_spf`, `has_dmarc` | A domain with no SPF and no DMARC is less likely to be a real business mailbox |
| **Plus tag** | `plus_tag` | `jane+news@acme.com` → `news` |

### Why use it?

- ✅ **Clear verdicts, not a wall of flags.** `deliverable-likely`, `risky` or `invalid`, plus a score and a human-readable `reason`. Filter on one column and you're done.
- ⚡ **Very fast.** DNS is looked up once per domain and cached: **1,000 emails across 60 domains in 1.7 s** in our test. No waiting on slow SMTP servers or greylisting.
- 🛡️ **Safe.** No SMTP probing, so your IP and domain never end up on blocklists, and the people on your list are never pinged.
- 📋 **Paste anything.** Accepts arrays, a pasted text blob (comma/space/newline separated), `Name <email>` and `mailto:` formats, quotes and trailing punctuation. Duplicates (case-insensitive) are removed and **not charged**.
- 🔗 **Chains with other Actors.** Point it at any dataset (for example **Website Contact Finder** results) and it reads the emails from it, including arrays of emails per row.
- 💸 **Fair billing.** You pay per unique email checked. Duplicates and emails we couldn't check because of a DNS outage are free.
- 📤 **Ready-to-use outputs.** A dataset with an **Overview** view, a `SUMMARY` record with counts, and a `DELIVERABLE` text file with just the good addresses, one per line.

### How to use Email Checker

1. Paste emails into **Emails** (or **Emails as text**), or enter a **Dataset ID** from another run.
2. Optional: mark role or free-provider addresses as **risky**, or switch off the SPF/DMARC lookups.
3. Click **Start**, then export the results as CSV, Excel or JSON, or download the `DELIVERABLE` list.

### Input example

```json
{
    "emails": ["jane@apify.com", "Support <support@hetzner.com>", "someone@gmial.com", "test@mailinator.com"],
    "checkSpfDmarc": true,
    "roleIsRisky": false,
    "freeIsRisky": false
}
```

Validate the emails found by Website Contact Finder:

```json
{ "datasetId": "<dataset ID of a Website Contact Finder run>", "datasetField": "emails" }
```

### Output example

```json
{
    "email": "jane@apify.com",
    "verdict": "deliverable-likely",
    "score": 95,
    "reason": "Domain accepts email (Google).",
    "reason_code": "ok",
    "valid_syntax": true,
    "domain": "apify.com",
    "has_mx": true,
    "mx_records": ["aspmx.l.google.com", "alt1.aspmx.l.google.com", "alt2.aspmx.l.google.com"],
    "mx_provider": "Google",
    "accepts_mail": true,
    "a_record_fallback": false,
    "null_mx": false,
    "disposable": false,
    "role": false,
    "no_reply": false,
    "free_provider": false,
    "did_you_mean": null,
    "plus_tag": null,
    "has_spf": true,
    "has_dmarc": true,
    "dns_error": null
}
```

Real results from a test run (12 inputs, 1 duplicate removed, 0.3 s):

| Email | Verdict | Score | Reason |
| --- | --- | --- | --- |
| jane@apify.com | deliverable-likely | 95 | Domain accepts email (Google). |
| john.doe@gmail.com | deliverable-likely | 90 | Domain accepts email (Google). Note: free email provider. |
| info@cloudflare.com | deliverable-likely | 80 | Domain accepts email. Note: role address (shared inbox). |
| someone@gmial.com | risky | 10 | Looks like a typo. Did you mean someone@gmail.com? |
| test@mailinator.com | risky | 10 | Disposable / throwaway email provider (mailinator.com). |
| noreply@github.com | invalid | 5 | No-reply address: messages are not read. |
| ceo@example.com | invalid | 0 | example.com publishes a "null MX": it accepts no email. |
| a@acme.con | invalid | 0 | The domain acme.con does not exist. Did you mean a@acme.com? |
| bob@this-domain-does-not-exist-xyz.com | invalid | 0 | The domain does not exist. |
| not-an-email | invalid | 0 | Not a valid email address (missing at sign). |

### Verdicts

| Verdict | When | What to do |
| --- | --- | --- |
| **deliverable-likely** | Valid syntax, domain accepts mail, not disposable or a typo | Safe to send. Role and free addresses are included but flagged |
| **risky** | Typo, disposable, A-record-only domain, unusual characters, or DNS temporarily failed | Fix the typo or review by hand before sending |
| **invalid** | Bad syntax, domain doesn't exist, domain accepts no mail (null MX / no MX and no A), no-reply | Remove from your list |

### How much does it cost?

You pay a small fixed price **per unique email checked** (see the **Pricing** tab). Platform usage is tiny (256 MB, no browser, no SMTP). Duplicates and emails that couldn't be checked because DNS failed are free. Set a maximum cost per run and the Actor stops before going over it.

### Use it from AI agents, Zapier, Make, n8n or the API

- **AI agents (MCP):** works with the [Apify MCP server](https://mcp.apify.com). Ask Claude or ChatGPT: *"Check these 200 emails and give me only the deliverable ones."*
- **No-code:** validate sign-ups or new CRM contacts in **Zapier**, **Make** or **n8n** before they reach your mailing tool.
- **API:** `POST https://api.apify.com/v2/acts/goldish_fireplace~email-checker/run-sync-get-dataset-items` with `{"emails": ["jane@acme.com"]}`.

### Limitations

- **It cannot confirm that a specific mailbox exists.** There is no SMTP check, so `typo.name@realcompany.com` can still be `deliverable-likely` if the domain accepts mail.
- **No catch-all detection.** That needs SMTP.
- **Disposable and free-provider lists are curated, not complete.** New throwaway domains appear every day; the list is updated with new versions of the Actor.
- **DNS outages.** If DNS lookups fail during a run, the affected emails are marked `risky` and not charged, so you can run them again.

### FAQ

**How do I clean an email list?** Paste the emails into **Emails as text** (or pass a dataset ID), click **Start**, then keep the rows with verdict `deliverable-likely` or download the `DELIVERABLE` file.

**Is it a free email validator?** You can try it with the free Apify plan credits. After that you pay a small fixed price per unique email checked (see the **Pricing** tab).

**Why no SMTP check?** SMTP "mailbox pinging" is slow, often blocked (port 25 is closed on most clouds), triggers greylisting, is unreliable on Gmail/Microsoft/catch-all domains, and can hurt your sender reputation. Email Checker stays on DNS and lists, which catches the problems that cause most bounces (bad syntax, dead domains, typos, throwaway addresses) instantly and safely. If you need mailbox-level verification for a high-stakes send, use a dedicated SMTP verification service on the `deliverable-likely` subset.

**Can it tell me if `jane@company.com` exists?** No. It tells you whether `company.com` accepts email and whether the address looks real. It doesn't know whether the mailbox `jane` exists.

**Does it detect catch-all domains?** No, that needs SMTP.

**Is my list stored or shared?** Only in your own Apify storage. Lookups go to public DNS-over-HTTPS resolvers (Cloudflare, with Google as a fallback) and include the **domain** only, never the full address.

**How fresh is the disposable list?** It's built from the community-maintained `disposable-email-domains` list (10,000+ domains) and updated with new versions of the Actor.

### Feedback

Spotted a wrong verdict or a missing disposable domain? Open an issue on the Issues tab.

### Related tools

- 🔎 **[Website Contact Finder](https://apify.com/goldish_fireplace/website-contact-finder)**: find emails, phones and social profiles for a list of websites, then validate them here.
- 🔗 **[Broken Link Checker](https://apify.com/goldish_fireplace/broken-link-checker)** · 📈 **[SEO Audit Crawler](https://apify.com/goldish_fireplace/seo-audit-crawler)**

# Actor input Schema

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

One email per line. "Jane Doe <jane@acme.com>", mailto: links and messy pasted lists are cleaned up automatically; duplicates are removed for free.

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

Or paste a whole column or text blob: emails separated by new lines, commas, semicolons or spaces.

## `datasetId` (type: `string`):

Check emails from another Apify dataset, e.g. the output of Website Contact Finder. Reads the fields email, emails and primaryEmail (or the field below).

## `datasetField` (type: `string`):

Field name holding the email(s) in that dataset. Leave empty to auto-detect.

## `roleIsRisky` (type: `boolean`):

Role addresses are flagged either way. Turn on for cold outreach where shared inboxes count as risky.

## `freeIsRisky` (type: `boolean`):

Free addresses are flagged either way. Turn on if you only want company addresses.

## `checkSpfDmarc` (type: `boolean`):

Also report whether the domain publishes SPF and DMARC records (a sign of a properly run mail domain).

## `maxConcurrency` (type: `integer`):

Domains looked up at once. Each domain is looked up only once per run.

## Actor input object example

```json
{
  "emails": [
    "jane@apify.com",
    "info@cloudflare.com",
    "someone@gmial.com",
    "test@mailinator.com",
    "bob@this-domain-does-not-exist-xyz.com",
    "not-an-email"
  ],
  "roleIsRisky": false,
  "freeIsRisky": false,
  "checkSpfDmarc": true,
  "maxConcurrency": 20
}
```

# Actor output Schema

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

No description

## `deliverable` (type: `string`):

No description

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

No description

# 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": [
        "jane@apify.com",
        "info@cloudflare.com",
        "someone@gmial.com",
        "test@mailinator.com",
        "bob@this-domain-does-not-exist-xyz.com",
        "not-an-email"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("goldish_fireplace/email-checker").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": [
        "jane@apify.com",
        "info@cloudflare.com",
        "someone@gmial.com",
        "test@mailinator.com",
        "bob@this-domain-does-not-exist-xyz.com",
        "not-an-email",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("goldish_fireplace/email-checker").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": [
    "jane@apify.com",
    "info@cloudflare.com",
    "someone@gmial.com",
    "test@mailinator.com",
    "bob@this-domain-does-not-exist-xyz.com",
    "not-an-email"
  ]
}' |
apify call goldish_fireplace/email-checker --silent --output-dataset

```

## MCP server setup

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

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/6nlE21Cgw91r1iBUp/builds/tejzf1BNLgYpQqgwI/openapi.json
