# Prospect Search API - Work Email and Mobile Phone Finder (`nabeelbaghoor/prospect-search-contact-finder-api`) Actor

Search a B2B prospect database by job title, seniority, department, location, headcount, revenue, technologies and funding stage, then reveal verified work email addresses and mobile phone numbers. Count a segment for free before you reveal it. Pay per result. Bring your own API key.

- **URL**: https://apify.com/nabeelbaghoor/prospect-search-contact-finder-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Business, Developer tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 40.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$15.00 / 1,000 results

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?

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

## Prospect Search API - Work Email and Mobile Phone Finder

Search a B2B prospect database by job title, seniority, department, location, headcount, revenue, technologies and funding stage, count the segment for free, then reveal verified work email addresses and mobile phone numbers for the people in it. One flat row per person or company.

### What this actor does

- **Counts a segment before you pay to reveal it.** The search mode returns how many people match your filters plus a sample of who they are, and spends no provider credits. Every preview row carries the true segment size, so you can tighten filters until the number is right and only then reveal.
- **Reveals in bulk or one at a time.** List mode hands the whole filter set to the provider, waits for it to finish, and writes out every revealed contact with email and phone. Individual reveal works from profile URLs, known email addresses, or names paired with an employer.
- **Waits properly for asynchronous jobs.** Revealing contacts is a job, not a request. The actor polls with a widening interval up to a timeout you set, reports the state as it goes, and only writes rows once the provider says the job finished.
- **Filters on the things that predict a reply.** Job change inside the last 30 to 90 days, headcount growth band, department headcount written as `sales:10-50`, technologies the company runs, technologies it does not, funding stage and revenue band.
- **Separates verified addresses from risky ones.** A finished list can be read as everything it resolved, only the addresses that passed verification, or only the ones that failed, so a send list and a review list come out of the same run.
- **Understands include and exclude on every text filter.** Titles, companies, industries, technologies and description keywords all take an exclude list, which is how you keep your own company and your existing customers out of a segment.
- **Reads messy input.** Pasted profile URLs lose their tracking parameters, pasted company URLs reduce to the bare hostname, and an email address reduces to its domain.
- **Never charges for a miss.** Only rows carrying a resolved person or company are billed.

### Input

| Field | What it does |
| --- | --- |
| `mode` | Prospect search, prospect list, individual reveal, company search, company enrichment or credits. |
| `jobTitles`, `jobTitlesExcluded` | Match or rule out title text. |
| `jobTitleLevels` | Seniority bands, from CXO to entry level. |
| `jobRoles`, `jobSubRoles` | Department and narrower function. |
| `locations`, `locationsExcluded` | Person location, as `city`, `state:`, `country:`, `continent:` or `group:`. |
| `companies`, `companiesExcluded`, `pastCompanies` | Current and former employers. |
| `companyLocations` | Where the company sits, written the same way as person locations. |
| `companyIndustries`, `companySizes`, `revenue`, `companyTypes` | Firmographics. |
| `technologies`, `technologiesExcluded` | Technographic filters. |
| `companyAnnualGrowth`, `departmentSizes`, `fundingStages` | Growth and funding signals. |
| `lastRoleChange`, `lastCompanyChange` | Job change recency windows. |
| `profileUrls`, `emails`, `fullNames` | What to reveal, for individual reveal. |
| `domains`, `companyNames`, `companySlugs` | Company identifiers for enrichment. |
| `enrichmentLevel` | None, partial, phone or full waterfall. |
| `acceptWorkEmail`, `acceptPersonalEmail`, `acceptGenericEmail` | Which address types to accept. |
| `listSegment` | Everything, verified only, or risky only. |
| `skipDuplicates` | Skip people earlier lists already revealed. |
| `jobTimeoutSeconds` | How long to wait for a reveal job. |
| `requestsPerMinute` | Pace the run under your plan's rate limit. |
| `skipNotFound` | Leave unresolved inputs out of the dataset. |
| `maxResults` | Hard cap on rows, and therefore on spend and run time. |
| `apiKey` | Your own API key. Stored as a secret. |

### Example output

```json
{
  "found": true,
  "mode": "prospectList",
  "query": "Heads of sales, US SaaS",
  "segment": "valid",
  "fullName": "Jane Doe",
  "firstName": "Jane",
  "lastName": "Doe",
  "jobTitle": "Head of Sales",
  "email": "jane.doe@example.com",
  "emailType": "work",
  "emailStatus": "valid",
  "linkedinUrl": "https://www.linkedin.com/in/example",
  "location": "San Francisco, California, United States",
  "company": "Example Inc",
  "companyDomain": "example.com",
  "companyIndustry": "Computer Software",
  "companySize": "201-500",
  "companyFounded": 2014,
  "companyRevenue": "$25M-$50M",
  "companyType": "private",
  "companyLastFundingRound": "series_b",
  "companyLastFundingAmount": 32000000,
  "companyLocation": "San Francisco, California, United States",
  "error": null,
  "raw": { }
}
```

### Frequently asked questions

#### What is a prospect search API?

A prospect search API is a query interface over a database of working professionals and the companies they work for. Instead of scraping profiles one by one, you describe the people you want with filters such as job title, seniority, department, location, company headcount, revenue band, technologies the company runs and how recently the person changed jobs, and the API returns everyone who matches. This actor exposes those filters as actor input and writes the matches to a dataset, one row per person, with the option to reveal each person's work email address and mobile number.

#### How do I find someone's work email address and phone number?

Use individual reveal when you have specific people, and prospect list when you have a filter set. Individual reveal accepts a profile URL, a known email address, or a full name together with a company domain or company name, and returns the work address, the mobile number and the verification status of the address. Prospect list does the same thing for a whole segment at once: it hands your filters to the provider, waits for the reveal job to finish, and writes out every contact it resolved. Set `enrichmentLevel` to `phone` or `full` when the mobile number matters, since the cheaper levels return the email only.

#### How do I avoid wasting credits on a bad segment?

Run `prospectSearch` first. It reports how many people match your filters and returns a free sample of up to thirty of them without spending any provider credits, and each row carries the true segment size. Adjust the filters until the count is the size you intended, then switch the same input to `prospectList` to reveal it. This matters because a filter that is one degree too broad, such as a title match without a seniority band, can multiply a segment tenfold, and you only find that out after paying if you reveal first.

#### What is the difference between the valid and risky segments?

A finished list separates addresses that passed verification from those that did not. `valid` returns only the addresses confirmed deliverable, which is what you send to. `risky` returns the ones that failed or could not be confirmed, usually catch-all domains and addresses whose mail server would not answer. `people` returns everything the list resolved. Sending to the risky segment is what damages a sending domain's reputation, so it is worth pulling it separately and either verifying it another way or leaving it alone.

#### Can it filter on the technologies a company uses?

Yes, in both directions. `technologies` keeps only companies running what you name, and `technologiesExcluded` rules out companies running something else, which is the usual way to skip accounts that already bought a competitor. Technographic filters combine with the firmographic ones, so a segment such as "companies of 201 to 500 people, running a named CRM, that grew headcount more than 20 percent last year, whose head of sales started in the last 90 days" is a single filter set rather than four separate lists you have to intersect yourself.

#### Does this work for account based prospecting?

Yes. `companySearch` finds the accounts matching company filters and returns firmographics, funding and profile identifiers for each, and `companyEnrich` takes domains, company names or profile slugs you already have and appends industry, headcount, revenue band, funding history, location and social profiles. A common two step run is to search for accounts, take the domains out of the dataset, and feed them back in as the `companies` filter on a people search so every person you reveal belongs to an account you already qualified.

#### Do I need my own API key?

Yes. This actor is bring your own key: it calls the prospecting API with credentials from your own account, so your plan governs your credits, your rate limit and your data rights. Put the key in the `apiKey` input, where it is stored as a secret, or supply it as the `DATA_API_KEY` environment secret. The actor's own charge is separate and is per row resolved, and rows that resolved to nothing are never charged for.

### Keyword map

Prospect search API, B2B contact database API, work email finder API, mobile phone number finder, lead list building API, sales prospecting API, job change data, technographic filters, firmographic search, account based prospecting, email verification status, contact enrichment API.

# Actor input Schema

## `mode` (type: `string`):

Prospect search counts the people matching your filters and returns a free sample without contact details. Prospect list reveals a whole segment, with work email addresses and phone numbers. Individual reveal works one named person or profile at a time. Company search and company enrichment work on accounts rather than people. Credits reports the balance left on your key.

## `jobTitles` (type: `array`):

Job titles to match, one per line. Matching is on the title text, so "head of sales" and "vp sales" are two separate entries rather than one query. Used by prospect search, prospect list and the free preview.

## `jobTitlesExcluded` (type: `array`):

Job titles to rule out, one per line. Excluding is how you keep assistants, interns and contractors out of a segment that otherwise matches.

## `jobTitleLevels` (type: `array`):

Keep only people at these seniority levels. This is the provider's own banding, applied server side, so it narrows the segment rather than the dataset.

## `jobRoles` (type: `array`):

Keep only people in these departments. Use this together with seniority when the title text varies too much to filter on directly.

## `jobSubRoles` (type: `array`):

Narrower functions inside a department, one per line, such as accounting, software or product management. The provider documents more than fifty of these, so they are taken as free text rather than as a dropdown that would go stale.

## `locations` (type: `array`):

Where the person is, one per line. A bare value is read as a city. Prefix it with a boundary and a colon to mean something else: state:California, country:United States, continent:Europe or group:EMEA.

## `locationsExcluded` (type: `array`):

Locations to rule out, written the same way as above.

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

Only people currently at these companies, one per line. This is how you turn a filter set into an account based list.

## `companiesExcluded` (type: `array`):

Companies to rule out, one per line, such as your own and your existing customers.

## `pastCompanies` (type: `array`):

Only people who used to work at these companies, one per line. Alumni of a company you sell to are often the fastest route into the next one.

## `domains` (type: `array`):

Company domains, one per line, used by individual reveal and company enrichment. A pasted URL is reduced to the bare hostname and an address is reduced to the part after the at sign, so a messy list still works.

## `companyNames` (type: `array`):

Company names, one per line, for individual reveal and company enrichment when you know the employer but not the domain.

## `companySlugs` (type: `array`):

Company profile slugs, one per line, for company enrichment. The slug is the last part of the company's profile URL.

## `profileUrls` (type: `array`):

Profile URLs to reveal, one per line. This is the most accurate way to reveal a person, because it identifies exactly one profile rather than a name that several people share. Individual reveal only.

## `emails` (type: `array`):

Known email addresses to reveal the person behind, one per line. Individual reveal only.

## `fullNames` (type: `array`):

Full names to reveal, one per line. A name alone is not enough to identify anyone, so each name is paired with each company domain or company name above: ten names and one company is ten reveals. Individual reveal only.

## `firstNames` (type: `array`):

Exact first names to match in a database search, one per line.

## `lastNames` (type: `array`):

Exact last names to match in a database search, one per line.

## `skills` (type: `array`):

Skills listed on the person's profile, one per line.

## `schools` (type: `array`):

Schools or universities attended, one per line.

## `majors` (type: `array`):

Fields of study, one per line.

## `linkedinSlugs` (type: `array`):

Personal profile slugs to match exactly, one per line. The slug is the last part of a profile URL.

## `lastRoleChange` (type: `string`):

Only people who started a new role inside this window. Someone ninety days into a new job is still choosing their tools, which is why this filter outperforms almost every other one on reply rate.

## `lastCompanyChange` (type: `string`):

Only people who joined a new employer inside this window.

## `companyLocations` (type: `array`):

Where the company is, one per line, written the same way as the person locations above. Use this rather than person location when the buying decision sits at headquarters.

## `companyLocationsExcluded` (type: `array`):

Company locations to rule out, written the same way as above.

## `companyIndustries` (type: `array`):

Industries to include, one per line.

## `companyIndustriesExcluded` (type: `array`):

Industries to rule out, one per line.

## `companySizes` (type: `array`):

Keep only companies in these headcount bands. These are the provider's own bands, so they are offered exactly as documented rather than as a free range.

## `revenue` (type: `array`):

Keep only companies in these revenue bands.

## `companyTypes` (type: `array`):

Keep only companies of these types.

## `technologies` (type: `array`):

Only companies running these technologies, one per line. Technographics are what turn a generic list into one where the first line of the email is about something the buyer already owns.

## `technologiesExcluded` (type: `array`):

Rule out companies running these technologies, one per line, such as a competitor they have already bought.

## `companyKeywords` (type: `array`):

Words that must appear in the company description, one per line.

## `companyKeywordsExcluded` (type: `array`):

Words that must not appear in the company description, one per line.

## `companyAnnualGrowth` (type: `array`):

Keep only companies growing headcount at these rates over the last year. Growth is the cheapest proxy there is for budget.

## `departmentSizes` (type: `array`):

Size of a named department, one per line, written as department:min-max, for example sales:10-50. A company with fifty engineers and two marketers is a different buyer from the reverse, even at the same total headcount.

## `fundingStages` (type: `array`):

Keep only companies at these funding stages.

## `yearFoundedFrom` (type: `string`):

Earliest founding year, as a four digit year.

## `yearFoundedTo` (type: `string`):

Latest founding year, as a four digit year.

## `enrichmentLevel` (type: `string`):

How much of each contact the provider resolves, and therefore how many of your credits a row costs. None returns the profile only, partial returns a work email where one is already known, phone adds the mobile number, and full runs the complete waterfall. Used by prospect list and individual reveal.

## `acceptWorkEmail` (type: `boolean`):

Accept work email addresses. Leave this on for B2B outreach.

## `acceptPersonalEmail` (type: `boolean`):

Accept personal email addresses as well. Turn this on only when you have a lawful basis for contacting people at a personal address.

## `acceptGenericEmail` (type: `boolean`):

Accept catch-all role addresses such as info@ and sales@. These reach a shared mailbox rather than the person you selected.

## `skipDuplicates` (type: `boolean`):

Skip contacts that earlier lists on this account already revealed, so the same person is not paid for twice. Prospect list only.

## `listName` (type: `string`):

The name the list is stored under on your provider account. Leave empty to name it after the run.

## `listSegment` (type: `string`):

Which slice of the finished list to write out. Valid returns only the addresses that passed verification, risky returns the ones that did not, and people returns everything the list resolved.

## `previewSize` (type: `integer`):

How many sample profiles the free preview returns. The provider caps this at 30 however large the matching segment is; the segment's true size is reported on every row.

## `jobTimeoutSeconds` (type: `integer`):

How long to wait for the provider to finish revealing a list or a person before giving up. Large lists take minutes, so this needs headroom; the actor polls with a widening interval rather than hammering the provider.

## `requestsPerMinute` (type: `integer`):

Pace the run under your plan's rate limit. Lower this if the provider starts refusing requests.

## `skipNotFound` (type: `boolean`):

Leave inputs that resolved to nothing out of the dataset. They are kept by default, because knowing which people the provider has nothing on is what makes a run auditable. Unresolved rows are never charged for either way.

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

Hard cap on rows, and therefore on spend and run time. In prospect list mode this is also the number of profiles the provider is asked to reveal.

## `apiKey` (type: `string`):

Your own API key for the prospecting API, taken from your provider account. Stored as a secret and never written to a log. You can also supply it as the DATA\_API\_KEY environment secret instead.

## Actor input object example

```json
{
  "mode": "prospectSearch",
  "jobTitles": [
    "head of sales"
  ],
  "jobTitleLevels": [],
  "jobRoles": [],
  "locations": [
    "country:United States"
  ],
  "lastRoleChange": "",
  "lastCompanyChange": "",
  "companySizes": [],
  "revenue": [],
  "companyTypes": [],
  "companyAnnualGrowth": [],
  "fundingStages": [],
  "enrichmentLevel": "partial",
  "acceptWorkEmail": true,
  "acceptPersonalEmail": false,
  "acceptGenericEmail": false,
  "skipDuplicates": false,
  "listSegment": "people",
  "previewSize": 30,
  "jobTimeoutSeconds": 1800,
  "requestsPerMinute": 120,
  "skipNotFound": false,
  "maxResults": 100
}
```

# Actor output Schema

## `results` (type: `string`):

Prospects, revealed contacts and enriched companies, one row each.

# 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 = {
    "jobTitles": [
        "head of sales"
    ],
    "locations": [
        "country:United States"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/prospect-search-contact-finder-api").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 = {
    "jobTitles": ["head of sales"],
    "locations": ["country:United States"],
}

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/prospect-search-contact-finder-api").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 '{
  "jobTitles": [
    "head of sales"
  ],
  "locations": [
    "country:United States"
  ]
}' |
apify call nabeelbaghoor/prospect-search-contact-finder-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/prospect-search-contact-finder-api"
        }
    }
}

```

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/gmVI9oZ7LtTJHePHi/builds/GAXMgh6CV6GiignAd/openapi.json
