# Bulk Email Deliverability & SMTP Verification (`nimbryxo-studio/bulk-email-deliverability-and-smtp-verification`) Actor

Check email addresses for syntax, MX records, disposable and role-based domains, and optionally SMTP mailbox existence and catch-all behavior, with a verdict and confidence score per address.

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

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## Bulk Email Deliverability & SMTP Verification

Feed this actor a list of email addresses and it checks each one's real deliverability — not just whether it's formatted correctly, but whether its domain can receive mail, whether it's a disposable or role-based address, and, at the deepest setting, whether the mailbox itself actually exists.

### What this actor does

- Validates email syntax and confirms the domain has valid MX (mail-exchange) records.
- Flags disposable/temporary email domains (matched against a bundled disposable-domain list) and role-based addresses such as `admin@`, `info@` or `support@`.
- Identifies addresses on common free consumer providers such as Gmail, Yahoo or Outlook (matched against a built-in list of domains).
- At the deepest verification setting, connects to the mail server to check whether the specific mailbox exists and whether the domain accepts any address at all (catch-all).
- Returns one record per unique address (duplicates are removed case-insensitively) with a verdict and a confidence score. Checks that were skipped at your chosen depth, or that came back inconclusive, are `null` inside `checks` rather than a guessed true/false.

### Output per email

| Field | Description |
|---|---|
| `email` | The normalized email address that was checked (the trimmed input as typed when the syntax check fails). |
| `verdict` | `valid`, `invalid`, `risky`, `disposable`, or `unknown`. |
| `confidence` | Confidence score from 0 to 100 for the verdict. |
| `checks.syntax` | Whether the address is correctly formatted. |
| `checks.mxRecord` | Whether the domain has valid mail-exchange records. |
| `checks.smtp` | `true` if the mail server accepted the mailbox, `false` if it answered "mailbox not found". `null` unless `verificationDepth` is `deep`, and also `null` in deep mode when the server's answer was inconclusive (timeout, temporary rejection, policy block). |
| `checks.disposable` | Whether the domain is a known disposable/temporary provider. `null` at `basic` depth. |
| `checks.roleBased` | Whether the address is a shared role address (e.g. `support@`). `null` at `basic` depth. |
| `checks.freeProvider` | Whether the domain is a free consumer email provider. `null` at `basic` depth. |
| `checks.catchAll` | Whether the domain accepted mail for a made-up test address at that domain. `null` unless `verificationDepth` is `deep`, or when that test was inconclusive. |
| `mxHost` | The domain's highest-priority mail server hostname; `null` when the syntax check failed or no MX record was found. |
| `reason` | Human-readable explanation for a non-valid verdict; `null` when the verdict is `valid`. |
| `verifiedAt` | ISO 8601 UTC timestamp of when the email was checked. |

If an unexpected error interrupts the check of one address, that address still gets a record: `verdict` is `unknown`, `confidence` is `0`, every `checks` value, `mxHost` and `verifiedAt` are `null`, and `reason` starts with `Verification error:`. When the syntax check fails, the remaining `checks` values are `null`; when no MX record is found, the disposable, role, free-provider, SMTP and catch-all checks stay `null`.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `emails` | List of strings | – | Email addresses to verify. Required. |
| `verificationDepth` | String (select) | `standard` | `basic` (syntax + MX only), `standard` (adds disposable/role-based/free-provider checks), or `deep` (adds mailbox-level SMTP verification and catch-all detection). |
| `concurrency` | Integer | `10` | Number of emails verified in parallel (1–50). |

#### Example: quick syntax and MX check

```json
{
  "emails": ["user@example.com", "test@gmail.com"],
  "verificationDepth": "basic"
}
```

#### Example: standard list-cleaning pass

```json
{
  "emails": ["user@example.com", "admin@tempmail.com", "sales@company.org"],
  "verificationDepth": "standard",
  "concurrency": 20
}
```

#### Example: maximum-accuracy deep check

```json
{
  "emails": ["prospect@target-company.com"],
  "verificationDepth": "deep",
  "concurrency": 5
}
```

### Use cases

- **List cleaning** — strip disposable and undeliverable addresses from a mailing list before a campaign.
- **Sign-up form validation** — batch-check addresses collected through a form to catch typos and throwaway domains.
- **Sales list hygiene** — verify prospect emails scraped or purchased elsewhere before outreach.
- **Bounce-rate reduction** — screen a list ahead of sending to avoid hitting invalid mailboxes.
- **CRM data quality** — periodically re-check stored contact emails for ones that have gone stale.

### FAQ

**How accurate is the verification?** `standard` depth catches syntax errors, missing MX records, disposable domains and role-based addresses. `deep` mode adds a mailbox-level SMTP check, but many mail servers rate-limit, greylist or refuse such checks. When that happens `checks.smtp` is `null`, and an address on a domain with MX records is still reported as `valid` with partial confidence, so a `valid` verdict on its own doesn't prove the mailbox exists.

**When is an address marked "risky"?** In `deep` mode the actor also asks the domain's mail server about a made-up address. If the server accepts that too, the domain is treated as catch-all: an accepted mailbox there proves little, so the verdict becomes `risky` and the confidence drops.

**What does an "unknown" verdict mean?** It appears when the check of that address hit an unexpected error. The `reason` field carries the error text and the `checks` values are `null`. A blocked or timed-out SMTP check does not produce `unknown`; see the accuracy answer above.

**Why are some `checks` fields `null`?** Each verification depth only runs a subset of checks, and checking stops early once an address fails syntax or has no MX record. Checks that weren't run, or whose answer was inconclusive, come back as `null` rather than a guessed value.

**What counts as a role-based address?** Addresses like `admin@`, `info@`, or `support@` that are typically shared by a team rather than belonging to one person — these tend to have higher bounce and lower engagement rates.

**Can I verify large batches?** Yes. Raise `concurrency` (up to 50) to speed up large lists. Records are written to the dataset once every address has been checked, so the dataset stays empty until the run is nearly finished.

**Does this rely on any third-party verification service?** No. MX and SMTP checks query DNS and the domain's own mail servers directly, and the disposable, role and free-provider checks use lists bundled with the actor.

# Actor input Schema

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

List of email addresses to verify

## `verificationDepth` (type: `string`):

How thoroughly to verify each email. Basic: syntax + MX only. Standard: adds disposable, role-based, and free provider checks. Deep: adds SMTP mailbox verification and catch-all detection.

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

Number of emails to verify in parallel. Higher values are faster but may trigger rate limits on SMTP servers.

## Actor input object example

```json
{
  "emails": [
    "test@gmail.com",
    "invalid@nonexistent-domain-xyz123.com"
  ],
  "verificationDepth": "standard",
  "concurrency": 10
}
```

# Actor output Schema

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

Dataset containing verification results for each email address

# 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",
        "invalid@nonexistent-domain-xyz123.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nimbryxo-studio/bulk-email-deliverability-and-smtp-verification").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",
        "invalid@nonexistent-domain-xyz123.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("nimbryxo-studio/bulk-email-deliverability-and-smtp-verification").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",
    "invalid@nonexistent-domain-xyz123.com"
  ]
}' |
apify call nimbryxo-studio/bulk-email-deliverability-and-smtp-verification --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nimbryxo-studio/bulk-email-deliverability-and-smtp-verification"
        }
    }
}
```

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/9RiemV8vYMg3CcH3S/builds/fENPkrRTVUG1ZZsjz/openapi.json
