# Bulk Email Verifier — Gmail, Outlook & Business Validation (`andrew_babo/email-verifier-bulk-validator`) Actor

Verify email lists at scale. Get honest valid/invalid verdicts for Gmail, Google Workspace, Microsoft 365, Outlook and business domains. No fake accuracy.

- **URL**: https://apify.com/andrew\_babo/email-verifier-bulk-validator.md
- **Developed by:** [Andrew Babo](https://apify.com/andrew_babo) (community)
- **Categories:** Lead generation, Developer tools
- **Stats:** 248 total users, 66 monthly users, 96.6% 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?

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 — Verify Gmail, Outlook & Business Emails at Scale

Clean any email list before you send. This Actor gives you honest, mailbox-level answers for **Gmail, Google Workspace, Microsoft 365, Outlook** and custom business domains — without sending a single email.

Most bulk verifiers return "unknown" for Gmail and Outlook because those providers hide mailbox existence. This Actor goes further: it can ask Google's sign-in page directly and Microsoft's HTTPS endpoint directly, so you get real `valid` / `invalid` verdicts instead of guesses.

### Why use this Actor

- **Cut bounce rate** — remove invalid, disposable and role-based addresses before your campaign.
- **Protect sender reputation** — no test emails are sent, so your domain is never flagged for probing.
- **Verify Gmail & Outlook** — get concrete verdicts on the providers most tools can only guess about.
- **Cheap at scale** — addresses are grouped by domain and checked in shared sessions, so large lists cost only Apify compute.
- **Honest results** — addresses that genuinely cannot be verified are labelled `unknown`, never faked as `valid`.

### What makes it different

| Provider / situation | Typical verifier | This Actor |
| --- | --- | --- |
| Gmail / Google Workspace | "Unknown" or guessed | `valid` / `invalid` via browser probe when you add residential proxies |
| Microsoft 365 / Outlook | "Unknown" or guessed | `valid` / `invalid` via HTTPS check |
| Catch-all / accept-all domains | Often guessed as `valid` | Clearly labelled `catch_all` so you decide the risk |
| Secure gateways (Proofpoint, Mimecast, Barracuda) | Often guessed as `invalid` | Labelled `unknown` + reason, protecting your reputation |
| Disposable / throwaway domains | Mixed handling | Marked `invalid` (or `risky` if you prefer) |

### Quick start

#### 1. From the Apify Console

1. Paste your email list into the **Emails to verify** field.
2. Choose **Balanced** speed (recommended).
3. If you want to verify Gmail / Google Workspace addresses, turn on **Verify Google mailboxes via the sign-in page** and paste your residential proxies into **Residential proxies**.
4. Click **Run**.
5. Download results from the Dataset tab.

#### 2. Minimal JSON input

```json
{
  "emails": [
    "lead@gmail.com",
    "contact@company.com",
    "support@apify.com"
  ],
  "speed": "balanced"
}
```

#### 3. Verify Gmail / Google Workspace (recommended setup)

Google blocks datacenter IPs, so Gmail verification needs real residential or ISP proxies.

```json
{
  "emails": ["lead@gmail.com", "name@company.com"],
  "speed": "balanced",
  "googleBrowserProbe": true,
  "residentialProxies": [
    "http://user:pass@host:port",
    "socks5://user:pass@host:1080"
  ],
  "googleProbeConcurrency": 4,
  "googleProbeMaxPerProxyPerHour": 60
}
```

- `googleBrowserProbe` — turns on the Gmail / Google Workspace check.
- `residentialProxies` — list of HTTP(S) or SOCKS5 proxies. Rotated round-robin.
- `googleProbeConcurrency` — how many browsers run at once. Keep it low (2–4) to stay under Google's radar.
- `googleProbeMaxPerProxyPerHour` — hourly quota per proxy. Exceeded proxies are rested automatically.

#### 4. Run it from your code

Use the Apify API or any SDK. The Actor returns a Dataset with one item per email and a summary in the key-value store.

```bash
curl -X POST https://api.apify.com/v2/acts/andrew_babo~email-verifier-bulk-validator/runs \
  -H 'Content-Type: application/json' \
  -d '{
    "emails": ["lead@gmail.com", "contact@company.com"],
    "speed": "balanced",
    "googleBrowserProbe": true,
    "residentialProxies": ["http://user:pass@host:port"]
  }'
```

### Output explained

One row per email:

```json
{
  "email": "lead@gmail.com",
  "domain": "gmail.com",
  "verdict": "valid",
  "reason": "google_mailbox_exists",
  "provider": "google",
  "isDisposable": false,
  "isRoleAccount": false,
  "isFreeProvider": true,
  "checkedAt": "2026-09-07T10:04:58.207Z"
}
```

#### Verdicts

| Verdict | Meaning | Safe to send? |
| --- | --- | --- |
| `valid` | Mailbox confirmed to exist | Yes |
| `invalid` | Mailbox does not exist, domain has no mail server, or disposable domain | No |
| `catch_all` | Domain accepts every address; mailbox-level state is unknowable | Only with care |
| `risky` | Deliverable but problematic (e.g. mailbox full or Gravatar-only signal) | Low volume only |
| `unknown` | Provider does not disclose mailbox state, or the probe was blocked | Your call |

### Speed and cost

- Microsoft 365 / Outlook and business SMTP: **10,000–15,000 emails/hour** per run.
- Gmail / Google Workspace: roughly **60–120 emails/hour per residential proxy** (limited by Google, not the Actor).
- Large lists are grouped by domain and cached, so cost stays low even for hundreds of thousands of addresses.

### FAQ

**Does it send real emails?**
No. It only opens a mail-server handshake and never sends a `DATA` command.

**Do I need proxies?**

- Required for Gmail / Google Workspace verification (`googleBrowserProbe`).
- Recommended for real SMTP `RCPT TO` checks if your host blocks outbound port 25.
- Not required for Microsoft 365 / Outlook HTTPS checks.

**Why are some Gmail addresses still "unknown"?**
Either `googleBrowserProbe` is off, no residential proxies were supplied, or the proxies were blocked by Google. Try fresh proxies or lower the hourly quota per proxy.

**Can it verify Yahoo, iCloud, Proton or QQ?**
Those providers do not disclose mailbox existence. The Actor returns `unknown` with a clear reason instead of guessing.

**Can I resume a large run?**
Yes. Progress is checkpointed and a restarted run continues where it stopped.

**How many emails can I verify in one run?**
There is no hard limit. Paste hundreds of thousands of addresses or point the Actor at a public URL with one email per line.

### Keywords

bulk email verifier, verify Gmail in bulk, Gmail email verification, Google Workspace email verifier, Outlook email verification, Microsoft 365 email checker, SMTP email verification, email list cleaning, reduce bounce rate, email validator API, catch-all email detection, disposable email checker, role account detection, lead list hygiene.

# Actor input Schema

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

List of email addresses to verify. Paste up to hundreds of thousands of addresses.

## `emailsUrl` (type: `string`):

Public URL of a plain-text or CSV file with one email per line. Merged with the list above.

## `speed` (type: `string`):

fast = DNS + provider checks only (fastest). balanced = adds SMTP and catch-all detection. deep = same checks, lower concurrency for strict mail servers.

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

0 = use the speed preset. Each domain uses a single mail-server session, so this is the real parallelism.

## `enableSmtp` (type: `boolean`):

Try a real RCPT TO check on port 25. Automatically skipped when the host blocks port 25.

## `enableMicrosoftCheck` (type: `boolean`):

Verify Microsoft 365 / Outlook mailboxes over HTTPS - works even without SMTP access.

## `detectCatchAll` (type: `boolean`):

Probe a random address per domain to detect accept-all mail servers. Requires SMTP access.

## `disposableVerdict` (type: `string`):

How throwaway/disposable domains should be labelled in the results.

## `heloName` (type: `string`):

Hostname announced in EHLO/HELO. Use a real fully-qualified hostname you control for best acceptance.

## `mailFrom` (type: `string`):

Envelope sender used in MAIL FROM. Leave empty (default) to use the null sender <>, which the widest range of mail servers accept for probing. If you set an address, use a domain you own with valid SPF — otherwise many servers reject the probe and results degrade to "unknown".

## `perEmailTimeoutMs` (type: `integer`):

Hard deadline for a single address. When it elapses the address is reported as unknown instead of stalling the batch.

## `smtpProxyUrl` (type: `string`):

Optional SOCKS5 or HTTP proxy that allows outbound TCP port 25, e.g. socks5://user:pass@host:1080. Most cloud hosts (including Apify) block port 25, so without such a proxy the run uses DNS/provider-level checks only. When supplied, real SMTP RCPT TO probing is used and results become mailbox-accurate.

## `googleBrowserProbe` (type: `boolean`):

Ask Google's own sign-in page whether a gmail.com / Google Workspace mailbox exists. Requires residentialProxies - datacenter IPs are rejected by Google. Measured 30/30 correct on real + control addresses. Off by default.

## `residentialProxies` (type: `array`):

HTTP(S) or SOCKS5 residential/ISP proxies, e.g. http://user:pass@host:port. Rotated round-robin, each with an hourly quota and a 30-minute cooldown after repeated blocks.

## `googleProbeConcurrency` (type: `integer`):

How many headed browsers run at once. One browser per proxy; keep this low to stay under Google's radar.

## `googleProbeMaxPerProxyPerHour` (type: `integer`):

Hourly quota per proxy. Exceeded proxies are skipped rather than burnt.

## Actor input object example

```json
{
  "emails": [
    "support@apify.com",
    "clearly-not-real-mailbox@apify.com",
    "test@mailinator.com"
  ],
  "speed": "balanced",
  "maxConcurrency": 0,
  "enableSmtp": true,
  "enableMicrosoftCheck": true,
  "detectCatchAll": true,
  "disposableVerdict": "invalid",
  "heloName": "verifier.local",
  "perEmailTimeoutMs": 12000,
  "googleBrowserProbe": false,
  "googleProbeConcurrency": 2,
  "googleProbeMaxPerProxyPerHour": 60
}
```

# Actor output Schema

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

Dataset with one row per email: verdict, score, reason, provider and flags.

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

Totals, verdict breakdown, duration and emails/hour.

# 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": [
        "support@apify.com",
        "clearly-not-real-mailbox@apify.com",
        "test@mailinator.com"
    ],
    "mailFrom": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("andrew_babo/email-verifier-bulk-validator").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": [
        "support@apify.com",
        "clearly-not-real-mailbox@apify.com",
        "test@mailinator.com",
    ],
    "mailFrom": "",
}

# Run the Actor and wait for it to finish
run = client.actor("andrew_babo/email-verifier-bulk-validator").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": [
    "support@apify.com",
    "clearly-not-real-mailbox@apify.com",
    "test@mailinator.com"
  ],
  "mailFrom": ""
}' |
apify call andrew_babo/email-verifier-bulk-validator --silent --output-dataset

```

## MCP server setup

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

```

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/5ynIdNAL9aP7vhuVF/builds/Mtk9etcAMMwjZzgjR/openapi.json
