# LinkedIn Profile Scraper with Email (`lulzasaur/linkedin-profile-scraper`) Actor

Extract LinkedIn profile data with email discovery. Parses JSON-LD, generates email patterns from name+company domain, optional SMTP verification. 2x cheaper.

- **URL**: https://apify.com/lulzasaur/linkedin-profile-scraper.md
- **Developed by:** [lulz bot](https://apify.com/lulzasaur) (community)
- **Categories:** Lead generation
- **Stats:** 6 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.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 Profile Scraper with Email

Extract LinkedIn profile data and discover email addresses. 2x cheaper than competitors at just $0.005/result.

### Features

- **JSON-LD parsing** — Extracts structured Person data (name, title, company, education)
- **Email pattern generation** — 15 common email formats from name + company domain
- **Company domain resolution** — MX record verification to find real company domains
- **Optional SMTP verification** — Confirm which generated emails actually exist
- **Profile data extraction** — Experience, education, skills, about section

### How it works

1. Fetches LinkedIn profile pages using residential proxies
2. Parses JSON-LD structured data (`application/ld+json`) for Person schema
3. Falls back to meta tags and visible HTML for additional data
4. Resolves company email domain via DNS MX record lookup
5. Generates 15 email pattern variations (first.last@, flast@, etc.)
6. Optionally verifies patterns via SMTP (RCPT TO check)

### Input

| Field | Type | Description |
|-------|------|-------------|
| profileUrls | string\[] | LinkedIn profile URLs (required) |
| verifyEmails | boolean | SMTP-verify generated patterns (default: false) |
| maxResults | integer | Maximum profiles to scrape (default: 100) |
| proxyConfiguration | object | Proxy settings (residential REQUIRED) |

### Output

Each result contains:

- `fullName`, `firstName`, `lastName` — Parsed name
- `headline` — Professional headline
- `currentCompany`, `companyDomain` — Company with resolved email domain
- `location` — Geographic location
- `about` — About section text
- `experience` — Job history (up to 5 entries)
- `education` — Schools and degrees (up to 3)
- `skills` — Listed skills (up to 20)
- `emails` — Direct emails found + verified generated emails
- `generatedEmails` — All 15 pattern variations with verification status
- `scrapedAt` — ISO timestamp

### Email Patterns Generated

Given "John Doe" at "Acme Inc" (acme.com):

- john@acme.com, john.doe@acme.com, johndoe@acme.com
- jdoe@acme.com, j.doe@acme.com, doe@acme.com
- doe.john@acme.com, doejohn@acme.com, doej@acme.com
- john\_doe@acme.com, jd@acme.com, john-doe@acme.com
- john.j@acme.com, j\_doe@acme.com, johnd@acme.com

### Pricing

Pay-per-event: **$0.005 per result** — 2x cheaper than the leading competitor.

### Notes

- Residential proxies are **required** — LinkedIn blocks datacenter IPs
- SMTP verification adds ~5-10 seconds per profile but confirms real emails
- LinkedIn public profiles provide rich structured data without login
- 3-second delay between requests to respect rate limits

# Actor input Schema

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

LinkedIn profile URLs to scrape (e.g. https://www.linkedin.com/in/username).

## `verifyEmails` (type: `boolean`):

Verify generated email patterns via SMTP (slower but confirms which emails exist).

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

Maximum number of profiles to scrape.

## `proxyConfiguration` (type: `object`):

Residential proxies REQUIRED for LinkedIn (blocks datacenter IPs).

## Actor input object example

```json
{
  "profileUrls": [
    "https://www.linkedin.com/in/satyanadella",
    "https://www.linkedin.com/in/jeffweiner08",
    "https://www.linkedin.com/in/williamhgates"
  ],
  "verifyEmails": false,
  "maxResults": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "profileUrls": [
        "https://www.linkedin.com/in/satyanadella",
        "https://www.linkedin.com/in/jeffweiner08",
        "https://www.linkedin.com/in/williamhgates"
    ],
    "maxResults": 3,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lulzasaur/linkedin-profile-scraper").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 = {
    "profileUrls": [
        "https://www.linkedin.com/in/satyanadella",
        "https://www.linkedin.com/in/jeffweiner08",
        "https://www.linkedin.com/in/williamhgates",
    ],
    "maxResults": 3,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("lulzasaur/linkedin-profile-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "profileUrls": [
    "https://www.linkedin.com/in/satyanadella",
    "https://www.linkedin.com/in/jeffweiner08",
    "https://www.linkedin.com/in/williamhgates"
  ],
  "maxResults": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call lulzasaur/linkedin-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=lulzasaur/linkedin-profile-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/Itc7UdMO7uMmx6S7x/builds/ucMOaaWBt2tlQlAKJ/openapi.json
