# Bulk Email Verifier & Validator (`tactful_anvil/bulk-email-verifier`) Actor

Verify email lists at $0.48/1,000 — syntax + MX via DNS-over-HTTPS, disposable/role/free flags, typo fixes (didYouMean), Gravatar existence evidence, mail-provider fingerprint and a 0-100 score. Unknown results, duplicates & garbage lines are never charged.

- **URL**: https://apify.com/tactful\_anvil/bulk-email-verifier.md
- **Developed by:** [Mr Zack](https://apify.com/tactful_anvil) (community)
- **Categories:** Lead generation, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.48 / 1,000 verified email (decisive result)s

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

## Bulk Email Verifier & List Cleaner — MX, Typo Fixes & Existence Evidence

Verify email lists at **$0.48 per 1,000** — the lowest price in the category — with checks the cheap verifiers don't do: **Gravatar existence evidence**, **typo autocorrect suggestions**, **mail-provider fingerprinting** and a transparent 0–100 deliverability score.

**Unknown results are never charged.** Neither are duplicates or unparseable lines. You pay only for decisive verdicts (valid / risky / invalid).

### Who this is for

- **Cold-email senders** — a 15–20% bounce rate can burn a sending domain in one campaign. Clean the list first, keep your sender reputation.
- **Lead-list buyers & scrapers** — 20–40% of scraped emails are dead. Chain this actor straight after any lead scraper (it reads emails from any Apify dataset).
- **CRM owners** — periodic hygiene: re-verify your contact base on a schedule and archive the dead rows before your ESP charges you for them.

Pairs perfectly with [Contact Details Scraper](https://apify.com/tactful_anvil/contact-details-scraper): scrape → pass its dataset ID here → send only what's deliverable.

### What each email goes through

1. **Syntax validation** (RFC-style, normalizes case/whitespace/`mailto:`)
2. **Typo detection** — `bob@gmial.com` → `didYouMean: bob@gmail.com` (one-edit distance against 25 major providers + common TLD slips like `.con` → `.com`). Recover leads other verifiers throw away.
3. **MX lookup** via DNS-over-HTTPS (Google + Cloudflare resolvers, RFC 5321 A-record fallback, RFC 7505 null-MX detection)
4. **Mail-provider fingerprint** — google-workspace, microsoft-365, zoho, proton, fastmail, mimecast, proofpoint, custom… Know which mailboxes are corporate-grade.
5. **Disposable check** against a continuously-maintained blocklist (8,000+ domains, refreshed at run start) + role-account (`info@`, `sales@`…) and free-provider flags
6. **Gravatar existence probe** — a hit proves this exact mailbox belongs to a real registered person. No other verifier in the category surfaces this.
7. **Domain liveness** — is there a live website behind the domain?
8. **Deliverability score 0–100** + verdict: `valid` / `risky` / `invalid` / `unknown`

### Output fields

| Field | Description |
|---|---|
| `email` | Normalized address |
| `status` | `valid` · `risky` · `invalid` · `unknown` (unknown = never charged) |
| `deliverabilityScore` | 0–100 composite (null when unknown) |
| `didYouMean` | Suggested fix when the domain looks like a typo |
| `mxStatus` / `mxHosts` | MX result + hosts |
| `mailProvider` | Fingerprinted mailbox provider |
| `isDisposable` / `isRole` / `isFree` | Hygiene flags |
| `hasGravatar` | Existence evidence: this exact email owns a Gravatar |
| `domainAlive` | Live website on the domain? |
| `syntaxValid`, `domain`, `verifiedAt` | Supporting detail |

A `SUMMARY` record in the key-value store gives you the run at a glance: valid %, provider breakdown, disposable/role/free counts, typo suggestions found, and exactly how many results you were charged for.

### Honest scope: what "verified" means here

This actor runs **MX-tier verification plus independent existence evidence** (Gravatar, domain liveness). It does **not** claim SMTP-handshake mailbox pings: from shared cloud IPs those are frequently greylisted, blocked, or answered by catch-all servers — which is how other tools end up labeling dead mailboxes "SMTP valid". We'd rather give you verifiable signals than a confident guess. For most list-cleaning use cases (killing hard bounces before they happen), MX + evidence is what does the work: an address whose domain has no mail server **cannot** receive email, full stop.

### Pricing that can't surprise you

- **$0.48 / 1,000 decisive results** + $0.01 per run — lowest in the category (typical competitors: $0.60–$5.00 / 1,000)
- `unknown` results (DNS unreachable): **free**
- Duplicates in your input: deduplicated up front, **free**
- Unparseable garbage lines: skipped, **free**

### How to schedule this actor (recommended)

List hygiene isn't a one-off — lists decay ~2–3% per month.

1. Open the actor page → **Schedules** tab → create a schedule (weekly or monthly fits most CRM/outreach cadences).
2. Point the input at your standing dataset (`datasetId` + `emailField`) so every run verifies your latest scraped or imported leads.
3. Add a Google Sheets or webhook integration and filter on `status = "valid"` — your sender only ever sees clean rows.

### Input example

```json
{
  "emails": ["jane.doe@acme.com", "bob@gmial.com", "info@startup.io"],
  "datasetId": "abc123DatasetFromYourLeadScraper",
  "emailField": "email"
}
```

`emailField` accepts a string, an array of strings, or objects with an `email` property — Contact Details Scraper output works with zero configuration.

### Fair use & privacy

Verification uses public DNS records and public Gravatar/domain endpoints only — no login, no inbox access, no email is ever sent, nothing is stored beyond your own dataset.

***

Questions or a field you wish existed? Open an issue on the actor — feature requests routinely ship within days. If this actor saved your sender reputation, a review genuinely helps an indie builder compete with the big resellers.

### Related Actors

- **[Contact Details Scraper](https://apify.com/tactful_anvil/contact-details-scraper)** — don't have an email list yet? Extract emails, phones and socials from any website list at $2.40/1,000 sites, then verify them here. Scrape → verify → outreach, all pay-per-event.

# Actor input Schema

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

One email per line. Duplicates and unparseable lines are skipped for free.

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

ID of any Apify dataset to pull emails from — chain this actor after any lead scraper (e.g. Contact Details Scraper). Combined with the list above.

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

Field in the dataset items holding the email. Accepts a string, an array of strings, or objects with an "email" property (works out of the box with Contact Details Scraper output).

## `checkGravatar` (type: `boolean`):

Probe Gravatar for each non-invalid email — a hit is strong evidence the exact mailbox exists (adds +15 to the score).

## `checkDomainLiveness` (type: `boolean`):

HEAD-check whether a live website answers on the email's domain (cached per domain, adds +10 to the score).

## `refreshDisposableList` (type: `boolean`):

Download the maintained 120k+ disposable-domain blocklist at run start (falls back to a bundled list when unreachable).

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

Parallel verifications (1–50).

## Actor input object example

```json
{
  "emails": [
    "jason@basecamp.com",
    "info@apify.com",
    "someone@gmial.com",
    "test@mailinator.com",
    "nobody@this-domain-does-not-exist-xk29.com"
  ],
  "emailField": "email",
  "checkGravatar": true,
  "checkDomainLiveness": true,
  "refreshDisposableList": true,
  "maxConcurrency": 20
}
```

# Actor output Schema

## `verifiedEmails` (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": [
        "jason@basecamp.com",
        "info@apify.com",
        "someone@gmial.com",
        "test@mailinator.com",
        "nobody@this-domain-does-not-exist-xk29.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tactful_anvil/bulk-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": [
        "jason@basecamp.com",
        "info@apify.com",
        "someone@gmial.com",
        "test@mailinator.com",
        "nobody@this-domain-does-not-exist-xk29.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("tactful_anvil/bulk-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": [
    "jason@basecamp.com",
    "info@apify.com",
    "someone@gmial.com",
    "test@mailinator.com",
    "nobody@this-domain-does-not-exist-xk29.com"
  ]
}' |
apify call tactful_anvil/bulk-email-verifier --silent --output-dataset

```

## MCP server setup

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