# LinkedIn Scraper API on Apify: People, Companies, Posts +++ (`socialhz/apify-linkedin-scraper-api`) Actor

Scrape LinkedIn on Apify from a list of URLs — people with work history and recent posts, company pages with follower and employee counts, and individual posts with engagement. No login, no cookies. Rates from $1.80 / 1,000.

- **URL**: https://apify.com/socialhz/apify-linkedin-scraper-api.md
- **Developed by:** [Socialhz](https://apify.com/socialhz) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $2.40 / 1,000 person profiles

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 Scraper: People, Companies & Posts

Give it a list of LinkedIn URLs. Get back people with their work history and recent posts, company pages with follower and employee counts, and individual posts with full engagement — in one run, with no LinkedIn login and no cookies.

Mix people, companies and posts in the same list. Each URL is routed to the right lookup automatically.

Built for lead research, competitor monitoring, recruitment sourcing and content analysis.

***

### What it does

- **People** — full work history, education, follower count, and their **recent posts and reposts with the complete text**, so you can see what someone actually talks about
- **Companies** — description, industry, size, **follower and employee counts**, every office location, and the companies LinkedIn lists as similar
- **Posts** — full text, reactions, reaction types, comments, and video with per-quality URLs and transcripts
- **Comments included free** — post comments are part of the post price, not a separate charge
- **Related profiles** — around twenty "people also viewed" per person, which turns one name into a prospect list
- **No login required** — no LinkedIn account, no cookies, no session token, ever
- **Every URL accounted for** — each one you supply comes back with a record, so you always know what was found
- **Honest about gating** — where LinkedIn hides a field from logged-out visitors, the record names it rather than leaving you guessing

***

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `urls` | array | — | **Required.** Mix people, companies and posts freely. Anything that is not one of those is skipped and costs nothing. Max `500` per run |
| `includePostComments` | boolean | `true` | Return comments on post URLs. Included in the post price |
| `includeRelatedProfiles` | boolean | `false` | Add the "people also viewed" list to person records. Included in the profile price |

**Accepted URL shapes**

```
People      linkedin.com/in/satyanadella
Companies   linkedin.com/company/microsoft
Schools     linkedin.com/school/harvard-university
Posts       linkedin.com/posts/…-activity-7298318111240257536-MZHu
            linkedin.com/feed/update/urn:li:activity:7298318111240257536
```

A missing `https://`, a trailing slash, a query string, or a regional subdomain like `in.linkedin.com` all work.

#### Example input

```json
{
  "urls": [
    "https://www.linkedin.com/in/satyanadella",
    "https://www.linkedin.com/company/microsoft",
    "https://www.linkedin.com/posts/satyanadella_activity-7298318111240257536-MZHu"
  ],
  "includePostComments": true,
  "includeRelatedProfiles": true
}
```

***

### Output

One record per URL. Every record carries `type` (`profile`, `company` or `post`), `url` (the page it is for) and `status`.

#### Person records

| Field | Type | Description |
|---|---|---|
| `fullName`, `firstName`, `lastName` | string | null | Name |
| `publicIdentifier` | string | null | The handle from the profile URL |
| `headline` | string | null | Profile headline |
| `location`, `country` | string | null | Stated location |
| `about` | string | null | About text |
| `followers`, `connections` | number | null | Audience size |
| `profilePhotoUrl`, `coverImageUrl` | string | null | Profile picture and banner |
| `currentCompany`, `currentSchool` | object | null | Present employer and school |
| `totalExperiences` | number | null | How many positions were found |
| `experience` | array | Work history with company, dates and duration |
| `education` | array | Education history |
| `activity` | array | **Recent posts and reposts with full text**, author and link. A repost is marked in `action` |
| `activityCount` | number | null | How many activity items were returned |
| `articles` | array | Long-form articles with title, link and cover image |
| `awards`, `volunteerExperience`, `recommendations`, `publications`, `websites` | array | Where the profile shows them publicly |
| `relatedProfiles` | array | "People also viewed". Empty unless requested |
| `fieldsWithheldByLinkedIn` | array | Which fields LinkedIn does not render publicly |
| `aboutTruncated` | boolean | null | Whether LinkedIn cut the About text |

#### Company records

| Field | Type | Description |
|---|---|---|
| `companyName`, `tagline`, `description` | string | null | Identity |
| `industry`, `specialties`, `companyType` | string | null | Classification |
| `companySize` | string | null | Band, e.g. `10,001+ employees` |
| `followersCount`, `employeesCount` | number | null | Audience and headcount |
| `headquarters`, `website` | string | null | Where and what |
| `logoUrl`, `coverImageUrl` | string | null | Company logo and banner |
| `locations` | array | Every office with address |
| `similarCompanies` | array | Ten companies LinkedIn lists as similar |
| `sampleEmployees` | array | A handful of staff with name, title and profile link |
| `recentPosts`, `companyUpdates` | array | A sample of the page's own content |

#### Post records

| Field | Type | Description |
|---|---|---|
| `postId`, `postType`, `postedAt` | | `text`, `image`, `video`, `article` or `discussion` |
| `caption`, `articleBody` | string | null | The post text |
| `hashtags` | array | Hashtags used in the post |
| `authorName`, `authorHandle`, `authorProfileUrl` | string | null | Who wrote it. Handle is `null` for company-page authors |
| `authorFollowerCount` | number | null | The author's total followers |
| `likeCount`, `commentCount`, `viewCount` | number | null | Engagement |
| `reactionTypes` | array | Which reactions are present — like, praise, empathy and so on |
| `comments` | array | Author, text, likes and timestamp per comment |
| `commentsReturned` | number | How many this record contains |
| `commentsRemaining` | boolean | Whether the post has more than LinkedIn shows publicly |
| `videoUrl`, `videoUrlsByQuality`, `transcript`, `captionsVttUrl` | | Video, at each quality, with transcript |
| `imageUrls`, `thumbnailUrl`, `durationSeconds` | | Media |

Every record also carries `status`: `ok`, `not_found` for a page that is not publicly visible, or `unavailable` if the source could not be reached.

***

### Pricing

Charged per page looked up, plus a small fixed fee when a run starts. **Comments on posts and related profiles are included** — there is no separate charge for either.

Prices fall on larger Apify plans.

| Event | Free plan | Starter | Scale | Business and above |
|---|---|---|---|---|
| Person profile | $2.90 per 1,000 | $2.70 | $2.55 | **$2.40 per 1,000** |
| Company page | $2.90 per 1,000 | $2.50 | $2.10 | **$1.80 per 1,000** |
| Post | $2.90 per 1,000 | $2.50 | $2.10 | **$1.80 per 1,000** |
| Run start | $0.005 per run | $0.005 | $0.005 | $0.005 |

A URL that is not a LinkedIn profile, company or post is rejected before any lookup and costs nothing.

#### Worked examples, at Business-plan rates

Totals are rounded to the nearest cent.

**Lead research — 250 people**
250 × $0.0024 + $0.005 = **≈$0.61**

**Competitor watch — 50 companies and 200 of their posts**
50 × $0.0018 + 200 × $0.0018 + $0.005 = **≈$0.46**

**Sourcing sweep — 750 people with related profiles**
750 × $0.0024 + $0.005 = **≈$1.81**

Set **Maximum cost per run** in the run options to cap spend. The Actor stops cleanly at that ceiling and returns everything it charged for.

***

### Good to know

**Comments on a post are capped at roughly ten.** That is LinkedIn's own limit — a public post page embeds about ten comments however many the post really has. `commentsRemaining` tells you when there are more. No tool reading public pages can return the rest.

**LinkedIn hides some profile fields from logged-out visitors.** Skills, certifications and per-position job titles are not rendered publicly, and the About text is often cut short. Rather than silently returning blanks, every person record lists exactly what was withheld in `fieldsWithheldByLinkedIn`.

**You supply the URLs.** There is no keyword or name search — this Actor reads pages you point it at.

***

### Tips

- **Start with people, add companies later.** Person records carry the richest signal, particularly the activity feed.
- **Turn on related profiles for sourcing.** One good profile yields around twenty adjacent ones, at no extra cost.
- **Use the activity feed to qualify.** It tells you whether someone actually posts, and what about, which a static profile cannot.
- **Keep lists tidy.** Every URL you supply is looked up, so a clean list keeps runs quick.

***

### Support

Report a problem through the **Issues** tab on this Actor's page. Issues are reviewed regularly.

When reporting, please include the run ID, the input you used, and what you expected.

For volume enquiries, custom requirements, or anything not specific to a single run, email **socialhtz@gmail.com**.

# Changelog

This Actor's version history is a separate document: https://apify.com/socialhz/apify-linkedin-scraper-api/changelog.md

# Actor input Schema

## `urls` (type: `array`):

The pages to scrape. Mix people, companies and posts freely — each URL is routed to the right lookup automatically. People look like linkedin.com/in/name, companies like linkedin.com/company/name, posts like linkedin.com/posts/… or linkedin.com/feed/update/urn:li:activity:… Anything that is not one of those is skipped and costs you nothing. Up to 500 URLs per run.

## `includePostComments` (type: `boolean`):

Applies to post URLs. LinkedIn shows about ten comments on a public post page whatever the real total, so this returns those and reports whether more exist. Included in the post price — there is no separate comment charge.

## `includeRelatedProfiles` (type: `boolean`):

Applies to person URLs. Adds the 'people also viewed' list — roughly 20 similar profiles with names and links, which is useful for building a prospect list from one starting point. Included in the profile price.

## Actor input object example

```json
{
  "urls": [
    "https://www.linkedin.com/in/williamhgates",
    "https://www.linkedin.com/company/microsoft"
  ],
  "includePostComments": true,
  "includeRelatedProfiles": false
}
```

# Actor output Schema

## `results` (type: `string`):

One record per URL looked up — a person, a company, or a post.

# 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 = {
    "urls": [
        "https://www.linkedin.com/in/williamhgates",
        "https://www.linkedin.com/company/microsoft"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("socialhz/apify-linkedin-scraper-api").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 = { "urls": [
        "https://www.linkedin.com/in/williamhgates",
        "https://www.linkedin.com/company/microsoft",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("socialhz/apify-linkedin-scraper-api").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 '{
  "urls": [
    "https://www.linkedin.com/in/williamhgates",
    "https://www.linkedin.com/company/microsoft"
  ]
}' |
apify call socialhz/apify-linkedin-scraper-api --silent --output-dataset

```

## MCP server setup

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

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/WBqEQJHcVpHl0aJEt/builds/b61weyZ75wkR7XJRk/openapi.json
