# Leadership Contact Finder (`toolzerhub/leadership-contact-finder`) Actor

Crawl corporate websites to discover leadership contacts. Extracts names, titles, emails, LinkedIn URLs, phone numbers, and infers department, seniority, and location for each decision maker.

- **URL**: https://apify.com/toolzerhub/leadership-contact-finder.md
- **Developed by:** [ToolzerHub](https://apify.com/toolzerhub) (community)
- **Categories:** Lead generation, Automation, Agents
- **Stats:** 2 total users, 1 monthly users, 75.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 results

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

## Leadership Contact Finder

An Apify Actor that crawls corporate websites, discovers leadership contacts (executives, founders, VPs, directors, etc.), generates their likely email addresses from detected domain patterns, and optionally verifies them via SMTP.

### Features

- **Targeted page discovery** — Sitemap + homepage navigation scanning for `/about`, `/team`, `/leadership`, `/people`, `/founders`, `/management`, and similar pages.
- **Multi-strategy person extraction**
  - Schema.org JSON-LD `Person` objects (highest confidence)
  - DOM pattern detection for team-member containers
  - Text regex fallback for title + name patterns
- **Email pattern detection** — Learns common patterns (`first.last`, `f.last`, `first`, `firstlast`, `first_last`, etc.) from emails found on the site.
- **SMTP email verification** — Async batch verification with MX lookup, connection reuse, conservative rate limits, and catch-all domain detection.
- **Company enrichment** — Extracts company name, industry keywords, location, and social profiles.
- **Title inference** — Infers department, function, and seniority from job titles.
- **Anti-bot infrastructure** — Scrapling-based stealth browser with adaptive proxy escalation: rotates datacenter IPs first, then escalates to residential only when a domain keeps blocking.
- **Clean output** — Names, titles, phones, and locations are whitespace-normalized to avoid broken values like embedded `\n` characters.

### Input

```json
{
  "domain": "example.com",
  "rolesPreset": "decision_makers",
  "customRoles": ["CMO", "Managing Director"],
  "maxItems": 50,
  "verifyEmails": true,
  "useProxy": {
    "useApifyProxy": false,
    "apifyProxyGroups": []
  },
  "useStealth": true,
  "solveCloudflare": false,
  "includeContactText": true,
  "stayOnDomain": true,
  "maxConcurrency": 10
}
````

Either `domain` or `startUrls` is required. `maxItems` controls how many leadership contacts you want back; the actor automatically crawls enough pages (up to `maxItems × 15`, capped at 500) to find them. `maxConcurrency` lives under the **Advanced** section. `concurrentRequests` is accepted as a backward-compatible alias for `maxConcurrency`.

#### Roles presets

| Preset | Covers |
|---|---|
| `decision_makers` | CEO, CTO, Founder, COO, VP, Director, President, Chief, Head, Manager, Lead, Owner, Partner, Executive |
| `c_suite` | CEO, CTO, CFO, COO, CMO, President, Chief |
| `founders` | Founder, Co-Founder |
| `vp_directors` | VP, Director, Head, Senior Manager |
| `all_leadership` | Union of all presets |
| `custom` | Uses the keywords you provide in `customRoles` |

### Output

The actor pushes **one flat item per discovered leadership contact**:

```json
{
  "name": "Kate Bueker",
  "firstName": "Kate",
  "lastName": "Bueker",
  "email": "kbueker@hubspot.com",
  "emailConfidence": "verified",
  "phone": "+18884827768",
  "linkedinUrl": "http://www.linkedin.com/in/kate-bueker-25b0231",
  "title": "Chief Financial Officer",
  "department": "c_suite, finance",
  "functions": "finance",
  "seniority": "c_suite",
  "headline": "Chief Financial Officer at HubSpot",
  "positionHistory": [],
  "location": "Boston, Massachusetts, United States",
  "city": "Boston",
  "country": "United States",
  "companyName": "HubSpot",
  "domain": "hubspot.com",
  "sourceUrl": "https://hubspot.com/about",
  "extractionMethod": "schema_org",
  "extractionConfidence": "high",
  "catchAllDomain": false,
  "companyInfo": {
    "industry": ["software", "technology", "saas"],
    "location": "Cambridge, MA",
    "socials": {
      "linkedin": "https://linkedin.com/company/hubspot",
      "twitter": "https://twitter.com/hubspot"
    }
  }
}
```

#### Field notes

- `department` combines inferred seniority and function.
- `functions` is the normalized business function (finance, marketing, sales, engineering, etc.).
- `seniority` is one of: `c_suite`, `founder`, `owner`, `vp`, `director`, `manager`, `senior`.
- `positionHistory` is currently empty (`[]`) because the actor does not scrape full career history.
- `phone` uses the first company phone discovered on the domain when a direct line is not available.
- `sourceUrl` is the page where the contact was discovered.
- `companyInfo` includes industry keywords, employee-count estimate, location, and social profile links discovered on the homepage.

### Confidence Levels

- `verified` — SMTP server accepted the email recipient.
- `pattern_match` — Generated from the site's most common email pattern but not SMTP-verified.
- `catch_all` — Domain accepts all addresses; verification is unreliable.
- `failed` — SMTP server rejected the generated candidate.
- `unknown` — Verification disabled or could not be completed.

### Best Practices

1. **Use a proxy** — SMTP verification and stealth browsing both benefit from a proxy. The actor auto-enables a datacenter proxy when stealth is on. Residential proxy is used automatically only after repeated blocks on the same domain, or when you explicitly select a residential proxy group.
2. **Disable verification for speed** — If you only need candidate emails, set `verifyEmails: false` to skip SMTP checks.
3. **Tune roles** — Use the `custom` preset with industry-specific keywords (e.g., `CMO`, `Principal`, `Managing Director`).
4. **Respect rate limits** — The actor uses conservative delays between domains and emails; avoid aggressive concurrency on the same mail server.

### Limitations

- SMTP verification may be blocked or rate-limited by recipient mail servers.
- Catch-all domains make verification unreliable; the actor flags these explicitly.
- Some websites hide team data behind JavaScript or require authentication; stealth mode helps but cannot guarantee access.
- Position history is not extracted from websites.

# Actor input Schema

## `domain` (type: `string`):

The company domain to crawl (e.g. example.com). Either domain or startUrls is required.

## `startUrls` (type: `array`):

Optional explicit start URLs. If domain is also provided, these override the default https://domain/.

## `rolesPreset` (type: `string`):

Which set of leadership titles to look for. Choose Custom to enter your own keywords.

## `customRoles` (type: `array`):

Job-title keywords used when Leadership Roles is set to Custom (e.g. CMO, Principal, Managing Director).

## `maxItems` (type: `integer`):

Maximum number of leadership contacts to return. The actor automatically crawls enough pages to find them.

## `verifyEmails` (type: `boolean`):

When enabled, generated candidate emails are verified against the target domain's mail server. Disable to speed up crawling when verification is not needed.

## `stayOnDomain` (type: `boolean`):

Only follow links that point to the same domain as the start URLs.

## `useStealth` (type: `boolean`):

Automatically escalate to a stealth browser when a page blocks the fast HTTP session.

## `solveCloudflare` (type: `boolean`):

Automatically solve Cloudflare Turnstile and Interstitial challenges. Requires useStealth=true.

## `includeContactText` (type: `boolean`):

Scan visible page text for email addresses used in pattern detection.

## `useProxy` (type: `object`):

Use Apify Proxy to avoid IP bans. By default the actor uses datacenter IPs and rotates them on blocks. Residential proxies are used only when a domain repeatedly fails or when you explicitly select a residential proxy group.

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

Number of pages to fetch in parallel.

## Actor input object example

```json
{
  "domain": "example.com",
  "startUrls": [
    {
      "url": "https://example.com/"
    }
  ],
  "rolesPreset": "decision_makers",
  "customRoles": [],
  "maxItems": 50,
  "verifyEmails": true,
  "stayOnDomain": true,
  "useStealth": true,
  "solveCloudflare": false,
  "includeContactText": true,
  "useProxy": {
    "useApifyProxy": false,
    "apifyProxyGroups": []
  },
  "maxConcurrency": 10
}
```

# Actor output Schema

## `dataset` (type: `string`):

Flat leadership contact records pushed to the default dataset.

# 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 = {
    "domain": "example.com",
    "startUrls": [
        {
            "url": "https://example.com/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("toolzerhub/leadership-contact-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 = {
    "domain": "example.com",
    "startUrls": [{ "url": "https://example.com/" }],
}

# Run the Actor and wait for it to finish
run = client.actor("toolzerhub/leadership-contact-finder").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 '{
  "domain": "example.com",
  "startUrls": [
    {
      "url": "https://example.com/"
    }
  ]
}' |
apify call toolzerhub/leadership-contact-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=toolzerhub/leadership-contact-finder",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Leadership Contact Finder",
        "description": "Crawl corporate websites to discover leadership contacts. Extracts names, titles, emails, LinkedIn URLs, phone numbers, and infers department, seniority, and location for each decision maker.",
        "version": "1.0",
        "x-build-id": "GQKBpHtDZOentrNn6"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/toolzerhub~leadership-contact-finder/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-toolzerhub-leadership-contact-finder",
                "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/toolzerhub~leadership-contact-finder/runs": {
            "post": {
                "operationId": "runs-sync-toolzerhub-leadership-contact-finder",
                "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/toolzerhub~leadership-contact-finder/run-sync": {
            "post": {
                "operationId": "run-sync-toolzerhub-leadership-contact-finder",
                "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",
                "properties": {
                    "domain": {
                        "title": "Target Domain",
                        "type": "string",
                        "description": "The company domain to crawl (e.g. example.com). Either domain or startUrls is required."
                    },
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "Optional explicit start URLs. If domain is also provided, these override the default https://domain/.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "rolesPreset": {
                        "title": "Leadership Roles",
                        "enum": [
                            "decision_makers",
                            "c_suite",
                            "founders",
                            "vp_directors",
                            "all_leadership",
                            "custom"
                        ],
                        "type": "string",
                        "description": "Which set of leadership titles to look for. Choose Custom to enter your own keywords.",
                        "default": "decision_makers"
                    },
                    "customRoles": {
                        "title": "Custom Role Keywords",
                        "type": "array",
                        "description": "Job-title keywords used when Leadership Roles is set to Custom (e.g. CMO, Principal, Managing Director).",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxItems": {
                        "title": "Max Contacts",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum number of leadership contacts to return. The actor automatically crawls enough pages to find them.",
                        "default": 50
                    },
                    "verifyEmails": {
                        "title": "Verify Emails via SMTP",
                        "type": "boolean",
                        "description": "When enabled, generated candidate emails are verified against the target domain's mail server. Disable to speed up crawling when verification is not needed.",
                        "default": true
                    },
                    "stayOnDomain": {
                        "title": "Stay On Domain",
                        "type": "boolean",
                        "description": "Only follow links that point to the same domain as the start URLs.",
                        "default": true
                    },
                    "useStealth": {
                        "title": "Adaptive Stealth",
                        "type": "boolean",
                        "description": "Automatically escalate to a stealth browser when a page blocks the fast HTTP session.",
                        "default": true
                    },
                    "solveCloudflare": {
                        "title": "Solve Cloudflare Challenges",
                        "type": "boolean",
                        "description": "Automatically solve Cloudflare Turnstile and Interstitial challenges. Requires useStealth=true.",
                        "default": false
                    },
                    "includeContactText": {
                        "title": "Extract Emails From Page Text",
                        "type": "boolean",
                        "description": "Scan visible page text for email addresses used in pattern detection.",
                        "default": true
                    },
                    "useProxy": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Use Apify Proxy to avoid IP bans. By default the actor uses datacenter IPs and rotates them on blocks. Residential proxies are used only when a domain repeatedly fails or when you explicitly select a residential proxy group.",
                        "default": {
                            "useApifyProxy": false,
                            "apifyProxyGroups": []
                        }
                    },
                    "maxConcurrency": {
                        "title": "Max Concurrent Requests",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Number of pages to fetch in parallel.",
                        "default": 10
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
