# Public Email Domain Verifier (`fetch_cat/public-osint-email-lookup-verifier-scraper`) Actor

Check email syntax, DNS mail routing, and public Gravatar presence without mailbox claims.

- **URL**: https://apify.com/fetch\_cat/public-osint-email-lookup-verifier-scraper.md
- **Developed by:** [Hanna Nosova](https://apify.com/fetch_cat) (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.38 / 1,000 item processeds

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?

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

## Public Email Domain Verifier

Public Email Domain Verifier normalizes a batch of email addresses and returns transparent, no-login signals for lead-list cleanup, form validation, and developer workflows. It checks email syntax, public DNS mail routing, role-account patterns, provider category, and an optional public Gravatar response. It does **not** log in, send email, access private data, or claim that a mailbox exists, belongs to someone, or can receive mail.

### What you get

Each submitted address produces one dataset row. Core fields include `email`, `normalizedEmail`, `syntaxValid`, `localPart`, `domain`, `tld`, `isRoleAccount`, `providerCategory`, `mxRecords`, `gravatarFound`, `gravatarProfileUrl`, `dnsStatus`, `verificationScope`, `warnings`, and `checkedAt`.

`verificationScope` and `warnings` make the boundary explicit: MX records show a domain's published mail routing only. A `gravatarFound` result is public profile-presence evidence, not identity or mailbox evidence.

### Input recipes

Provide one to 100 email addresses in `emails`. Use `maxConcurrency` (1–10) to control parallel public DNS checks. **Practical limits:** availability depends on public DNS and Gravatar responding during the run. DNS routing may change after `checkedAt`; retry a `lookup_failed` row later rather than treating it as a permanent result.

#### Recipe: clean a small lead list

```json
{
  "emails": ["contact@apify.com", "sales@example.org", "not-an-email"],
  "maxConcurrency": 3
}
```

#### Recipe: check role inboxes for routing signals

```json
{
  "emails": ["support@apify.com", "info@example.com", "hello@company.test"],
  "maxConcurrency": 5
}
```

#### Recipe: export normalized addresses

```json
{
  "emails": [" Contact@Apify.com ", "admin@domain.invalid"],
  "maxConcurrency": 1
}
```

Download the default dataset as JSON, CSV, Excel, or through the Apify API after the run completes.

### Reading results

- `syntaxValid: false` means the input did not match the actor's conservative email syntax check; DNS is not queried.
- `dnsStatus: mx_present` means public MX records were returned for the domain.
- `dnsStatus: no_mx` means public DNS returned no MX data or the domain could not be found.
- `dnsStatus: lookup_failed` preserves a transient DNS failure as an output row instead of silently dropping it.
- `providerCategory` is `free` for a small maintained list of common consumer providers, otherwise `business_or_custom`.
- `isRoleAccount` flags common local parts such as `info`, `support`, `sales`, and `admin`.

### What this verifier cannot prove

This Actor is deliberately conservative. It cannot verify inbox ownership, delivery, account access, or whether a person is associated with an address. It does not use SMTP probing, breached-data sources, password-protected sources, or private credentials. Treat its output as public DNS and normalization evidence only.

### Pricing

See the [live Apify Pricing tab](https://apify.com/fetch_cat/public-osint-email-lookup-verifier-scraper/pricing) for current start and per-item rates by plan. Invalid addresses still produce a useful result row and are charged as processed items.

### Examples

Use the input recipes above as copy-paste examples in the Apify Console. For automation, pass the same JSON to `fetch_cat/public-osint-email-lookup-verifier-scraper` and read the default dataset. Start with a short representative batch before processing a large list.

### Who is it for?

This Actor is for CRM operators, sales-operations teams, developers, and researchers who need a reproducible public-data check before routing or enriching a list. It is not a deliverability service, identity verifier, or consent record.

### API usage

Run `fetch_cat/public-osint-email-lookup-verifier-scraper` with an `emails` array using the Apify API, JavaScript client, Python client, n8n, Make, or any tool that can start an Actor and download a dataset. Preserve `warnings` and `verificationScope` in downstream tables so other users understand the signal boundary.

#### JavaScript

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/public-osint-email-lookup-verifier-scraper').call({ emails: ['contact@apify.com'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('APIFY_TOKEN')
run = client.actor('fetch_cat/public-osint-email-lookup-verifier-scraper').call(run_input={'emails': ['contact@apify.com']})
items = client.dataset(run['defaultDatasetId']).list_items().items
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/fetch_cat~public-osint-email-lookup-verifier-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"emails":["contact@apify.com"]}'
```

### MCP

Add the Actor to a compatible MCP client, then ask the assistant to run it with an `emails` array:

```bash
claude mcp add apify -- npx -y @apify/mcp-server
```

```json
{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": ["-y", "@apify/mcp-server"],
      "env": { "APIFY_TOKEN": "YOUR_APIFY_TOKEN" }
    }
  }
}
```

Example prompts: “Verify public DNS routing for `contact@apify.com`” or “Normalize these emails and retain the warnings.” In an MCP-enabled workflow, keep `verificationScope` and `warnings` with each row; they are required context for interpreting an otherwise simple boolean signal.

### FAQ

#### Does an MX record prove an email address exists?

No. It proves only that the domain publishes mail-routing records. It does not validate an individual mailbox.

#### Does this Actor send an email or use SMTP verification?

No. It only performs local parsing and public DNS/Gravatar requests; it never sends an email.

#### Why did an invalid address still appear in the dataset?

The Actor preserves invalid input as a row with `dnsStatus: not_checked`, making it easy to filter or correct input without losing records.

#### Can I use this for a CRM import?

Yes, as a transparent pre-cleaning signal. Do not use it as proof of identity, consent, deliverability, or mailbox ownership.

#### Why is `gravatarFound` null sometimes?

The public request can time out or reject a request. `null` records an unavailable public observation; it is not a negative result.

#### How should I handle `lookup_failed`?

Keep the row and retry it later. The Actor does not hide a failed public DNS request behind a guessed value.

#### Is a free provider always a personal address?

No. `providerCategory` only classifies the domain from a limited common-provider list. It makes no claim about the user or their purpose.

#### What happens to duplicate emails?

The Actor removes exact duplicate submitted strings within a run so that a batch yields one row per unique input value.

### Related Actors

Use this public-signal verifier alongside your own consented lead sources and exports:

- [LinkedIn Jobs Scraper](https://apify.com/fetch_cat/linkedin-jobs-scraper) for public job-posting workflows.
- [Google Search Results Scraper](https://apify.com/fetch_cat/google-search-results-scraper) for public web-research workflows.
- [Website Content Crawler Lite](https://apify.com/fetch_cat/website-content-crawler-lite) to collect public company pages.
- [GitHub Repositories Search Scraper](https://apify.com/fetch_cat/github-repositories-search-scraper) for public developer-project discovery.
- [Amazon Products & Search Scraper](https://apify.com/fetch_cat/amazon-products-search-scraper) for public product research.

Combine this verifier with your existing CRM export or lead source, then filter records by `syntaxValid` and `dnsStatus` while retaining the original email and warnings for auditability.

### Support

Open an issue on this Actor's Apify page with the affected domain and observed `dnsStatus`. Do not include passwords, API tokens, or other sensitive information.

# Actor input Schema

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

One or more email addresses to normalize and inspect. Up to 100 per run.

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

Parallel public DNS lookups (1–10).

## Actor input object example

```json
{
  "emails": [
    "contact@apify.com",
    "not-an-email"
  ],
  "maxConcurrency": 5
}
```

# 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": [
        "contact@apify.com",
        "not-an-email"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetch_cat/public-osint-email-lookup-verifier-scraper").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": [
        "contact@apify.com",
        "not-an-email",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("fetch_cat/public-osint-email-lookup-verifier-scraper").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": [
    "contact@apify.com",
    "not-an-email"
  ]
}' |
apify call fetch_cat/public-osint-email-lookup-verifier-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fetch_cat/public-osint-email-lookup-verifier-scraper"
        }
    }
}

```

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/JhHBj4ETsy3IOBjRb/builds/h8tTfwmzFaHGKi3Fi/openapi.json
