# Company Leadership Scraper (`automation-lab/company-leadership-contact-finder`) Actor

Crawl public company websites and export source-attributed leaders, roles, biographies, and explicitly published business contact details.

- **URL**: https://apify.com/automation-lab/company-leadership-contact-finder.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Lead generation, Business
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 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 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

## Company Leadership Scraper

Extract **company leadership** records from public company websites without guessing private contact data.

Supply company homepages, team pages, or leadership pages. The Actor finds structured public leader cards and returns each person's name, role, company, exact source page, biography URL, biography text, and any LinkedIn profile, business email, or phone number explicitly published with that person.

The result is a source-attributed dataset for prospecting, account research, CRM enrichment, executive mapping, and scheduled leadership-change monitoring.

### What Company Leadership Scraper does

The Actor performs bounded HTTP crawling on each supplied website.

It:

1. fetches the supplied page;
2. follows likely same-domain leadership, executive, management, board, people, team, and about links;
3. reads schema.org `Person` markup, JSON-LD, and common semantic people-card layouts;
4. applies optional leadership-role keywords;
5. deduplicates people by company, name, and role;
6. saves typed records to the default Apify dataset.

It never generates email patterns, guesses names, or labels an email as verified.

A contact field is present only when the source page explicitly publishes it.

### Who is it for

**Sales and revenue operations teams** can map publicly listed executives before outreach.

**Recruiters and executive researchers** can collect current public leadership roles with source links.

**CRM data teams** can enrich company accounts with cited people and job titles.

**Market intelligence analysts** can schedule repeated runs and compare leadership datasets over time.

**Developers and automation teams** can send normalized records to Sheets, Airtable, HubSpot, Salesforce, a warehouse, or an internal review queue.

Use a dedicated LinkedIn Actor when your workflow begins with LinkedIn search rather than company websites.

Use an email verification Actor when you need to verify an address after collecting it lawfully.

### Why use source-attributed leadership data

Many contact tools merge third-party databases, inferred email patterns, and stale profiles.

This Actor uses the supplied public company domain as the evidence boundary.

Every row includes `sourceUrl`.

This makes it easier to:

- audit where a name and role came from;
- distinguish published facts from inferred enrichment;
- revisit the underlying profile;
- remove stale records after a scheduled comparison;
- review contact data before outreach.

The trade-off is intentional: a site that publishes no usable leadership markup may return no records.

### Data extracted

| Field | Meaning |
| --- | --- |
| `name` | Person name published by the source |
| `role` | Published leadership title |
| `company` | Site or company name exposed by the page |
| `companyWebsite` | Normalized origin for the supplied website |
| `sourceUrl` | Exact page supporting the record |
| `bioUrl` | Public profile or biography URL, when found |
| `bio` | Biography text from the same card or structured data |
| `linkedInUrl` | LinkedIn profile explicitly linked by the source |
| `email` | Business email explicitly published with the person |
| `phone` | Phone number explicitly published with the person |
| `scrapedAt` | UTC extraction timestamp |

Nullable fields are returned as `null` when the website does not publish them.

### Getting started

1. Open the Actor input page.
2. Add one or more public company websites or leadership-page URLs.
3. Set `maxItems` to the maximum number of people you need.
4. Keep `maxPagesPerWebsite` small for a targeted page, or increase it for homepage discovery.
5. Optionally provide role keywords such as `CEO`, `chief`, `director`, or `head of sales`.
6. Choose whether to include biography text.
7. Start the run.
8. Open the **Leadership contacts** dataset view.
9. Export JSON, CSV, Excel, XML, RSS, or connect the dataset to another service.

A working small input is:

```json
{
  "startUrls": [
    { "url": "https://www.mozilla.org/en-US/about/leadership/" }
  ],
  "maxItems": 20,
  "maxPagesPerWebsite": 1,
  "includeBio": true
}
```

### Input parameters

#### `startUrls`

Required list of public HTTP(S) company pages.

You may mix homepages and direct leadership pages in one run.

The Actor follows only likely leadership links on the same origin; it does not crawl the open web.

#### `maxItems`

Maximum number of unique leadership records across all inputs.

Allowed range: 1 to 10,000.

The default is 100.

#### `maxPagesPerWebsite`

Maximum number of pages inspected for each supplied website.

Allowed range: 1 to 50.

Use 1 for a known direct leadership page.

The default is 10 for bounded discovery.

#### `roleKeywords`

Optional case-insensitive phrases matched against published role text.

If omitted, the Actor uses a broad leadership set including chief, CEO, CTO, CFO, COO, president, founder, partner, director, vice president, head of, chair, executive, officer, and manager.

#### `includeBio`

Set to `false` to omit biography text while retaining names, roles, URLs, and contact fields.

The default is `true`.

### Output example

A current public leadership page produces records shaped like this:

```json
{
  "name": "Anthony Enzor-DeMeo",
  "role": "CEO, Mozilla Corporation",
  "company": "Mozilla",
  "companyWebsite": "https://www.mozilla.org/",
  "sourceUrl": "https://www.mozilla.org/en-US/about/leadership/",
  "bioUrl": "https://www.mozilla.org/en-US/about/leadership/#anthony-enzor-demeo",
  "bio": "As CEO of Mozilla Corporation, Anthony leads the vision and corporate strategy...",
  "linkedInUrl": null,
  "email": null,
  "phone": null,
  "scrapedAt": "2026-08-19T06:10:00.000Z"
}
```

The exact people and roles may change after the documentation date.

Always use `sourceUrl` for current evidence.

### How much does it cost to extract company leadership contacts?

Pricing uses one `start` event per run and one tiered `item` event per saved leadership record.

The FREE item price is $0.023. The BRONZE item price is $0.020, and each higher-volume tier decreases through SILVER, GOLD, PLATINUM, and DIAMOND. Every run also has a $0.005 start event.

At BRONZE, a run that saves 10 leaders costs $0.205: one $0.005 start event plus 10 item events.

At BRONZE, a scheduled run saving 100 leaders costs $2.005. Your actual tier is determined by your Apify plan.

Blocked pages, rejected cards, duplicate people, and pages with no accepted leaders do not create item events.

Apify platform compute is included in pay-per-event pricing rather than billed as an extra Actor fee.

### Filtering executive roles

To find chief executives and presidents only:

```json
{
  "startUrls": [
    { "url": "https://www.mozilla.org/en-US/about/leadership/" }
  ],
  "roleKeywords": ["CEO", "chief", "president"],
  "maxItems": 25,
  "maxPagesPerWebsite": 1,
  "includeBio": false
}
```

Filtering applies equally to direct leadership URLs and pages discovered from a homepage.

A leader is returned only when the published role contains at least one requested phrase.

### Recurring CRM enrichment workflow

Create an Apify Schedule for weekly or monthly execution.

Use stable company inputs and save each run's dataset ID.

Then compare rows by:

```text
companyWebsite + name + role
```

Possible downstream actions include:

- flag a newly listed executive for manual review;
- close or update a stale CRM contact;
- send source URLs to an account owner;
- append current roles to a warehouse history table;
- notify a research channel when leadership changes.

The Actor provides snapshots; it does not itself send alerts or calculate historical diffs.

### API usage with cURL

Set `APIFY_TOKEN` in your environment, then run:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~company-leadership-contact-finder/runs?token=$APIFY_TOKEN&waitForFinish=300" \
  -H "Content-Type: application/json" \
  -d '{
    "startUrls": [{"url":"https://www.mozilla.org/en-US/about/leadership/"}],
    "maxItems": 20,
    "maxPagesPerWebsite": 1
  }'
```

Fetch dataset items using the `defaultDatasetId` returned by the run.

```bash
curl "https://api.apify.com/v2/datasets/DATASET_ID/items?clean=true&format=json"
```

### API usage with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/company-leadership-contact-finder').call({
  startUrls: [{ url: 'https://www.mozilla.org/en-US/about/leadership/' }],
  maxItems: 20,
  maxPagesPerWebsite: 1,
  includeBio: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### API usage with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/company-leadership-contact-finder').call(run_input={
    'startUrls': [{'url': 'https://www.mozilla.org/en-US/about/leadership/'}],
    'maxItems': 20,
    'maxPagesPerWebsite': 1,
    'includeBio': True,
})

items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use with MCP and AI agents

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/company-leadership-contact-finder"
```

For **Claude Desktop**, **Cursor**, and **VS Code**, add this MCP server configuration to the client's MCP settings:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/company-leadership-contact-finder"
    }
  }
}
```

Example prompts showing MCP usage include:

- “Use the Company Leadership Scraper MCP tool to extract the chief executives from these five public company leadership pages.”
- “Build a cited table of directors and their source URLs for these company domains.”
- “Collect publicly displayed LinkedIn links for the leaders on this team page.”

Review contact data and source terms before using an agent to trigger outreach.

### Integrations

Use Apify integrations to export datasets to Google Sheets, Airtable, Slack, Zapier, Make, or webhooks.

For a CRM pipeline, keep `sourceUrl`, `scrapedAt`, and the original company input beside every imported contact.

Do not overwrite a verified internal CRM field merely because a public page omits it.

A null field means “not published in the parsed source,” not “the person has no such contact method.”

### Limits and expected behavior

The Actor is HTTP-first and does not launch a browser.

JavaScript-only pages may expose no usable people cards.

Login-required, CAPTCHA-protected, or consistently blocked pages are unsupported.

Page templates vary, so uncommon card markup may not be recognized.

The Actor intentionally avoids broad text guessing because false people records are worse than a smaller cited result set.

It follows only same-origin likely leadership links.

It does not perform search-engine discovery, LinkedIn scraping, email pattern generation, SMTP verification, or private-database enrichment.

Transient network failures and temporary HTTP 429/5xx responses receive bounded retries.

Stable 4xx errors are logged and skipped.

### Tips for better results

Prefer a direct public team or leadership URL when you know it.

Use a homepage only when you want bounded leadership-page discovery.

Increase `maxPagesPerWebsite` gradually rather than setting 50 for every site.

Use precise role phrases for a smaller prospecting list.

Keep biography text enabled for research and disable it for a compact CRM import.

Inspect logs for skipped pages and inspect `sourceUrl` before acting on a record.

Schedule modest recurring runs to reduce unnecessary requests to source websites.

### Troubleshooting

#### The run succeeds but returns no rows

Open the supplied page without logging in and confirm that names and roles are present in server-delivered HTML.

Try the site's direct leadership, management, board, team, or people page.

Increase `maxPagesPerWebsite` if you supplied only a homepage.

Remove overly narrow `roleKeywords`.

A JavaScript-only or unusual layout may not be supported.

#### Some contact fields are null

The source did not explicitly link those details with the person card.

This is expected and prevents invented contact data.

#### A website is skipped

Check logs for its HTTP status or content type.

Verify that the URL is public HTTP(S), reachable without an account, and returns HTML.

#### The item limit is reached early

`maxItems` applies across all supplied websites.

Increase it or run different company batches separately.

### Responsible use and legality

Use this Actor only for public data you are permitted to collect and process.

Respect website terms, robots guidance, rate limits, privacy rights, and applicable data-protection and marketing laws.

Public availability does not automatically authorize every use.

Maintain a lawful purpose, minimize stored personal data, honor deletion or objection requests, and review outreach rules for each jurisdiction.

Do not use the Actor for harassment, discrimination, sensitive profiling, or bypassing access controls.

The Actor does not bypass authentication or infer private emails.

### Related Automation Lab Actors

- [Website Contact Details Extractor](https://apify.com/automation-lab/website-contact-details-extractor) collects organization-level contact, social, and address fields from public websites.
- [LinkedIn Profile URL Finder](https://apify.com/automation-lab/linkedin-profile-url-finder) helps when you already know a person's identity and need a public profile URL.
- [Email Finder](https://apify.com/automation-lab/email-finder) supports a separate email discovery workflow.

Choose the narrowest Actor that matches your evidence and compliance needs.

### FAQ

#### Does it verify emails?

No. It returns only email addresses explicitly published with a leader and makes no verification claim.

#### Does it scrape LinkedIn?

No. It returns a LinkedIn profile URL only when the supplied company website explicitly links it.

#### Can I supply company homepages?

Yes. The Actor follows a bounded set of likely same-domain leadership links.

#### Can I supply direct team pages?

Yes. Set `maxPagesPerWebsite` to 1 for the smallest targeted run.

#### Does it monitor changes automatically?

Use an Apify Schedule and compare successive datasets. The Actor produces snapshots but does not calculate diffs or alerts.

#### Are duplicate leaders charged twice?

Not within one run when company host, normalized name, and role match. Rejected and duplicate cards do not create item events.

#### Can it crawl login-protected pages?

No. The supported scope is anonymously reachable public company websites.

#### Can it find every decision maker?

No. It finds leadership records that the supplied public pages publish in recognizable structured or semantic layouts.

# Actor input Schema

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

Public HTTP(S) company homepages, about pages, team pages, or leadership pages. Homepages are followed to likely same-domain leadership pages.

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

Stop after saving this many unique people across all supplied websites.

## `maxPagesPerWebsite` (type: `integer`):

Maximum number of same-domain homepage, about, team, people, board, management, or leadership pages to inspect per input website.

## `roleKeywords` (type: `array`):

Optional case-insensitive role phrases. Only people whose published role contains one of these phrases are returned.

## `includeBio` (type: `boolean`):

Include biography text when it is published in the same leadership card or structured Person data.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.mozilla.org/en-US/about/leadership/"
    }
  ],
  "maxItems": 20,
  "maxPagesPerWebsite": 5,
  "includeBio": true
}
```

# Actor output Schema

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

Default dataset containing all extracted leadership records.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.mozilla.org/en-US/about/leadership/"
        }
    ],
    "maxItems": 20,
    "maxPagesPerWebsite": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/company-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 = {
    "startUrls": [{ "url": "https://www.mozilla.org/en-US/about/leadership/" }],
    "maxItems": 20,
    "maxPagesPerWebsite": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/company-leadership-contact-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 '{
  "startUrls": [
    {
      "url": "https://www.mozilla.org/en-US/about/leadership/"
    }
  ],
  "maxItems": 20,
  "maxPagesPerWebsite": 5
}' |
apify call automation-lab/company-leadership-contact-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/company-leadership-contact-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/NpvvgytI6BXOBg86w/builds/NoFVg0N19vbVdH31H/openapi.json
