# Bulk SMTP Email Verifier (`automation-lab/smtp-email-verifier`) Actor

Verify email addresses via full SMTP RCPT TO handshake — detects valid, invalid, catch-all, and unknown mailboxes. No API keys. ~$0.001/email.

- **URL**: https://apify.com/automation-lab/smtp-email-verifier.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Developer tools
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 SMTP Email Verifier

Verify email addresses using a full SMTP RCPT TO handshake — the same method professional email validation services use. Goes beyond DNS MX lookup to actually confirm whether a mailbox exists on the mail server, detect catch-all domains, and classify results as **valid**, **invalid**, **catch-all**, or **unknown**.

### 🔍 What does it do?

This actor performs deep email verification by:

1. **Syntax validation** — checks RFC 5321 format before touching the network
2. **DNS MX lookup** — confirms the domain has a working mail server
3. **SMTP RCPT TO handshake** — connects to the actual mail server and asks whether the mailbox exists, without sending any email
4. **Catch-all detection** — tests whether the domain accepts all addresses (making SMTP verification unreliable for that domain)
5. **Provider detection** — identifies mail providers (Google Workspace, Microsoft 365, Proofpoint, etc.)
6. **Disposable domain check** — flags temporary email providers
7. **Role-based address detection** — flags admin@, support@, info@, and similar addresses

#### How is it different from the Bulk Email MX Verifier?

| Feature | [Bulk Email MX Verifier](https://apify.com/automation-lab/email-mx-verifier) | **Bulk SMTP Email Verifier** |
|---------|--------------|------------------------------|
| Syntax check | ✅ | ✅ |
| DNS MX lookup | ✅ | ✅ |
| SMTP RCPT TO | ❌ | ✅ |
| Catch-all detection | ❌ | ✅ |
| Confirms mailbox exists | ❌ | ✅ |
| Speed | Very fast | Slower (network I/O per domain) |
| Cost | Lower | Slightly higher |
| Best for | Fast bulk pre-screening | Accurate final verification |

Use the MX Verifier first to screen out obvious invalid emails, then run the SMTP Verifier on the remaining list for deeper accuracy.

### 👤 Who is it for?

- **Email marketers** cleaning lists before campaigns to reduce bounce rates and protect sender reputation
- **Sales teams** validating leads from scrapers, CRMs, or enrichment tools before outreach
- **SaaS developers** verifying email addresses at signup or during onboarding
- **DevOps/IT teams** auditing contact databases for deliverability issues
- **Data engineers** building ETL pipelines that include email quality scoring
- **Recruiters** verifying candidate contact emails before sending interview invitations

### 💡 Why use this actor?

- **No API keys required** — direct SMTP connections, no third-party email validation service fees
- **Catch-all domain detection** — prevents false positives from domains that accept everything
- **Bulk processing** — verify thousands of emails in a single run with configurable concurrency
- **Detailed output** — SMTP response codes, provider detection, and structured result classification
- **Privacy-safe** — no email data is stored or shared externally
- **Pay-per-email pricing** — only pay for what you verify

### 📊 Output data

| Field | Type | Description |
|-------|------|-------------|
| `email` | string | The email address that was verified |
| `smtpStatus` | string | `valid`, `invalid`, `catch-all`, or `unknown` |
| `isValid` | boolean | `true` only when SMTP returned 250 OK |
| `isCatchAll` | boolean | `true` if domain accepts all addresses |
| `smtpCode` | number | Raw SMTP response code (e.g. 250, 550) |
| `smtpMessage` | string | Raw SMTP response message |
| `isValidSyntax` | boolean | Whether email format is valid |
| `syntaxErrors` | array | List of syntax errors if any |
| `domain` | string | Email domain |
| `hasMxRecords` | boolean | Whether domain has DNS MX records |
| `mxRecords` | array | MX records with priority and hostname |
| `mxProvider` | string | Detected mail provider name |
| `isDisposable` | boolean | Whether domain is a known temp email provider |
| `isRoleBased` | boolean | Whether address is role-based (admin@, info@, etc.) |
| `suggestion` | string | Typo correction suggestion if detected |
| `error` | string | Error message if verification failed unexpectedly |
| `checkedAt` | string | ISO 8601 timestamp of verification |

#### Understanding SMTP status values

- **`valid`** — SMTP server returned 250 OK for RCPT TO. Mailbox exists (unless domain is catch-all).
- **`invalid`** — SMTP server returned 550–554 permanent failure. Mailbox does not exist.
- **`catch-all`** — Domain accepts all addresses regardless of mailbox existence. Individual mailbox checks are unreliable.
- **`unknown`** — Server was unreachable, timed out, returned a temporary 4xx error, or blocked verification. Not necessarily invalid — retry later or treat as risky.

### 🛠️ How to use it

#### Step 1 — Prepare your email list

Enter email addresses directly in the **Email addresses** input field, one per line. The actor deduplicates automatically.

#### Step 2 — Configure SMTP settings (optional)

- **SMTP port**: Use **25** for direct SMTP (blocked on many cloud providers — works reliably on Apify's cloud infrastructure), **587** for submission (requires AUTH on most servers), or **465** for SMTPS.
- **Timeout**: Increase to 20–30 seconds for slow international mail servers.
- **Catch-all detection**: Leave enabled unless you're verifying disposable/test domains you know accept everything.

#### Step 3 — Run and export

Click **Start** and wait for results. Export to CSV, JSON, or Excel from the **Dataset** tab. Filter by `smtpStatus = "valid"` to get your clean list.

### ⚙️ Input parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `emails` | array | required | Email addresses to verify |
| `fromEmail` | string | `verify@smtp-check.test` | MAIL FROM address used in SMTP handshake |
| `smtpPort` | integer | `25` | TCP port for SMTP connection (25, 587, or 465) |
| `smtpTimeoutSecs` | integer | `15` | Seconds to wait per SMTP connection |
| `catchAllTest` | boolean | `true` | Test domains for catch-all behavior before verifying mailboxes |
| `retryCount` | integer | `1` | Retry attempts on temporary failures |
| `concurrency` | integer | `10` | Max simultaneous SMTP connections |
| `maxEmailsPerDomain` | integer | `20` | Max emails verified per domain before pausing (anti-rate-limit) |

### 📤 Output example

```json
{
  "email": "user@example.com",
  "smtpStatus": "valid",
  "isValid": true,
  "isCatchAll": false,
  "smtpCode": 250,
  "smtpMessage": "OK",
  "isValidSyntax": true,
  "syntaxErrors": [],
  "domain": "example.com",
  "hasMxRecords": true,
  "mxRecords": [{"priority": 10, "exchange": "mail.example.com"}],
  "mxProvider": "Google Workspace",
  "isDisposable": false,
  "isRoleBased": false,
  "suggestion": null,
  "error": null,
  "checkedAt": "2026-04-07T10:30:00.000Z"
}
````

### 💡 Tips for best results

#### Use with Bulk Email MX Verifier for cost efficiency

Run the [MX Verifier](https://apify.com/automation-lab/email-mx-verifier) first to filter out syntax errors, missing MX records, and disposable domains. Then run the SMTP Verifier only on emails that passed the MX check. This typically cuts your SMTP verification list by 15–30%, reducing cost and time.

#### Handle catch-all domains

Catch-all domains (where the server accepts any address) cannot be verified via SMTP. Common catch-all examples: many corporate domains, Zoho Mail, some cPanel hosts. For catch-all emails, use engagement data (open/click history) to determine validity instead.

#### Interpret `unknown` results carefully

`unknown` does NOT mean invalid. It means the server:

- Did not respond (greylisting or firewall)
- Returned a temporary 4xx error (try again in 5–10 minutes)
- Rejected the verification probe (some servers block RCPT TO probing)

For large list cleaning, treat `unknown` as "unverifiable" rather than "invalid" to avoid false positives.

#### Adjust concurrency for large lists

- **Small lists (< 500 emails)**: Default concurrency of 10 is fine
- **Large lists (1,000+)**: Keep concurrency at 10–20 to avoid triggering anti-spam rate limits on mail servers
- **Single domain lists**: Set `maxEmailsPerDomain` to 5–10 to avoid being blocked

#### Port selection

Port 25 provides the most accurate SMTP verification but is blocked on many cloud providers' outbound traffic. **Apify's cloud infrastructure supports port 25 outbound**, making this actor more effective when run on Apify than on your own server. Port 587 (submission) typically requires AUTH, so verification will return `unknown` for most servers on that port.

### 💰 How much does it cost to verify email addresses via SMTP?

Pricing uses pay-per-event (PPE) billing — you only pay for what you actually verify.

| Plan | Start fee | Per email verified |
|------|-----------|-------------------|
| FREE | $0.035 | $0.00100 |
| BRONZE | $0.033 | $0.00090 |
| SILVER | $0.030 | $0.00080 |
| GOLD | $0.026 | $0.00065 |
| PLATINUM | $0.021 | $0.00050 |
| DIAMOND | $0.018 | $0.00040 |

**Example costs:**

- 100 emails → ~$0.14 (FREE tier)
- 1,000 emails → ~$1.04 (FREE tier) | ~$0.93 (BRONZE)
- 10,000 emails → ~$10.04 (FREE tier) | ~$6.53 (GOLD)

All runs include start + per-email charges regardless of verification result (valid, invalid, catch-all, or unknown).

### 🔌 Integrations

#### Connect with Google Sheets

Use Apify's Google Sheets integration to automatically export verified email results to a spreadsheet. Map `smtpStatus`, `isValid`, and `isCatchAll` columns for easy list filtering.

#### Zapier / Make.com workflow

Trigger email list verification when new contacts are added to your CRM:

1. New contact added in HubSpot/Salesforce → Apify actor run starts
2. Actor verifies email → pushes results to dataset
3. Zapier webhook reads dataset → updates CRM contact with deliverability score

#### n8n automation

Combine with n8n's HTTP node to verify emails inline in your data enrichment pipeline. Pass the dataset output directly to your email service provider (Mailchimp, SendGrid, ActiveCampaign) to suppress invalid addresses.

### 🤖 Use with Claude (MCP)

Connect this actor to Claude as a tool for real-time email list verification in your AI workflows.

**Claude Code:**

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/smtp-email-verifier"
```

**Claude Desktop / Cursor / VS Code** (`claude_desktop_config.json` or `mcp.json`):

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com?tools=automation-lab/smtp-email-verifier"
        }
    }
}
```

**Example prompts:**

- *"Verify these 50 emails via SMTP and give me a summary of valid vs invalid vs catch-all"*
- *"Check if these email addresses from our CRM export are deliverable"*
- *"Identify which of these prospect emails have catch-all domains"*

### 🖥️ API usage

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });

const run = await client.actor('automation-lab/smtp-email-verifier').call({
    emails: ['user@example.com', 'contact@company.com'],
    smtpPort: 25,
    smtpTimeoutSecs: 15,
    catchAllTest: true,
    concurrency: 10,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
const valid = items.filter(i => i.smtpStatus === 'valid');
console.log(`Valid emails: ${valid.length}/${items.length}`);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient(token='YOUR_API_TOKEN')

run = client.actor('automation-lab/smtp-email-verifier').call(run_input={
    'emails': ['user@example.com', 'contact@company.com'],
    'smtpPort': 25,
    'smtpTimeoutSecs': 15,
    'catchAllTest': True,
    'concurrency': 10,
})

items = client.dataset(run['defaultDatasetId']).list_items().items
valid = [i for i in items if i['smtpStatus'] == 'valid']
print(f"Valid emails: {len(valid)}/{len(items)}")
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/automation-lab~smtp-email-verifier/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "emails": ["user@example.com", "contact@company.com"],
    "smtpPort": 25,
    "smtpTimeoutSecs": 15,
    "catchAllTest": true,
    "concurrency": 10
  }'
```

### ⚖️ Legal and compliance

This actor performs passive SMTP verification — it connects to mail servers and sends standard SMTP commands (EHLO, MAIL FROM, RCPT TO) but never delivers any email. This is standard practice used by all major email validation services and is compliant with SMTP standards (RFC 5321).

**Before verifying email lists:**

- Ensure you have a lawful basis for processing the email addresses under GDPR/CCPA
- Only verify emails you collected legitimately
- Do not use verification results to spam or harass individuals

This actor does not store any email addresses or verification results beyond your own Apify dataset storage. All SMTP connections are made directly from Apify's infrastructure.

### ❓ FAQ

**Q: Why are many results showing as `unknown`?**

A: Most cloud hosting environments block outbound port 25 to prevent spam. If you're running locally or on a cloud provider that blocks port 25, most results will timeout. On Apify's cloud, port 25 is available for legitimate SMTP verification. Alternatively, switch to port 587 — though most servers require AUTH on that port.

**Q: What does "catch-all" mean and why are those emails `isValid: false`?**

A: A catch-all domain accepts any email address regardless of whether a real mailbox exists. For example, `anyrandomstring@catchalldomain.com` will return a 250 OK response. Since we can't distinguish real mailboxes from non-existent ones, we mark these as `catch-all` and set `isValid: false`. Treat catch-all addresses as "unverifiable" in your workflow.

**Q: Is this the same as sending a test email?**

A: No. The SMTP handshake stops after RCPT TO — no email is ever composed or delivered. The connection is closed (QUIT) after receiving the RCPT TO response. This is a standard passive probe technique used by every professional email validation service.

**Q: Why is my Gmail/Microsoft address showing as `unknown`?**

A: Large providers like Google and Microsoft actively block RCPT TO probing as an anti-abuse measure. They accept the SMTP connection but return a generic response that doesn't reveal whether a specific mailbox exists. This is expected behavior and is why even enterprise email validation services struggle with Google/Microsoft addresses.

**Q: How long does verification take?**

A: SMTP verification is I/O-bound — each email requires a full TCP connection and SMTP handshake. With the default 15-second timeout and 10 concurrency, expect roughly 30–60 emails/minute for responding servers, or slower when timeouts occur frequently.

**Q: How is this different from free online email verification tools?**

A: Online tools typically use third-party databases and APIs with limited free tiers. This actor connects directly to mail servers with no intermediary, giving you raw SMTP responses. You also get batch processing, API access, and data stored in your own Apify account.

### 🔗 Related actors

- [Bulk Email MX Verifier](https://apify.com/automation-lab/email-mx-verifier) — faster DNS-only verification for pre-screening large lists
- [Email Finder](https://apify.com/automation-lab/email-finder) — find email addresses from company domains
- [Email Deliverability Checker](https://apify.com/automation-lab/email-deliverability-checker) — SPF, DKIM, DMARC, blacklist checks
- [Email Enrichment](https://apify.com/automation-lab/email-enrichment) — enrich email addresses with company and contact data
- [Email Syntax Validator](https://apify.com/automation-lab/email-syntax-validator) — lightweight syntax-only validation

# Actor input Schema

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

List of email addresses to verify via SMTP. Accepts up to 10,000 emails per run.

## `fromEmail` (type: `string`):

Email address to use in the SMTP MAIL FROM command. Some servers reject connections from free email providers.

## `smtpPort` (type: `integer`):

TCP port to connect to on the MX server. Use 25 (standard SMTP), 587 (submission), or 465 (SMTPS). Port 25 is blocked on many cloud providers.

## `smtpTimeoutSecs` (type: `integer`):

Maximum seconds to wait for each SMTP connection and response. Increase for slow mail servers.

## `catchAllTest` (type: `boolean`):

Test each domain with a random non-existent address first. If the server accepts it, the domain is catch-all — individual mailbox checks are unreliable.

## `retryCount` (type: `integer`):

Number of additional retry attempts on connection failure or temporary errors (4xx responses).

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

Maximum number of simultaneous SMTP connections. Keep low to avoid triggering rate limits on mail servers.

## `maxEmailsPerDomain` (type: `integer`):

Throttle verification per domain to avoid being blocked. Emails beyond this limit per domain per time window are queued.

## Actor input object example

```json
{
  "emails": [
    "user@google.com",
    "contact@github.com",
    "test@mailinator.com",
    "invalid-email",
    "admin@microsoft.com"
  ],
  "fromEmail": "verify@smtp-check.test",
  "smtpPort": 25,
  "smtpTimeoutSecs": 15,
  "catchAllTest": true,
  "retryCount": 1,
  "concurrency": 10,
  "maxEmailsPerDomain": 20
}
```

# Actor output Schema

## `overview` (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": [
        "user@google.com",
        "contact@github.com",
        "test@mailinator.com",
        "invalid-email",
        "admin@microsoft.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/smtp-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": [
        "user@google.com",
        "contact@github.com",
        "test@mailinator.com",
        "invalid-email",
        "admin@microsoft.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/smtp-email-verifier").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "user@google.com",
    "contact@github.com",
    "test@mailinator.com",
    "invalid-email",
    "admin@microsoft.com"
  ]
}' |
apify call automation-lab/smtp-email-verifier --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/smtp-email-verifier",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Bulk SMTP Email Verifier",
        "description": "Verify email addresses via full SMTP RCPT TO handshake — detects valid, invalid, catch-all, and unknown mailboxes. No API keys. ~$0.001/email.",
        "version": "0.1",
        "x-build-id": "vFyZRaTRN2ok20l60"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/automation-lab~smtp-email-verifier/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-automation-lab-smtp-email-verifier",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/automation-lab~smtp-email-verifier/runs": {
            "post": {
                "operationId": "runs-sync-automation-lab-smtp-email-verifier",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/automation-lab~smtp-email-verifier/run-sync": {
            "post": {
                "operationId": "run-sync-automation-lab-smtp-email-verifier",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "emails"
                ],
                "properties": {
                    "emails": {
                        "title": "📧 Email addresses",
                        "type": "array",
                        "description": "List of email addresses to verify via SMTP. Accepts up to 10,000 emails per run.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "fromEmail": {
                        "title": "📤 Sender email (MAIL FROM)",
                        "type": "string",
                        "description": "Email address to use in the SMTP MAIL FROM command. Some servers reject connections from free email providers.",
                        "default": "verify@smtp-check.test"
                    },
                    "smtpPort": {
                        "title": "🔌 SMTP port",
                        "minimum": 1,
                        "maximum": 65535,
                        "type": "integer",
                        "description": "TCP port to connect to on the MX server. Use 25 (standard SMTP), 587 (submission), or 465 (SMTPS). Port 25 is blocked on many cloud providers.",
                        "default": 25
                    },
                    "smtpTimeoutSecs": {
                        "title": "⏱️ SMTP timeout (seconds)",
                        "minimum": 5,
                        "maximum": 60,
                        "type": "integer",
                        "description": "Maximum seconds to wait for each SMTP connection and response. Increase for slow mail servers.",
                        "default": 15
                    },
                    "catchAllTest": {
                        "title": "🎯 Detect catch-all domains",
                        "type": "boolean",
                        "description": "Test each domain with a random non-existent address first. If the server accepts it, the domain is catch-all — individual mailbox checks are unreliable.",
                        "default": true
                    },
                    "retryCount": {
                        "title": "🔄 Retry attempts",
                        "minimum": 0,
                        "maximum": 3,
                        "type": "integer",
                        "description": "Number of additional retry attempts on connection failure or temporary errors (4xx responses).",
                        "default": 1
                    },
                    "concurrency": {
                        "title": "⚡ Concurrency",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of simultaneous SMTP connections. Keep low to avoid triggering rate limits on mail servers.",
                        "default": 10
                    },
                    "maxEmailsPerDomain": {
                        "title": "🏢 Max emails per domain per batch",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Throttle verification per domain to avoid being blocked. Emails beyond this limit per domain per time window are queued.",
                        "default": 20
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
