# Email Verifier without SMTP: MX, Disposable, Typos (`webify-lab/email-verifier-no-smtp`) Actor

Bulk email checker that never sends mail and never opens SMTP connections. Syntax, MX and null MX via DNS over HTTPS, disposable domains, role addresses, free mail, typo suggestions and mail provider detection. Status, score 0 to 100 and reasons per address.

- **URL**: https://apify.com/webify-lab/email-verifier-no-smtp.md
- **Developed by:** [Batu T.](https://apify.com/webify-lab) (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.35 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 without SMTP: Syntax, MX, Disposable, Typos

Clean an email list without ever talking to a mail server. This Actor never sends a message and never opens an SMTP connection. That makes it fast, safe for your IP reputation and invisible to the recipients' mail servers.

### Be clear about what this is

Without SMTP nobody can prove that a mailbox exists. This Actor scores **deliverability risk** from public facts: is the address well formed, can the domain receive mail at all, is it a throwaway domain, a shared role mailbox or a likely typo. An address marked `valid-looking` can still bounce if the mailbox was deleted. An address marked `invalid` will not receive mail.

### Checks per address

| check | how |
|---|---|
| Syntax | practical subset of RFC 5322 (dot-atom local part up to 64 characters, domain up to 253, no IP literals, no quoted local parts) |
| Normalization | trims spaces and `mailto:`, unwraps `Name <a@b.de>`, lowercases the domain, converts international domains to punycode (`müller.de` to `xn--mller-kva.de`) |
| Typos | edit distance against common providers (gmail, googlemail, gmx, web.de, t-online, outlook, hotmail, live, yahoo, icloud, posteo, freenet, proton, aol and more) and common TLD slips such as `.con` or `.dee` |
| Domain | MX records over DNS over HTTPS (Google, Cloudflare as fallback), A and AAAA as implicit MX, null MX (RFC 7505), domain does not exist (NXDOMAIN) |
| Disposable | bundled snapshot of the open disposable-email-domains list, subdomains included |
| Role address | info, kontakt, contact, office, support, sales, noreply, admin, buero, verwaltung, rechnung, bewerbung and about 100 more |
| Free mail | gmail, gmx, web.de, t-online, yahoo, outlook, hotmail, icloud, proton, posteo, freenet, mail.de and more |
| Mail provider | from the MX hosts: Google Workspace, Microsoft 365, IONOS, Strato, Hostinger, Zoho, Proton, GMX and web.de, T-Online, Yahoo, iCloud, Mimecast, Proofpoint and more |

DNS answers are cached per domain during a run, so 10,000 addresses at the same company cost one lookup.

### Output per address

| field | meaning |
|---|---|
| `email` | normalized address (domain lowercased and in punycode) |
| `status` | `valid-looking`, `risky` or `invalid` |
| `score` | 0 to 100, higher is safer to send to |
| `reasons`, `reasonCodes` | every finding as a sentence and as a stable code |
| `didYouMean` | suggested correction for a likely typo |
| `isDisposable`, `isRoleBased`, `isFreeProvider` | flags |
| `domainExists`, `hasMx`, `nullMx`, `implicitMx`, `mxRecords` | DNS facts |
| `mailProvider` | who hosts the mailbox, if recognizable |

### How the status is decided

- `invalid` (score 0): broken syntax, domain does not exist, null MX, or the domain has neither MX nor A/AAAA records.
- `risky`: disposable domain, likely typo, DNS errors, mail only via implicit MX, or a score below 70.
- `valid-looking`: everything checked looks fine. Role addresses lose 15 points and stay `valid-looking` when nothing else is wrong.

### Input

A list of addresses, a pasted text block (one per line or separated by commas or semicolons), or both. Duplicates are removed (case-insensitive). Each check can be switched off.

### Pricing

You pay per checked address. Addresses with broken syntax count as checked, since that is a result. Internal errors (for example both DNS services unreachable) are not charged.

### Limits

- No SMTP: mailbox existence and catch-all domains cannot be detected.
- The disposable list is a snapshot (source below). New throwaway domains appear daily.
- Provider detection only knows the hosts listed above; others return `null`.

### Data source

Disposable domains: [disposable-email-domains/disposable-email-domains](https://github.com/disposable-email-domains/disposable-email-domains), CC0 1.0 (public domain), snapshot of commit e4f0910 from 2026-10-23 with 9,927 domains.

Not affiliated with Google, Microsoft, Cloudflare or any mail provider named here.

### FAQ

**Does it send an email or connect to the mail server?** No. It never opens an SMTP connection and never sends a message. It only checks syntax, bundled lists and public DNS records.

**What am I charged for?** One event per checked address. Addresses with broken syntax count as checked because the verdict is a result. Internal errors, for example when both DNS over HTTPS services are unreachable, are pushed as items with an `error` field and are not charged.

**Can it tell me if a mailbox exists or if a domain is catch-all?** No. Without SMTP that cannot be detected. A `valid-looking` address can still bounce if the mailbox was deleted.

**What happens when a DNS lookup fails?** If the resolvers answer with an error such as SERVFAIL, the address gets the reason code `dns_error` and the status `risky`, because deliverability is unknown. If neither Google nor Cloudflare DNS can be reached at all, the address is returned as an error item.

**How many addresses can one run handle?** Up to `maxEmails` (default 100,000, maximum 1,000,000) after duplicates are removed. DNS answers are cached per domain, so many addresses at the same domain need only one lookup.

### Use with AI agents (MCP)

This Actor works as a tool for Claude, ChatGPT, Cursor and other MCP clients through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp). Add only this Actor:

```
https://mcp.apify.com?tools=webify-lab/email-verifier-no-smtp
```

On first use the server signs you in with OAuth. Alternatively send the header `Authorization: Bearer <APIFY_TOKEN>`. Agents on the default Apify MCP setup can also find this Actor with `search-actors` and run it with `call-actor`. Pricing is the same as in Apify Console: you pay per result.

# Actor input Schema

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

One address per entry. An entry may also contain several addresses separated by commas, semicolons or line breaks.

## `emailsText` (type: `string`):

Optional. Paste a list with one address per line or separated by commas or semicolons. Combined with the list above.

## `checkDns` (type: `boolean`):

Look up MX records over DNS over HTTPS (Google, Cloudflare as fallback), detect null MX, missing domains and implicit MX.

## `checkDisposable` (type: `boolean`):

Flag throwaway mail domains using the bundled open list (about 9,900 domains).

## `checkRoleBased` (type: `boolean`):

Flag shared mailboxes such as info, kontakt, office, support, sales, noreply, buero, verwaltung.

## `checkFreeProvider` (type: `boolean`):

Flag consumer mail domains such as gmail.com, gmx.de, web.de, t-online.de, outlook.com, yahoo.com.

## `suggestTypos` (type: `boolean`):

Suggest the intended domain for common misspellings, for example gmial.com to gmail.com or gmx.dee to gmx.de.

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

Addresses processed at the same time. DNS answers are cached per domain within a run.

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

Safety limit per run. Duplicates are removed before the limit is applied.

## Actor input object example

```json
{
  "emails": [
    "info@siemens.com",
    "kontakt@web.de",
    "someone@gmial.com",
    "test@mailinator.com",
    "not-an-email"
  ],
  "emailsText": "",
  "checkDns": true,
  "checkDisposable": true,
  "checkRoleBased": true,
  "checkFreeProvider": true,
  "suggestTypos": true,
  "concurrency": 20,
  "maxEmails": 100000
}
```

# Actor output Schema

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

One item per unique address: input, email (normalized), status (valid-looking, risky, invalid), score (0 to 100), reasons, reasonCodes, localPart, domain, asciiDomain, syntaxValid, didYouMean, isDisposable, isRoleBased, isFreeProvider, domainExists, hasMx, nullMx, implicitMx, mxRecords, mailProvider, checkedAt; or input and error.

# 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": [
        "info@siemens.com",
        "kontakt@web.de",
        "someone@gmial.com",
        "test@mailinator.com",
        "not-an-email"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("webify-lab/email-verifier-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": [
        "info@siemens.com",
        "kontakt@web.de",
        "someone@gmial.com",
        "test@mailinator.com",
        "not-an-email",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("webify-lab/email-verifier-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": [
    "info@siemens.com",
    "kontakt@web.de",
    "someone@gmial.com",
    "test@mailinator.com",
    "not-an-email"
  ]
}' |
apify call webify-lab/email-verifier-no-smtp --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,webify-lab/email-verifier-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/5WtlCifDvukuEsbyP/builds/G7cHLSj3jXTm2v5vB/openapi.json
