# Email Verify — syntax, MX, disposable & role detection (`titian_troupe/email-verify`) Actor

Clean an email list before you send to it. RFC 5322 syntax, MX records, 60+ disposable domains and 30+ role-account prefixes, with a 0-100 deliverability score and the reason behind every verdict.

- **URL**: https://apify.com/titian\_troupe/email-verify.md
- **Developed by:** [Rumblingb](https://apify.com/titian_troupe) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## 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 Verify — syntax, MX, disposable & role detection

Clean an email list before you send to it. Give the Actor a list of addresses; get back a row per address with a 0–100 deliverability score and the reasons behind it.

No API key. No account with a third-party verification vendor. Runs on your Apify account.

### What it checks

| Check | What it catches |
|---|---|
| **RFC 5322 syntax** | Typos, missing TLDs, doubled `@`, leading/trailing dots, over-length local parts |
| **MX records** | Domains that cannot receive mail at all — the single biggest source of hard bounces |
| **Disposable domains** | 60+ throwaway providers (Mailinator, Guerrilla Mail, 10MinuteMail, YOPmail …) |
| **Role accounts** | `admin@`, `info@`, `support@`, `noreply@` and 30+ others — deliverable, but they hurt engagement rates and often trip spam filters |

### Output

One dataset row per address:

```json
{
  "email": "support@apify.com",
  "valid": true,
  "score": 55,
  "syntaxValid": true,
  "domain": "apify.com",
  "isDisposable": false,
  "isRoleAccount": true,
  "mxValid": true,
  "mxRecords": ["aspmx.l.google.com (priority: 1)"],
  "reason": null,
  "checkedAt": "2026-07-27T17:20:00.000Z"
}
```

A `SUMMARY` record is written to the key-value store with totals for valid, bad-syntax, no-MX, disposable and role addresses.

### How the score works

- **0** — syntax is invalid. Nothing else is checked and no DNS query is made.
- **10** — syntax is fine but the domain has no MX records. It cannot receive mail.
- **70** — baseline for a syntactically valid address on a domain that accepts mail.
- **−40** disposable domain · **−15** role account
- **±30** if the optional SMTP probe runs and the mailbox is accepted / rejected

`valid` is `true` when the domain has MX records, the domain is not disposable, and the score is at least 50. Role accounts stay `valid` but score lower — they are genuinely deliverable, so the decision to keep them is yours.

### Input

```json
{
  "emails": ["support@apify.com", "someone@mailinator.com", "bad@@format"],
  "checkSmtp": false,
  "maxConcurrency": 10
}
```

- `emails` *(required)* — addresses to verify. Wire this to another Actor's output to clean scraped leads in place.
- `checkSmtp` — see the honest limitation below. Default `false`.
- `smtpTimeoutMs` — per-address SMTP timeout. Default `10000`.
- `maxConcurrency` — parallel DNS resolutions, 1–50. Default `10`.

### Honest limitations

Read this before you rely on the output.

**SMTP mailbox probing is off by default and will usually not work in the cloud.** Outbound port 25 is blocked on most cloud networks, Apify's included. With `checkSmtp: true` you will typically get `smtpReached: false` — which tells you nothing about the mailbox. The option exists for self-hosted runs where port 25 is open. It is not a defect in the Actor; it is how cloud networking works, and any tool claiming reliable cloud-side SMTP verification is either using a relay service or is not doing what it says.

**Even a working SMTP probe is not proof.** Many servers accept every `RCPT TO` and bounce later (catch-all). Greylisting returns a temporary 4xx on first contact. Treat `smtpAccepted: false` as a signal, never a verdict.

**This does not detect catch-all domains, spam traps, or whether a human still reads the mailbox.** It removes addresses that provably cannot receive mail, plus the two categories that most reliably damage sender reputation. That is the large majority of list rot, and it is what it claims to do — nothing more.

**The disposable-domain list is static.** New throwaway providers appear constantly. It covers the well-known ones and is not exhaustive.

### Typical use

1. Scrape or export leads.
2. Run this Actor over the address column.
3. Drop `valid: false`, and decide separately whether you want `isRoleAccount: true`.
4. Send.

Cutting hard bounces protects your sending domain's reputation, which is far more expensive to repair than to preserve.

### Local development

```bash
npm install
node --test test.mjs      # 14 tests, no network required
```

The verification logic lives in `lib.js` with injectable DNS and SMTP dependencies, so the suite runs fully offline.

MIT licensed.

# Actor input Schema

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

Addresses to verify. Paste a list or wire this to the output of another Actor.

## `checkSmtp` (type: `boolean`):

Off by default. Outbound port 25 is blocked on most cloud networks, so this usually cannot reach a mail server and will slow the run without adding signal. Enable only if you know port 25 is open for your run.

## `smtpTimeoutMs` (type: `integer`):

Per-address SMTP timeout. Ignored unless the SMTP probe is enabled.

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

How many addresses to resolve in parallel.

## Actor input object example

```json
{
  "emails": [
    "support@apify.com",
    "notarealmailbox@mailinator.com",
    "bad@@format"
  ],
  "checkSmtp": false,
  "smtpTimeoutMs": 10000,
  "maxConcurrency": 10
}
```

# 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": [
        "support@apify.com",
        "notarealmailbox@mailinator.com",
        "bad@@format"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("titian_troupe/email-verify").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": [
        "support@apify.com",
        "notarealmailbox@mailinator.com",
        "bad@@format",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("titian_troupe/email-verify").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": [
    "support@apify.com",
    "notarealmailbox@mailinator.com",
    "bad@@format"
  ]
}' |
apify call titian_troupe/email-verify --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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