# LinkedIn Email Finder (`khadinakbar/linkedin-email-finder`) Actor

Find and verify work emails from LinkedIn profile URLs. Public data, no cookies. MCP/API-ready.

- **URL**: https://apify.com/khadinakbar/linkedin-email-finder.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 20 total users, 11 monthly users, 98.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $40.00 / 1,000 email founds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## LinkedIn Email Finder

LinkedIn Email Finder is an Apify Actor for teams and AI agents that start with a public LinkedIn profile URL, or a known person plus company domain, and want one lead record with a work email, verification status, and confidence details. It accepts public LinkedIn profile URLs in `linkedinUrls` or direct person-and-domain records in `directLeads`, and each processed lead produces one dataset item that represents the suitable deliverable email candidate for that person. Useful fields include `name`, `company`, `companyDomain`, `email`, `emailStatus`, `confidence`, `smtpVerified`, `candidates`, and `source`, so the output is ready for enrichment, review, and downstream outreach. This Actor is usable through Apify and through Apify MCP.

### Best fit and connected workflows

This Actor fits workflows where a LinkedIn profile is the source of truth and the next step is a work email with verification context.

Use it when you have:

- a public LinkedIn profile URL for a person you want to enrich
- a known full name plus company domain for direct email generation and verification
- an AI-assisted sourcing flow that needs profile-to-email enrichment in one tool
- a lead pipeline that already has profile URLs from another LinkedIn Actor

A natural workflow connection is:

- use the LinkedIn People Search Scraper to discover people profiles
- pass the verified public profile URL into this Actor
- use the returned email record to enrich CRM or outreach records

Two other upstream sources that pair well with this Actor are:

- Then use LinkedIn Ad Library Search Scraper
- Then use LinkedIn Company Search Scraper

### Practical scenario

Nina, an SDR, has a public LinkedIn URL for a marketing leader and a company domain already stored in her CRM. She sends the profile URL in `linkedinUrls`, or uses `directLeads` when she already knows the person's full name and company domain. The Actor returns `name`, `company`, `companyDomain`, `email`, `emailStatus`, `confidence`, and `smtpVerified`. Nina reviews `emailStatus` and `smtpVerified`, then sends the lead to her next outreach step with the record already enriched.

### Input

| Field | Type | Purpose |
|---|---|---|
| `linkedinUrls` | array of strings | Public LinkedIn profile URLs to resolve into a person, company, domain, and work email |
| `directLeads` | array of objects | Known person plus company domain for direct email generation and verification |
| `includeUnverified` | boolean | Returns the highest-probability email when SMTP confirmation is unavailable or catch-all handling applies |
| `maxResults` | integer | Hard cap on how many leads are processed and billed in one run |
| `maxCandidatesPerLead` | integer | Maximum number of ranked email patterns to test per lead |

Focused input example:

```json
{
  "linkedinUrls": [
    "https://www.linkedin.com/in/satyanadella"
  ],
  "includeUnverified": true,
  "maxResults": 1,
  "maxCandidatesPerLead": 15
}
```

Direct lead example:

```json
{
  "directLeads": [
    {
      "fullName": "Jane Doe",
      "companyDomain": "acme.com",
      "companyName": "Acme"
    }
  ],
  "includeUnverified": true,
  "maxResults": 1
}
```

### Output

The dataset contains one record per processed lead. The overview view shows the suitable deliverable email per lead with verification status and confidence.

| Field | Type | Purpose |
|---|---|---|
| `query` | string | Original input used for the lead |
| `name` | string or null | Resolved person name |
| `headline` | string or null | Public profile headline when available |
| `location` | string or null | Public profile location when available |
| `company` | string or null | Current company name |
| `companyDomain` | string or null | Company website domain used for email discovery |
| `companyUrl` | string or null | Company website URL when available |
| `email` | string or null | suitable deliverable work email for the lead |
| `emailStatus` | string or null | Verification status of the returned email |
| `confidence` | integer or null | Confidence score for the returned email |
| `isRole` | boolean or null | Indicates whether the address is a role inbox |
| `smtpVerified` | boolean or null | Indicates whether the mailbox was confirmed by SMTP RCPT probe |
| `candidates` | array or null | Tested email candidates with their statuses and scores |
| `source` | string or null | Resolution source for the lead |
| `scrapedAt` | string or null | Time the lead was resolved |

Illustrative output record:

```json
{
  "query": "https://www.linkedin.com/in/satyanadella",
  "name": "Satya Nadella",
  "headline": "Chairman and CEO",
  "location": "Seattle, Washington, United States",
  "company": "Microsoft",
  "companyDomain": "microsoft.com",
  "companyUrl": "https://www.microsoft.com/",
  "email": "satya.nadella@microsoft.com",
  "emailStatus": "valid",
  "confidence": 96,
  "isRole": false,
  "smtpVerified": true,
  "candidates": [
    {
      "email": "satya.nadella@microsoft.com",
      "status": "valid",
      "confidence": 96,
      "pattern": "{first}.{last}"
    }
  ],
  "source": "scrapecreators",
  "scrapedAt": "2026-01-01T00:00:00.000Z"
}
```

### How it works

1. The Actor accepts public LinkedIn profile URLs or direct leads with `fullName` and `companyDomain`.
2. For LinkedIn inputs, it resolves the person to a name and current company through ScrapeCreators, with SociaVault as fallback.
3. It looks up the company website domain.
4. It generates ranked email permutations and tests them up to `maxCandidatesPerLead`.
5. It checks DNS MX and then uses SMTP RCPT verification when the execution environment allows outbound probing.
6. It returns the highest-confidence address, the verification status, and the tested candidate list.

The live contract also includes graceful MX-valid-unverified handling when SMTP probing is unavailable in the execution environment, which keeps the returned record honest and clearly labeled.

### Pricing

LinkedIn Email Finder uses Pay per event pricing on Apify, plus standard Apify platform usage for the run itself. The live Pricing tab is the source of truth for current pricing details.

Events in the live contract:

- Actor start: charged once per run, scaled by allocated RAM
- Profile resolved: charged when a lead is resolved to a name and company website domain
- Email found: charged when a deliverable work email is returned for a lead

Example in words: if a run starts, resolves three profiles, and returns two deliverable emails, the billed events follow that event pattern. Review the live Pricing tab before running to see the current pricing view in Apify.

### Use with AI agents (MCP)

This Actor is available through Apify MCP as a tool for profile-to-email enrichment.

Tool description: resolve a LinkedIn profile URL or direct lead into a work email record with company, domain, status, confidence, and candidate data.

Exact Actor identity: `khadinakbar/linkedin-email-finder`

> Find a work email for this LinkedIn profile URL and return the lead record with name, company, domain, email status, confidence, and SMTP verification. Use the dataset output to decide the next workflow step.

Output interpretation:

- `emailStatus` shows the verification state of the returned email
- `smtpVerified` indicates whether the mailbox was confirmed by SMTP probe
- `confidence` helps compare records when a run returns multiple leads
- `candidates` shows the patterns tested for that lead
- `source` indicates whether the lead came from ScrapeCreators, SociaVault, or direct input

Provenance and scope:

- Inputs are public LinkedIn profile URLs or direct person-plus-domain records
- The Actor resolves profile data, generates email candidates, and verifies deliverability signals
- The dataset row is the primary output for downstream automation

Pagination and cost guidance:

- Use `maxResults` to cap how many leads are processed and billed in one run
- Use `maxCandidatesPerLead` to control how many permutations are tested per lead
- Read dataset items when you need the complete lead list, then use the output summary for run-level counts

### Apify API example

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

const client = new ApifyClient({
  token: process.env.APIFY_TOKEN,
});

const input = {
  linkedinUrls: ['https://www.linkedin.com/in/satyanadella'],
  includeUnverified: true,
  maxResults: 1,
  maxCandidatesPerLead: 15,
};

const run = await client.actor('khadinakbar/linkedin-email-finder').call(input);

const dataset = client.dataset(run.defaultDatasetId);
const { items } = await dataset.listItems();

console.log('Run output:', run);
console.log('Dataset items:', items);
```

### Best results and outcome guidance

Use `linkedinUrls` when the LinkedIn profile is the starting point, and use `directLeads` when you already know the person's full name and company domain. Set `includeUnverified` to match your workflow:

- `true` when you want the available email candidate together with its status
- `false` when you want mailbox-confirmed addresses in the `email` field only

If you are processing a larger queue, set `maxResults` to match your budget and process dataset items in batches. When a lead already has a verified company domain, direct leads provide the most direct path into email generation and verification.

### Continue the workflow

- Then use [💼 LinkedIn Jobs Scraper — Salary, Remote & Easy Apply](https://apify.com/khadinakbar/linkedin-jobs-scraper) to extend LinkedIn Email Finder research with a complementary discovery contract.
- Then use [LinkedIn People Search Scraper](https://apify.com/khadinakbar/linkedin-people-search-scraper) to extend LinkedIn Email Finder research with a complementary discovery contract.

### Design note

I found that the live output contract centers on a single dataset record per lead, with `query` as the source reference and `emailStatus` plus `smtpVerified` as the main verification signals. That makes the dataset item the key unit for downstream automation.

### FAQ

#### Can I start from a LinkedIn profile URL?

Yes. `linkedinUrls` is the primary input for public LinkedIn profile URLs.

#### Can I use this after finding people in another LinkedIn Actor?

Yes. A common workflow is to discover people with a LinkedIn search Actor, then pass the verified public profile URL into this Actor for email enrichment.

#### What if I already know the company domain?

Use `directLeads` with `fullName`, `companyDomain`, and optional `companyName`.

#### What does one output record represent?

One dataset item represents one processed lead with the suitable deliverable email found for that lead.

#### How do I read the verification result?

Check `emailStatus`, `smtpVerified`, and `confidence` together. The candidate list shows the tested patterns for that lead.

### Responsible use

Use the output in line with applicable laws, internal policies, and platform terms. This Actor works with public data and standards-based mail verification. Treat the returned email as enrichment data for professional workflows, and review your messaging, storage, and outreach practices before use.

# Actor input Schema

## `linkedinUrls` (type: `array`):

Public LinkedIn profile URLs to find a work email for, e.g. 'https://www.linkedin.com/in/williamhgates'. Each profile is resolved to a name + current company via ScrapeCreators (SociaVault fallback), the company website domain is looked up, then an email is generated and verified. Defaults to empty. NOT a search query and NOT a company URL — for company-wide enumeration use a company scraper instead.

## `directLeads` (type: `array`):

Skip LinkedIn lookup and find an email directly from a known person + company. Each item is an object like {"fullName": "Jane Doe", "companyDomain": "acme.com", "companyName": "Acme"}. Use this when you already know the company domain and only need email generation + SMTP verification. companyName is optional. Defaults to empty.

## `includeUnverified` (type: `boolean`):

When true (default), if the mail server cannot be SMTP-probed (port 25 blocked) or is catch-all, the highest-probability pattern email is still returned with a confidence score and an honest emailStatus. When false, only mailbox-confirmed ('valid') emails are returned in the email field. Set false for strict deliverability-only output.

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

Hard cap on how many leads are processed and billed this run (across linkedinUrls + directLeads). Protects your budget on large inputs. Defaults to 100. Minimum 1.

## `maxCandidatesPerLead` (type: `integer`):

How many ranked email permutations to verify per person before stopping (verification stops early once a mailbox is SMTP-confirmed). Higher = more thorough, slower. Defaults to 15. Range 1-15.

## Actor input object example

```json
{
  "linkedinUrls": [
    "https://www.linkedin.com/in/satyanadella"
  ],
  "directLeads": [
    {
      "fullName": "Jane Doe",
      "companyDomain": "acme.com",
      "companyName": "Acme"
    }
  ],
  "includeUnverified": true,
  "maxResults": 1,
  "maxCandidatesPerLead": 1
}
```

# Actor output Schema

## `emails` (type: `string`):

Dataset of leads with their best deliverable email and verification status.

## `summary` (type: `string`):

Counts of profiles resolved, emails found, and estimated cost.

## `runSummary` (type: `string`):

Terminal outcome and persisted dataset count for delayed readback.

# 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 = {
    "linkedinUrls": [
        "https://www.linkedin.com/in/williamhgates"
    ],
    "directLeads": [],
    "includeUnverified": true,
    "maxResults": 1,
    "maxCandidatesPerLead": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/linkedin-email-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 = {
    "linkedinUrls": ["https://www.linkedin.com/in/williamhgates"],
    "directLeads": [],
    "includeUnverified": True,
    "maxResults": 1,
    "maxCandidatesPerLead": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/linkedin-email-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 '{
  "linkedinUrls": [
    "https://www.linkedin.com/in/williamhgates"
  ],
  "directLeads": [],
  "includeUnverified": true,
  "maxResults": 1,
  "maxCandidatesPerLead": 1
}' |
apify call khadinakbar/linkedin-email-finder --silent --output-dataset

```

## MCP server setup

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