# 🔥 Linkedin Companies & Profiles Bulk Scraper (`bebity/linkedin-premium-actor`) Actor

Companies & Profiles Linkedin scraper.
Get comprehensive profiles of individuals and companies based on your keywords and filters.
Unleash the power of data! 🌐🔍

- **URL**: https://apify.com/bebity/linkedin-premium-actor.md
- **Developed by:** [Bebity](https://apify.com/bebity) (community)
- **Categories:** Lead generation
- **Features:** Limited permissions
- **Stats:** 16,069 total users, 124 monthly users, 99.7% runs succeeded, 354 bookmarks
- **User rating**: 3.27 out of 5 stars

## Pricing

from $2.80 / 1,000 profile — identity & current positions

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Premium Actor — by Bebity](https://i.ibb.co/JRP0vXWh/banner.png)

### 🔁 Version 10 — Rebuilt 100% from scratch · June 2026

> **The entire scraper has been rewritten from A to Z.** This is the **tenth major version** of Bebity's LinkedIn scraper — the whole scraping engine was thrown away and rebuilt from the ground up to talk **directly to LinkedIn's modern interface** (no brittle HTML scraping, no legacy glue). It is **faster, far more reliable, and returns more complete data** than any previous version.
>
> **This rebuild is final — done for good.** The architecture is stable; from here we only add data and polish on top of it.

***

**LinkedIn Premium Actor** extracts complete, structured data from [LinkedIn](https://www.linkedin.com) — both **people profiles** and **company pages** — from a simple list of search terms, names, or URLs. Give it keywords (`"growth marketer"`), full names (`"Jane Doe"`), or direct LinkedIn URLs, and get clean JSON back: identity, experience, education, skills, certifications, company size, locations, and more.

It is built for **recruiters, sales teams, marketers, and data analysts** who need reliable LinkedIn data at scale, without maintaining a scraper themselves.

***

### What can LinkedIn Premium Actor do?

- 🔍 **Search or direct lookup** — pass a keyword/name to *search*, or a LinkedIn URL / `/in/{slug}` / `/company/{slug}` to fetch *one exact* profile or company.
- 📚 **Bulk input** — one list mixing search terms, names, and URLs. Each entry is routed automatically.
- 🌍 **Location filter** — narrow people searches by one or several locations (typed place names *or* raw LinkedIn geo IDs).
- 🏢💼 **Company & job-title filters** — ask for the people at one company, or for an exact job title, and combine both with your keywords and location.
- 👤🏢 **Profiles & companies** — switch between people and company pages with a single field.
- 🧩 **Pick your sections** — choose exactly which profile sections to scrape (about, experience, skills, languages, contact info…) for faster, cheaper runs.
- 🔗 **Every row names its input** — each result carries the entry that produced it plus a `status` / `reason`, so outputs line up with inputs without relying on ordering.
- 📦 **Clean, consistent JSON** — field names are harmonized across profiles and companies, every field documented below.

Together with the **Apify platform**, you also get scheduling, a full **API**, integrations (Make, Zapier, n8n…), monitoring, proxy rotation, and storage — all without writing infrastructure code.

***

### What data can LinkedIn Premium Actor extract?

#### From a LinkedIn profile

| Field | Description |
|---|---|
| `input`, `status`, `reason` | The entry that produced the row, whether it resolved (`FOUND` / `NOT_FOUND`), and why not |
| `vanityName`, `linkedinUrl`, `urn` | Public handle, canonical URL, and stable member URN |
| `profileId` | LinkedIn's stable member id (`ACoAAA…`) — survives the member editing their profile URL, and is accepted back as input |
| `firstName`, `lastName`, `headline` | Identity and professional headline |
| `location`, `industry` | Location and industry |
| `summary` | The "About" section |
| `profilePictureUrl`, `coverImageUrl` | Profile photo and background/cover image |
| `followersCount`, `connectionsCount` | Audience size |
| `currentTitle`, `currentCompany` | The role the profile still lists as ongoing — flat, no need to walk `experience[]` |
| `careerStartYear`, `firstDegreeYear` | Earliest year across the work history and across education |
| `experience[]` | Roles: title, company (with `companyId` / `companyUrl`), type, dates (as displayed **and** as `startDateISO` / `endDateISO`), duration, location, description |
| `education[]` | Schools, degrees, fields of study, dates |
| `certifications[]` | Licenses & certifications with issuer and date |
| `skills[]`, `languages[]` | Skills list and languages with proficiency |
| `volunteer[]`, `honors[]`, `organizations[]`, `projects[]` | Additional sections when present |
| `contactInfo` | Profile URL and public websites (each with its label and the category the member picked), plus an email only when the member made one public — opt-in section |

#### From a LinkedIn company

| Field | Description |
|---|---|
| `input`, `status`, `reason` | The entry that produced the row, whether it resolved (`FOUND` / `NOT_FOUND`), and why not |
| `vanityName`, `linkedinUrl`, `companyId` | Handle, URL, numeric ID |
| `name`, `tagline`, `description` | Company name, tagline, "About" text |
| `industry`, `industryId`, `foundedYear` | Industry label, its stable numeric id (the safe thing to join on), and founding year |
| `employeeCount`, `employeeCountRange` | Staff size (exact and/or bracket) |
| `followersCount` | Company-page followers |
| `websiteUrl`, `phone`, `callToAction` | Contact and CTA button |
| `specialities[]`, `hashtags[]` | Focus areas and page hashtags |
| `headquarter`, `locations[]` | HQ and all offices (with lat/long) |
| `logoUrl`, `coverImageUrl` | Brand images |
| `pageType`, `verified`, `active`, `jobSearchUrl` | Page metadata and jobs link |

***

### How to scrape LinkedIn data — step by step

1. Open the actor and pick an **Action**: `Profiles 👤` or `Companies 🏢`.
2. In **Search terms, names or URLs**, add your entries — e.g. `growth marketer`, `Jane Doe`, or `https://www.linkedin.com/in/janedoe`.
3. (Optional) Set a **Limit** per search term, add a **Location** filter, or restrict **Profile data to scrape**.
4. Click **Start** ▶️.
5. When the run finishes, download your results from the **Output / Storage** tab as **JSON, CSV, Excel, or HTML**, or pull them via the **Apify API**.

***

### Input

The actor takes the following input. Open the **Input** tab for the interactive form, or pass JSON via the API.

| Field | Key | Type | Description |
|---|---|---|---|
| 🎯 Action | `action` | string | `get-profiles` or `get-companies`. |
| 🔍 Search terms, names or URLs | `keywords` | string\[] | One bulk list. Each entry is a **search term** (capped by `limit`) **or** a **direct lookup** (full URL, `/in/{slug}`, `/company/{slug}` → exactly one result, ignores `limit`). A bare slug without the `/in/` or `/company/` marker is treated as a search. |
| 🔢 Limit | `limit` | integer | Max rows **per search term**. Ignored for direct URLs/slugs. |
| 🌍 Location | `location` | string\[] | Filter people searches by location (`get-profiles` only). Type a place name (matched to LinkedIn's autocomplete) or paste a raw geo ID / URN. Multiple = match ANY. |
| 🏢 Current company | `company` | string | Narrow a people search to the members who currently work there — this is how you get a company's employees. Accepts a company URL, its slug, or its name (a URL or slug is the most reliable). |
| 💼 Job title | `jobTitle` | string | Narrow a people search to this job title, matched as an exact phrase (e.g. `Data Scientist`). |
| 🧩 Profile data to scrape | `profileFields` | string\[] | Which profile sections to fetch (`about`, `experience`, `languages`, `skills`, `honors`, `projects`, `organizations`, `contact`). Each one is a single extra request per profile. Default = `about` (cheapest). Select all for a full scrape. Base identity is always returned. |

#### Input example

```json
{
  "action": "get-profiles",
  "keywords": [
    "growth marketer",
    "Jane Doe",
    "https://www.linkedin.com/in/janedoe"
  ],
  "limit": 10,
  "location": ["Paris", "United States"],
  "company": "https://www.linkedin.com/company/stripe/",
  "jobTitle": "Data Scientist",
  "profileFields": ["about", "experience", "skills", "contact"]
}
```

***

### Output

You can download the dataset produced by LinkedIn Premium Actor in any format — **JSON, CSV, Excel, or HTML** — or access it through the Apify API. Every field is documented in the actor's **output schema**, and the Console shows two clean table views: **Profiles** and **Companies**.

#### Profile output example

The example below is **maximal** — it shows every field the actor can return for a profile. A real run includes whichever sections the person has actually filled in, and whichever you requested via **`profileFields`**.

```json
{
  "input": "growth marketer",
  "status": "FOUND",
  "reason": null,
  "vanityName": "janedoe",
  "linkedinUrl": "https://www.linkedin.com/in/janedoe",
  "profileId": "ACoAAABEXAMPLE1234",
  "firstName": "Jane",
  "lastName": "Doe",
  "headline": "Data & Cloud Architect",
  "location": "Greater Toulouse Metropolitan Area",
  "industry": "IT Services and IT Consulting",
  "urn": "urn:li:member:123456789",
  "summary": "Passionate about turning data into business value across cloud and BI projects.",
  "profilePictureUrl": "https://media.licdn.com/dms/image/v2/EXAMPLE/profile-displayphoto-shrink_800_800/0/0000000000000",
  "coverImageUrl": "https://media.licdn.com/dms/image/v2/EXAMPLE/profile-displaybackgroundimage-shrink_350_1400/0/0000000000000",
  "followersCount": 1261,
  "connectionsCount": 500,
  "currentTitle": "Data & Cloud Architect",
  "currentCompany": "Example Consulting",
  "careerStartYear": 2008,
  "firstDegreeYear": 2005,
  "experience": [
    {
      "title": "Data & Cloud Architect",
      "companyName": "Example Consulting",
      "companyId": "12345678",
      "companyUrl": "https://www.linkedin.com/company/12345678/",
      "employmentType": "Full-time",
      "startDate": "Jan 2021",
      "endDate": "Present",
      "startDateISO": "2021-01",
      "endDateISO": null,
      "duration": "5 yrs 6 mos",
      "location": "Toulouse, France",
      "description": "Lead data architecture and BI delivery for enterprise clients."
    },
    {
      "title": "BI Engineer",
      "companyName": "Example Corp",
      "employmentType": "Full-time",
      "startDate": "Jan 2008",
      "endDate": "Dec 2020",
      "duration": "12 yrs",
      "location": "Toulouse, France"
    }
  ],
  "education": [
    {
      "schoolName": "Example University",
      "degreeName": "Master's degree",
      "fieldOfStudy": "Information Systems",
      "startDate": "2005",
      "endDate": "2006",
      "activities": "Data science club, student association"
    }
  ],
  "certifications": [
    {
      "name": "AWS Certified Data Engineer - Associate",
      "issuingOrganization": "Amazon Web Services (AWS)",
      "issuedDate": "2025 · Expires Oct 2028"
    }
  ],
  "skills": ["AWS", "SQL", "Apache Spark", "Business Intelligence", "Data Warehouse"],
  "languages": [
    { "name": "English", "proficiency": "Full professional" },
    { "name": "French", "proficiency": "Native or bilingual" }
  ],
  "volunteer": [
    { "role": "Mentor", "organization": "Example Nonprofit", "dateRange": "2022 - Present", "cause": "Education" }
  ],
  "honors": [
    { "title": "Employee of the Year", "description": "Recognized for outstanding delivery." }
  ],
  "organizations": [
    { "name": "Example Data Association", "role": "Board Member", "dateRange": "2019 - 2023", "description": "Community programs and events." }
  ],
  "projects": [
    { "name": "Real-time Analytics Platform", "dateRange": "2023 - 2024", "description": "Built a streaming analytics pipeline on AWS." }
  ],
  "contactInfo": {
    "profileUrl": "https://www.linkedin.com/in/janedoe",
    "websites": [
      { "url": "https://example.com", "label": "example.com", "type": "Company" }
    ]
  }
}
```

#### Company output example

```json
{
  "input": "https://www.linkedin.com/company/examplesoftware/",
  "status": "FOUND",
  "reason": null,
  "vanityName": "examplesoftware",
  "linkedinUrl": "https://www.linkedin.com/company/examplesoftware/",
  "companyId": "12345678",
  "name": "Example Software Inc.",
  "tagline": "Turning ideas into tailored software.",
  "description": "Example Software builds custom web, mobile and Web3 solutions for ambitious companies.",
  "websiteUrl": "https://example.com",
  "phone": { "number": "0600000000" },
  "industry": "Software Development",
  "industryId": "4",
  "employeeCountRange": { "start": 2, "end": 10 },
  "foundedYear": 2020,
  "specialities": ["software", "web", "mobile", "scraping"],
  "headquarter": { "city": "Paris", "geographicArea": "France", "postalCode": "92060", "country": "FR" },
  "locations": [
    { "localizedName": "Paris", "city": "Paris", "country": "FR", "latitude": 48.88075, "longitude": 2.275646, "headquarter": true }
  ],
  "followersCount": 333,
  "logoUrl": "https://media.licdn.com/dms/image/v2/EXAMPLE/company-logo_400_400/0/0000000000000/example_logo",
  "coverImageUrl": "https://media.licdn.com/dms/image/v2/EXAMPLE/image-scale_191_1128/0/0000000000000/example_cover",
  "pageType": "COMPANY",
  "verified": false,
  "active": true,
  "jobSearchUrl": "https://www.linkedin.com/jobs/search?f_C=12345678",
  "callToAction": { "text": "Visit website", "type": "VIEW_WEBSITE", "url": "https://www.example.com" },
  "hashtags": ["software", "development", "web3"]
}
```

> **Note on field naming.** Field names are now consistent across both output types: `followersCount`, `coverImageUrl`, and `industry` mean the same thing on a profile and on a company. Some fields are intentionally distinct because the concepts differ — a person has a `profilePictureUrl` and a `summary`, a company has a `logoUrl` and a `description`.

***

### How much does it cost to scrape LinkedIn?

Web scraping cost depends on **how much data you pull** and **which sections you request**. A few tips to keep runs lean:

- Use the **`profileFields`** option to scrape only the sections you actually need — each section is one extra request, so fewer sections = faster and cheaper runs.
- Use **direct URLs / slugs** when you already know the exact profiles or companies — they skip search entirely.
- Keep **`limit`** sensible: `limit × number of search terms` is the upper bound on search rows.

Check the actor's pricing tab on Apify Store for the exact, up-to-date rate. You can run small test batches first to estimate the cost of a larger job.

***

### Why run LinkedIn Premium Actor on Apify?

Your scraper plus the **Apify platform** is the complete package:

- **API & integrations** — call it from your code, or wire it to Make, Zapier, n8n, Google Sheets, and more.
- **Scheduling & monitoring** — run it on a cron, get alerts, keep history.
- **Proxy rotation** built in.
- **Storage** — datasets in JSON/CSV/Excel, served over API.

***

### FAQ

#### Is it legal to scrape LinkedIn?

> Our scrapers only return what a member has published on their own profile and chosen to share publicly — nothing that sits behind a private setting. We therefore believe that our scrapers, when used for ethical purposes by Apify users, are safe. However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

#### What is the difference between a search and a direct lookup?

A **search term** (e.g. `"growth marketer"`) returns up to `limit` results and can be narrowed by `location`. A **direct lookup** (a full LinkedIn URL or a `/in/{slug}` / `/company/{slug}` path) returns exactly one matching profile or company and ignores `limit`.

#### Why did my name get treated as a URL (or vice-versa)?

Entries are routed automatically: anything with a `/in/` or `/company/` marker (or a full URL) is a direct lookup; everything else is a search. A bare handle without that marker is treated as a search term.

***

### Support & feedback

**Your feedback matters** — this actor evolves quickly. Want more fields, filters, or locations? Open the **Issues** tab on the actor's Apify Store page, or reach out to us directly. We ship improvements fast. 🚀

***

Made with ❤️ by **[Bebity](https://bebity.io)**

# Changelog

This Actor's version history is a separate document: https://apify.com/bebity/linkedin-premium-actor/changelog.md

# Actor input Schema

## `action` (type: `string`):

What to scrape: people profiles or companies.

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

One bulk list. Each entry is either a SEARCH term ("web developer", "John Doe") — searched and capped by the limit — OR a DIRECT lookup: a full LinkedIn URL, or a "/in/{slug}" (profiles) / "/company/{slug}" (companies) path. Direct lookups return exactly one result each and ignore the limit. A bare slug WITHOUT the /in/ or /company/ marker is treated as a search term.

## `limit` (type: `integer`):

Max rows per search term: limit=5 over 2 search terms returns up to 10 rows. Ignored for direct URLs/slugs — each is always scraped.

## `location` (type: `array`):

Filter people-search results by location (get-profiles only). Type a place name (e.g. "Paris", "United States", "Greater London") — it is matched against LinkedIn's location autocomplete and the best match is used. Add several to widen the filter (matches ANY of them). You can also paste a raw LinkedIn geo id (e.g. 106383538) or geo URN to skip the lookup. Unrecognized entries are skipped with a warning.

## `company` (type: `string`):

Narrow a people search to members who currently work at this company — this is how you get the employees of a company. Accepts a company URL (https://www.linkedin.com/company/stripe/), its slug (stripe) or its name (Stripe); a URL or slug is the most reliable. Combines with keywords, location and job title. Ignored for company runs and for direct profile URLs.

## `jobTitle` (type: `string`):

Narrow a people search to this job title, matched as an exact phrase (e.g. "Data Scientist"). Combines with keywords, location and current company.

## `profileFields` (type: `array`):

Which profile sections to scrape (profiles only). Each option is one LinkedIn request — pick only what you need for faster, cheaper runs. Default is About (cheapest single section). Select all options to scrape the full profile. Base identity (name, headline, location, picture, follower/connection counts) is always returned.

## Actor input object example

```json
{
  "action": "get-profiles",
  "keywords": [
    "web dev"
  ],
  "limit": 1,
  "company": "https://www.linkedin.com/company/stripe/",
  "jobTitle": "Data Scientist",
  "profileFields": [
    "about"
  ]
}
```

# Actor output Schema

## `dataset` (type: `string`):

Every row of this run, profiles and companies together, as JSON.

## `profiles` (type: `string`):

Profile rows only, as the Profiles table shows them.

## `companies` (type: `string`):

Company rows only, as the Companies table shows them.

## `csv` (type: `string`):

The same rows as a spreadsheet file. Nested fields (experience, education, locations) are flattened by the export.

# 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 = {
    "profileFields": [
        "about"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bebity/linkedin-premium-actor").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 = { "profileFields": ["about"] }

# Run the Actor and wait for it to finish
run = client.actor("bebity/linkedin-premium-actor").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 '{
  "profileFields": [
    "about"
  ]
}' |
apify call bebity/linkedin-premium-actor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bebity/linkedin-premium-actor"
        }
    }
}
```

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/od6RadQV98FOARtrp/builds/oVOgTdAZJOdHRIhIo/openapi.json
