Company Executives & Decision Makers: Leadership Team Scraper avatar

Company Executives & Decision Makers: Leadership Team Scraper

Pricing

$2.00 / 1,000 person founds

Go to Apify Store
Company Executives & Decision Makers: Leadership Team Scraper

Company Executives & Decision Makers: Leadership Team Scraper

Find decision makers, CEOs, founders and executives from company domains. Reads each company's team, about, leadership, management and Impressum pages; returns every named employee and team member with job title, seniority, LinkedIn and published email. B2B contacts; emails never guessed.

Pricing

$2.00 / 1,000 person founds

Rating

0.0

(0)

Developer

Data Gleaner

Data Gleaner

Maintained by Community

Actor stats

0

Bookmarked

11

Total users

7

Monthly active users

10 minutes ago

Last modified

Share

Company Leadership & Team Page Scraper: names, roles and LinkedIn from company websites

Get a company's leadership team, team members and team page contacts from the company website. Give it company domains and it returns every named person the company publishes on its team, about, leadership, management or Impressum pages, with job title, seniority, the LinkedIn profile the site links and the email the site publishes. It answers "who works at this company", "who runs this company" and "list the team members on this company's website" for a whole list of domains at once. $0.002 per person until 3 November 2026 and $0.004 per person from then; domains with no team page are free.

It never guesses or verifies emails. An email is returned only when the company's own page shows it for that person (a mailto: link or the address written in the person's card). Shared inboxes such as info@, sales@ or hello@ are not attributed to anyone, and no firstname@domain pattern is ever invented.

To try it: paste one or more company domains into domains and click Start. With an empty input it runs a small built-in example (two domains, at most 5 people).

What it does

For each domain it reads the home page, finds the links in the navigation and footer that lead to the team, about, leadership, management, founders or Impressum / legal-notice page (in English, German, French, Spanish, Dutch and Italian), and reads at most maxPagesPerDomain of them (default 4). An about page that links on to a separate team page is followed. If the home page links to none of them, it tries the usual paths (/team, /about, /leadership, /impressum and similar).

From each page it extracts the people three ways:

  • Structured data: schema.org Person in JSON-LD or microdata, and an Organization's founder, member or employee.
  • Team cards: the repeated name-and-title blocks of a team grid, with the LinkedIn /in/ link and personal email inside the same card. When a grid gives some people a department instead of a title ("Design", "Customer Success"), it is read from the same slot the other cards use.
  • Impressum / legal notice: the people named after Geschäftsführer, Vertreten durch, Vorstand, Aufsichtsrat, Inhaber, Managing Director, Represented by and similar labels, with that label as the title.

Then it keeps out what is not the company's team: customer testimonials and quotes, blog and article bylines, investor and partner logos, menu items, people described as working elsewhere ("CTO at Initech", "former VP"), and navigation text that looks like a name.

Each person gets a seniority from the title: founder, c-level (CEO, CFO, President, Managing Director, Geschäftsführer), vp, director (including Head of), board (board members, Aufsichtsrat, advisors listed under a board heading), manager or other. Rows come out most senior first.

Use cases

  • Sales prospecting: the founders, executives and department heads of every company on a target account list, with their LinkedIn profiles.
  • CRM enrichment: add the leadership team to company records you already have.
  • Recruiting and market mapping: who runs engineering, product or marketing at a set of competitors.
  • Due diligence and investor research: the management and supervisory board named in a German, Austrian or Swiss company's Impressum.
  • AI agents that need "the leadership team of company X" or "who works at company X" as a tool call, paying only when people are found.

Input

{
"domains": ["baremetrics.com", "mongodb.com", "sipgate.de", "https://thoughtbot.com/team"],
"maxPeoplePerDomain": 25,
"seniority": ["founder", "c-level", "vp"],
"maxPagesPerDomain": 4,
"maxConcurrency": 10,
"delaySecs": 0.5
}
  • domains: bare domains, full URLs, or a direct team page URL.
  • startUrls: also accepted, in the common Apify format ([{"url": "https://example.com"}]); merged with domains, duplicates removed.
  • maxPeoplePerDomain: keep at most this many people per company, most senior first (default 25; 0 means no limit).
  • seniority: return only these levels. Empty returns everyone. People filtered out are not charged.
  • maxPagesPerDomain: pages read per domain after the home page (default 4, at most 10).
  • inferEmails: optional, off by default. See "Inferred emails" below.
  • datasetId: optional, the ID of another Actor's dataset; its websites are added to domains. datasetUrlField names the website field if it is unusual.
  • companyNames: optional, company names instead of websites. See "Have company names, not websites?" below.
  • maxConcurrency, delaySecs, requestTimeoutSecs, respectRobotsTxt (default on) and proxyConfiguration (default none).

Have company names, not websites?

Put the names in companyNames, one per line (add a location after a comma for same-named companies, e.g. Bosch, Germany). The Actor first runs Company Domain Finder on your account to find each company's official website, then reads those websites' team pages exactly like the ones in domains.

{"companyNames": ["Stripe", "Notion", "Basecamp"]}
  • What it bills: Company Domain Finder charges its own $0.0008 per website found (nothing when no website is found) on your account. This Actor then charges its usual price per person found, and nothing for the rest. The two charges appear as separate runs in your account.
  • Output: each person row has companyName (the name you gave) and the resolved domain. A name with no website found, or only a low-confidence guess, gets one free row with failureReason: "no website found for company name" and no person.
  • Names are merged with domains, startUrls and datasetId, and a website that appears twice is read once. If the lookup fails or runs out of time, the affected names come back as free rows with a failureReason (such as "company lookup did not finish in time") and the run still succeeds.

Run it after Google Maps Scraper or any scraper

Open the source Actor's Integrations tab, add this Actor (datagleaner/team-page-contacts) and set its input to:

{"datasetId": "{{resource.defaultDatasetId}}"}

Every time the source run succeeds, this Actor reads the websites from its results (website, url, domain, site, homepage, link, companyWebsite or web, the first one present), skips items with no website, social-media or map links, and duplicates, and returns the team of each company. Each person also carries sourceName, the title or name of the source item (for example the Google Maps place name). Billing is the same: one event per person found.

The same works from code, for one finished run:

run = client.actor("datagleaner/team-page-contacts").call(run_input={"datasetId": "SOURCE_DATASET_ID"})

The status message tells how many domains were read from the dataset and how many items had no website.

It also works as an integration without setting any input: in the source Actor's Integrations tab choose Add integration and pick this Actor, and the dataset is passed automatically.

Output

One row per person.

{
"domain": "baremetrics.com",
"companyName": "Baremetrics",
"personName": "Luke Marshall",
"jobTitle": "CEO",
"seniority": "c-level",
"linkedinUrl": null,
"email": "luke@baremetrics.com",
"emailSource": "mailto-link",
"sourceUrl": "https://baremetrics.com/about",
"input": "baremetrics.com",
"scrapedAt": "2026-10-09T14:56:34+00:00"
}
{
"domain": "mongodb.com",
"companyName": "MongoDB",
"personName": "Mike Berry",
"jobTitle": "Chief Financial Officer",
"seniority": "c-level",
"linkedinUrl": "https://www.linkedin.com/in/mike-berry-59b7961",
"email": null,
"emailSource": null,
"sourceUrl": "https://www.mongodb.com/company/leadership",
"input": "mongodb.com",
"scrapedAt": "2026-10-09T14:55:02+00:00"
}
  • linkedinUrl is filled only when the company's page links that person's LinkedIn /in/ profile. It is never searched for elsewhere.
  • email and emailSource (mailto-link or page-text) are filled only when the page publishes a personal address for that person.
  • sourceUrl is the page the person was found on, so every row can be checked.

A per-domain summary (status, pages read, people found and pushed) is saved in the key-value store as DOMAIN_SUMMARY. Its status is ok, noPeople, noTeamPage, unreachable, blockedByRobots, notHtml, invalidDomain or error.

Inferred emails (optional)

Set inferEmails to true and people whose email the site does not publish may also get a best guess. The Actor learns the company's address pattern (first.last@, flast@, first@, firstlast@, f.last@ and a few more) only from personal addresses the site itself publishes on the pages it reads, matched to the named people it finds. Shared inboxes such as info@ or sales@ and addresses on other domains are ignored. With no published example there is no pattern, and no guess is made.

Extra fields, only when the option is on:

  • inferredEmail: the guessed address, kept apart from email so you can always tell a published address from an inferred one. A published email is never overwritten, and the person then has no inferredEmail.
  • emailPattern: the pattern used, for example first.last.
  • emailPatternEvidence: up to 3 published addresses that support the pattern.
  • emailConfidence: high with 2 or more consistent published examples, medium with 1.

Be honest with your own list: an inferred email is a guess from the site's published pattern. It is not verified with a mail server, so some will bounce. Check before you send at volume. Names with accents or hyphens are converted to plain ASCII, and names that cannot be split into first and last name are skipped. There is no extra charge: you pay the same price per person with the option on or off.

How accurate is it?

Measured on 56 real team, about, leadership and Impressum pages from SaaS companies, agencies, enterprises and German publishers, hand-labelled person by person (755 people): precision 100%, recall 98%. On the last 20 of those pages, labelled before the extractor ever saw them, it scored precision 100% and recall 82% before any tuning. Precision is held highest on purpose: a name in the output is a real person the company lists, not a customer quoting it or a menu item.

How much does it cost?

Pay per event: US$2.00 per 1,000 people (event person-found, US$0.002 each) until 3 November 2026. From 3 November 2026 the price is US$4.00 per 1,000 people (US$0.004 each); the raise has been announced to users 14 days ahead, as the platform requires. You pay once per named person with a role, published on the company's own site. Domains with no team page, no named people, or that are unreachable are free, and people removed by your seniority filter or maxPeoplePerDomain are not charged.

Worked example: 500 company domains averaging 6 people each is 3,000 people: 3,000 x $0.002 = $6 until 3 November 2026, and 3,000 x $0.004 = $12 from then. To pay only for leaders, set seniority to ["founder", "c-level", "vp"]: a typical company then returns 2 to 5 people. Platform usage is small because the Actor makes plain HTTP requests only.

How to get the leadership team of a list of companies

  1. Paste the company domains into domains, one per line.
  2. Set seniority to the levels you want, or leave it empty for the whole team.
  3. Click Start. Rows appear as each domain finishes, most senior person first.
  4. Export the dataset as CSV, Excel or JSON, or read it through the API.

Limits

  • Only what the company publishes. A company with no team or about page that names people returns nothing (and costs nothing). It does not search LinkedIn, Crunchbase or anywhere else.
  • No JavaScript rendering. Team pages that load their people with scripts after the page opens, and sites that block non-browser clients (HTTP 403 or 429), return nothing. Setting proxyConfiguration helps with some blocks.
  • Names need a first and last name. Cards that show a first name only ("Anna, Support") are skipped.
  • People named only in running prose ("our founder Jane started the company in 2015") are not extracted; titled cards, structured data and Impressum labels are.
  • Up to 10 pages per domain; default 4. A domain gets no new request after 90 seconds; a very slow server is returned with what was found by then, so one slow site cannot hold the whole run open.

Use with Python

# pip install apify-client
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("datagleaner/team-page-contacts").call(
run_input={"domains": ["baremetrics.com", "mongodb.com"], "seniority": ["founder", "c-level"]}
)
for row in client.dataset(run.default_dataset_id).iterate_items():
print(row["companyName"], row["personName"], row["jobTitle"], row["linkedinUrl"])

Use with JavaScript / Node.js

// npm install apify-client
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('datagleaner/team-page-contacts').call({
domains: ['baremetrics.com', 'mongodb.com'],
seniority: ['founder', 'c-level'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const row of items) console.log(row.companyName, row.personName, row.jobTitle);

Use it from n8n, Make, Zapier or an AI agent

Actor ID: datagleaner/team-page-contacts

Minimal input:

{"domains": ["baremetrics.com", "mongodb.com"]}

Each tool below runs this Actor with your own Apify API token.

  • n8n: add the Apify node (@apify/n8n-nodes-apify). On n8n Cloud you install it from the community node registry. Choose Run an Actor and get dataset, set Actor to datagleaner/team-page-contacts and paste the input above.

  • Make: use the Apify app's Run an Actor module, then Get Dataset Items to read the results. Watch Actor Runs can trigger a scenario when a run finishes.

  • Zapier: use the Apify action Run Actor, then the search Fetch dataset items. The trigger Finished Actor run starts a Zap when a run ends.

  • AI agents (MCP): connect to https://mcp.apify.com/?tools=datagleaner/team-page-contacts. In Claude Code:

    claude mcp add --transport http apify "https://mcp.apify.com/?tools=datagleaner/team-page-contacts"
    

    Then run /mcp to sign in to Apify in your browser. Other clients can sign in with OAuth or send the header Authorization: Bearer YOUR_APIFY_TOKEN. Clients that run local MCP servers can use Apify's package (@apify/actors-mcp-server, run with npx -y and APIFY_TOKEN set) instead. Then ask the agent in plain words, for example:

    Who is on the leadership team of mongodb.com, baremetrics.com and sipgate.de? Give me a table of name, title and LinkedIn, with the page each one came from.

  • LangChain (Python):

# pip install langchain-apify, then set APIFY_TOKEN in your environment
import json
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("datagleaner/team-page-contacts")
result = tool.invoke({"run_input": json.loads('{"domains": ["baremetrics.com", "mongodb.com"]}')})

Use over plain HTTP

Agents and scripts without MCP can call it in one HTTP request and get the rows back:

curl -X POST "https://api.apify.com/v2/acts/datagleaner~team-page-contacts/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"domains": ["mongodb.com"], "seniority": ["founder", "c-level"]}'

FAQ

How do I find who works at a company from its website? Put the company's domain in domains. The Actor finds the team, about and leadership pages from the site's own navigation and returns each named person with their title, seniority and the page they appear on.

Does it find email addresses? Only the ones the company itself publishes for that person, such as a mailto: link on the team card. By default it never guesses an address and never gives a person a shared info@ or sales@ inbox. If you turn on inferEmails, people without a published email can also get an inferredEmail built from the pattern the site itself publishes (kept in separate fields, not verified with mail servers, no extra charge).

Does it return LinkedIn profiles? Yes, when the company's page links the person's LinkedIn profile. The link is normalised to https://www.linkedin.com/in/<slug>. It does not search LinkedIn.

Will it include customers from testimonials? No. Quotes, testimonials and case-study people are removed, as are people described as working at another company. On the labelled test pages, no customer or reviewer was returned as a team member.

Does it work on German Impressum pages? Yes. Managing directors (Geschäftsführer), the executive board (Vorstand), the supervisory board (Aufsichtsrat) and owners (Inhaber) are read from the legal notice with that role as the title.

Can I get only the founders and executives? Set seniority to ["founder", "c-level"]. Everyone else is left out and not charged.

I need the company's general contact details, not people. Use Website Contact Details Scraper for emails, phones and social profiles, or Company Enrichment by Domain for a one-row company profile.

  • Google Maps Leads Scraper: local businesses from Google Maps with their phones, website emails and the decision makers named on their team pages, in one run.
  • Website Contact Details Scraper: emails, phone numbers, social profiles and contact forms from a list of websites.
  • Company Enrichment by Domain: domain to company profile (name, logo, official social profiles, contacts, founding date).
  • Hiring Signal Leads: companies that are hiring sales reps now, each with a decision-maker contact, when you do not yet have a list of domains.

Responsible use

This Actor reads publicly available pages that companies publish about themselves, and returns only what those pages show. Names, titles and work emails are still personal data: you are responsible for complying with the law that applies to you, including GDPR, CCPA and anti-spam rules, when you store the results or contact the people in them.