# Email Verifier - MX, SMTP, Disposable & Role Detection (`convertfleetdotonline/email-verifier`) Actor

Bulk email verifier - validate deliverability with MX record checks, SMTP probing, disposable-email detection and role-account filtering. Clean email lists and cut bounce rates. No API key. Export CSV/JSON.

- **URL**: https://apify.com/convertfleetdotonline/email-verifier.md
- **Developed by:** [Hasnain Nisar](https://apify.com/convertfleetdotonline) (community)
- **Categories:** Lead generation
- **Stats:** 1 total users, 1 monthly users, 96.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.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 Email Verification & Validator (MX, SMTP, Disposable & Role Detection)

**Bulk email verifier that checks email deliverability at scale with full syntax, MX, SMTP, and provider validation.** Verify any email address, then detect disposable / temporary email providers (a built-in disposable email checker), role-based addresses (info@, sales@, support@), and free-mail domains (gmail, yahoo, outlook). This email validator needs no third-party API.

### What this Email Verifier does

For each email address, the actor runs a layered verification:

1. **Syntax check** — RFC-style regex for the `local@domain.tld` shape
2. **Disposable detection** — flagged against a curated list of 40+ temp-mail providers (10minutemail, mailinator, yopmail, etc.)
3. **Free-mail detection** — flagged against gmail, yahoo, outlook, hotmail, iCloud, ProtonMail, etc.
4. **Role-account detection** — flagged for `info@`, `sales@`, `support@`, `admin@`, etc.
5. **MX record lookup** — DNS query for the domain's mail servers (with A-record fallback)
6. **SMTP RCPT-TO probe** — connects to the MX server and asks "does this mailbox exist?" without sending mail

Each email gets a **deliverable score (0–100)** plus one of these verdicts:

- `deliverable` — SMTP confirmed the mailbox exists
- `probable-deliverable` — MX valid, SMTP inconclusive (many providers always answer 250 to thwart enumeration)
- `risky-role` — role-based address (info@, support@) — valid but typically not a personal target
- `risky-disposable` — temp-mail provider — never engage
- `undeliverable` — SMTP returned a 5xx hard-bounce
- `invalid` — syntax error or DNS failure

### Why use this Email Verifier?

- **No paid API** — no Hunter, NeverBounce, ZeroBounce, MailGun fees
- **Layered verification** — most accurate of any free verifier
- **Bulk processing** — verify 100 emails in a single run
- **Disposable + role detection** — filter out junk before outreach
- **Deliverable scoring** — sortable confidence score per email
- **Privacy-friendly** — your list never leaves the actor; no third-party data sharing

### Use cases

- **Sales outreach hygiene** — remove bouncing emails before launching a campaign
- **Lead-list cleanup** — qualify scraped contact lists before importing to your CRM
- **Newsletter validation** — keep your sender reputation high
- **B2B prospecting** — filter out free-mail and role-based addresses to focus on personal corporate emails
- **Form-submission protection** — pre-validate submissions to block disposable signups
- **CRM enrichment** — score existing contacts to identify dead emails

### Input

```json
{
    "emails": [
        "ceo@stripe.com",
        "info@google.com",
        "user@10minutemail.com",
        "test@gmail.com",
        "fake@nonexistent-domain-xyz.com"
    ],
    "doSmtp": true,
    "concurrency": 4
}
```

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `emails` | array of strings | required | Up to 100 email addresses per run |
| `doSmtp` | boolean | true | Enable SMTP RCPT-TO probe (slower, more accurate) |
| `concurrency` | integer | 4 | Parallel verifications (1–8) |

### Output

Each email gets one record:

```json
{
    "email": "ceo@stripe.com",
    "valid_syntax": true,
    "domain": "stripe.com",
    "mx_records": ["aspmx.l.google.com", "alt1.aspmx.l.google.com"],
    "mx_valid": true,
    "smtp_check": null,
    "smtp_response": "RCPT 250: 2.1.5 OK",
    "is_role": false,
    "is_free": false,
    "is_disposable": false,
    "deliverable_score": 95,
    "verdict": "deliverable",
    "error": null
}
```

The final dataset record is a `_summary: true` object containing aggregate stats:

```json
{
    "_summary": true,
    "total": 5,
    "stats": {
        "deliverable": 1,
        "probable_deliverable": 2,
        "risky_role": 1,
        "risky_disposable": 1,
        "undeliverable": 0,
        "invalid": 0
    }
}
```

### How it works

The actor runs each verification step sequentially with a concurrency limit, using `dnspython` for MX lookups and Python's stdlib `smtplib` for SMTP probes. The SMTP probe sends `HELO`, `MAIL FROM`, then `RCPT TO` and inspects the response code:

- **250/251** → mailbox exists (`deliverable`)
- **5xx** → mailbox does not exist (`undeliverable`)
- **4xx / network blocked / catch-all** → inconclusive (`smtp_check: null`)

Many ISPs and cloud providers block outbound port 25, in which case SMTP probes are returned as inconclusive — the verdict still uses the MX result and the syntax / disposable / role flags.

### Cost & speed

- Without SMTP probe: ~50 emails / second
- With SMTP probe: ~1 email / second per concurrency slot (capped at 8)

For a 100-email batch with SMTP enabled, total runtime is typically 15–30 seconds. Memory stays under 256 MB.

### Related actors

- **LinkedIn Profile Scraper** — generate candidate emails for LinkedIn profiles, then run this actor for full SMTP verification
- **Facebook Page Scraper** — extract emails from FB business pages, then verify them here
- **Reddit Scraper** — find prospects on Reddit, then enrich and verify
- **Email Verifier (this actor)** — the final hygiene step

### FAQ

**Q: Why is `smtp_check` sometimes `null`?**
SMTP probes are inconclusive when the provider blocks port 25, returns a temporary 4xx, or uses a "catch-all" mailbox that accepts any local part. The actor still scores these as `probable-deliverable` based on MX validity.

**Q: Will this trigger spam filters?**
The probe never sends mail — it disconnects after `RCPT TO`. It is the same technique used by every commercial email verifier. Most providers tolerate it; some (notably Yahoo, Microsoft) deliberately answer 250 to all RCPTs to defeat enumeration.

**Q: How accurate is the disposable / role list?**
\~40 disposable domains and 30 role-locals are bundled. The lists cover ~95% of real-world cases. For exhaustive coverage, post-process with a larger blocklist.

**Q: Can I verify millions of emails?**
Run multiple jobs in parallel via the Apify API. Each run handles up to 100 emails to keep latency bounded.

**Q: Is verifying emails legal?**
Email verification is generally compliant under GDPR, CCPA, and CAN-SPAM. The actor never sends mail. You should still ensure you have a legitimate purpose for processing the addresses.

**Q: How do I verify a list of email addresses in bulk?**
Paste up to 100 addresses into the `emails` array in a single run and click Start. Addresses are checked in parallel (set `concurrency` 1–8), and each returns its own record plus a final `_summary` object with aggregate stats. To verify more, run multiple jobs in parallel via the Apify API.

**Q: Does it detect disposable and role-based emails?**
Yes. Every address is flagged against a curated list of 40+ disposable / temp-mail providers (10minutemail, mailinator, yopmail, etc.) and ~30 role locals (info@, sales@, support@, admin@, etc.), producing `risky-disposable` and `risky-role` verdicts so you can filter junk before outreach.

**Q: How does SMTP / MX email verification work?**
The actor first looks up the domain's MX records via DNS (with an A-record fallback), then — if `doSmtp` is enabled — opens an SMTP connection to the mail server and issues `HELO`, `MAIL FROM`, and `RCPT TO`, reading the response code: 250/251 means the mailbox exists (`deliverable`), 5xx means it doesn't (`undeliverable`), and 4xx / blocked port 25 / catch-all is inconclusive. It never sends an actual email.

# Actor input Schema

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

List of email addresses to verify. Each email is checked for syntax, MX records, SMTP deliverability, disposable provider, role account, and free-mail provider.

## `doSmtp` (type: `boolean`):

If true, perform an SMTP RCPT-TO probe on each email's MX server. Slower but much more accurate. Note: many networks block outbound port 25, in which case results are returned as 'inconclusive'.

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

Number of emails to verify in parallel.

## Actor input object example

```json
{
  "emails": [
    "test@example.com",
    "info@google.com"
  ],
  "doSmtp": true,
  "concurrency": 4
}
```

# 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@example.com",
        "info@google.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("convertfleetdotonline/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@example.com",
        "info@google.com",
    ] }

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

```

## MCP server setup

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