# LinkedIn Email Finder API - Work Emails, Phones, Profiles (`nabeelbaghoor/linkedin-email-finder-api`) Actor

Find work emails, personal emails and phone numbers behind professional profiles. Search people by job title, seniority, skills, company, technology and job change signals, pull decision makers at any company, and enrich a profile URL, an email or a domain. Pay per result. Bring your own API key.

- **URL**: https://apify.com/nabeelbaghoor/linkedin-email-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, 0.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/platform/actors/running/actors-in-store#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

## LinkedIn Email Finder API - Work Emails, Phones, Profiles

Find the work email, personal email and phone number behind a professional profile, search for people by job title, seniority, skills, employer, tenure and job change signals, pull the decision makers at any company, and enrich a profile URL, an email address or a company domain into a full record. One flat row per person or company.

### What this actor does

- **Turns profile URLs into contact details.** Paste a list of public profile URLs and get back the work addresses, personal addresses and phone numbers the provider holds for each one, with a verification status on the work address.
- **Searches people on the filters that actually segment a market.** Job title with optional related titles, past job title, job function, seniority, skills, current and past employer, excluded employers, domain, location with a radius, industry, education, company size, years of experience, years in the current role, and whether the person changed jobs recently.
- **Finds decision makers without knowing any names.** Give it a domain or a company name and it walks the senior people at that company page by page.
- **Searches companies by what is in their stack.** Company search filters on technologies, industry, headcount, revenue range, founding year and headquarters location, and returns the funding history alongside the firmographics.
- **Enriches three different starting points.** A profile URL, an email address or a company domain all resolve to the same flat row shape, so lists that started life in different systems end up in one table.
- **Keeps credit spend deliberate.** Revealing contact details is what spends provider contact credits, so it is off unless you ask for it. With it off you still get the full profile, the employer and a flag for each contact type the provider holds, which is enough to decide who is worth revealing.
- **Paces per route, not per run.** The provider's ceilings differ by an order of magnitude between profile search and the rest, so the actor throttles to the ceiling of the route it is calling rather than slowing every request to the slowest one.
- **Never charges for a miss.** Only rows carrying a resolved result are billed.

### Input

| Field | What it does |
| --- | --- |
| `mode` | People search, company search, decision makers, profile contacts, profile enrichment, email enrichment or company enrichment. |
| `jobTitles` | Current job titles to match. |
| `pastJobTitles` | Titles held earlier in a career. |
| `jobFunctions` | Broad functions such as Engineering or Sales. |
| `seniorities` | Seniority levels such as Director or Vice President. |
| `skills` | Skills listed on the profile. |
| `companies` | Company names, as employers or as search targets. |
| `pastCompanies` | Previous employers. |
| `excludeCompanies` | Companies to leave out of the results. |
| `companyFilter` | Whether company names match current, past or either. |
| `domains` | Company domains. |
| `profileUrls` | Public profile URLs to look up. |
| `emails` | Addresses to enrich into a profile. |
| `locations` | Locations to match. |
| `locationRadiusMiles` | Widen each location to a radius. |
| `industries` | Industries to match. |
| `education` | Schools and degrees. |
| `technologies` | Technologies the company runs. |
| `companySizes` | Headcount bands. |
| `yearsOfExperience` | Total career length bands. |
| `yearsInCurrentRole` | Tenure in the current job. |
| `recentlyChangedJobs` | Only people who started a new role recently. |
| `revealContactInfo` | Return actual addresses and phones, not just availability. |
| `dataTypes` | Which contact types to ask for. |
| `minRevenue`, `maxRevenue` | Company revenue range. |
| `foundedFrom`, `foundedTo` | Company founding year range. |
| `pageSize` | Results per request, up to the provider's maximum of 25. |
| `requestsPerMinute` | Pace the run below the provider's ceilings. |
| `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": "peopleSearch",
  "query": "people search",
  "fullName": "Jane Doe",
  "headline": "Engineering leader, payments infrastructure",
  "position": "VP of Engineering",
  "jobFunction": "Engineering",
  "seniority": "Vice President",
  "organization": "Example Labs",
  "companyDomain": "example.com",
  "companySize": 850,
  "companyIndustry": "Financial Services",
  "industry": "Financial Services",
  "location": "San Francisco Bay Area",
  "country": "United States",
  "linkedinUrl": "https://www.linkedin.com/in/janedoe",
  "profilePictureUrl": "https://media.example.com/photo.jpg",
  "emails": ["jane.doe@example.com"],
  "workEmails": ["jane.doe@example.com"],
  "personalEmails": null,
  "workEmailStatus": "verified",
  "phones": ["+14155550123"],
  "hasWorkEmail": true,
  "hasPersonalEmail": true,
  "hasPhone": true,
  "workStatus": null,
  "followers": 4210,
  "skills": ["Distributed Systems", "Payments"],
  "experience": [],
  "education": [],
  "updatedAt": "2026-07-30T00:00:00Z",
  "error": null,
  "raw": { }
}
```

### Frequently asked questions

#### What data does this contact finder API return for a person?

Each person row carries the full name, headline, current job title, job function and seniority, the employer with its domain, size and industry, the location and country, the profile URL and picture, the work and personal email addresses with a verification status on the work address, phone numbers, follower count, skills, and the work and education history. Contact values are returned only when you turn on reveal contact details; otherwise each row still carries a flag for every contact type the provider holds.

#### How do I find the decision makers at a list of companies?

Use decision makers mode and give it your list of domains or company names. It walks the senior people at each company page by page, so a list of two hundred accounts becomes a list of the people worth contacting at each one, without you having to know a single name in advance. Turn on reveal contact details when you want the addresses in the same pass rather than a second one.

#### What is the difference between profile contacts and profile enrichment?

Profile contacts returns only what you can reach the person on: work addresses, personal addresses and phone numbers. Profile enrichment returns the whole record, which is the professional history, education, skills, employer firmographics and the contact fields together. Use the first when you already have a segmented list and only need addresses; use the second when the rows need to stand on their own in a CRM.

#### Can I search for companies by the technology they use?

Yes. Company search takes a list of technologies and returns the companies running them, which you can narrow further by industry, headcount band, revenue range, founding year and headquarters location. Each company row carries the description, type, size, employee count, revenue, industry, headquarters, specialties, the full technology list, follower count, and the funding history with total raised, round count, funding status and the latest round date.

#### How do I find people who just changed jobs?

Turn on recently changed jobs in people search, optionally alongside a years in current role band of under one year. A job change is the strongest timing signal in most B2B motions, because a new hire revisits budgets, tooling and vendors in their first months. Pair it with the job titles and company size bands you sell into and you have a list that is both relevant and timely.

#### Does turning off reveal contact details make the search useless?

No, and leaving it off is usually the right first pass. With it off, the provider returns the full profile plus a flag for each contact type it holds, so you can see exactly which of the matched people are reachable by work email, personal email or phone before spending a single contact credit. Run the search with it off, filter the dataset down to the people you actually want, then run the profile contacts mode over just those profile URLs.

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

Yes. This actor does not include data access. You use your own API key from ContactOut, which is the provider whose contact data API this actor calls, created on their dashboard. Your own plan, credit balance and terms apply. Paste the key into the `apiKey` field, where it is stored as an Apify secret and sent in a request header rather than a URL parameter, so it never appears in a log line or a redirect.

#### How does this handle rate limits?

The provider publishes different ceilings per route family: 60 requests per minute on profile search, 150 on the contact availability checks and 1000 on everything else. The actor knows which ceiling belongs to which route and paces to that one, spacing requests evenly rather than bursting. A rate limit response is retried with backoff. A refusal for entitlement reasons, which is how a spent credit balance or a route outside your plan is reported, stops the run instead, because retrying cannot fix either.

#### What happens when a profile URL or an address returns nothing?

The row is written with `found: false` and an `error` giving the provider's own reason, and the run continues to the next input. Misses are not charged for. Set `skipNotFound` to true to leave them out of the dataset entirely.

#### How much does a run cost?

Pricing is pay per result: you are charged for each profile or company returned to the dataset, and never for misses or duplicates. Apify platform usage is included in the per-result price. Your own API provider's search and contact credits are separate and billed by them.

### Keyword map

LinkedIn email finder, work email lookup API, contact data API, B2B people search API, decision maker finder, phone number lookup API, profile enrichment API, email enrichment API, company technographics search, job change signals, sales prospecting data, recruiting sourcing API, candidate contact finder, CRM contact enrichment, company firmographics API, funding data by company, lead list building, personal email finder, work email status, ICP filtering

# Actor input Schema

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

People search finds profiles matching your filters. Company search finds companies. Decision makers returns the senior people at a company. Profile contacts and profile enrichment take a list of profile URLs. Email enrichment turns an address into a profile, and company enrichment turns a domain into a company.

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

Current job titles to match, one per line. People search only.

## `pastJobTitles` (type: `array`):

Titles the person held earlier in their career, one per line. Useful for finding people who have since been promoted out of a role you sell into. People search only.

## `jobFunctions` (type: `array`):

Broad functions such as Engineering, Marketing or Sales, one per line. Coarser than a job title and useful when titles vary between companies. People search only.

## `seniorities` (type: `array`):

Seniority levels such as Manager, Director or Vice President, one per line. People search only.

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

Skills listed on the profile, one per line. People search only.

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

Company names, one per line. In people search these are the current employers to match. In company search they are the companies to look up. In decision makers mode each name is one company to walk.

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

Companies the person used to work at, one per line. People search only.

## `excludeCompanies` (type: `array`):

Companies to leave out of the results, one per line. The quickest way to keep your own customers and your own staff out of a prospecting list. People search only.

## `companyFilter` (type: `string`):

Whether the company names above should match where someone works now, where they used to work, or either. People search only.

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

Company domains, one per line. Used by people search, company search, company enrichment and decision makers. A pasted URL is reduced to the bare hostname, so a messy list still works.

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

Public professional profile URLs, one per line. Used by profile contacts and profile enrichment. A bare handle is expanded to a full URL and tracking parameters are stripped, so a list copied out of a browser still works.

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

Email addresses, one per line. Used by email enrichment. An address pasted inside a longer string, such as a mail header, is extracted before the request.

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

Locations to match, one per line. In people search this is where the person is; in company search it is where the company is.

## `locationRadiusMiles` (type: `integer`):

Widen each location to a radius around it, up to 500 miles. Useful when a metropolitan area is spelled differently on different profiles. People search only.

## `currentWorkLocations` (type: `array`):

Where the person works now, one per line, as distinct from where they live. People search only.

## `pastWorkLocations` (type: `array`):

Where the person used to work, one per line. People search only.

## `industries` (type: `array`):

Industries to match, one per line. Used by people search and company search.

## `education` (type: `array`):

Schools or degrees on the profile, one per line. People search only.

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

Technologies the company runs, one per line. This is the technographic filter: it finds companies by what is in their stack rather than by what they say they do. Company search only.

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

Headcount bands to match. Used by people search and company search.

## `yearsOfExperience` (type: `array`):

Total career length bands. People search only.

## `yearsInCurrentRole` (type: `array`):

How long the person has been in the job they hold now. Short tenures pair well with the recently changed jobs filter; long ones find people overdue for a move. People search only.

## `recentlyChangedJobs` (type: `boolean`):

Only return people who started a new role recently. A job change is the strongest buying signal in most B2B motions, because budgets and tooling get revisited. People search only.

## `includeRelatedJobTitles` (type: `boolean`):

Widen each job title to the titles the provider considers equivalent, so Head of Engineering also matches VP Engineering and Engineering Director. People search only.

## `currentTitlesOnly` (type: `boolean`):

Match the job titles above against the role someone holds now rather than anything in their history. On by default. People search only.

## `keyword` (type: `string`):

A free text term matched across the profile, for anything the structured filters do not cover. People search only.

## `name` (type: `string`):

Narrow a people search to one named person. Combine it with a company or a domain when the name is a common one. People search only.

## `minRevenue` (type: `integer`):

Only return companies at or above this annual revenue. Company search only.

## `maxRevenue` (type: `integer`):

Only return companies at or below this annual revenue. Company search only.

## `foundedFrom` (type: `integer`):

Only return companies founded in or after this year. Company search only.

## `foundedTo` (type: `integer`):

Only return companies founded in or before this year. Company search only.

## `headquartersOnly` (type: `boolean`):

Match a company's location against its headquarters rather than any office it has. Company search only.

## `revealContactInfo` (type: `boolean`):

Return the actual email addresses and phone numbers rather than only whether they exist. This is what spends your provider contact credits, so it is off by default: with it off you still get the full profile, the employer and a flag for each contact type the provider holds.

## `dataTypes` (type: `array`):

Which contact types to ask for. In people search this also narrows the results to profiles that have them. In profile contacts mode it decides which addresses are returned. Leave empty for the provider's default.

## `detailedExperience` (type: `boolean`):

Return the full role by role work history rather than the current position alone. People search only.

## `detailedEducation` (type: `boolean`):

Return the full education history rather than a summary. People search only.

## `pageSize` (type: `integer`):

How many profiles or companies to ask for in one search request. The provider allows up to 25, which is the default. The actor pages through the results until they run out, so this changes the request count rather than the total returned.

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

Pace the run below the provider's own per-route ceilings, which are 60 per minute on profile search, 150 on the contact availability checks and 1000 elsewhere. Leave empty to use each route's own ceiling, which is what you want unless your plan is capped lower.

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

Leave inputs the provider had nothing for out of the dataset. Off by default, because keeping the misses is what lets you see which inputs resolved and which did not. Misses are never charged for either way.

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

Stop after this many rows. This is the cap on both spend and run time.

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

Your own API key for the contact data API, sent in the request header rather than a URL parameter, so it never appears in a log line or a redirect. Required for every lookup. Stored as a secret.

## Actor input object example

```json
{
  "mode": "peopleSearch",
  "jobTitles": [
    "Head of Engineering"
  ],
  "companyFilter": "current",
  "companySizes": [],
  "yearsOfExperience": [],
  "yearsInCurrentRole": [],
  "recentlyChangedJobs": false,
  "includeRelatedJobTitles": false,
  "currentTitlesOnly": true,
  "headquartersOnly": false,
  "revealContactInfo": false,
  "dataTypes": [],
  "detailedExperience": false,
  "detailedEducation": false,
  "pageSize": 25,
  "skipNotFound": false,
  "maxResults": 100
}
```

# Actor output Schema

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

Professional profiles with their contact details, and company records, 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 Engineering"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/linkedin-email-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 Engineering"] }

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/linkedin-email-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 Engineering"
  ]
}' |
apify call nabeelbaghoor/linkedin-email-finder-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/linkedin-email-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/sffKHRSAeydB06g3G/builds/69lauMw3JtCfMpUUs/openapi.json
