# Email Verifier (`zinin/email-verifier`) Actor

Verify email addresses by syntax and domain/MX resolution with an honest, tiered verdict — no live mailbox probe pretending to be one.

- **URL**: https://apify.com/zinin/email-verifier.md
- **Developed by:** [Tim Zinin](https://apify.com/zinin) (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.85 / 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/platform/actors/running/actors-in-store#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

Check a list of email addresses by syntax and by actually resolving the domain's mail
servers (MX records) — with an honest, tiered verdict instead of a single misleading
"valid/invalid". No live mailbox probe pretending to confirm delivery.

### What you get

- Syntax check, domain resolution and MX lookup for every address — a real DNS answer,
  not a guess.
- A tiered verdict (`valid_syntax_and_mx`, `invalid_syntax`, `domain_not_found`, `no_mx`,
  `unknown`) instead of a flat true/false that hides WHY an address failed.
- Mail provider detection (Google Workspace, Microsoft 365, Yahoo, Yandex, Zoho,
  ProtonMail, Amazon SES, Fastmail, iCloud and more) from the MX records themselves.
- Disposable-domain and role-account (`info@`, `admin@`, `support@`...) flags — useful
  signals for cleaning a list before outreach.
- A known "catch-all" warning where the mail PROVIDER itself is documented to accept any
  address regardless of whether the mailbox exists (currently: Yahoo) — a static fact,
  not a live probe.
- Runs on Apify: schedule it, monitor it, call it from the API, export to
  JSON/CSV/Excel or push straight into your own pipeline.

### How to run it

1. Click **Try for free** — no card needed on the free plan.
2. Paste your list of email addresses into **Emails**.
3. Hit **Start** and pull the results from the dataset (UI, API or webhook).

### Pricing

Pay-per-event: **$0.005 per run start + $0.001 per email verified**. Every verdict —
including a confirmed "this address is invalid" — is a real, delivered answer and is
billed the same way; only a genuine DNS infrastructure hiccup (not a verdict on the
address) is returned for free. 1,000 emails = $1.00 + the one-time start fee.

### Input

| Field | Required | What it does |
|---|---|---|
| `emails` | yes | Email addresses to verify. Max 100 per run. |
| `maxConcurrency` | no | How many emails to check in parallel (default 10). |

```json
{
    "emails": ["test@gmail.com", "not-a-real-email", "someone@this-domain-zzq123.example"]
}
```

### Output

```json
{
    "email": "test@gmail.com",
    "syntaxValid": true,
    "domainResolves": true,
    "mxFound": true,
    "mxRecords": [
        "gmail-smtp-in.l.google.com",
        "alt1.gmail-smtp-in.l.google.com",
        "alt2.gmail-smtp-in.l.google.com"
    ],
    "provider": "Google Workspace",
    "disposable": false,
    "roleAccount": false,
    "catchAllRisk": false,
    "verdict": "valid_syntax_and_mx",
    "mailboxChecked": false,
    "checkedAt": "2026-07-30T07:51:36.835Z"
}
```

| Field | Meaning |
|---|---|
| `verdict` | `valid_syntax_and_mx` (domain can receive mail), `invalid_syntax`, `domain_not_found` (confirmed non-existent domain), `no_mx` (domain exists but cannot receive mail — including RFC 7505 "null MX" domains that explicitly opt out), or `unknown` (DNS infrastructure hiccup — not a verdict on the address). |
| `mxRecords` | Mail server hostnames, sorted by priority. |
| `provider` | Mail provider detected from the MX records, or `null` when none was found or matched. |
| `disposable` | Domain matches a static list of known temp-mail providers. Not exhaustive. |
| `roleAccount` | Local part looks like a shared inbox (`info@`, `support@`, ...) rather than a person. |
| `catchAllRisk` | `true` only when the detected PROVIDER is documented to accept mail for any address on its servers regardless of mailbox existence — a static, known-behavior flag, not a per-domain live test. |
| `mailboxChecked` | Always `false`. See FAQ. |
| `error` | `null` for every real verdict, including "invalid" ones; only set when a DNS infrastructure error prevented a verdict at all. |

#### Related tools

Related tools for adjacent workflows in B2B lead generation and data enrichment.

| Actor | What it does |
|---|---|
| [Company Profile Lookup](https://apify.com/zinin/company-lookup) | Pair it in the B2B lead generation and data enrichment workflow: Turn a domain or company name into one unified company card: website tech stack (CMS, ecommerce, key tech)... |
| [URL to Markdown Converter](https://apify.com/zinin/url-to-markdown) | Pair it in the B2B lead generation and data enrichment workflow: Fetch any URL and convert it into clean, LLM-ready Markdown — headings, links, lists and emphasis... |
| [Company Registry Enricher](https://apify.com/zinin/company-registry-enricher) | Pair it in the B2B lead generation and data enrichment workflow: Turn a company name, LEI or UK company number into an official registry card: legal name, status,... |
| [Counterparty Risk Rollup — Sanctions, Courts, Registry, Hiring](https://apify.com/zinin/counterparty-risk-rollup) | Pair it in the B2B lead generation and data enrichment workflow: One call, one row per counterparty: sanctions screening (OFAC + EU), legal-entity registry (GLEIF),... |
| [Intent Signal Aggregator](https://apify.com/zinin/intent-signal-aggregator) | Pair it in the B2B lead generation and data enrichment workflow: Is this company in-market right now? Combines public hiring activity (Greenhouse, Lever, Ashby) and recent... |

### FAQ / Limitations

**Does a `valid_syntax_and_mx` verdict mean the mailbox exists?** No — it means the
DOMAIN is correctly configured to receive mail. Confirming one specific mailbox exists
requires an SMTP conversation with the mail server, which this Actor does not perform
(`mailboxChecked` is always `false`). Cloud platforms — this one included — commonly
cannot open outbound port 25 at all, which is why a live per-mailbox check is not
offered as a false promise here.

**What this is NOT.** Not a deliverability guarantee, not a spam-score check, and not
proof a specific person still reads that inbox. `catchAllRisk` flags a PROVIDER-level
known behavior (some mail providers accept any address on their servers), not a
per-domain catch-all test — that would require the same live SMTP conversation this
Actor deliberately does not perform.

Found an address this Actor should classify differently, or need a bulk mailbox-check
add-on for your case? Open an issue on this Actor's page.

# Actor input Schema

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

Email addresses to verify.

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

How many emails to check in parallel.

## Actor input object example

```json
{
  "emails": [
    "test@gmail.com",
    "not-a-real-email",
    "someone@this-domain-zzq123.example"
  ],
  "maxConcurrency": 10
}
```

# Actor output Schema

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

API URL for the default dataset items produced by this run.

# 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": [
        "test@gmail.com",
        "not-a-real-email",
        "someone@this-domain-zzq123.example"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("zinin/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": [
        "test@gmail.com",
        "not-a-real-email",
        "someone@this-domain-zzq123.example",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("zinin/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 '{
  "emails": [
    "test@gmail.com",
    "not-a-real-email",
    "someone@this-domain-zzq123.example"
  ]
}' |
apify call zinin/email-verifier --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/qG11Fm10zi2F0067B/builds/N0cJtaFcwaEt2bXq2/openapi.json
