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

🏷️ From $1.30 / 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. Filter by department. Pay per person delivered.

- **URL**: https://apify.com/wildorigins/decision-maker-finder.md
- **Developed by:** [Wild Origins](https://apify.com/wildorigins) (community)
- **Categories:** Lead generation, AI, Automation
- **Stats:** 36 total users, 26 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.30 / 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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Decision Maker Finder

Company domains in, the people who run them out. One row per person with name, LinkedIn URL, an evidence grade, title and department where published, and a built work email. You pay per person delivered, and a company that returns nobody costs nothing.

### 🔍 What does Decision Maker Finder do?

Decision Maker Finder turns a list of companies into a list of people. For each company it finds the people publicly tied to it, keeps only those with current evidence of working there, classifies each by department and seniority where a title is published, and filters to the departments you asked for. When you give a domain and ask for emails, it works out the company's email naming convention and applies it to every person's name.

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 five thousand domains, choose the departments, and get one table with a LinkedIn URL and an evidence grade per person, without a seat, a login or a browser extension, ready for a CRM import or an API call.

### ⚡ What makes it different?

Three things, each a measured fact rather than a claim.

- **Every person is proven, not guessed.** A row is delivered only when there is public evidence that the person works at that company now. The `evidence` field grades how strong that proof is. Namesakes, former employees and people at similarly named firms are dropped before you are charged.
- **Every real person is delivered.** Many public listings prove where someone works without stating their job title. Those people are kept and marked `roleEvidence: query` so you can filter them, and they are usually the majority of a company's real people. On a run of fifty companies that returned 248 people, a title only filter would have returned 78.
- **It runs in parallel and it does not fall over.** Up to twenty companies are worked at once. A company whose lookup fails is skipped and named in the status message; it never ends the run. Fifty companies finish in about two minutes.

Nothing is fetched from LinkedIn, so there is nothing to log in to and no account at risk.

### 📊 What data can I extract?

| Field | What it holds |
|---|---|
| 🏢 company | The company name used for the lookup |
| 🌐 domain | The domain you gave, or null for a bare name |
| 👤 name, firstName, lastName | The person as their public profile shows them |
| 💼 title | Their published job title, or null when none is published |
| 🗂️ roleCategory | leadership, sales, marketing, engineering, product, finance, operations, hr, other, or unclassified when no title is published |
| 📶 seniority | c-level, vp, director, head, manager, lead, individual, or unknown |
| 🧭 roleEvidence | title when the department was read from a published title, query when the person matched the roles you asked for but publishes no title |
| 🔗 linkedinUrl | Their public profile URL |
| 📍 location | Location, when published |
| 🧾 employerEvidence | The employer their public profile names, when it names one |
| ✅ evidence | How strongly the person is tied to the company: experience is the strongest grade, then headline, then snippet |
| ✉️ email | The work address built from the naming convention |
| 🔤 emailPattern | The convention used, such as first.last |
| 📊 emailConfidence | How sure the convention is, 0 to 1 |
| 📋 emailCandidates | Every convention applied to the name, the chosen one first |
| 🔎 source | Where the person was found |
| 🕒 foundAt | When the row was produced |

### 💡 Why find decision makers?

- **Outbound lists.** A list of target accounts becomes a list of named people with LinkedIn URLs and addresses, ready for a sequence.
- **Account research.** Before a call, see who leads sales, product and finance at the company, with an evidence grade 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. Leave the parallel lanes at four for a short list, or raise them for a long one.
4. Run it. Each row is one person. Download as JSON, CSV or Excel, or read it over the API.

### ⚙️ Settings

| Setting | What it does | Default |
|---|---|---|
| companies | Domains or names, one per line, up to 5,000 per run | |
| roles | leadership, sales, marketing, engineering, product, finance, operations, hr, any. Up to three per company | leadership |
| maxPeoplePerCompany | 1 to 50. Bounds the bill per company | 10 |
| includeUntitled | Keep people proven to work at the company who publish no job title. On, they are delivered marked unclassified and charged as a standard person. Off, only titled people are delivered, about a third as many, each charged on the titled only event at a higher rate | on |
| concurrency | Companies worked at once, 1 to 20. Raising it multiplies throughput | 4 |
| generateEmails | Build addresses from the naming convention. Same price either way. Off is faster | on |
| searchPages | 1 to 3, how far to look per department. A company stops early once it has delivered maxPeoplePerCompany, or once looking further would find nobody new | 2 |
| useProxyOnBlock | Leave on. Off, most companies come back unsearched on a long list | on |

### ⬇️ Input

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

### ⬆️ Output

#### Table view

| Company | Name | Title | Department | Seniority | Role evidence | Email | LinkedIn |
|---|---|---|---|---|---|---|---|
| Monzo | Jane Smith | Chief Marketing Officer | marketing | c-level | title | jane.smith@monzo.com | linkedin.com/in/jane-smith |
| Monzo | TS Anil | | unclassified | unknown | query | | linkedin.com/in/tsanil |

#### JSON

```json
{
  "company": "Monzo",
  "domain": "monzo.com",
  "name": "Jane Smith",
  "firstName": "Jane",
  "lastName": "Smith",
  "title": "Chief Marketing Officer",
  "roleCategory": "marketing",
  "seniority": "c-level",
  "roleEvidence": "title",
  "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": "search",
  "foundAt": "2026-09-03T09:00:00.000Z"
}
```

### 🏃 Running large lists, and how long they take

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

| Companies | Lanes | Run time |
|---|---|---|
| 2 | 4 | about 20 seconds |
| 50 | 12 | 90 seconds to 2 minutes |
| 200 | 12 | about 7 minutes |
| 1,000 | 20 | about 25 minutes |
| 5,000 | 20 | about 2 hours |

The first two rows are measured; the rest scale from them, and answer times vary, so treat them as the middle of a range. The first few seconds of any run are the container starting rather than the work. Memory makes no difference: 256 MB was measured at 7% CPU with twenty lanes, so leave it there.

**Set the run timeout to fit the list.** A run stops starting new companies a minute before its own time limit and finishes cleanly, naming what it did not reach. The default is 3,600 seconds, which covers about 1,500 companies at twenty lanes. For 5,000 companies set the timeout to 10,800 seconds. You pay per delivered person rather than per minute, so a generous timeout costs nothing.

**For 20,000 companies or more**, split the list into runs of 5,000 and start them together. Each run is its own container with its own lanes, so four runs of 5,000 at twenty lanes finish in about the same two hours as one. Over the API that is one loop:

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

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const chunks = [];
for (let i = 0; i < companies.length; i += 5000) chunks.push(companies.slice(i, i + 5000));

const runs = await Promise.all(chunks.map((c) => client.actor('spookyweb/decision-maker-finder').start(
  { companies: c, roles: ['leadership'], concurrency: 20, generateEmails: false },
  { timeout: 10800, memory: 256 },
)));
```

Then read each run's dataset when its status is SUCCEEDED. Every run's status message says how many companies it attempted, how many returned nobody, and how many were skipped, so a partial run is never silent.

### 🎯 How sure is each row?

Every row carries two grades.

`evidence` says how strongly the person is tied to the company. **experience** is the strongest: their public profile names the company as their current employer. **headline** means their current headline names it. **snippet** means their own profile summary does. People whose profile names a different current employer, people who only mention the company as a past role, and namesakes are not delivered and not charged for.

`roleEvidence` says where the department came from. **title** means it was read from a published job title. **query** means the person matched the roles you asked for but publishes no title, so the department is unclassified. Many senior people publish no title on their public listing; the second row in the table above is Monzo's chief executive. Switch includeUntitled off to leave those rows out.

### ✉️ How emails are built

When you give a domain and ask for emails, the company's email naming convention is worked out and applied to each person's name. jane.smith is first.last, jane\_smith is first\_last, j.smith is flast. emailConfidence says how sure the convention is.

Be realistic about that. Most companies give away nothing about their convention, and on a measured sample of twenty four UK companies, from banks to law firms to agencies, not one did. 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

- Up to 5,000 companies per run, 50 people per company, 3 departments per company, 20 lanes.
- A company with few people publicly tied to 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.
- A company whose lookup fails is skipped and counted in the status message. The rest of the run is unaffected.

### 💰 How much does it cost?

| Event | Price |
|---|---|
| Person | $0.00175 per person delivered |
| Person, titled only | $0.00225 per person, when includeUntitled is off |
| Actor start | $0.00005 per run |

Charged once per person delivered. A person costs the same however much looking it took, and whether an email was built or not. A company that returns nobody costs nothing beyond the run start.

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

Paid Apify plans pay less per person: **$0.0016** on Bronze, **$0.00145** on Silver and **$0.0013** on Gold. Platinum and Diamond are arranged with Apify directly and bill at the Gold rate. The Apify listing always shows the current rates.

Switching includeUntitled off delivers only titled people, about a third as many for the same lookup, and each one is charged on the titled only event instead: **$0.00225**, falling to **$0.0021** on Bronze, **$0.00195** on Silver and **$0.0018** on Gold and above. Fewer rows at a higher rate, because the lookup costs the same either way.

### 🔌 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 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 and roleEvidence grades so the agent can judge each person 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'],
  concurrency: 12,
});
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. Nothing is fetched from LinkedIn and no account is involved.

#### Why did a company return nobody?

Either few people are publicly tied to that company, or those who are do not show current evidence of working there. Try the company's most common trading name, the any department, or raise searchPages to 3.

#### What is a person with no title?

Someone proven to work at the company whose public listing shows no job title. They are real people at the company, often senior ones, and they are usually the majority of what is found. They come through with roleCategory unclassified and roleEvidence query. Filter on roleEvidence if you only want titled rows, or switch includeUntitled off to leave them out of the run and the bill.

#### How accurate are the emails?

They are built, not verified against the mail server. When the convention can be established, emailConfidence says how sure it is. Usually it cannot, 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?

It grades how strongly the person is tied to the company. experience is the strongest, then headline, then snippet. Former employees, people at similarly named firms and namesakes are not delivered and not charged for.

#### What happens if a company cannot be looked up?

It is retried, and if it still cannot be reached it is reported as not searched in the status message. Nothing is charged for it and the rest of the run continues.

#### How many lanes should I use?

Four for a short list. Twelve to twenty for anything over a few hundred companies. Memory can stay at 256 MB whatever the lane count.

#### 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, plus contact conventions companies publish. 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 5,000 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. The strongest associations with the company come 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 far to look for people at each company for each department, from 1 to 3. One is enough for a leadership search at a small company; three are worth it for a whole department at a large one. A company stops early once it has delivered the people you asked for.

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

Leave on. It is carried by the Actor and adds nothing to your bill; you pay per person delivered. Off, most companies on a long list come back as not searched.

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

How many companies to work in parallel, from 1 to 20. Raising it multiplies throughput. Four suits most lists. Raise it for lists of thousands.

## `includeUntitled` (type: `boolean`):

Some people are proven to work at the company but publish no job title, so the department cannot be read. On, they are delivered with roleCategory unclassified and roleEvidence query, and every person is charged on the standard Person event. Off, only people with a published title are delivered, about a third as many, and each one is charged on the Person, titled only event at a higher rate. The Apify listing shows both rates.

## Actor input object example

```json
{
  "companies": [
    "monzo.com",
    "wise.com"
  ],
  "roles": [
    "leadership"
  ],
  "maxPeoplePerCompany": 5,
  "generateEmails": true,
  "searchPages": 2,
  "useProxyOnBlock": true,
  "concurrency": 4,
  "includeUntitled": 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("wildorigins/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("wildorigins/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 wildorigins/decision-maker-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,wildorigins/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/aQVQBKzCnX0PQQj9H/openapi.json
