# Email Verifier & Validator - MX, Syntax & Disposable Check (`teddythebuilder/email-verifier`) Actor

Bulk email validation without sending anything: syntax, domain and MX records, disposable domains (10,000+), role accounts, free providers and typo suggestions. Result status, reason and score per address. No mailbox probing. Export CSV/JSON or call via API.

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

## Pricing

from $0.55 / 1,000 email checkeds

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

### What does Email Verifier & Validator do?

Email Verifier & Validator checks a list of email addresses and tells you, for each one, whether it is worth sending to. It runs the checks that can be **proven from public data**: the syntax of the address, whether the domain exists, whether the domain publishes mail servers (MX records), whether the domain is a known disposable or throw-away provider, whether the address is a shared role account such as `info@` or `sales@`, whether it uses a free provider such as Gmail, and whether the domain looks like a typo of a popular one (`gmial.com`, `hotmial.com`, `yahho.com`).

Every address gets one row with a clear `status` (`valid`, `risky`, `invalid` or `unknown`), a machine-readable `reason`, a 0-100 `score` and the individual flags, so you can filter a list in one click and export it as CSV, Excel or JSON, or call the actor from your own code through the Apify API.

**What it does not do:** it never connects to a mail server and never sends a message. It therefore cannot tell you whether the mailbox `jane@company.com` exists on that company's server. Tools that claim to do so rely on SMTP probing, which is unreliable (many servers accept everything or block probes) and can damage the reputation of the IP address doing the probing. This actor is the safe, cheap first pass that removes the addresses that are certain to bounce or that you should not mail, before you pay for anything heavier.

### Why use Email Verifier & Validator?

- **Cut hard bounces.** Invalid syntax, domains that do not exist and domains that explicitly refuse mail (null MX) are removed before you send.
- **Keep disposable signups out.** The actor ships with the community-maintained disposable-email-domains blocklist (10,000+ domains, CC0 licence) and also matches subdomains of listed domains.
- **Fix typos instead of losing leads.** `someone@gmial.com` is flagged with the suggestion `someone@gmail.com`, so a form submission can be corrected rather than discarded.
- **Fast and cheap.** DNS answers are cached per domain, so a list of 10,000 addresses at 800 domains costs 800 DNS lookups. Typical speed is several hundred addresses per second.
- **No credentials, no accounts, no proxies.** Everything is public DNS data.
- **Transparent.** The `reason` tells you exactly why an address got its status; the `mxHosts` field shows the mail servers that were found.
- **Works in pipelines.** Feed it the dataset of a contact scraper run, pass a pasted column of emails, or call it from n8n, Make, Zapier or your own application.

### What data can you extract?

| Field | Description |
|---|---|
| `email` | The address as you supplied it |
| `normalizedEmail` | Cleaned address with the domain lower-cased and internationalised domains converted to their ASCII (punycode) form |
| `status` | `valid`, `risky`, `invalid` or `unknown` |
| `reason` | Why: `domain_accepts_email`, `role_account`, `possible_typo`, `disposable_domain`, `no_mx_but_address_record`, `domain_does_not_exist`, `domain_does_not_accept_email`, `dns_lookup_failed`, or a syntax problem such as `missing_at_sign` |
| `score` | 0-100 deliverability confidence from public data only |
| `syntaxValid` / `problem` | Whether the address is well-formed and what is wrong if not |
| `domain`, `localPart` | The two halves of the address |
| `isDisposable` | The domain (or a parent domain) is on the disposable blocklist |
| `isRole` | The local part is a shared role such as info, sales, support, admin, noreply |
| `isFreeProvider` | Gmail, Outlook, Yahoo, iCloud, Proton, GMX and about 90 other consumer providers |
| `suggestion` | A corrected address when the domain is one edit away from a popular provider |
| `dnsStatus` | `mx`, `implicit_mx` (no MX but an address record), `null_mx`, `no_mail_records`, `nxdomain` or `error` |
| `mxHosts` | Up to five MX hosts in priority order |
| `checkedAt` | Timestamp of the check |

#### What the statuses mean

- **valid**: the syntax is correct, the domain publishes MX records, it is not disposable, not a role account and not a probable typo. This does not prove the mailbox exists.
- **risky**: the domain accepts mail but something calls for care: a shared role account (low engagement, often a gatekeeper), a disposable domain, a probable typo, or a domain that relies on an address record instead of MX.
- **invalid**: the address would bounce or cannot be an address: bad syntax, a domain that does not exist, or a domain that publishes no mail servers or a null MX (RFC 7505).
- **unknown**: the DNS lookup failed on every resolver (rare). Run those addresses again.

### How to use Email Verifier & Validator (step by step)

1. Open the actor and paste your addresses into **Email addresses** (one per line), or paste any text into **Or paste a text blob**. You can also point the actor to an Apify dataset (for example the output of a contact scraper) with **Dataset ID** and the **Email field** name.
2. Leave **Remove duplicate addresses** on. Duplicates are not charged.
3. Click **Start**. A list of a few hundred addresses finishes in seconds.
4. Open the **Results** tab. Filter on `status`, then export CSV, Excel or JSON.
5. Send to `valid`, review `risky` (especially `possible_typo` rows, where the `suggestion` is usually right), drop `invalid`.

The default input checks three example addresses and finishes in a few seconds, so you can see the output format before using your own list.

### Input example

```json
{
  "emails": ["info@apify.com", "someone@gmial.com", "test@mailinator.com", "bad@@example.com"],
  "deduplicate": true,
  "maxEmails": 10000
}
```

Reading the addresses from the output of another run:

```json
{
  "datasetId": "YOUR_DATASET_ID",
  "emailField": "email"
}
```

### Output example

```json
{
  "type": "email",
  "email": "someone@gmial.com",
  "normalizedEmail": "someone@gmial.com",
  "syntaxValid": true,
  "problem": null,
  "domain": "gmial.com",
  "localPart": "someone",
  "isDisposable": true,
  "isRole": false,
  "isFreeProvider": false,
  "suggestion": "someone@gmail.com",
  "dnsStatus": "implicit_mx",
  "mxHosts": [],
  "status": "risky",
  "reason": "possible_typo",
  "score": 35,
  "checkedAt": "2026-11-11T18:00:00Z"
}
```

### How much does it cost?

Email Verifier & Validator uses pay-per-event pricing.

| Event | Price (Free plan) | When it is charged |
|---|---|---|
| Actor start | $0.0005 | Once per run |
| Email checked | $0.001 ($1 per 1,000 emails) | Every address that was checked |

Duplicates, empty lines and rows that only report a problem reading a dataset are **free**. Paid Apify plans get Store discounts (Bronze −15%, Silver −30%, Gold and up −45%).

Worked examples (Free plan prices):

- **A 500-address signup export:** about **$0.50**.
- **A 10,000-address newsletter list:** about **$10**.
- **Checking each new lead from a webhook:** one address per run costs $0.0015 including the start fee; batch addresses in one run to avoid paying the start fee each time.

You can set a maximum total charge for the run in the Apify run options; the actor stops cleanly when the limit is reached.

### Use cases

- **Clean a mailing list** before an outreach or newsletter campaign to protect your sender reputation.
- **Check leads** exported from a CRM, a form tool or a scraper; combine with the [Website Contact Scraper](https://apify.com/teddythebuilder/website-contact-scraper) to find and check company emails in one flow.
- **Block disposable signups** by calling the actor from your registration backend.
- **Repair typos** in lead forms and event registrations using the `suggestion` field.
- **Audit a database** for role accounts, free-provider addresses and dead domains.
- **Enrich B2B lists:** `isFreeProvider` separates company addresses from personal ones.

### Use with AI agents, MCP and the API

You can run the actor from the Apify API, the JavaScript and Python clients, n8n, Make, Zapier or any MCP-capable agent through Apify's MCP server. A minimal call with the Python client:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("teddythebuilder/email-verifier").call(run_input={"emails": ["jane@example.com", "bob@mailinator.com"]})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["email"], row["status"], row["reason"])
```

The dataset is flat JSON, so an agent can read it directly: filter on `status == "valid"` and use `suggestion` to propose a correction to the user.

### Integrations

Use Apify's integrations to send the results to Google Sheets, Airtable, Slack, a webhook or a database, or to start a run automatically when a new lead arrives. Schedule the actor to re-check a list every month, because domains expire and mail setups change.

### Data source and legality

All checks use public information: the syntax rules of RFC 5321/5322, public DNS answers (MX, A and AAAA records) fetched through DNS-over-HTTPS from Cloudflare with Google Public DNS as fallback, and the open [disposable-email-domains](https://github.com/disposable-email-domains/disposable-email-domains) blocklist, released under CC0 1.0. The actor never contacts the mail servers of the addresses you submit, never sends email and stores nothing beyond the run's dataset.

Email addresses can be personal data. You are responsible for having a lawful basis (for example legitimate interest or consent) to process and to contact the people in your list, and for following anti-spam rules such as GDPR, ePrivacy, CAN-SPAM and CASL.

### FAQ

**Can it tell me whether a specific mailbox exists?**
No. Confirming a mailbox requires an SMTP conversation with the recipient's server. Large providers answer the same for every address, many company servers accept everything and then bounce later, and probing from shared IP addresses gets those addresses blocklisted. This actor does not do it, on purpose. It tells you what is certain: which addresses cannot work and which need care.

**Why is a Gmail address `valid` even if the account does not exist?**
Because a public DNS lookup can only confirm that the domain is set up to receive mail. If you need mailbox-level confirmation, use an SMTP-based verifier on the addresses that this actor marks `valid`; you will pay for fewer addresses there.

**Why is `info@company.com` marked risky?**
Role accounts are usually shared inboxes. They are deliverable but have lower engagement and a higher complaint rate for cold outreach. Filter them out or keep them as you wish.

**What is the difference between `invalid` and `risky`?**
`invalid` means the address cannot receive mail (bad syntax, no such domain, no mail servers). `risky` means it probably can, but there is a reason to be careful.

**What happens with internationalised addresses?**
Domains in non-Latin scripts are converted to punycode (`müller.de` becomes `xn--mller-kva.de`) and checked normally. Non-ASCII local parts are accepted when they contain no forbidden characters.

**What if DNS lookups fail?**
The actor retries and falls back to a second resolver. If both fail, the row is `unknown` and you can re-run it.

**How is the score calculated?**
It is a simple, fixed mapping from the checks: 90 for a clean address on a domain with MX records, 65 for a domain with only an address record, 60 for a role account, 35 for a probable typo, 15 for a disposable domain, 5 or 0 for invalid. It is a sorting aid, not a probability.

**Is there a limit on the list size?**
Up to 1,000,000 addresses per run (default 10,000). Large lists are processed in batches of 200 with 25 parallel checks.

**How often is the disposable list updated?**
It is bundled at build time and refreshed with each new version of the actor.

### Related actors

- [Website Contact Scraper](https://apify.com/teddythebuilder/website-contact-scraper): find company emails, phones and social profiles on websites, then verify them here.
- [Domain WHOIS & DNS Lookup API](https://apify.com/teddythebuilder/domain-whois-dns-api): registration, DNS, SPF and DMARC records of a domain.
- [Tech Stack Detector](https://apify.com/teddythebuilder/tech-stack-detector): which technologies a website uses.
- [Website SEO Audit Crawler](https://apify.com/teddythebuilder/website-seo-audit): crawl a site and find broken links and SEO issues.

### Changelog and support

- **1.0 (November 2026):** first release. Syntax, MX, disposable (10,000+ domains), role accounts, free providers, typo suggestions, dataset input.

Questions or feature requests? Open an issue on the actor page. We reply within 24 hours.

# Actor input Schema

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

One address per line. Pasting a column from a spreadsheet works. Formats like Name <a@b.com> and mailto: links are understood.

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

Any text with addresses separated by spaces, commas, semicolons or line breaks (for example a CSV column or a mailing-list export). Added to the list above.

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

ID of an Apify dataset (for example the output of a contact scraper run). The field below is read from every item.

## `emailField` (type: `string`):

Name of the field that holds the address in the dataset items.

## `deduplicate` (type: `boolean`):

Check every distinct address once (case-insensitive). Duplicates are not charged.

## `maxEmails` (type: `integer`):

Upper limit of addresses per run. You pay per address checked.

## Actor input object example

```json
{
  "emails": [
    "info@apify.com",
    "someone@gmial.com",
    "test@mailinator.com"
  ],
  "emailField": "email",
  "deduplicate": true,
  "maxEmails": 10000
}
```

# Actor output Schema

## `results` (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": [
        "info@apify.com",
        "someone@gmial.com",
        "test@mailinator.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("teddythebuilder/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": [
        "info@apify.com",
        "someone@gmial.com",
        "test@mailinator.com",
    ] }

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

```

## MCP server setup

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