# Leads Finder ✅ B2B Emails, Apollo Alternative (`atomus/leads-finder`) Actor

Find B2B leads across 500M+ people with Apollo-style filters: title, seniority, location, company industry, size, tech, funding — plus 557 specific job functions (Revenue Operations, Clinical Trials), not just 35 broad departments. Optional email + company data. Pay per lead. Cheaper than Apollo.

- **URL**: https://apify.com/atomus/leads-finder.md
- **Developed by:** [Atomus APIs](https://apify.com/atomus) (community)
- **Categories:** Lead generation, Automation, Agents
- **Features:** Limited permissions
- **Stats:** 238 total users, 63 monthly users, 100.0% runs succeeded, 3 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $6.00 / 1,000 lead founds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Leads Finder

<table width="100%" style="border:none;border-radius:10px;background:#120306">
<tr><td style="padding:34px;border:none">
<span style="color:#F59E0B;font-size:13px;font-weight:700;letter-spacing:2px">LEADS FINDER &nbsp;&bull;&nbsp; B2B LEADS API</span><br><br>
<span style="color:#F5F5F6;font-size:40px;font-weight:800;letter-spacing:-1.2px">Describe your buyer.<br>Get the list.</span><br><br>
<span style="color:#D6D3D1;font-size:16px">No input list of URLs. Describe who you want — job title, seniority, location, and their company's industry, size, tech stack, revenue and funding stage — and get one structured record per matching person: current role, work history, education, skills, certifications and LinkedIn badges. Then, optionally, <b style="color:#F5F5F6">their verified business email</b>. Every filter is free; you pay per lead returned. No LinkedIn account, no login, no cookies.</span><br><br>
<span style="background:#10B981;color:#FFFFFF;font-size:13px;font-weight:700;padding:6px 13px;border-radius:5px">PAY ONLY FOR LEADS FOUND</span>
<span style="background:#1C1917;color:#F59E0B;font-size:13px;font-weight:700;padding:6px 13px;border-radius:5px">&nbsp;557 JOB FUNCTIONS TO TARGET&nbsp;</span>
</td></tr>
</table>

#### Copy to your AI assistant

Paste this into ChatGPT, Claude, Cursor, or any LLM to start using this Actor right away.

```
atomus/leads-finder is an Apify Actor that finds B2B leads from a description of who you want instead of from a list of URLs: it searches a database of 500M+ people with Apollo-style person and company filters and returns one structured JSON row per lead - full_name, headline, title, seniority, location, linkedin_url, company_name, last_updated, plus a raw object carrying the complete work history, education, skills, certifications, volunteering, organizations, LinkedIn badges and follower counts. Use it whenever someone needs to build a prospect or candidate list from scratch - outbound prospecting, ICP list building, recruiting sourcing, or feeding a sales agent fresh leads - without a LinkedIn account, cookies, or a per-seat subscription. Run it with curl: curl -X POST "https://api.apify.com/v2/acts/atomus~leads-finder/run-sync-get-dataset-items?token=APIFY_TOKEN" -H "Content-Type: application/json" -d '{"title":["Head of Marketing"],"seniority":["director","vp"],"companyIndustry":["software"],"employeeSize":["51-100","101-200","201-500"],"personCountry":["United States"],"maxResults":100}'. Or in Python: ApifyClient("APIFY_TOKEN").actor("atomus/leads-finder").call(run_input={"jobFunction":["revenue_operations"],"personCountry":["United States"],"maxResults":50}) then client.dataset(run["defaultDatasetId"]).list_items().items. Every input is optional: title (string[]), titleMatchMode ("SMART"|"WORD"|"STRICT"), seniority (string[] of c_suite, vp, director, manager, senior, mid-level, entry, intern, owner, founder, head, partner), department (string[], 39 broad departments), jobFunction (string[], 557 narrow functions), the three location levels personCountry (202 countries) / personState (513 states and regions) / personCity (free text, combined with the two above so "Austin" + "Texas" + "United States" searches Austin, Texas (spell places out, "Austin, TX" matches nobody)), keyword, skill, profileBadge (openToWork, hiring, jobSeeker, premium, creator, openLink), the company filters companyDomain, companyIndustry (dropdown, 919 catalog industries) with companyIndustryOther as free text for anything outside it, companyCountry / companyState / companyCity, companyTechnology (dropdown of the 1,668 most-used technologies) with companyTechnologyOther as free text for anything outside it, companyType, employeeSize and companyRevenue (each a tick-list of bands, e.g. ["1-10","201-500"], and the ticks need NOT be adjacent), companyFundingType, exclude twins for keyword, title, seniority and company industry (excludeKeyword drops the recruiters and consultants a broad keyword drags in, before they are returned and billed), maxResults (int 1-10000, default 100, and this is your spend cap), skipFirst (int, default 0: skip the first N matches of the SAME search and start there, so a second run continues where the first stopped instead of paying for those leads again; every row carries total_matches so you know how many are left), findEmail (bool, adds a verified business email per lead, paid Apify plans only, and much slower) and includeCompanyDetails (bool, adds a company_details firmographic block). Fields no longer in the form still work when sent by API: minEmployees, maxEmployees, minRevenue, maxRevenue, fullName, previousTitle, certification, language, degree, fieldOfStudy, minCurrentJobYears, minTotalExperienceYears, companyLinkedin, companyNaics, companySic and the remaining exclude twins. Type free-text values in English: the data is indexed in English, so "Alemanha" matches 0 where "Germany" matches 296,021. Use department OR jobFunction, never both: they combine with OR upstream, so filling both either changes nothing or widens the search and the bill. Every row carries a status ("success" | "not_found" | "error"); you are charged 0.006 USD per lead returned, plus 0.006 per email actually found and 0.0035 per company_details returned, while not_found and error rows are free. Full input schema, every enum and default, and the complete output field list: GET https://api.apify.com/v2/acts/atomus~leads-finder/build/default
```

***

### B2B Leads MCP Server: use these Actors from ChatGPT, Claude or Cursor

Point your AI assistant at Atomus and it can build a prospect list on its own: find the people, pull their full profiles, and enrich the companies behind them. No glue code, no scraping logic in your prompts.

```json
{
  "mcpServers": {
    "atomus": {
      "url": "https://mcp.apify.com?tools=atomus/leads-finder,atomus/google-maps-scraper,atomus/linkedin-company-scraper,atomus/linkedin-company-employees,atomus/linkedin-profile-scraper",
      "headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
    }
  }
}
```

Then ask, in plain language:

> "Find 100 heads of revenue operations at Series B software companies in the US, then pull the full firmographics for every company they work at."

That one sentence uses two Actors in a row. Pinning the `tools=` list is what keeps your assistant on these Actors instead of reaching for whatever scraper it finds first.

***

### How to find B2B leads

#### An ICP in one query

```json
{
  "title": ["Head of Marketing"],
  "seniority": ["director", "vp"],
  "companyIndustry": ["software"],
  "employeeSize": ["51-100", "101-200", "201-500", "501-1000"],
  "personCountry": ["United States"],
  "maxResults": 100
}
```

Person filters and company filters combine with AND, so each one you add narrows the list. Every filter here is free — only the leads that come back are billed.

#### Target a niche function, not a whole department

```json
{ "jobFunction": ["revenue_operations"], "personCountry": ["United States"], "maxResults": 100 }
```

Measured live: the `sales` department matches 28,449,940 people, while the `revenue_operations` function matches 86,195. Use `jobFunction` when you want the niche and leave `department` empty.

#### Companies running a specific technology

```json
{
  "seniority": ["c_suite", "vp"],
  "companyTechnology": ["salesforce"],
  "companyIndustry": ["financial services"],
  "maxResults": 200
}
```

`companyTechnology` and `companyIndustry` only accept values from the supported catalogs (`salesforce`, `react`, `software`, `financial services`), so a free-text guess quietly matches nothing.

#### Catch companies at the moment they start spending

```json
{
  "title": ["Head of Sales", "VP Sales"],
  "companyFundingType": ["series_a", "series_b"],
  "employeeSize": ["11-20", "21-50", "51-100", "101-200"],
  "maxResults": 150
}
```

Funding stage plus headcount is the timing filter: a company that just raised and is still small is the one about to buy.

#### Filter on buying and hiring intent

```json
{ "profileBadge": ["hiring"], "department": ["engineering_technical"], "personCountry": ["Germany"], "maxResults": 100 }
```

`hiring` and `openToWork` are LinkedIn's own badges, so they are current-state signals: who is actively recruiting, and who is open to moving.

#### Add the verified business email

```json
{
  "title": ["Account Executive"],
  "companyIndustry": ["software"],
  "personCountry": ["United Kingdom"],
  "maxResults": 100,
  "findEmail": true
}
```

Emails are a paid add-on on paid Apify plans, charged only when an email is actually found. The run gets much slower and the dataset stays empty until the very end — see the warning under **Input** before you turn it on.

#### Everyone at a named account list

```json
{
  "companyLinkedin": [
    "https://www.linkedin.com/company/stripe",
    "https://www.linkedin.com/company/figma"
  ],
  "seniority": ["director", "vp", "c_suite"],
  "maxResults": 200
}
```

`companyLinkedin` pins exact companies. `companyDomain` is broader and also drags in subsidiaries.

***

### Input

Every parameter is optional. Leave them all empty and the search is unconstrained, capped only by `maxResults`.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `maxResults` | integer | `100` | 1 to 10,000 leads. This is your hard spend cap — you pay per lead returned, so a run can never cost more than this. |
| `title` | string\[] | (none) | Current job titles to match, e.g. `["Account Executive"]`. |
| `titleMatchMode` | string | `SMART` | `SMART` (fuzzy, catches "Sr. Software Engineer"), `WORD` (whole words), `STRICT` (exact title). Also applies to `excludeTitle`. |
| `seniority` | string\[] | (none) | `c_suite`, `vp`, `director`, `manager`, `senior`, `mid-level`, `entry`, `intern`, `owner`, `founder`, `head`, `partner`. |
| `department` | string\[] | (none) | 39 broad departments (35 current plus 4 legacy aliases), e.g. `sales`, `marketing`, `engineering_technical`. |
| `jobFunction` | string\[] | (none) | 557 narrow functions, each prefixed by its department: `Sales › Revenue Operations`, `Medical Health › Clinical Trials`. |
| `findEmail` | boolean | `false` | Add-on: a verified business email per lead. Paid Apify plans only. Billed only when an email is found. |
| `includeCompanyDetails` | boolean | `false` | Add-on: the full firmographic record of each lead's current company, in `company_details`. Billed per lead that returns a company. |

**Free person filters:** `personCountry`, `personState`, `personCity`, `keyword` (headline / summary text), `skill`, `profileBadge` (`openToWork`, `hiring`, `jobSeeker`, `premium`, `creator`, `openLink`).

**Free company filters:** `companyCountry`, `companyState`, `companyCity`, `companyDomain`, `companyIndustry`, `companyTechnology`, `companyType` (`public_company`, `privately_held`, `self_owned`, `self_employed`, `partnership`, `non_profit`, `educational`, `government_agency`), `employeeSize`, `companyRevenue`, `companyFundingType` (19 stages from `pre_seed` and `angel` through `series_a`–`series_f`, `private_equity`, `ipo` and `post_ipo`).

**Free exclusions:** `excludeKeyword`, `excludeTitle`, `excludeSeniority`, `excludeCompanyIndustry`. Exclusion happens upstream, so an excluded lead is never returned and never billed.

> **`excludeKeyword` is what keeps a broad keyword affordable.** Searching `keyword: ["payments"]` also brings in every recruiter and consultant who wrote *payments* in their headline, and you pay for those rows because billing is per lead returned. Excluding drops them before they are returned. Measured live on the c-suite baseline of 8,628,955: `payments` alone matches 6,912, and `payments` minus `recruiter` matches 6,911. It searches the same place `keyword` does (headline and summary), so type it in English too.

> **Company size and revenue are one tick-list each, and the ticks do not have to be next to each other.** `employeeSize` takes any of `1-10`, `11-20`, `21-50`, `51-100`, `101-200`, `201-500`, `501-1000`, `1001-2000`, `2001-5000`, `5001-10000`, `10000+`; `companyRevenue` takes `0-100000` through `10000000000+`. Ticking `1-10` and `201-500` returns exactly those two groups and none of the companies in between, in a single search. Measured live on the c-suite baseline: `1-10` alone matches 1,285,255 and `201-500` alone 349,539, and the two together come back as 1,634,794, the exact sum, not the 3,191,599 that searching 1 to 500 returns.

**Filters that still work but are no longer in the form.** The form was cut from 58 fields to 29 so that the ones that matter are findable. These keep working exactly as before in a saved task or an API call, they are simply not rendered any more: `minEmployees`, `maxEmployees`, `minRevenue`, `maxRevenue` (superseded by the two band tick-lists above, and ignored as a pair as soon as a band is ticked), `fullName`, `previousTitle`, `certification`, `language`, `degree`, `fieldOfStudy`, `minCurrentJobYears`, `minTotalExperienceYears`, `companyLinkedin`, `companyNaics`, `companySic`, `location`, `companyLocation`, and the exclude twins `excludeDepartment`, `excludeJobFunction`, `excludePersonCountry`, `excludePersonState`, `excludePersonCity`, `excludeCompanyCountry`, `excludeCompanyState`, `excludeCompanyCity`, `excludeCompanyTechnology`, `excludeCompanyType`, `excludeLocation`, `excludeCompanyLocation`.

> **Type free-text values in English.** Anything you type by hand (`title`, `keyword`, `skill`, `personCity`, `companyCity`) goes to the search as written, and the data is indexed in English. Measured live: `Germany` matches 296,021 c-suite people and `Alemanha` matches 0; `United States` matches 2,905,694 and `Estados Unidos` matches 0. Watch out for the quiet version of this: `Spain` matches 109,723 and `Espanha` matches **2**, which looks like a working run rather than an empty one. Casing and accents are safe: `São Paulo`, `Sao Paulo` and `sao paulo` all match the same 69,452.

> **Department and Job function are the same filter at two levels of detail — use one or the other, never both.** They combine with OR upstream, so filling both either changes nothing (measured live: `sales` alone matches 28,449,940 people, and `sales` + `revenue_operations` matches 28,449,940 too, because the function already sits inside the department) or *widens* your results and your bill (a function from a different department gets ADDED). Want a whole department? Use `department`. Want a niche? Use `jobFunction` and leave `department` empty. This does **not** apply to the exclude twins, where combining them legitimately drops both groups.

> **A continent works too.** `personCountry` and `companyCountry` list the six continents above the 202 countries, because the provider matches them: `Europe` returns 2,135,173 people and `North America` 3,354,584. Named blocs do not — `European Union`, `Latin America`, `Middle East` and `Nordics` all match nobody — so they are not offered.

> **Location is three fields, not one: country, state and city.** They combine into a single place, so country `United States` + state `Texas` + city `Austin` searches Austin, Texas. Country and state are dropdowns; city is free text because no usable list of every city exists. **Spell places out.** Measured live: `Austin, TX` matches 0 people and `Austin, Texas` matches 23,273; `London, UK` matches 0 and `London` matches 114,442. The same applies to the company side (`companyCountry`, `companyState`, `companyCity`).

> **`companyIndustry` and `companyTechnology` are dropdowns of the data source's own catalog** — all 919 industries, and the 1,668 technologies used by 500+ companies out of the 16,041 it knows. The option values are the source's own lowercase spelling (`software`, `salesforce`), which is what these fields already accepted, so an existing API call keeps working. The LinkedIn-style label is the wrong one: `Computer Software` matches 0, `software` matches 161,323. For a value outside either dropdown, use `companyIndustryOther` or `companyTechnologyOther` — both are free text and are merged into the same filter. They matter because the option lists are a snapshot: Apify refuses a run whose value is not in a field's list, so an industry the data source adds later would stop a saved run rather than merely not filter it.

> **`companyNaics` and `companySic` need the full code.** `541511` and `7372` work; the sector prefixes `54` and `73` match nothing at all. Both are API-only now, listed above.

> **⏳ The email add-on makes a run take minutes instead of seconds, and the dataset stays empty until the end.** Email lookup is an asynchronous batch job: it is submitted in one piece and every result arrives together at the finish. That is not a failure — watch the run status message, which reports how many emails have been found so far. Do not abort. If you do stop the run, hit **Resurrect** in the Apify console: it resumes from its checkpoint, nothing is re-submitted, and nothing is charged twice.

***

### What data does the Leads Finder return?

One row per lead, each carrying a `status` (`success` | `not_found` | `error`). Flat fields cover what most people filter and export on; `raw` carries the complete profile underneath.

| Group | Fields |
|---|---|
| **Identity** | `full_name` · `headline` · `title` (current role) · `seniority` · `location` · `linkedin_url` |
| **Company** | `company_name` (the current employer's name) |
| **Email (add-on)** | `email` · `email_status` (e.g. `VALID`) — present only when `findEmail` is on **and** a deliverable email was found |
| **Company details (add-on)** | `company_details` — the full firmographic block: funding rounds, every office, complete tech stack, industries, revenue band. Present only when `includeCompanyDetails` is on and the lead has a company |
| **Full profile** | `raw`: `profile` (name, headline, summary, picture, industry), `position_groups` (complete work history with company, dates and titles), `educations`, `skills`, `certifications`, `volunteer_experiences`, `organizations`, `member_badges`, `statistics` (follower and connection counts, career tenure dates), `link` (LinkedIn and other profile URLs) |
| **Freshness** | `last_updated` — when the upstream source last refreshed this person (`YYYY-MM-DD`) |
| **Provenance** | `_metadata.extracted_at` — ISO timestamp of the lookup |

Firmographics live **only** in `company_details`, the paid add-on. They are stripped out of `raw`, so a run without the add-on never receives them.

#### Example row

```json
{
  "status": "success",
  "full_name": "Leonardo Specht",
  "headline": "SWE @ Stripe | Ex Amazon, Meta",
  "title": "Software Engineer",
  "company_name": "Stripe",
  "location": "Dublin, County Dublin, Ireland, Europe",
  "seniority": "senior",
  "linkedin_url": "https://www.linkedin.com/in/leospecht",
  "last_updated": "2026-07-20",
  "email": "lspecht@stripe.com",
  "email_status": "VALID",
  "raw": {
    "profile": { "full_name": "Leonardo Specht", "summary": "...", "industry": "Computer Software" },
    "position_groups": [
      { "company": { "name": "Stripe" }, "date": { "start": "2022", "end": null },
        "profile_positions": [{ "title": "Software Engineer", "location": "Dublin" }] }
    ],
    "educations": [{ "school": { "name": "UFRGS" }, "degree_name": "BSc", "field_of_study": "Computer Science" }],
    "skills": ["Go", "Kubernetes", "Distributed Systems"],
    "member_badges": { "premium": true, "open_to_work": false }
  },
  "_metadata": { "extracted_at": "2026-09-04T12:44:21.000Z" }
}
```

`status: "not_found"` means the filters matched nobody, and it is free. `status: "error"` carries a plain-language `reason` and an `error_kind`, and is also free.

#### Where the data comes from

The Actor queries a continuously refreshed database of enriched professional profiles rather than crawling LinkedIn itself — which is why there is no cookie, no session and no ban risk. It filters on each person's **current** title and company, so you get people in the role today, and `last_updated` on every row tells you how recent that record is.

***

### How much does it cost to find B2B leads?

**$0.006 per lead returned** ($6.00 per 1,000). Pay-per-event: `not_found` and `error` rows are free, and `maxResults` is a hard cap on both the leads and the bill.

| Leads | Cost |
|---|---|
| 100 | $0.60 |
| 1,000 | $6.00 |
| 2,500 | $15.00 |
| 10,000 | $60.00 |

**Add-ons, only when you turn them on:**

| Add-on | Price | Charged when |
|---|---|---|
| Verified business email | $0.006 per email ($6.00 per 1,000) | Only when a deliverable email is found. A lead with no verifiable email is free. Paid Apify plans only. |
| Full company details | $0.0035 per company ($3.50 per 1,000) | Only on leads that actually return a company. |

There is **no search fee and no floor** — filters cost nothing however aggressive they are, and a run that matches nobody charges nothing. If you set Apify's maximum-charge cap below the cost of a single lead, the run stops before doing any paid work and tells you so, rather than half-billing.

**Free plan:** 10 leads per calendar month so you can inspect every field before paying. The counter resets on the 1st. Turning the email add-on on from a free plan does not fail the run: the add-on is skipped and never charged, and your leads are still delivered in full.

***

### What do people use the Leads Finder for?

- **Outbound prospecting**: build a targeted list by title, seniority, industry and company size, then export it straight to your sequencer.
- **ICP list building**: describe the exact buyer — function, headcount band, funding stage, tech stack — and get only the people who match.
- **Technographic targeting**: find decision-makers at companies already running a specific technology, so the pitch writes itself.
- **Funding-triggered outreach**: catch Series A and B companies while the budget is new.
- **Recruiting sourcing**: filter on skills, certifications, degrees, previous titles, years of experience and the `openToWork` badge.
- **CRM and warehouse enrichment**: pull leads by company domain or LinkedIn URL and load structured rows into HubSpot, Salesforce or your database.
- **Territory and market sizing**: the match count tells you how many people fit an ICP before you spend anything on the list.
- **AI agent context**: hand a sales agent a fresh, structured stream of qualified leads.

***

### Leads Finder vs Apollo, ZoomInfo and Lusha vs cookie-based scrapers

| | This Leads Finder | Apollo / ZoomInfo / Lusha | Cookie-based LinkedIn scrapers |
|---|---|---|---|
| **Pricing** | Pay per lead returned ($0.006), hard spend cap per run | Per-seat subscriptions, usually annual | Subscription plus your own account |
| **Commitment** | None — run once and stop | Contract and seat count | Ongoing tool + account risk |
| **Account / ban risk** | None (no account, no cookies) | None | High — your LinkedIn account can be restricted |
| **Targeting depth** | 557 job functions, 39 departments, 12 seniorities, plus company tech, revenue and funding | Comparable, behind the platform UI | Whatever the search page shows you |
| **Emails** | Add-on, billed only when found | Bundled into plan credits | Rarely, and unverified |
| **Automation** | API, scheduler and MCP out of the box | API on higher tiers | Manual, or a fragile browser session |
| **Best for** | Pay-as-you-go prospecting, pipelines, AI agents | Teams wanting one all-in-one sales platform | One-off manual list pulls |

***

### FAQ

#### What is a B2B leads finder?

A leads finder searches a large professional database and returns the people who match your filters — job title, seniority, function, location, company industry, size, technology, revenue and funding stage — so you build a prospect list from a description instead of hunting site by site or buying a static list.

#### How do I find B2B leads without a LinkedIn account or cookies?

Fill in the filters and run the Actor. It queries an enriched profile database rather than crawling LinkedIn, so there is no login, no session cookie, no browser and no ban risk. Filters in, structured lead rows out.

#### Can I use this from ChatGPT or Claude?

Yes, two ways. Paste the "Copy to your AI assistant" block above into any LLM and it will write the call for you. Or connect the **B2B Leads MCP server** config above, and every Atomus Actor becomes a native tool your assistant can call on its own, including chaining several in one request.

#### How much does it cost?

$0.006 per lead returned ($6 per 1,000). Emails are $0.006 each and only when found; full company details are $0.0035 each. `not_found` and `error` rows are free. Free Apify plans include 10 leads per month so you can check the output before paying.

#### How do I control what I spend?

Set `maxResults`. You are charged per lead returned and the run stops at your cap, so the maximum cost of a run is known before you start. Filters themselves are always free, so narrowing the audience only ever lowers the bill.

#### Should I use Department or Job function?

One or the other, never both. They are two levels of the same taxonomy and combine with OR, so filling both either changes nothing or widens your search. Use `department` for a whole department, `jobFunction` for a niche — that is the difference between all 28,449,940 people in Sales and the 86,195 in Revenue Operations.

#### Do I get email addresses?

Yes, as an opt-in add-on on paid Apify plans. Turn on `findEmail` and each lead comes back with a verified business `email` and an `email_status`. You are charged only for emails actually found. Expect the run to take much longer and to produce nothing until the end.

#### Why is my run with emails on taking so long and showing no results?

That is normal up to 100 leads: at that size the lookup is one batch job, so the results all arrive together at the finish. Above 100 leads the emails are bought 100 at a time and each page is delivered as soon as it is verified, so rows appear as the run goes. Either way the run status message reports progress, and if you stop the run use **Resurrect**, which resumes from the checkpoint without re-charging.

#### How many leads can one run return?

Up to 10,000. The underlying source surfaces at most a few thousand people per query, so a very broad search returns what exists rather than the number you asked for — and you are never charged for leads that do not exist. For a bigger pull, split the query by location, seniority or company size.

#### How fresh is the data?

Every row carries `last_updated`, the date the upstream source last refreshed that person, so you always know how stale a record is before you use it.

#### Is it legal to use?

This Actor returns professional and business data from licensed and publicly available sources. You are responsible for using the output in line with applicable laws (GDPR/CCPA), platform terms, and your own compliance requirements. It is an independent tool, not affiliated with LinkedIn, Apollo, ZoomInfo or Lusha.

#### Can I run this on a schedule?

Yes. Apify [Schedules](https://docs.apify.com/platform/schedules) run the Actor on a cron interval and [webhooks](https://docs.apify.com/platform/integrations/webhooks) push each finished run into your systems — which is how a funding-stage filter becomes a weekly feed of newly funded accounts.

***

### All Atomus scrapers

<span style="background:#10B981;color:#FFFFFF;font-size:13px;font-weight:700;padding:6px 13px;border-radius:5px">2.4M+ RESULTS DELIVERED</span>

### Support

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by LinkedIn Corporation, Apollo.io, ZoomInfo or Lusha. All trademarks are property of their respective owners.

Use the data returned by this Actor in compliance with applicable data protection laws (GDPR, CCPA) and the terms of the platforms involved. Do not use it for spam, harassment, or unlawful purposes.

# Actor input Schema

## `maxResults` (type: `integer`):

Hard cap on how many leads to return. This is your spend cap (you pay per lead returned). The run stops once it hits this or runs out of matches. LinkedIn surfaces at most a few thousand per query. ⏱️ With the email add-on on, plan on about 1 hour of run time per 5,000 leads and set the run timeout to match (Run options, Timeout). A run that reaches its timeout first keeps everything it delivered and tells you how to Resurrect it for the rest.

## `countOnly` (type: `boolean`):

Answer how many leads match these filters and stop, without pulling any. Free: nothing is charged, and the count is the whole match total, not capped by Max results. Use it to check a filter set before paying for the real run. Limited to 50 previews per month per account.

## `skipFirst` (type: `integer`):

Already pulled leads from this exact search and want the next batch? Put how many you already have here and the run starts right after them, so you never pay twice for the same lead. Leave it at 0 to start from the top. Every lead comes back with total_matches, the size of the whole list, so you always know how much is left. Keep the filters identical: a different search is a different list.

## `sectionRole` (type: `string`):

UI section

## `title` (type: `array`):

Match leads whose CURRENT title contains any of these, e.g. "Software Engineer", "Account Executive". Leave empty for all titles. Write titles in English: the data source only indexes English job titles.

## `titleMatchMode` (type: `string`):

SMART = fuzzy (recommended, catches "Sr. Software Engineer"). WORD = whole words. STRICT = exact title only. Also applies to the Exclude titles filter below.

## `seniority` (type: `array`):

Keep only these seniority levels. Leave empty for all.

## `department` (type: `array`):

Keep only leads in these broad departments — the ENTIRE department. Use this OR "Job function", never both: measured live, Sales alone matches 28,449,940 people and Sales + Revenue Operations matches 28,449,940 too, because the function already sits inside the department. A function from a DIFFERENT department gets ADDED to your results instead (the two combine with OR), widening your search and your bill — never narrowing it.

## `jobFunction` (type: `array`):

Keep only leads in these specific job functions — pick these INSTEAD of a department when you want precision: Revenue Operations (86,195 people) rather than all of Sales (28,449,940). Every option is prefixed with its department, so typing "sales" narrows the list to the ~20 sales functions instead of scrolling all 557. Leave "Department" empty when you use this — filling both either changes nothing or widens your results.

## `excludeTitle` (type: `array`):

Drop leads whose CURRENT title matches any of these (uses the Title match mode above), e.g. exclude "intern", "assistant". Leave empty to skip. Write titles in English, same as the field above.

## `excludeSeniority` (type: `array`):

Drop leads at these seniority levels. Leave empty to skip.

## `sectionPersonLocation` (type: `string`):

UI section

## `personCountry` (type: `array`):

Keep only leads living in these countries. Pick from the list — every option is a value this data source is known to accept. Typing a place it does not know returns no leads at all. Leave empty for all.

## `personState` (type: `array`):

Keep only leads living in these states, provinces or regions. Combined with the country above. Pick from the list — every option is a value this data source is known to accept. Typing a place it does not know returns no leads at all. Leave empty for all.

## `personCity` (type: `array`):

Keep only leads living in these cities. Free text, because there is no usable list of every city. It is combined with the country and state you picked above, so "Austin" with state "Texas" and country "United States" is sent as "austin, texas, united states". Spell the city out: "Austin, TX" returns zero leads, "Austin, Texas" returns thousands. Leave empty for all. Write the city in English. "Munich" works, "Munchen" does not, and a city name in your own language can return a handful of wrong leads instead of none, which is harder to notice.

## `sectionPersonExtras` (type: `string`):

UI section

## `keyword` (type: `array`):

Free-text keywords matched in the lead's headline/summary, e.g. "kubernetes", "payments". Leave empty to skip. Write keywords in English: profiles are indexed in English.

## `excludeKeyword` (type: `array`):

Drop leads whose headline/summary matches any of these, e.g. search "payments" but exclude "recruiter", "consultant". Excluded leads are never returned, so you are never charged for them. Leave empty to skip. Write keywords in English, same as the field above.

## `skill` (type: `array`):

Free-text skills the lead lists, e.g. "Kubernetes", "Salesforce". Leave empty to skip. Write skills in English: "machine learning", not "aprendizado de maquina".

## `profileBadge` (type: `array`):

Keep only leads carrying these LinkedIn badges. "hiring" and "openToWork" are strong intent signals. Leave empty for all.

## `companyDomain` (type: `array`):

Keep only leads at companies with these website domains, e.g. "stripe.com". Broad match (also drags in subsidiaries). Leave empty for all.

## `companyIndustry` (type: `array`):

Keep only leads whose company is in these industries. Every option is one of the 919 industry names this data source publishes, so nothing you pick can come back empty for not existing. Typing a LinkedIn-style label instead — "Computer Software", "Information Technology & Services" — returns zero leads. Leave empty for all.

## `companyIndustryOther` (type: `array`):

For an industry the dropdown above does not offer. The dropdown holds the data source's catalog as it stood when this build shipped, and that catalog grows — a value it has added since is REJECTED by the dropdown, which stops the run rather than merely not filtering it. Type it here instead. Spell it the way the source does: lowercase, and its own vocabulary rather than the LinkedIn label ("software", not "Computer Software"). Leave empty unless the dropdown was missing something. Write it in English and in the wording the industry list above uses, since this field is matched against the same catalog.

## `excludeCompanyIndustry` (type: `array`):

Drop leads whose company is in these industries. Excluded rows are never returned, so they are never charged. Leave empty to skip.

## `companyTechnology` (type: `array`):

Keep only leads whose company uses these technologies. The list holds the 1,668 most widely used technologies in the data source, sorted by how many companies run them — enough to cover an ICP without a dropdown nobody can scroll. Leave empty for all.

## `companyTechnologyOther` (type: `array`):

For a technology the dropdown above does not offer. The data source knows 16,041 technologies and the dropdown carries the 1,668 used by 500+ companies, so a niche tool lives here instead. Spell it the way the source does — lowercase, the plain product name ("outsystems", "retool"). A name it does not know matches nothing rather than erroring. Leave empty unless the dropdown was missing something. Write the product name in English, as the vendor spells it ("HubSpot", "Google Analytics").

## `companyType` (type: `array`):

Keep only leads whose company is one of these types. Leave empty for all.

## `employeeSize` (type: `array`):

Tick every company size you want. They do not have to be next to each other: "1 to 10" plus "201 to 500" returns exactly those two groups and none of the companies in between, in one search. Leave empty for any size.

## `companyRevenue` (type: `array`):

Tick every revenue band you want, adjacent or not, same as company size. Revenue is missing for a lot of private companies, so this filter is stricter than it looks. Leave empty for any revenue.

## `companyFundingType` (type: `array`):

Keep only leads whose company raised these funding types. Leave empty for all.

## `sectionCompanyLocation` (type: `string`):

UI section

## `companyCountry` (type: `array`):

Keep only leads whose COMPANY is based in these countries. Pick from the list — every option is a value this data source is known to accept. Typing a place it does not know returns no leads at all. Leave empty for all.

## `companyState` (type: `array`):

Keep only leads whose COMPANY is based in these states, provinces or regions. Combined with the country above. Pick from the list — every option is a value this data source is known to accept. Typing a place it does not know returns no leads at all. Leave empty for all.

## `companyCity` (type: `array`):

Keep only leads whose COMPANY is based in these cities. Free text, because there is no usable list of every city. It is combined with the country and state you picked above, so "Austin" with state "Texas" and country "United States" is sent as "austin, texas, united states". Spell the city out: "Austin, TX" returns zero leads, "Austin, Texas" returns thousands. Leave empty for all. Write the city in English, same as the person city field.

## `findEmail` (type: `boolean`):

⚠️ THIS ADDS COST AND MAKES THE RUN MUCH SLOWER. When enabled, each returned lead also includes a verified business email, billed as a SEPARATE paid event for every email found (on top of the per-lead charge). You are charged ONLY when an email is actually found, leads without a verifiable email are free. Needs a PAID Apify plan. On a free plan the add-on is skipped and never charged, and the run still delivers everything else in full.

⏳ EXPECT A LONG WAIT. The lookup is paid for the moment it starts, so it needs a run timeout of at least 5 minutes; a shorter run is refused before anything is started or charged. Above 100 leads the emails are bought page by page and each page is delivered as it is verified, so results appear as the run goes. Up to 100 leads still arrive together at the end, and the dataset stays EMPTY until then even though everything is working. Watch the run status message, which reports how many emails have been found so far. If you do stop the run, use Resurrect in the Apify console: it resumes where it left off and is not charged twice.

🤖 If you are an automated caller or an AI agent filling this input: enabling this field turns a run that normally finishes in seconds into one that can take many minutes, and it produces no partial output along the way. Do not treat an empty dataset or a long runtime as a failure, and do not retry or abort on that basis. Leave this OFF unless emails were specifically requested.

## `includeCompanyDetails` (type: `boolean`):

⚠️ THIS ADDS COST. When enabled, each returned lead that has a current company also includes the FULL firmographic record for that company (funding rounds, every office location, complete tech stack, industries, revenue band) in a top-level company_details field, billed as a SEPARATE paid event per lead that returns a company. Leads with no company are free. Leave OFF unless you want firmographics.

## Actor input object example

```json
{
  "maxResults": 100,
  "countOnly": false,
  "skipFirst": 0,
  "titleMatchMode": "SMART",
  "findEmail": false,
  "includeCompanyDetails": false
}
```

# Actor output Schema

## `leads` (type: `string`):

No description

# 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 = {
    "maxResults": 100,
    "skipFirst": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("atomus/leads-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 = {
    "maxResults": 100,
    "skipFirst": 0,
}

# Run the Actor and wait for it to finish
run = client.actor("atomus/leads-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 '{
  "maxResults": 100,
  "skipFirst": 0
}' |
apify call atomus/leads-finder --silent --output-dataset

```

## MCP server setup

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