# Decision-Maker Email Finder — Verified B2B Contacts (`dev-hoss/decision-maker-email-finder`) Actor

Find decision-makers (CEO, founder, C-level, VP, director) at any company domain with high-confidence B2B email addresses. Crawls team, about and contact pages, infers the company email pattern, checks DNS/MX and scores each contact. No LLM, no proxies needed.

- **URL**: https://apify.com/dev-hoss/decision-maker-email-finder.md
- **Developed by:** [Hossam Mohamed](https://apify.com/dev-hoss) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $40.00 / 1,000 company checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Decision-Maker Email Finder — Verified B2B Contacts

Find **decision-makers** (CEO, founder, C-level, VP, director) at any company domain with **high-confidence B2B email addresses** — built for outbound teams, lead-gen agencies and AI agents.

Give it a list of domains. It crawls each company's homepage plus team / leadership / about / contact pages, extracts people and their roles, infers the company's email pattern from any published addresses, checks the domain's mail (MX) records, and returns ranked contacts with an honest confidence score for every email.

No LLM calls, no proxies needed, fully deterministic.

> Honest confidence labels on every email — `on-site`, pattern-observed, MX-confirmed or guess. No fake "verified" claims; you decide what is safe to send.

### AI agent quick start

**Actor tool ID:** `dev-hoss/decision-maker-email-finder`

- Send `domains` (1–200). Filter dataset items by `type === "contact"` for people; `type === "domain-summary"` gives coverage (people found, pattern, MX, provider).
- Rank by `emailConfidence` (`on-site` > `high` > `medium` > `low`) — the Actor already orders contacts by role seniority, then confidence, capped by `maxContactsPerDomain`.
- JavaScript-rendered team pages may yield no role-matched people: that is a `no-role-match` summary, not a failure.

### How confidence works (no fake "verified" labels)

| Confidence | Meaning |
|---|---|
| `on-site` | The company itself published this exact email next to the person |
| `high` | The email pattern was observed in ≥2 emails published on the site |
| `medium` | The standard `first.last@` pattern + the domain has mail (MX) records |
| `low` | A pattern guess without corroboration |
| `generic` | Role inbox (`info@`, `contact@`) — only if you enable generic emails |

We deliberately do **not** claim "verified deliverable" for pattern-based guesses — anyone promising that from a crawler is guessing too. Confidence ranks are honest so you can decide what to send.

### Quick start

```json
{
    "domains": ["basecamp.com", "automattic.com"],
    "maxContactsPerDomain": 3
}
```

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `domains` | array (required) | — | 1–200 company domains or URLs. A URL path is used as a hint (e.g. `https://acme.com/team`). |
| `roles` | array | senior list | Role keywords to match (case-insensitive, plurals handled). Edit to target departments or specific titles. |
| `maxContactsPerDomain` | integer | `3` | Contacts returned per company, ranked by seniority + confidence. |
| `maxPagesPerDomain` | integer | `6` | Homepage + team/about/contact pages per company. |
| `includeGenericEmails` | boolean | `false` | Also return `info@`-style inboxes when no person matches. |
| `concurrency` | integer | `5` | Domains processed in parallel. |
| `proxyConfiguration` | object | off | Optional. Public pages only — rarely needed. |

### Output (default dataset)

**`contact` — one per decision-maker:**

```json
{
    "type": "contact",
    "company": "basecamp.com",
    "name": "Jason Fried",
    "role": "co-founder",
    "email": "jason.fried@basecamp.com",
    "emailConfidence": "medium",
    "pattern": "first.last",
    "linkedinUrl": null,
    "mxFound": true,
    "mailProvider": "other",
    "sourceUrl": "https://basecamp.com/about",
    "checkedAt": "2026-09-12T12:00:00.000Z"
}
```

Plus `domain-summary` (coverage: people found, emails on site, pages fetched, pattern, MX), `error` (unreachable domains) and `info` records. Contacts are ranked by role seniority, then email confidence.

### Honest limitations

- **JavaScript-rendered team pages** (e.g. Zapier, GitHub) may yield no role-matched people — the run reports `no-role-match` instead of pretending. Static HTML sites (most SMB and mid-market companies) work best.
- Emails are pattern-inferred unless published on-site — sendability is never guaranteed. MX + provider checks catch dead domains and webmail, not full SMTP validation.
- Only public pages are visited. No logins, no scraping of LinkedIn member data.

### How much does it cost?

Pay per event: a small fee per domain checked plus a fee per contact found (the result itself). Compare: dedicated email-finder SaaS charges $30–$100+/month, and verified-contact actors charge ~$0.14 per contact.

### Who is this for?

- **Outbound / SDR teams** — find the right person at target accounts with a defensible email guess
- **Lead-gen agencies** — bulk domain lists in, ranked contacts out
- **Recruiters & journalists** — reach founders and executives directly
- **AI agents** — enrichment tool calls with structured, schema-documented output

### Use with AI agents

Documented JSON input schema, one stable record per contact, no auth beyond the caller's own Apify token. Simplest integration:

```
POST https://api.apify.com/acts/dev-hoss~decision-maker-email-finder/run-sync-get-dataset-items?token=YOUR_API_TOKEN
Content-Type: application/json

{"domains": ["basecamp.com", "automattic.com"], "maxContactsPerDomain": 3}
```

Also works with Apify's hosted MCP server (`mcp.apify.com`).

# Actor input Schema

## `domains` (type: `array`):

Company domains or URLs to search for decision-makers, e.g. \["basecamp.com", "https://zapier.com"]. Up to 200 per run.

## `roles` (type: `array`):

Role keywords to match against people's titles. Contacts whose role matches are ranked by seniority. Edit this list to target e.g. only \["ceo", "founder"] or add "marketing", "sales" for department heads.

## `maxContactsPerDomain` (type: `integer`):

Return at most this many contacts per company, ranked by role seniority and email confidence.

## `maxPagesPerDomain` (type: `integer`):

How many pages are fetched per company: the homepage plus team/leadership/about/contact pages discovered from it.

## `includeGenericEmails` (type: `boolean`):

Also return generic inboxes (info@, contact@, hello@) when no named decision-maker is found.

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

How many domains are processed in parallel.

## `proxyConfiguration` (type: `object`):

Optional proxy. Team pages and contact pages are public — rarely needed.

## Actor input object example

```json
{
  "domains": [
    "basecamp.com",
    "automattic.com"
  ],
  "roles": [
    "ceo",
    "chief",
    "founder",
    "co-founder",
    "owner",
    "president",
    "managing director",
    "partner",
    "cto",
    "cmo",
    "cio",
    "coo",
    "cro",
    "vp",
    "vice president",
    "head of",
    "director",
    "general manager"
  ],
  "maxContactsPerDomain": 3,
  "maxPagesPerDomain": 6,
  "includeGenericEmails": false,
  "concurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `contacts` (type: `string`):

One record per found contact: name, role, email, confidence score, source page and mail-provider facts.

# 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 = {
    "domains": [
        "basecamp.com",
        "automattic.com"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dev-hoss/decision-maker-email-finder").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 = {
    "domains": [
        "basecamp.com",
        "automattic.com",
    ],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("dev-hoss/decision-maker-email-finder").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 '{
  "domains": [
    "basecamp.com",
    "automattic.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call dev-hoss/decision-maker-email-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dev-hoss/decision-maker-email-finder"
        }
    }
}
```

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/oGnFctDJtokFDahcR/builds/0YFfdPlojgC3R2lcD/openapi.json
