# LinkedIn Email Finder - Verified Work Emails from Profile URLs (`memo23/linkedin-email-finder`) Actor

Paste LinkedIn profile URLs, get each person's work email confirmed by their company's mail server. Reads the public profile (no login, no cookies), finds the employer's domain and checks the likely addresses over SMTP with catch-all detection. $0.03 per confirmed email, other rows free.

- **URL**: https://apify.com/memo23/linkedin-email-finder.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Lead generation, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$30.00 / 1,000 confirmed work emails

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

## LinkedIn Email Finder - Verified Work Emails from Profile URLs

**Paste LinkedIn profile URLs. Get back each person's work email, confirmed by their own company's mail server.**

You pay **$0.03 for each confirmed email** and nothing else - no fee per profile, no fee for catch-all guesses, no fee for profiles where no address could be confirmed. No LinkedIn login, no cookies, no API keys.

### Why Use This Scraper?

- **You pay only for confirmed emails.** One event, $0.03, charged only when the company's mail server accepted that exact mailbox on a domain that is not catch-all. Every other row is free.
- **Real mailbox check, not a pattern guess.** The likely addresses (first.last@, flast@, first@ ...) are asked of the company's mail server one by one, with a random-address test that catches catch-all domains.
- **The company's own pattern first.** The company website is scanned for published addresses, so when the company writes `j.doe@` or `jdoe@`, that pattern is tried before the generic ones.
- **No LinkedIn account at risk.** Profiles are read the way a logged-out visitor sees them. You never hand over cookies or a session.
- **A row for every profile, with the reason.** Each profile gets a status (`confirmed`, `catch-all`, `unverified`, `not-found`, `no-company` ...) and a `sendDecision` (send / review / skip), so you know what to do with the ones that did not confirm.
- **Track record.** The same lookup engine runs inside [memo23/email-finder](https://apify.com/memo23/email-finder): **642 of 661 public runs succeeded over the last 30 days (97.1%)**.

#### Price and reliability against the best-known alternative

| | This actor | pequod-labs/linkedin-profile-verified-email |
| --- | --- | --- |
| Per confirmed / verified email | **$0.03** | $0.028 + $0.004 for the profile = **$0.032** |
| Profile read, no email found | **free** | $0.004 |
| Catch-all best guess | free | free |
| Public runs succeeded, last 30 days | **97.1%** (642 of 661, same engine in memo23/email-finder) | 95.4% (719 of 754) |

Figures read from the Apify Store on 2026-10-01.

### Overview

This actor is for sales, recruiting and growth teams who already have a list of people on LinkedIn - from Sales Navigator, a search export, a CRM, an event attendee list - and need an email they can actually send to.

For each profile URL it returns one dataset row: the person's name and headline, their current employer and its domain, the work email, and the mail server's verdict on that email. The output is flat, so it exports straight to CSV, Excel, Google Sheets or a CRM import.

An email is marked `confirmed` only when the company's mail server said the mailbox exists and the domain does not accept every address. That is the email you are billed for.

### Supported Inputs

#### URL types

| Input | Example | Supported |
| --- | --- | --- |
| Public profile URL | `https://www.linkedin.com/in/satyanadella/` | Yes |
| Country subdomain | `https://uk.linkedin.com/in/jane-doe-4b2a1c9` | Yes (normalized to www) |
| URL with tracking parameters | `https://www.linkedin.com/in/jane-doe?trk=public_profile` | Yes (cleaned) |
| Profile URL plus a company domain | `https://www.linkedin.com/in/jane-doe/, acme.com` | Yes - the domain is used for that person |

#### Copy-pasteable input

```json
{
    "linkedinUrls": [
        "https://www.linkedin.com/in/satyanadella/",
        "https://www.linkedin.com/in/dharmesh/"
    ]
}
```

#### Bulk paste

Paste a whole column into **Bulk paste** - one profile per line. A line can carry the person's company domain after a comma or a tab, which skips the employer lookup for that person:

```text
https://www.linkedin.com/in/satyanadella/
https://www.linkedin.com/in/jane-doe-4b2a1c9/, acme.com
https://www.linkedin.com/in/john-smith	globex.io
```

Both fields can be used together. Duplicates across them are removed, and a duplicate that brings a domain the first mention lacked keeps the domain.

#### Unsupported inputs

- Company pages (`linkedin.com/company/...`), job posts, posts, groups and search result URLs - only `/in/` profiles.
- Sales Navigator lead URLs (`linkedin.com/sales/lead/...`) - open the lead and copy its public `/in/` URL.
- Names without a profile URL - use [memo23/email-finder](https://apify.com/memo23/email-finder) (name + company domain) instead.
- Personal emails (Gmail, Outlook.com and the like). This actor finds work emails at the person's current employer.

### Use Cases

| Who | What they use it for |
| --- | --- |
| Sales teams and SDRs | Turn a Sales Navigator or LinkedIn search export into a sequence-ready list with confirmed work emails |
| Recruiters | Reach a candidate at work after finding them on LinkedIn, without InMail credits |
| Agencies and lead-gen shops | Enrich client prospect lists in bulk and bill only for what confirmed |
| Founders and growth teams | Email the people who engaged with a post, attended an event, or follow a competitor |
| RevOps and data teams | Fill missing emails in CRM contacts that already carry a LinkedIn URL |

### How It Works

![How the LinkedIn Email Finder works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-linkedin-email-finder.png)

1. **Read the profile.** Each URL is opened as a logged-out visitor to read the name, headline and current employer. When LinkedIn hides a profile from every logged-out visitor, the search engine's listing for that exact profile is used instead.
2. **Find the employer's domain.** The company name is matched to its website (a company-name match, so a namesake domain is not accepted). A domain you supply on the line or in **Company domain** skips this step.
3. **Learn the company's address pattern.** The company website is scanned for published addresses. A direct match, or the pattern they show (first.last, f.last ...), moves to the front of the queue.
4. **Ask the mail server.** Up to four likely addresses are checked with the company's mail server in order, plus a random address to detect catch-all domains. The first address the server accepts on a non-catch-all domain is confirmed.
5. **Bill and save.** A confirmed email is billed once at $0.03 and saved with its evidence. Every other outcome is saved free, with its status.

### Input Configuration

#### Input fields

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `linkedinUrls` | array of strings | - | Public `linkedin.com/in/...` profile URLs. An entry may carry a domain after a comma: `https://www.linkedin.com/in/jane-doe/, acme.com`. |
| `linkedinUrlsText` | string (textarea) | - | Bulk paste, one profile per line, optional domain after a comma or tab. |
| `companyDomain` | string | - | Domain used for every profile that has no domain on its own line, instead of the employer read from LinkedIn. |
| `smtpCheck` | boolean | `true` | Confirm each email with the company's mail server. Off: unconfirmed best guesses only, nothing billed. |
| `onlyConfirmed` | boolean | `false` | Keep only confirmed emails in the dataset. Off: every profile gets a row (free unless confirmed). |
| `maxItems` | integer | `1000` | Most profiles processed per run, after duplicates are removed. Free Apify plans: 25 per run. |
| `maxConcurrency` | integer | `5` | Profiles processed in parallel (1-20). |

#### Common scenarios

**A list of profiles, every row back for review:**

```json
{
    "linkedinUrls": [
        "https://www.linkedin.com/in/satyanadella/",
        "https://www.linkedin.com/in/dharmesh/"
    ]
}
```

**Everyone works at one company - set the domain once:**

```json
{
    "linkedinUrlsText": "https://www.linkedin.com/in/jane-doe-4b2a1c9/\nhttps://www.linkedin.com/in/john-smith-81b2a/",
    "companyDomain": "acme.com"
}
```

**Import-ready output - only the billed, confirmed rows:**

```json
{
    "linkedinUrlsText": "https://www.linkedin.com/in/satyanadella/\nhttps://www.linkedin.com/in/dharmesh/",
    "onlyConfirmed": true,
    "maxItems": 500
}
```

**Spending cap.** Set **Maximum cost per run** in the run options. The actor stops starting new profiles once the cap cannot pay for another confirmed email, and never returns a confirmed email it could not bill.

### Output Overview

One row per input profile (or per confirmed profile with `onlyConfirmed`). Each row has three groups of fields:

- **The person** - `fullName`, `title` (the LinkedIn headline), `companyName`, `linkedinUrl`, your original `input` line and its position `inputIndex`.
- **The email** - `email`, `status`, `sendDecision`, `billed`, `confidence`, `pattern`, `mailboxConfirmed`.
- **The evidence** - `companyDomain` and where it came from, the mail provider, the mail server's answer, and the ranked candidate addresses with the server's answer for each.

Rows are written as profiles finish, so their order can differ from your list. Sort by `inputIndex` to restore it.

The dataset has three views in the console: **Emails** (the import columns), **Verification details** and **Profile lookup**.

### Output Samples

Real rows from a platform run on 2026-10-01 (build 0.0.1, two of the five profiles confirmed and billed), trimmed. Email local parts are masked in this README; the dataset carries the full address.

#### Confirmed, company pattern first.last (billed)

```json
{
    "inputIndex": 2,
    "linkedinUrl": "https://www.linkedin.com/in/dharmesh/",
    "fullName": "Dharmesh Shah",
    "title": "HubSpot",
    "companyName": "HubSpot",
    "companyDomain": "hubspot.com",
    "domainSource": "profile",
    "email": "d*******.s****@hubspot.com",
    "status": "confirmed",
    "sendDecision": "send",
    "billed": true,
    "mailboxConfirmed": true,
    "confidence": "high",
    "pattern": "first.last",
    "smtpStatus": "confirmed",
    "emailProvider": "google-workspace",
    "mxValid": true,
    "candidates": [
        { "email": "d*******.s****@hubspot.com", "pattern": "first.last", "score": 40, "smtp": "accepted" },
        { "email": "d*******@hubspot.com", "pattern": "first", "score": 15 }
    ]
}
```

#### Confirmed after the server refused first.last (billed)

```json
{
    "inputIndex": 1,
    "linkedinUrl": "https://www.linkedin.com/in/satyanadella/",
    "fullName": "Satya Nadella",
    "title": "Chairman and CEO",
    "companyName": "Microsoft",
    "companyDomain": "microsoft.com",
    "email": "s****@microsoft.com",
    "status": "confirmed",
    "sendDecision": "send",
    "billed": true,
    "confidence": "medium",
    "pattern": "first",
    "emailProvider": "microsoft-365",
    "candidates": [
        { "email": "s****@microsoft.com", "pattern": "first", "score": 15, "smtp": "accepted" },
        { "email": "s****.n******@microsoft.com", "pattern": "first.last", "score": 40, "smtp": "rejected" }
    ]
}
```

`confidence` is `medium` here because a first-name-only mailbox at a large company could belong to someone else with that first name. The mailbox is real; the attribution is less certain than for first.last.

#### Catch-all domain (free)

```json
{
    "inputIndex": 3,
    "linkedinUrl": "https://www.linkedin.com/in/patrickcollison/",
    "fullName": "Patrick Collison",
    "companyName": "Stripe",
    "companyDomain": "stripe.com",
    "email": "p******.c*******@stripe.com",
    "status": "catch-all",
    "sendDecision": "review",
    "billed": false,
    "confidence": "medium",
    "smtpStatus": "catch-all"
}
```

#### Profile LinkedIn hides from logged-out visitors (free)

```json
{
    "inputIndex": 4,
    "input": "https://www.linkedin.com/in/rauchg/, vercel.com",
    "companyDomain": "vercel.com",
    "domainSource": "input-line",
    "fullName": null,
    "email": null,
    "status": "no-name",
    "sendDecision": "skip",
    "billed": false
}
```

### Key Output Fields

#### Person

| Field | Description |
| --- | --- |
| `inputIndex` | Position of the profile in your de-duplicated input (1-based) |
| `input` | Your original entry or line |
| `linkedinUrl` | Normalized profile URL |
| `fullName` | Name as shown on LinkedIn (or from the URL when the page is hidden) |
| `title` | LinkedIn headline or current job title |
| `companyName` | Current employer as shown on LinkedIn |
| `nameSource` / `profileSource` | `profile`, `search-result` or `url-slug` |

#### Email

| Field | Description |
| --- | --- |
| `email` | Confirmed address, or the best unconfirmed guess (catch-all / unverified), or null |
| `status` | `confirmed`, `catch-all`, `unverified`, `not-found`, `no-mail-server`, `no-company`, `no-name`, `charge-limit` |
| `sendDecision` | `send` (confirmed), `review` (catch-all or unverified), `skip` (everything else) |
| `billed` | True only for the confirmed row that was charged |
| `mailboxConfirmed` | The mail server accepted this mailbox and the domain is not catch-all |
| `confidence` | `high` (confirmed with first and last name), `medium`, `low` |
| `pattern` | Address pattern of `email`: `first.last`, `flast`, `first` ... |

#### Evidence

| Field | Description |
| --- | --- |
| `companyDomain` | Domain the addresses were built on |
| `domainSource` | `profile` (matched from the employer), `input-line`, `input` (Company domain field) |
| `smtpStatus` | Mail server's overall answer: `confirmed`, `rejected`, `catch-all`, `unknown`, `skipped` |
| `emailSource` | `site-match` (published on the company site), `site-pattern` (company style learned from the site), `pattern` |
| `emailProvider` | Mail host read from DNS: `google-workspace`, `microsoft-365`, `proofpoint`, `mimecast` ... |
| `mxValid` | The domain accepts email |
| `candidates[]` | Up to six ranked addresses `{ email, pattern, score, smtp }` with the server's answer for each one checked |
| `checkedAt` | ISO timestamp |

### FAQ

#### What exactly am I billed for?

Only `person-email-confirmed`, $0.03, once per profile whose work email the company's mail server confirmed on a domain that is not catch-all. The `billed` field shows it on every row. Profiles without a confirmed email cost nothing, whatever the reason.

#### Why do some rows say catch-all?

Some companies' mail servers accept mail for any address, so no checker can tell a real mailbox from a made-up one there. You get the most likely address for free, marked `catch-all` and `sendDecision: review`.

#### Is an email sent to the person?

No. The check stops before any message is sent: the server is asked whether it would accept mail for the address, and the conversation ends there.

#### Do I need a LinkedIn account or cookies?

No. Profiles are read as a logged-out visitor sees them. No session, cookie or account of yours is used, so nothing on your LinkedIn account is at risk.

#### What if LinkedIn shows the wrong company, or none?

Add the right domain after the URL on that line (`..., acme.com`), or set **Company domain** for the whole list. A domain you give always wins over the one read from LinkedIn.

#### Why did a profile return no-name?

A few members hide their public profile from every logged-out visitor, and the search engine had no listing for it either. When the URL itself spells a name (`jane-doe-4b2a1c9`), the actor still uses that; a one-word URL (`rauchg`) leaves nothing to build an address from.

#### Does it find personal emails or phone numbers?

No. Only work emails at the person's current employer. For phones and company inboxes, see [memo23/email-finder](https://apify.com/memo23/email-finder).

#### How fast is it?

Most profiles take 5-10 seconds, nearly all of it the mail server check; slow servers such as Microsoft 365 can take 20-30 seconds. With the default concurrency of 5, a list of 1,000 profiles takes roughly 20-40 minutes.

#### Can I cap what a run costs?

Yes. Set **Maximum cost per run**. The actor stops starting new profiles when the cap cannot pay for another confirmed email, and a confirmed email it cannot bill is withheld (`status: charge-limit`), never given away and never overcharged.

#### Is there a free trial?

Free Apify plan users can process up to 25 profiles per run, billed the same way from their monthly platform credit.

### Support

- **Found a bug or need a new field?** Open a ticket on the **Issues** tab of this actor - it's the fastest way to reach me and I actively maintain this actor.
- **Email:** <muhamed.didovic@gmail.com>
- **Website:** [muhamed-didovic.github.io](https://muhamed-didovic.github.io/)

### Additional Services

Need something beyond the standard output? I build and maintain custom actors and data pipelines:

- Email lookups wired into your CRM or outreach tool on a schedule
- Custom fields, filters or export formats for your workflow
- Private or dedicated actors for high-volume or compliance-sensitive use

Reach out via the Issues tab or email and describe what you need.

### Explore More Scrapers

- [**LinkedIn People Search**](https://apify.com/memo23/linkedin-people-search) - find profiles by company, title and industry, no login; feed the URLs into this actor
- [**LinkedIn Company Employees Scraper**](https://apify.com/memo23/linkedin-company-people-scraper) - list the people at a company
- [**Decision Maker Finder**](https://apify.com/memo23/decision-maker-finder) - company in, C-suite contacts with confirmed emails out
- [**B2B Email Finder & Verifier**](https://apify.com/memo23/email-finder) - emails by company domain, company name, or person name plus domain
- [**Email Verifier & Validator**](https://apify.com/memo23/email-verifier) - bulk SMTP and catch-all check for addresses you already have

Full list at [apify.com/memo23](https://apify.com/memo23).

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/linkedin-email-finder`).

**Purpose:** LinkedIn `/in/` profile URL -> the person's work email, confirmed by the company's mail server over SMTP with catch-all detection. No LinkedIn login.

**Minimal input:**

```json
{ "linkedinUrls": ["https://www.linkedin.com/in/satyanadella/"], "maxItems": 10 }
```

**Output:** one row per profile - inputIndex, input, linkedinUrl, fullName, title, companyName, companyDomain, domainSource, email, status, sendDecision, billed, mailboxConfirmed, confidence, pattern, smtpStatus, emailSource, emailProvider, mxValid, candidates\[] {email, pattern, score, smtp}, checkedAt.

**Behaviors an agent should know:**

- Use only rows with `status: "confirmed"` (equivalently `sendDecision: "send"`) as deliverable; `catch-all` and `unverified` rows carry an unconfirmed guess.
- Billing: `person-email-confirmed` $0.03 per confirmed row, nothing else. `billed` is true on exactly those rows.
- `onlyConfirmed: true` drops every non-billed row from the dataset.
- A domain after the URL (`"https://www.linkedin.com/in/x/, acme.com"`) or `companyDomain` overrides the employer read from LinkedIn.
- Rows arrive out of input order; sort by `inputIndex`.
- `smtpCheck: false` returns pattern guesses only and bills nothing.
- Free Apify plans: 25 profiles per run.

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by LinkedIn Corporation or Microsoft Corporation, or any of their subsidiaries. All trademarks mentioned are the property of their respective owners.

The actor accesses only publicly available LinkedIn profile pages - no authenticated endpoints, paid features, or content behind the linkedin.com login wall - and checks addresses with mail servers without sending any message. Users are responsible for ensuring their use complies with LinkedIn's Terms of Service, applicable data-protection and anti-spam law (GDPR, CCPA, CAN-SPAM, etc.), and any contractual obligations of their own organization.

***

### SEO Keywords

linkedin email finder, linkedin profile email finder, find email from linkedin profile, linkedin to email, linkedin email extractor, linkedin email scraper, Apify linkedin email, work email finder, verified email finder, SMTP email verification, catch-all email detection, b2b email finder, bulk linkedin email lookup, sales navigator email finder, prospect email list, recruiter email finder, cold outreach emails, lead enrichment, CRM email enrichment, Hunter alternative, Apollo alternative, Lusha alternative, RocketReach alternative

# Actor input Schema

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

Public linkedin.com/in/... profile links, one per entry. Each profile is read as a logged-out visitor (name, headline, current employer), the employer's website is found, and the likely work addresses are checked with the company's mail server. No LinkedIn login or cookies. To give a company domain for one person, add it after the URL: https://www.linkedin.com/in/jane-doe/, acme.com

## `linkedinUrlsText` (type: `string`):

Paste a whole column from a spreadsheet or CRM export: one LinkedIn profile URL per line. A line may carry the person's company domain after a comma or tab (https://www.linkedin.com/in/jane-doe/, acme.com). Duplicates across both fields are removed.

## `companyDomain` (type: `string`):

Use this domain for every profile that has no domain on its own line, instead of the employer read from LinkedIn. Handy when the whole list works at one company (acme.com), or when LinkedIn shows a parent brand rather than the domain people send mail from.

## `smtpCheck` (type: `boolean`):

On by default. The likely addresses are checked one by one with the company's mail server (an SMTP mailbox check, nothing is sent), plus a random-address test that detects catch-all domains. The first address the server accepts on a domain that is not catch-all is returned as confirmed - that is the only result you pay for. Turned off, you get unconfirmed best guesses from the address pattern only, and nothing is billed.

## `onlyConfirmed` (type: `boolean`):

Off by default: every profile gets a row, so you can see why a profile has no confirmed email (catch-all domain, no reply from the server, no employer on the profile). Those rows are free. Turn on to keep only confirmed emails in the dataset - the same rows you are billed for.

## `maxItems` (type: `integer`):

Most profiles to process in this run, after duplicates are removed. Free Apify plans are capped at 25 per run.

## `maxConcurrency` (type: `integer`):

Profiles processed in parallel.

## Actor input object example

```json
{
  "linkedinUrls": [
    "https://www.linkedin.com/in/satyanadella/",
    "https://www.linkedin.com/in/dharmesh/"
  ],
  "smtpCheck": true,
  "onlyConfirmed": false,
  "maxItems": 1000,
  "maxConcurrency": 5
}
```

# Actor output Schema

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

Name, employer, domain, email, status (confirmed, catch-all, unverified, not-found, ...) and whether the row was billed.

## `all` (type: `string`):

Every field, including the ranked candidate addresses and the mail server's answer for 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 = {
    "linkedinUrls": [
        "https://www.linkedin.com/in/satyanadella/",
        "https://www.linkedin.com/in/dharmesh/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/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/satyanadella/",
        "https://www.linkedin.com/in/dharmesh/",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("memo23/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/satyanadella/",
    "https://www.linkedin.com/in/dharmesh/"
  ]
}' |
apify call memo23/linkedin-email-finder --silent --output-dataset

```

## MCP server setup

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