# Email Verifier & Validator - Bulk Syntax, MX Check, No SMTP (`pennydata/bulk-email-validator-no-smtp`) Actor

Email verifier and validator for bulk lists: syntax, MX records, disposable, role and free-provider flags, typo suggestions. No SMTP probing. $1 per 1,000 emails, DNS failures free.

- **URL**: https://apify.com/pennydata/bulk-email-validator-no-smtp.md
- **Developed by:** [Jeremy Larsen](https://apify.com/pennydata) (community)
- **Categories:** Lead generation, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 email validateds

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?

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

## Email Verifier & Validator - Bulk, $1/1k, No SMTP

**Email verifier and validator** for bulk lists: paste addresses or give a CSV URL and get one row per unique email with syntax, MX/DNS, disposable-domain, role-account and free-provider flags plus typo suggestions. It never probes mail servers (no SMTP), so it does not claim a mailbox exists. You pay only for rows that were checked, and DNS failures are free.

**Free to try:** a new Apify account includes free monthly platform credit, enough to validate the output on a few dozen emails before you pay anything. This Actor has no hidden minimums: failed items are never billed.

### How to use Bulk Email Validator

1. Open the Actor and paste addresses into **emails**, or set **csvUrl** to a public CSV.
2. Click **Start**. Duplicates are removed (case-insensitive) and validated once.
3. Open the **Output** tab or download JSON/CSV/Excel. The `SUMMARY` record shows counts by status.
4. Re-run rows with status `unknown` (DNS failure) later; they were not charged.

### Pricing

Pay per event, no subscription and no compute fees on top. Price: **$1.00 per 1,000 emails**.

| Event | When it is charged | Price |
|---|---|---|
| `email-validated` | One email address checked (syntax, DNS/MX, disposable, role, free-provider). | $0.001 |

Failed, blocked or unknown items are not billed. Set a maximum cost per run in the run options to cap spend.

### Example input

```json
{
  "emails": [
    "jane@gmail.com",
    "info@example.com",
    "bob@mailinator.com",
    "x@gmial.com",
    "not-an-email"
  ]
}
```

### Example output

Illustrative sample of the output shape (field names from the Actor; values shown for a disposable address).

```json
{
  "input": "bob@mailinator.com",
  "email": "bob@mailinator.com",
  "valid": false,
  "status": "disposable",
  "reason": "disposable_domain",
  "domain": "mailinator.com",
  "hasMx": true,
  "isDisposable": true,
  "isRole": false,
  "isFreeProvider": false,
  "didYouMean": null
}
```

### Details and limits

Cleans an email list **without contacting any mail server**. For every address it checks:

| Check | Output field |
|---|---|
| Syntax (RFC 5321/5322-style, length limits, IDN domains converted to punycode) | `status = invalid_syntax`, `reason` |
| Domain DNS: MX records, A/AAAA fallback, RFC 7505 null-MX | `hasMx`, `hasARecord`, `mxRecords` |
| Disposable / throwaway domain (incl. subdomains of listed domains) | `isDisposable` |
| Role account (`info@`, `admin@`, `support@`, `noreply@` ...) | `isRole` |
| Free mailbox provider (Gmail, Outlook, Yahoo, iCloud, Proton ...) | `isFreeProvider` |
| Typo suggestion for common providers (`gmial.com`, `hotmial.com`, `outlok.com`) | `didYouMean` |

`valid` is `true` when the syntax is correct, the domain can receive mail (MX, or A/AAAA fallback) and it is not a disposable domain.

### What this does NOT do (read before buying)

- **No SMTP probing.** It cannot tell whether a specific mailbox (`jane@company.com`) exists. `valid: true` means "the address is well-formed and its domain accepts mail", not "the mailbox exists". Catch-all domains, full mailboxes and non-existent users on real domains pass.
- Disposable detection is only as good as the open list (about 9 900 domains). New throwaway services are missed until the list is updated; the list in this version was fetched 2026-10-15.
- The role and free-provider lists are short hand-curated lists, not exhaustive.
- Typo suggestions cover about ten big providers only and are suggestions, not corrections.
- DNS answers can change between runs (domains get new records); flags for a given domain are deterministic only while its DNS is.

### Privacy

Only the emails you supply are processed. Nothing is stored beyond the run's dataset and summary (subject to your Apify retention settings). No third-party API is called; only DNS queries for the email domains are sent.

### Data sources and licenses

Disposable domains: [disposable-email-domains](https://github.com/disposable-email-domains/disposable-email-domains), **CC0 1.0**. See `data/SOURCES.md`.

### More from PennyData

- [Website Screenshot & URL to PDF](https://apify.com/pennydata/shot-pdf): Full-page screenshots and URL/HTML to PDF with headless Chromium.
- [App Store Reviews Scraper](https://apify.com/pennydata/appstore-reviews-rss): Apple app reviews by app ID and country from the public RSS feed.
- [Bulk Domain WHOIS & DNS Lookup](https://apify.com/pennydata/bulk-domain-whois-dns-lookup): Availability, registrar, expiry, nameservers, MX and TXT via RDAP.
- [Website Tech Stack Detector](https://apify.com/pennydata/website-tech-stack-detector): CMS, ecommerce, analytics, CDN and JS frameworks per URL.

### FAQ

**Does it check that the mailbox exists?**\
No. It never opens an SMTP connection, so `valid: true` means well-formed with a domain that accepts mail, not that the mailbox exists. This is why it is cheap and why it cannot get your IP blocklisted.

**Is it legal?**\
It only sends DNS queries for the email domains you supply and calls no third-party API. You are responsible for having a lawful basis to process the addresses you submit (e.g. under GDPR).

**Need a custom field, a higher volume or a different source?**\
Open an issue on the Actor page and describe what you need; custom variants are possible.

**Is it maintained?**\
Yes. Reports of breakage are answered through the Issues tab, and runs that fail are not billed.

Built with AI assistance (Claude); maintained by the publisher.

# Actor input Schema

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

List of email addresses to validate.

## `csvUrl` (type: `string`):

Public http(s) URL of a CSV file. Uses the column whose header contains 'email', or the first column if there is no such header.

## `csvColumn` (type: `string`):

Header of the column holding emails.

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

Safety cap on unique emails processed.

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

Parallel DNS validations.

## Actor input object example

```json
{
  "emails": [
    "test@gmail.com",
    "info@example.com"
  ],
  "maxEmails": 10000,
  "concurrency": 10
}
```

# Actor output Schema

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

// Run the Actor and wait for it to finish
const run = await client.actor("pennydata/bulk-email-validator-no-smtp").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",
        "info@example.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("pennydata/bulk-email-validator-no-smtp").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@gmail.com",
    "info@example.com"
  ]
}' |
apify call pennydata/bulk-email-validator-no-smtp --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,pennydata/bulk-email-validator-no-smtp"
        }
    }
}
```

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/LCwVvjCqjn1rS7Qbh/builds/zMRANdJLeYmgnVCXC/openapi.json
