# Decision Maker Finder (`spookyweb/decision-maker-finder`) Actor

🏷️ From $0.54 / 1K | Company domain or name in, the people who run it out: name, title, LinkedIn URL, location and a work email built from the company's naming convention where its site publishes one. Filter by department. Pay per person delivered.

- **URL**: https://apify.com/spookyweb/decision-maker-finder.md
- **Developed by:** [丂卩ㄖㄖҜㄚ](https://apify.com/spookyweb) (community)
- **Categories:** Lead generation, AI, Automation
- **Stats:** 4 total users, 3 monthly users, 83.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.54 / 1,000 people

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

## Decision Maker Finder

Give it a company domain or name and it returns the people who run that company: name, title, department, seniority, LinkedIn URL, location, and a work email built from the company's naming convention, read off its own site where it publishes one. One row per person, and you pay only for people delivered.

### 🔍 What does Decision Maker Finder do?

Decision Maker Finder turns a list of companies into a list of people. For each company it reads what two public search engines publish about LinkedIn profiles that name the company, keeps the profiles whose own listing says the person works there, classifies each one by department and seniority, and filters to the departments you asked for. When you give a domain, it also reads the company's own contact and about pages, works out the email naming convention from the addresses published there, and applies it to every person's name.

No LinkedIn page is ever fetched, so there is nothing to log in to and no account at risk. Every fact comes from a public search listing or from the company's own website. It runs on plain HTTP with no browser, which is why a company costs a few seconds and a fraction of a cent.

The official route to the same people is LinkedIn's own people search, and Sales Navigator for filtering by seniority and function. Both are good at one company at a time, and both leave you copying names into a sheet. Decision Maker Finder is for the list: give it fifty domains, choose the departments, and get one table with a title, a LinkedIn URL and an address per person, without a seat, a login or a browser extension, ready for a CRM import or an API call.

### 📊 What data can I extract?

| Field | What it holds |
|---|---|
| 🏢 company | The company name used for the search |
| 🌐 domain | The domain you gave, or null for a bare name |
| 👤 name, firstName, lastName | The person as their public listing shows them |
| 💼 title | The headline they publish, usually their job title |
| 🗂️ roleCategory | leadership, sales, marketing, engineering, product, finance, operations, hr or other |
| 📶 seniority | c-level, vp, director, head, manager, lead or individual |
| 🔗 linkedinUrl | Their public profile URL |
| 📍 location | Location from the listing, when shown |
| 🧾 employerEvidence | The employer named in the listing's Experience field |
| ✅ evidence | Which field tied the person to the company: experience, headline or snippet |
| ✉️ email | The work address built from the naming convention |
| 🔤 emailPattern | The convention used, such as first.last |
| 📊 emailConfidence | Share of the company's published addresses that follow it, 0 to 1 |
| 📋 emailCandidates | Every convention applied to the name, the chosen one first |
| 🔎 source | Which engine listed the profile |
| 🕒 foundAt | When the row was produced |

### 💡 Why find decision makers?

- **Outbound lists.** A list of target accounts becomes a list of named people with titles and addresses, ready for a sequence.
- **Account research.** Before a call, see who leads sales, product and finance at the company, with the evidence for each.
- **Enrichment.** Add people to a CRM record that only holds a company name and website.
- **Partnerships and PR.** Find the head of partnerships or communications rather than writing to info@.
- **Recruiting.** See who runs engineering or people at a company you are hiring from or selling to.

### 🚀 How do I use Decision Maker Finder?

1. Paste company domains, one per line. Names work too, but domains give you emails.
2. Pick the departments. Leadership is the default and returns founders, chief officers, vice presidents and directors.
3. Set how many people you want per company and how many search pages to read.
4. Run it. Each row is one person. Download as JSON, CSV or Excel, or read it over the API.

### ⬇️ Input

```json
{
  "companies": ["monzo.com", "wise.com"],
  "roles": ["leadership", "marketing"],
  "maxPeoplePerCompany": 10,
  "generateEmails": true,
  "searchPages": 2,
  "useProxyOnBlock": true
}
```

- **companies**: domains or names, up to 200 per run.
- **roles**: leadership, sales, marketing, engineering, product, finance, operations, hr, any. Up to three are searched per company.
- **maxPeoplePerCompany**: 1 to 50. Bounds the bill per company.
- **generateEmails**: build addresses from the naming convention. Same price either way.
- **searchPages**: 1 to 3 pages per department, about twenty profiles a page.
- **useProxyOnBlock**: retry once through Apify Proxy on a fresh address when an engine challenges the request.

### ⬆️ Output

#### Table view

| Company | Name | Title | Department | Seniority | Email | Confidence | LinkedIn |
|---|---|---|---|---|---|---|---|
| Monzo | Jane Smith | Chief Marketing Officer | marketing | c-level | jane.smith@monzo.com | 1 | linkedin.com/in/jane-smith |

#### JSON

```json
{
  "company": "Monzo",
  "domain": "monzo.com",
  "name": "Jane Smith",
  "firstName": "Jane",
  "lastName": "Smith",
  "title": "Chief Marketing Officer",
  "roleCategory": "marketing",
  "seniority": "c-level",
  "linkedinUrl": "https://www.linkedin.com/in/jane-smith-1a2b3c",
  "location": "London",
  "employerEvidence": "Monzo Bank",
  "evidence": "experience",
  "email": "jane.smith@monzo.com",
  "emailPattern": "first.last",
  "emailConfidence": 1,
  "emailCandidates": ["jane.smith@monzo.com", "janesmith@monzo.com", "jsmith@monzo.com"],
  "source": "brave",
  "foundAt": "2026-08-26T09:00:00.000Z"
}
```

### 🎯 How attribution works

A search for a company name returns namesakes, former employees, customers and event pages alongside the people you want. Each profile is kept only when the company's distinctive words appear as whole words in the listing's Experience field, in the current headline with no "ex", "former" or "previously" in front, or in the person's own profile summary. A listing whose Experience field names a different employer is dropped whatever the rest of the text says, and so is a search result that is an article or an event rather than the profile itself. The evidence field says which signal matched, and experience is the one to trust most. A person whose only link to the company is a shared surname, or a company whose name is a fragment of another, is dropped.

### ✉️ How emails are built

When you give a domain, the homepage, contact and about pages are read and every published address is collected. Role addresses such as info@, sales@ and customer.care@ are ignored. The personal ones reveal the convention by shape: jane.smith is first.last, jane\_smith is first\_last, j.smith is flast. The convention that explains the most addresses is applied to each person, and emailConfidence is the share it explained.

Be realistic about how often that happens. Most company sites publish only role addresses, and on a measured sample of twenty four UK companies, from banks to law firms to agencies, not one published a personal address on its contact or about pages. In that case, which is the usual case, first.last is assumed because it is the most common convention, emailConfidence is 0.2 to say so, and emailCandidates lists every convention so you can verify or try the alternatives. A name that cannot form an address, such as an initial for a surname, leaves email empty. Treat the address as a strong first guess to verify, not as a verified fact.

### 📏 Limits

**Run timeout.** A run stops starting new work shortly before its own time limit and finishes cleanly with whatever it has, naming what it did not reach. The Actor's default is 3600 seconds, which is enough for the largest input it accepts. If you set a shorter limit in your own run settings, integration or API call, expect fewer results and a note in the run's status message saying so. You pay per delivered result rather than per minute, so a generous timeout costs you nothing.

- Up to 200 companies per run, 50 people per company, 3 departments per company, 3 search pages per department.
- Each company takes roughly 5 to 20 seconds depending on how many departments and pages you ask for. The run stops starting new companies a minute before its own timeout and the status message says how many were not attempted, so give a 200 company list a timeout of an hour or split it across runs.
- People come from public search listings. A company with few profiles that name it, or a very common name, returns fewer rows. An empty result is reported in the status message, not as a failure.
- Emails are built, not verified. The confidence score and the candidate list are there so you can verify with the tool of your choice.
- Runs stop cleanly at your per run spending cap. Everything delivered before the cap is kept.

### ⏱️ How long does a run take?

Measured on real runs, so you can tell a normal run from one that has stalled.

| Input size | Typical run time |
|---|---|
| 2 companies | about 20 seconds |
| 30 companies | about 4 minutes |

The first few seconds of any run are the container starting rather than the work. A run is never silently stuck: progress is logged as it goes, and if it runs out of time it stops early, keeps everything collected so far and says in the status message what was left.

### 💰 How much does it cost?

| Event | Price |
|---|---|
| Person found | $0.0009 |
| Actor start | $0.00005 per run |

Charged once per person delivered. A person costs the same whether one search page or three were read, whether an email was built or not, and whether the company took one engine or two. A company that returns nobody costs nothing beyond the run start.

So ten people at one company cost **$0.00905** including the run start, and a list that returns 1,000 people costs **$0.90005**.

Paid Apify plans pay less per person: **$0.000765** on Bronze, **$0.00063** on Silver, **$0.00054** on Gold, **$0.00045** on Platinum and **$0.00036** on Diamond. The Apify listing always shows the current rates.

### 🔌 Integrations

Schedule it to refresh a target account list weekly, chain it after [Company Domain Finder](https://apify.com/spookyweb/company-domain-finder) so bare company names become domains first, and pass each row's firstName, lastName and domain to the people input of [Company Email Finder](https://apify.com/spookyweb/company-email-finder) with verifyMx on, which reads more of the site for the convention and checks the domain can receive mail. Results go to Google Sheets, Airtable, Slack, Make, Zapier or a webhook through Apify integrations.

AI agents can call it through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) as `spookyweb/decision-maker-finder`. The input schema is the tool definition, the output schema tells the agent where the rows are, and every row carries the evidence field so the agent can judge attribution itself.

### 🔗 Using Decision Maker Finder with the Apify API

```bash
curl -X POST "https://api.apify.com/v2/acts/spookyweb~decision-maker-finder/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"companies": ["monzo.com"], "roles": ["leadership"], "maxPeoplePerCompany": 10}'
```

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

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('spookyweb/decision-maker-finder').call({
  companies: ['monzo.com', 'wise.com'],
  roles: ['leadership', 'sales'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

See the [Apify API documentation](https://docs.apify.com/api/v2) for scheduling, webhooks and dataset exports.

### ❓ FAQ

#### Does it log in to LinkedIn?

No. It never fetches a LinkedIn page. Every person comes from what public search engines already list about public profiles, plus the company's own website for the email convention.

#### Why did a company return nobody?

Either the search engines list few profiles that name that company, or the people listed did not carry the company in their Experience field, headline or snippet. Try the company's most common trading name, the any department, or three search pages.

#### How accurate are the emails?

They are built, not verified against the mail server. When the company's site publishes personal addresses the convention is read from them and emailConfidence is the share of addresses it explained. Most sites publish only role addresses, in which case the address is the first.last guess at a confidence of 0.2. Either way emailCandidates gives you the alternatives, and an email verification tool is the right next step before sending.

#### What does the evidence field mean?

experience means the profile listing names the company as the person's employer, which is the strongest signal. headline means the company appears in their current job headline. snippet means the person's own profile summary names it as their employer. A listing whose experience field names a different employer, a headline or summary that mentions the company only as a past role, and a search result that is an event or article page rather than the profile itself are all left out, so a former employee or a namesake is not delivered and not charged for.

#### What happens when a search engine blocks the request?

The query is retried once through Apify Proxy on a fresh address when useProxyOnBlock is on. The retry adds nothing to your bill: you pay per person delivered and the proxy usage is carried by the Actor. If both engines still challenge, the company is reported as not searched in the status message and nothing is charged for it.

#### Can I get everyone at a company, not just leaders?

Yes. Set roles to any, or pick the departments you want, and raise maxPeoplePerCompany and searchPages.

### ⚖️ Is it legal to use Decision Maker Finder?

It collects information that people publish on a public professional profile and that search engines index, plus contact conventions companies publish on their own websites. That is generally lawful to collect. Personal data is still personal data: if you contact the people it finds, you are responsible for having a lawful basis, honouring opt outs, and complying with GDPR, the UK PECR rules, CAN-SPAM or whichever regime applies to you and to them. Use it for business contact, not for anything a person would find intrusive.

### 👍 Your feedback

If a company comes back with the wrong people, or a naming convention is read wrongly, open an issue on the Issues tab with the company and what you expected. Custom versions, a different output shape, or an integration built for your pipeline are all possible: get in touch.

### 🔎 You might also like

- [Company Domain Finder](https://apify.com/spookyweb/company-domain-finder): company name in, website out.
- [Company Email Finder](https://apify.com/spookyweb/company-email-finder): the addresses a company publishes, its naming convention and an MX check.
- [Company Data Enrichment](https://apify.com/spookyweb/company-enrichment): firmographics from the company's own site.
- [Lead List Enricher](https://apify.com/spookyweb/lead-list-enricher): a pasted company list enriched in one run.
- [Website Contact Scraper](https://apify.com/spookyweb/website-contact-scraper): emails, phones and socials from any website.

# Actor input Schema

## `companies` (type: `array`):

One company per line, as a website domain (monzo.com) or a company name (Monzo Bank). A domain is better: the company's own site is read to work out its email naming convention, so every person comes back with an address. A bare name still finds people but leaves the email empty. Up to 200 per run.

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

Which people to return. leadership means founders, chief officers, managing directors, vice presidents and directors of any department, which is the usual meaning of decision maker. The department options return everyone found in that function at any level. any returns every person found. Up to three departments are searched per company.

## `maxPeoplePerCompany` (type: `integer`):

The most people to deliver for one company, from 1 to 50. People are taken in the order the search engines rank them, which puts the strongest associations with the company first. This bounds the bill per company.

## `generateEmails` (type: `boolean`):

Build a work email for each person from the naming convention read off the company's own site, with a confidence score and every alternative pattern listed. Turn off if you only want names, titles and LinkedIn URLs. The price is the same either way.

## `searchPages` (type: `integer`):

How many pages of search results to read for each department at each company, from 1 to 3. Each page holds about twenty profiles. One page is enough for a leadership search at a small company; three pages are worth it for a whole department at a large one.

## `useProxyOnBlock` (type: `boolean`):

Search engines occasionally challenge a busy address. When that happens the query is retried once through Apify Proxy on a fresh address. The retry costs you nothing extra: you pay per person delivered and the proxy usage is carried by the Actor. Turn off to keep runs proxy free; a challenged company is then reported as not searched.

## Actor input object example

```json
{
  "companies": [
    "monzo.com",
    "wise.com"
  ],
  "roles": [
    "leadership"
  ],
  "maxPeoplePerCompany": 5,
  "generateEmails": true,
  "searchPages": 2,
  "useProxyOnBlock": true
}
```

# Actor output Schema

## `people` (type: `string`):

One row per person delivered: company, name, title, department, seniority, LinkedIn URL, location, the evidence tying them to the company, and the built email with its confidence and alternatives.

# 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 = {
    "companies": [
        "monzo.com",
        "wise.com"
    ],
    "roles": [
        "leadership"
    ],
    "maxPeoplePerCompany": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("spookyweb/decision-maker-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 = {
    "companies": [
        "monzo.com",
        "wise.com",
    ],
    "roles": ["leadership"],
    "maxPeoplePerCompany": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("spookyweb/decision-maker-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 '{
  "companies": [
    "monzo.com",
    "wise.com"
  ],
  "roles": [
    "leadership"
  ],
  "maxPeoplePerCompany": 5
}' |
apify call spookyweb/decision-maker-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,spookyweb/decision-maker-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/0E9hqPGELuJAqynhO/builds/UqW5mJZFXO95vmSj5/openapi.json
