# 💼 LinkedIn B2B Email Scraper (`simpleapi/linkedin-b2b-emails-scraper`) Actor

- **URL**: https://apify.com/simpleapi/linkedin-b2b-emails-scraper.md
- **Developed by:** [SimpleAPI](https://apify.com/simpleapi) (community)
- **Categories:** Lead generation, Automation, Developer tools
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 1,000 results

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/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 Scraper — B2B Leads, Seniority Scores and Domains

LinkedIn Email Scraper finds business and personal email addresses tied to LinkedIn profiles, company pages, and bios by running keyword searches through Google and parsing the matching results. Each run returns structured leads with fields like `email`, `keyword`, `pattern`, `title`, `description`, and `url`, and can optionally attach a decision-maker seniority score or crawl a company's public employee directory. Sales teams, agencies, and researchers use it to build outreach lists without ever touching LinkedIn's login wall. Configure your keywords and patterns once, and every run since stays reproducible and schema-stable.

### What is LinkedIn Email Scraper?

LinkedIn Email Scraper is an Apify Actor that discovers email addresses associated with LinkedIn profiles and company pages by searching Google for indexed LinkedIn content matching your keywords, then extracting any email address, title, and description found in the result. It returns a normalized JSON dataset — no LinkedIn account, login, or cookies are required for either the core email search or the optional employee-directory crawl, since both work entirely against public Google results and public LinkedIn pages.

- Discovers leads by keyword, searched across up to 29 built-in B2B corporate-email patterns (or a single broad query in personal mode)
- Returns the identifying/contact fields needed for outreach: `email`, `title`, `url`, `description`
- Optional decision-maker seniority scoring buckets each lead into Founder / C-Suite / VP / Director / Manager / IC with a 0-100 score
- Optional no-login employee directory discovery adds real employee profiles (`fullname`, `headline`, `current_company`, `location`) per target company
- Supports a location filter, a custom personal-email-domain allowlist, and per-pattern volume caps
- Output is a standard Apify dataset, exportable in Apify's standard formats (JSON, CSV, Excel, XML)

### What data can I extract with LinkedIn Email Scraper?

Every run pushes rows containing the following fields (the exact keys written by the Actor's row-building logic, not just the default table view):

| Field | Example Value | Use Case |
| --- | --- | --- |
| `email` | `"hr@acmecorp.com"` | The email address extracted from the Google result |
| `keyword` | `"marketing"` | Which input keyword produced this lead |
| `pattern` | `"contact_at_domain"` | Which of the 29 B2B search patterns matched (b2b mode only) |
| `leadType` | `"b2b"` | Whether the row is a `b2b` email, `personal` email, or `employee` directory record |
| `title` | `"Acme Corp - Marketing Team \| LinkedIn"` | The raw Google result title / LinkedIn page headline |
| `url` | `"https://www.linkedin.com/company/acme-corp/"` | The LinkedIn URL the email or profile was found on |
| `description` | `"Contact us at hr@acmecorp.com for partnership inquiries..."` | Google's snippet text, useful for verifying context before outreach |
| `network` | `"LinkedIn.com"` | Platform searched (always LinkedIn.com) |
| `location` | `"London"` | The location filter applied to the query, if any |
| `scraped_at` | `"2026-07-25T14:02:31Z"` | UTC timestamp the row was collected |

The default dataset view surfaces 8 of these columns (`email`, `keyword`, `pattern`, `leadType`, `title`, `url`, `description`, `network`); `location` and `scraped_at` are still written to every row and available in the raw JSON or a custom view.

#### Decision-maker and employee signals

Turning on `enableSeniorityScoring` adds six more fields to every row: `personName`, `jobTitle`, and `company` (parsed from the "Name - Title - Company" pattern in the LinkedIn result snippet), plus `seniority` (one of Founder / C-Suite / VP / Director / Manager / IC), `decisionMakerScore` (0-100), and `matchedTitle` (the raw text the classifier matched on). A sales team searching "software agency" can turn this on, set `targetSeniority` to `["Founder", "C-Suite"]`, and get only owner- and executive-level leads instead of every title match. Turning on `enableEmployeeDirectory` instead adds `fullname`, `headline`, `current_company`, and `profile_url` for each employee found on a target company's public people/about pages.

#### Targeting and filter fields

Three inputs control which leads make it into the dataset: `patterns` narrows a b2b run to specific corporate-email search patterns instead of all 29 (e.g. only `hr_recruitment` and `careers_hiring`); `customDomains` restricts personal-mode results to a strict allowlist of email domains (e.g. only `@gmail.com`); and `location` appends a geographic term to every query so results skew toward a city, region, or country. Combined with `targetSeniority`, these fields let a run narrow from "every LinkedIn email mentioning marketing" down to a short list of named decision-makers at a specific location.

### Why not build this yourself?

Finding emails on LinkedIn through Google means fetching paginated SERP results, detecting when Google has served a CAPTCHA or consent interstitial instead of real results, and escalating through proxy tiers without stalling the run on a single block — this Actor's proxy state machine moves from a direct connection to a datacenter proxy to a residential proxy automatically, with the residential tier always pre-provisioned so one blocked request doesn't end the run. It also runs 29 distinct search-pattern templates, deduplicates emails across all of them, classifies personal vs. corporate domains, and — for the optional employee-directory feature — parses company and profile pages for JSON-embedded identifiers, XPath-based name/title/location extraction, and Nominatim geocoding fallback for bare city names. Building and maintaining that pipeline (block detection, proxy rotation, HTML parsing across LinkedIn's markup, geocoding) is a standing engineering cost; running it as a configured Actor is not.

If you need one or two email addresses for known companies, a manual Google search is faster. If you need this at keyword scale, across many companies and locations, in a structured, repeatable format, that's what this Actor is built for.

### How to use data extracted from LinkedIn?

#### B2B sales and lead generation

Sales teams are the primary users: set `keywords` to an industry or role term, leave `mode` at `"b2b"` to run some or all 29 corporate patterns, and set `maxEmails` and `maxEmailsPerPattern` to size the run. The dataset lands with `email`, `title`, `description`, and `url` per lead, ready to push into a CRM or outreach tool. Turning on `enableSeniorityScoring` and setting `targetSeniority` to `["Founder", "C-Suite", "VP"]` filters the same run down to leads worth prioritizing for a founder- or executive-level pitch, instead of every generic company inbox the patterns surface.

#### Agencies running outbound campaigns for clients

Agencies running the same keyword set repeatedly for different clients can swap `keywords`, `location`, and `patterns` per client brief while keeping the rest of the configuration fixed, producing a consistently shaped dataset run over run. For clients that hand over a target-account list instead of a keyword, `enableEmployeeDirectory` with `companyUrls` set to those accounts' LinkedIn company pages returns a per-company employee roster (`fullname`, `headline`, `current_company`) that can be benchmarked or audited alongside the email leads.

#### Market and account-based research

Combining `enableEmployeeDirectory` with `enableSeniorityScoring` builds an account map for ABM research: point `companyUrls` at a shortlist of target accounts, and the resulting rows show which employees at each company were discoverable, their headline/title, and — when the title parses cleanly — a seniority bucket, giving a rough read on how top-heavy or IC-heavy a target account's public presence looks.

#### AI agents and automated pipelines

Because the Actor runs as a standard Apify Actor with a JSON input and dataset output, it drops into an agent pipeline as a callable enrichment tool: an agent can pass a company name or keyword as `keywords`, receive structured email/lead rows back, and chain the result into a CRM-write or outreach-drafting step without any custom scraping code of its own.

### 🔼 Input sample

`keywords` is the only required field; every other input has a default. The table below matches the Actor's input schema exactly.

| Parameter | Required | Type | Description | Example Value |
| --- | --- | --- | --- | --- |
| `keywords` | Yes | array | Search terms used to find LinkedIn profiles via Google | `["marketing", "real estate"]` |
| `mode` | No | string (`"b2b"` | `"personal"`, default `"b2b"`) | b2b = corporate/company patterns; personal = Gmail/Outlook/personal-domain discovery | `"b2b"` |
| `customDomains` | No | array | Personal mode only: strict allowlist of email domains to keep | `["@gmail.com", "@outlook.com"]` |
| `patterns` | No | array | B2B mode only: which of the 29 built-in patterns to run (empty = all 29) | `["contact_at_domain", "business_development"]` |
| `platform` | No | string (enum `"LinkedIn.com"`, default `"LinkedIn.com"`) | Target platform (locked to LinkedIn) | `"LinkedIn.com"` |
| `location` | No | string (default `""`) | Optional geographic filter added to every search query | `"London"` |
| `maxEmails` | No | integer (1-50000, default 10) | Hard cap on total emails collected across the whole run | `200` |
| `maxEmailsPerPattern` | No | integer (1-5000, default 15) | Cap on emails collected per individual B2B pattern | `25` |
| `useProxy` | No | boolean (default `true`) | Enables Apify Proxy with datacenter-to-residential escalation | `true` |
| `proxyConfiguration` | No | object (default `{"useApifyProxy": true, "apifyProxyGroups": ["GOOGLE_SERP"]}`) | Proxy override; a residential fallback tier is always prepared alongside it | see JSON example |
| `enableSeniorityScoring` | No | boolean (default `false`) | Classifies each lead into a seniority bucket + 0-100 decision-maker score | `true` |
| `targetSeniority` | No | array | Used only when seniority scoring is on: keep only matching buckets | `["Founder", "C-Suite"]` |
| `enableEmployeeDirectory` | No | boolean (default `false`) | Crawls a company's public people/about pages for employee profiles (no login) | `true` |
| `companyUrls` | No | array | Used only when employee directory is on: LinkedIn company URLs/names to crawl | `["https://www.linkedin.com/company/microsoft"]` |
| `maxEmployeesPerCompany` | No | integer (1-500, default 10) | Cap on employee profiles discovered + enriched per company | `20` |

```json
{
  "keywords": ["marketing agency"],
  "mode": "b2b",
  "patterns": ["contact_at_domain", "business_development", "hr_recruitment"],
  "location": "New York",
  "maxEmails": 150,
  "maxEmailsPerPattern": 30,
  "useProxy": true,
  "enableSeniorityScoring": true,
  "targetSeniority": ["Founder", "C-Suite", "VP"]
}
```

**Common pitfall:** `customDomains` and `patterns` are mode-specific — `customDomains` only filters `personal` mode and `patterns` only applies in `b2b` mode, so setting either while the other mode is active does nothing. Likewise, `targetSeniority` is only enforced when `enableSeniorityScoring` is `true`; leaving scoring off means every seniority-shaped input is silently ignored and no rows are filtered.

### 🔽 Output sample

Output is a standard Apify dataset — one JSON object per row, exportable in Apify's standard formats (JSON, CSV, Excel, XML). A default B2B run (no optional features enabled) produces rows shaped like this:

```json
{
  "network": "LinkedIn.com",
  "keyword": "marketing agency",
  "title": "Acme Growth Partners - Business Development | LinkedIn",
  "description": "Reach our business development team at partnerships@acmegrowth.com for collaboration inquiries.",
  "url": "https://www.linkedin.com/company/acme-growth-partners/",
  "email": "partnerships@acmegrowth.com",
  "leadType": "b2b",
  "location": "New York",
  "pattern": "business_development",
  "scraped_at": "2026-07-25T14:02:31Z"
}
```

When `enableSeniorityScoring` is on, every row also carries `personName`, `jobTitle`, `company`, `seniority`, `decisionMakerScore`, and `matchedTitle`. When `enableEmployeeDirectory` is on, employee rows carry `leadType: "employee"` along with `fullname`, `headline`, `current_company`, and `profile_url` instead of an `email`. One honest caveat: when an employee profile is blocked or fails to load, the Actor still pushes a row containing an `error` field (e.g. `"Login required or blocked"`) instead of dropping it silently, and that row is still charged as a `row_result` event — filter these out downstream with an expression like `!record.error` if you only want successfully enriched profiles.

### How do you filter and target specific email leads?

Targeting starts with the choice between `mode: "b2b"`, which runs corporate search-pattern templates tuned to surface `contact@`, `hr@`, and similar business addresses, and `mode: "personal"`, which runs a single broader query and optionally restricts results to a `customDomains` allowlist. Within b2b mode, `patterns` narrows which of the 29 templates run — pick `hr_recruitment` and `careers_hiring` for talent-facing contacts, or `business_development` and `sponsor_me` for partnership contacts — instead of running all 29 and sorting afterward. `location` adds a geographic term to every query without needing a separate radius or bounding-box field. Volume is controlled by `maxEmails` (a hard cap on the whole run) and `maxEmailsPerPattern` (a per-pattern cap that prevents one high-yield pattern from consuming the entire run's budget before others get a chance). Quality filtering comes from `enableSeniorityScoring` plus `targetSeniority`, which drops any lead whose parsed title doesn't match the requested seniority buckets before it's ever pushed to the dataset (and before it's charged).

```json
{ "keywords": ["real estate"], "mode": "b2b", "patterns": ["hr_recruitment", "careers_hiring"], "location": "London", "maxEmails": 200, "maxEmailsPerPattern": 50 }
```

```json
{ "keywords": ["fitness coach"], "mode": "personal", "customDomains": ["@gmail.com"], "maxEmails": 100 }
```

```json
{ "keywords": ["marketing agency"], "mode": "b2b", "enableSeniorityScoring": true, "targetSeniority": ["Founder", "C-Suite"], "maxEmails": 150 }
```

### ▶️ Want to try other LinkedIn scrapers?

| Scraper Name | What it extracts |
| --- | --- |
| LinkedIn Company Scraper: Search By Name, Keyword or URL | Resolves a company name/keyword/id to its canonical LinkedIn page, then scrapes industry, size, HQ, specialties, and employees |
| LinkedIn Company About Scraper With Firmographic Enrichment | Firmographic data per company: specialties, founded year, organization type, follower count, HQ, and employee count/range |
| LinkedIn Company Employees Scraper With Growth Tracker | Public employee roster and headcount snapshot per company, for building a headcount-over-time series across scheduled runs |
| LinkedIn Profile Scraper | Full person profile data from a LinkedIn URL: experience, education, posts, and more |
| Instagram B2B Email Scraper & Phone Leads | The same B2B email/phone-lead discovery approach applied to Instagram bios and profiles |
| Alibaba Email Scraper & Trade Assurance Details | Supplier emails and Trade Assurance details from Alibaba listings |

### How to extract LinkedIn data programmatically

The Actor runs as a standard Apify Actor: one authenticated REST call starts a run, and the dataset comes back as structured JSON — no scraping code of your own required.

#### Python example

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")

run = client.actor("simpleapi/linkedin-b2b-emails-scraper").call(run_input={
    "keywords": ["marketing agency"],
    "mode": "b2b",
    "patterns": ["contact_at_domain", "business_development"],
    "maxEmails": 100,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["email"], item["title"], item["url"])
```

#### MCP for AI agents

This Actor is callable through Apify's Actors MCP Server, which exposes any Apify Actor as a tool to an MCP-compatible client (Claude, and other MCP-aware agent frameworks):

```bash
npx @apify/actors-mcp-server --actors simpleapi/linkedin-b2b-emails-scraper
```

An agent building an outbound-prospecting pipeline can call the Actor as a tool with a company or industry keyword and receive structured email leads back to feed directly into a drafting or CRM-write step.

#### Export to spreadsheets or CRM

Apify datasets export directly to CSV or Excel from the run's Storage tab. Map `email` to your CRM's email column, `title` and `description` to a notes/context field, `url` to the LinkedIn link field, and — when seniority scoring is on — `company` and `seniority` to segment your import by account and decision-maker level.

### Is it legal to scrape LinkedIn B2B emails?

Scraping publicly accessible LinkedIn pages and Google's public search results is generally permitted, since this Actor only reads content that is already indexed and visible without logging in. That said, email addresses — including business emails like `hr@acmecorp.com` — are personal data under GDPR and, depending on context, under the CCPA, because an email address can identify or contact a specific person even in a corporate context. Anyone storing or using the collected emails for outreach needs a lawful basis (e.g. legitimate interest for B2B marketing) and must honor opt-out/erasure requests. This Actor does not itself send any emails or make storage decisions — that responsibility sits with whoever uses the output. Consult legal counsel for commercial applications involving bulk storage of personal data.

### ❓ FAQ

#### Does this scraper require a LinkedIn login or cookies?

No. Both the core email search and the optional employee-directory crawl work entirely against Google's public search results and LinkedIn's public pages — no `li_at` cookie, LinkedIn account, or API key is required.

#### Can I get employee profile data along with the email leads?

Yes. Turning on `enableEmployeeDirectory` and setting `companyUrls` (or falling back to `keywords` as company-name search terms) adds rows with `leadType: "employee"` carrying `fullname`, `headline`, `current_company`, and `profile_url`, alongside the email-lead rows from the main search.

#### How accurate is the email data?

The Actor returns the email exactly as it appears in Google's indexed snippet of the LinkedIn page at request time. Accuracy depends on whether the underlying LinkedIn content is current — Google's index can lag behind the live page. Run collected addresses through a standard email-verification step before large outreach sends.

#### How many emails can I get per run?

Up to `maxEmails`, which accepts 1-50,000 and defaults to 10. In b2b mode, `maxEmailsPerPattern` (1-5,000, default 15) additionally caps how many emails any single one of the 29 patterns can contribute, so the total run budget isn't consumed by one high-yield pattern.

#### What happens if an employee profile fails to load?

The row is still pushed (and still charged as a `row_result` event) with an `error` field describing the failure (e.g. `"Login required or blocked"`, `"HTTP 999"`) instead of `fullname`/`headline` data. Filter these out downstream by excluding rows where `error` is present.

#### Can I target only decision-makers instead of every match?

Yes. Turn on `enableSeniorityScoring` and set `targetSeniority` to the buckets you want (`Founder`, `C-Suite`, `VP`, `Director`, `Manager`, `IC`); any lead whose parsed title doesn't match one of those buckets is dropped before it's pushed or charged.

#### Does this scraper work with Claude, ChatGPT, and AI agent frameworks?

Yes. It is reachable through Apify's Actors MCP Server (`npx @apify/actors-mcp-server --actors simpleapi/linkedin-b2b-emails-scraper`) for MCP-compatible clients, and callable as a standard HTTP endpoint by any agent framework that can make a REST call.

#### Does it include personal emails like Gmail or Yahoo addresses?

Only in `mode: "personal"`. B2B mode explicitly filters out personal-domain addresses so only corporate emails remain, while personal mode can further restrict results to a `customDomains` allowlist (e.g. only `@gmail.com`).

#### Can I use this without a LinkedIn API key or developer account?

Yes. No LinkedIn API key, developer account, or LinkedIn login of any kind is required — only an Apify account to run the Actor.

### Conclusion

LinkedIn Email Scraper turns a keyword and a set of search patterns into a structured list of B2B or personal email leads from LinkedIn, with optional seniority scoring and no-login employee directory discovery layered on top when needed. It's built for sales teams, agencies, and researchers who need repeatable, schema-stable outreach data rather than a one-off manual search. Configure your keywords, patterns, and filters in the input above, then run the Actor on Apify to get your first dataset of leads.

# Actor input Schema

## `keywords` (type: `array`):

🔎 Search terms used to find LinkedIn profiles via Google (e.g. marketing, fitness, real estate). ✨ Add one or many — each is searched across every enabled pattern.

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

🏢 b2b = corporate/company email patterns (hiring, contact, partnerships…) | 👤 personal = Gmail/Outlook/personal-domain discovery, optionally filtered by customDomains.

## `customDomains` (type: `array`):

👤 Personal mode ONLY: strictly enforced allowlist — only emails ending in one of these domains are kept (e.g. @gmail.com, @outlook.com). Leave empty to keep every personal-domain email found. ⏭️ Ignored in B2B mode.

## `patterns` (type: `array`):

🏢 B2B mode ONLY: which of the 29 built-in corporate-email search patterns to run (e.g. email\_for\_bookings, bio\_email\_basic, contact\_at\_domain, business\_development). 📂 Leave empty to run ALL 29 patterns.

## `platform` (type: `string`):

📱 Target platform for email discovery (locked to LinkedIn).

## `location` (type: `string`):

🗺️ Optional geographic filter added to every search query (e.g. London, New York). 🌍 Leave empty for global results.

## `maxEmails` (type: `integer`):

🎯 Hard cap on total emails collected across all keywords and patterns in this run.

## `maxEmailsPerPattern` (type: `integer`):

📈 Cap on emails collected per individual B2B search pattern (🏢 B2B mode only).

## `useProxy` (type: `boolean`):

✅ Enable Apify proxy for Google Search requests, with automatic datacenter → residential escalation on a block. ⭐ Recommended: on. Turning this off forces direct-only connections (no proxy escalation at all).

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

🔧 Optional proxy override when 🛡️ Use Apify Proxy is enabled. A RESIDENTIAL fallback tier is always prepared alongside your chosen proxy group, so a single block never stalls the whole run. 🎯 Leave as default for best performance.

## `enableSeniorityScoring` (type: `boolean`):

🧠 Classify every lead's parsed job title into a seniority bucket (Founder / C-Suite / VP / Director / Manager / IC) and a 0-100 decisionMakerScore, so you can prioritize outreach to real decision-makers.

## `targetSeniority` (type: `array`):

🔎 Only used when Seniority Scoring is ON. Keep only leads matching these seniority buckets (e.g. Founder, C-Suite, VP, Director, Manager, IC). Leave empty to keep every seniority level.

## `enableEmployeeDirectory` (type: `boolean`):

👥 Additionally crawl each company's LinkedIn people/about pages (no login required) to discover real employee profile URLs, then enrich each with fullname, headline, current company and location.

## `companyUrls` (type: `array`):

🔎 Only used when Employee Directory Discovery is ON. LinkedIn company URLs (e.g. https://www.linkedin.com/company/microsoft) or plain company names to crawl for employees. Leave empty to fall back to the Keywords field as company-name search terms.

## `maxEmployeesPerCompany` (type: `integer`):

📈 Cap on employee profiles discovered + enriched per company target (Employee Directory Discovery only).

## Actor input object example

```json
{
  "keywords": [
    "marketing"
  ],
  "mode": "b2b",
  "customDomains": [
    "@outlook.com",
    "@gmail.com"
  ],
  "patterns": [
    "email_for_bookings",
    "bio_email_basic",
    "contact_at_domain",
    "business_development"
  ],
  "platform": "LinkedIn.com",
  "location": "",
  "maxEmails": 10,
  "maxEmailsPerPattern": 15,
  "useProxy": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "GOOGLE_SERP"
    ]
  },
  "enableSeniorityScoring": false,
  "targetSeniority": [],
  "enableEmployeeDirectory": false,
  "companyUrls": [],
  "maxEmployeesPerCompany": 10
}
```

# 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 = {
    "keywords": [
        "marketing"
    ],
    "customDomains": [
        "@outlook.com",
        "@gmail.com"
    ],
    "patterns": [
        "email_for_bookings",
        "bio_email_basic",
        "contact_at_domain",
        "business_development"
    ],
    "location": "",
    "targetSeniority": [],
    "companyUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("simpleapi/linkedin-b2b-emails-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 = {
    "keywords": ["marketing"],
    "customDomains": [
        "@outlook.com",
        "@gmail.com",
    ],
    "patterns": [
        "email_for_bookings",
        "bio_email_basic",
        "contact_at_domain",
        "business_development",
    ],
    "location": "",
    "targetSeniority": [],
    "companyUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("simpleapi/linkedin-b2b-emails-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 '{
  "keywords": [
    "marketing"
  ],
  "customDomains": [
    "@outlook.com",
    "@gmail.com"
  ],
  "patterns": [
    "email_for_bookings",
    "bio_email_basic",
    "contact_at_domain",
    "business_development"
  ],
  "location": "",
  "targetSeniority": [],
  "companyUrls": []
}' |
apify call simpleapi/linkedin-b2b-emails-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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