# MailTester Ninja Email Verifier (`mailtester-ninja/email-verifier`) Actor

Verify email lists in bulk with each recipient’s mail server, without sending any message. Flags invalid, disposable and catch-all addresses. Runs on your MailTester Ninja key, free token included.

- **URL**: https://apify.com/mailtester-ninja/email-verifier.md
- **Developed by:** [MailTester Ninja](https://apify.com/mailtester-ninja) (community)
- **Categories:** Lead generation, Marketing, Automation
- **Features:** Limited permissions
- **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/actors/running/actors-in-store.md#pay-per-usage

## 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

## MailTester Ninja Email Verifier

Verify a list of email addresses in real time before you send. For each address, the Actor asks the recipient's mail server whether the mailbox exists, without sending any message, and tells you whether it is **valid**, **invalid** or **risky** (for example a catch-all domain that accepts every address). It runs on your own [MailTester Ninja](https://mailtester.ninja/) key, at the speed your key allows, and returns one row per address that you can export to CSV, Excel or JSON, or send to your CRM.

### What can it do?

- Check lists of up to 100,000 addresses per run, pasted one per line.
- Detect invalid mailboxes, domains with no mail server, disposable addresses and catch-all domains.
- Keep your results in the order of your list, with the domain and the mail server used for each check.
- Remove duplicates and ignore lines without an address, so you only pay for real checks.
- Stay within the rate of your key automatically, and resume after a temporary limit on its own.

### Why verify before you send?

Invalid addresses bounce, and too many bounces hurt your sender reputation and your deliverability. Verifying a list before a campaign, before cold outreach or before importing leads into a CRM keeps your bounce rate low. Customers report a bounce rate below 1% after verifying their lists with MailTester Ninja.

MailTester Ninja checks each address live with its mail server, so the answer reflects the mailbox as it is today, not a database built months ago. No copy of the addresses you verify is kept.

### How much does it cost?

You pay two things, both small:

- **Apify platform usage** for running the Actor. A run uses 256 MB of memory and mostly waits for mail servers, so even large lists cost very little. The Apify free plan is enough to try it.
- **Your MailTester Ninja key**, which sets how many addresses you can check a day:
  - a **free API token** (`mtf_...`, 50 checks a day for 7 days, no card) from [mailtester.ninja/free-email-verification-api](https://mailtester.ninja/free-email-verification-api/);
  - a **subscription key** (`sub_...`), with plans from $6.99 a week for 100,000 checks a day, on [mailtester.ninja/verify-emails-unlimited](https://mailtester.ninja/verify-emails-unlimited/).

Without a key, the Actor only checks the three sample addresses of the input, so you can see what the output looks like.

### How to use it

1. Paste your addresses in **Email addresses**, one per line. Lines such as `Jane Doe <jane@example.com>` or comma-separated lists work too.
2. Paste your MailTester Ninja key in **MailTester Ninja key**, without the braces. Apify stores it encrypted.
3. Click **Start**. Results appear as they come in; the status line shows the progress.
4. Download the results in the format you need, or use the Apify API, a schedule or an integration to send them elsewhere.

### Input example

```json
{
  "emails": [
    "info@apple.com",
    "hello@stripe.com",
    "no.such.user.2026@gmail.com"
  ],
  "apiKey": "sub_your_key"
}
```

### Output example

```json
[
  {
    "position": 1,
    "email": "info@apple.com",
    "result": "valid",
    "code": "ok",
    "message": "Accepted",
    "domain": "apple.com",
    "mx": "mx-in.g.apple.com",
    "checkedAt": "2026-11-03T21:52:10.000Z"
  },
  {
    "position": 2,
    "email": "hello@stripe.com",
    "result": "risky",
    "code": "mb",
    "message": "Catch-All",
    "domain": "stripe.com",
    "mx": "aspmx.l.google.com",
    "checkedAt": "2026-11-03T21:52:12.000Z"
  },
  {
    "position": 3,
    "email": "no.such.user.2026@gmail.com",
    "result": "invalid",
    "code": "ko",
    "message": "Rejected",
    "domain": "gmail.com",
    "mx": "gmail-smtp-in.l.google.com",
    "checkedAt": "2026-11-03T21:52:13.000Z"
  }
]
```

A summary of the run (counts per result and per verdict, duration) is saved in the key-value store under `OUTPUT`.

### What do the results mean?

| result | code | Typical messages | What to do |
|---|---|---|---|
| `valid` | `ok` | Accepted | Send. |
| `invalid` | `ko` | Rejected, No MX, Disposable, Limited, Invalid syntax | Remove from your list. |
| `risky` | `mb` | Catch-All, MX Error, Timeout, SPAM Block, Greylisted, Abuse | Uncertain. A catch-all domain accepts every address, so the mailbox cannot be confirmed. Decide by risk, or check again later for temporary answers. |
| `not_checked` | `--` | Daily limit reached, key required | No verdict. Never remove an address for this reason: check it again with a key or the next day. |

### Speed and limits

Each key allows its daily limit divided by 8,640 checks per 10 seconds, for all your tools together. The Actor reads the limit of your key and paces itself accordingly: about one check per second with a $6.99 plan, more with higher plans or a higher quantity at checkout. A free API token allows one check every 30 seconds. A check usually takes one to a few seconds, and up to 45 seconds for slow mail servers. If the daily limit of the key is reached during a run, the remaining addresses are returned as `not_checked`.

### Integrations

Run the Actor from the Apify API, on a schedule, or from Make, Zapier, n8n and other tools through Apify integrations. AI agents can call it through the Apify MCP server. MailTester Ninja also has its own [REST API](https://mailtester.ninja/api/), official SDKs and [integrations](https://mailtester.ninja/integrations/), and an email finder that guesses a work address from a name and a company domain.

### FAQ

**Does the Actor send emails to the addresses?** No. The check stops before any message is sent.

**Are my addresses stored?** MailTester Ninja keeps no copy of the addresses you verify. The results are stored in your own Apify storage, under your control. See the [privacy policy](https://mailtester.ninja/privacy/).

**Why is the key `free` refused?** That key is limited per IP address, and Apify shares its IP addresses between users. Use a free API token instead.

**Why are some addresses risky?** Some domains accept every address (catch-all), so no tool can tell whether a given mailbox exists there. Others answer with a temporary refusal: check them again later.

### Support

Questions, feedback or a feature request: write to contact@mailtester.ninja or use the [contact page](https://mailtester.ninja/contact/). You can also open an issue on this Actor.

# Changelog

This Actor's version history is a separate document: https://apify.com/mailtester-ninja/email-verifier/changelog.md

# Actor input Schema

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

One address per line. Duplicates are checked once. Up to 100,000 addresses per run.

## `apiKey` (type: `string`):

Your subscription key (sub\_...) from https://mailtester.ninja/verify-emails-unlimited/ or a free API token (mtf\_..., 50 checks a day) from https://mailtester.ninja/free-email-verification-api/. Paste it without the braces. Stored encrypted by Apify.

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

Upper bound on simultaneous checks. The Actor always stays within the rate of your key (its daily limit divided by 8,640 requests per 10 seconds), so you rarely need to change this.

## Actor input object example

```json
{
  "emails": [
    "info@apple.com",
    "hello@stripe.com",
    "no.such.user.2026@gmail.com"
  ],
  "maxConcurrency": 20
}
```

# Actor output Schema

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

One item per address with its result (valid, invalid, risky or not_checked), the verdict code and label, the domain and the mail server used.

## `summary` (type: `string`):

Counts per result and per verdict, number of addresses checked and run duration.

# 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@apple.com",
        "hello@stripe.com",
        "no.such.user.2026@gmail.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mailtester-ninja/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": [
        "info@apple.com",
        "hello@stripe.com",
        "no.such.user.2026@gmail.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("mailtester-ninja/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": [
    "info@apple.com",
    "hello@stripe.com",
    "no.such.user.2026@gmail.com"
  ]
}' |
apify call mailtester-ninja/email-verifier --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mailtester-ninja/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/3as22sOpZan57fCoU/builds/sRQz9Nne5Ox8nCaDQ/openapi.json
