# LinkedIn Profile Feed Scraper with Likers & Commenters (`vexaloom-labs/linkedin-profile-feed-scraper-with-likers`) Actor

Pull posts from a LinkedIn profile's activity feed or a direct post URL, with engagement counts, hashtags, media, and optionally the people who liked or commented on each post. Requires a LinkedIn session cookie.

- **URL**: https://apify.com/vexaloom-labs/linkedin-profile-feed-scraper-with-likers.md
- **Developed by:** [vexaloom-labs](https://apify.com/vexaloom-labs) (community)
- **Categories:** Social media, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 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.
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 Public Post Scraper — Profile Feeds, Comments & Video

Collect public LinkedIn posts without logging in. Give the actor one or more post links, or a profile URL, and it returns the post text, the author and their follower count, reaction and comment totals, the comments LinkedIn shows to logged-out visitors, images, videos with duration and (optionally) the full video transcript. No account, no cookie, no browser session.

### Ways to use it

1. **Specific posts** — paste any LinkedIn post link (`linkedin.com/posts/...`), a feed-update link (`/feed/update/urn:li:activity:...`, also `ugcPost`), or just the numeric activity ID. Country subdomains (`uk.linkedin.com/...`) work too.
2. **A profile's recent posts** — provide a profile URL and the actor reads the profile's public activity feed, then opens each post it finds for the full record.

Set `mode` to force one pipeline, or leave it on `Auto` and the actor figures it out from the URLs you supply.

### What each row contains

- `postId`, `postUrl`, `postedAt` (ISO 8601), `inputUrl`, `scrapedAt`
- `authorName`, `authorProfileUrl`, `authorAvatar`, `authorFollowers`
- `content` — the full post text, exactly as published
- `hashtags` — pulled out of the text
- `reactionsCount`, `commentsCount`
- `comments` — the newest comments visible to logged-out visitors: `authorName`, `text`, `postedAt`, and `reactionsCount` when the comment has likes
- `mediaType` — `text`, `image`, `video` or `repost`
- `mediaUrls` / `mediaItems` — image links, or the MP4 link plus its poster frame for videos
- `videoDuration` (e.g. `PT1M14S`), `videoTranscript` when you turn it on
- `isRepost` and `repostOf` (original author and reshared text) for reshares

Optional extras with a session cookie for people who still want them: `likers` (first visible page), `commenters` (with profile URLs), `reactionBreakdown`, `repostsCount` and `viewsCount` — plus profile feeds that paginate past the logged-out ceiling. See the cookie note below.

### Examples

A single post:

```json
{
  "mode": "postUrls",
  "postUrl": "https://www.linkedin.com/posts/nvidia_ai-is-technology-that-is-built-and-improved-activity-7508569677040893954-sffp",
  "maxPosts": 1
}
```

A batch of posts with quality filters:

```json
{
  "mode": "postUrls",
  "postUrls": [
    "https://www.linkedin.com/posts/nvidia_ai-is-technology-that-is-built-and-improved-activity-7508569677040893954-sffp",
    "urn:li:activity:7469496437156925441"
  ],
  "minReactions": 25,
  "includeReposts": false,
  "postedLimit": "month"
}
```

A profile's latest posts with their top comments:

```json
{
  "mode": "profilePosts",
  "profileUrl": "https://www.linkedin.com/in/mohamed-rhioui",
  "maxPosts": 10,
  "maxComments": 10
}
```

### Input reference

| Field | What it does | Default |
|---|---|---|
| `mode` | `auto`, `postUrls`, or `profilePosts` | `auto` |
| `profileUrl` | Profile URL or bare username (profile-feed mode) | – |
| `postUrl` / `postUrls` | One or many post links, feed-update links, URNs, or activity IDs | – |
| `maxPosts` | Upper bound on returned posts | `10` (max 200) |
| `postedLimit` | Any time / past hour / 24h / week / month / 3 / 6 months / year | Any time |
| `postedAfter`, `postedBefore` | Exact date window (`2026-01-31` or ISO 8601) | – |
| `maxComments` | Top comments kept per post (LinkedIn caps this at 10) | `10` |
| `includeVideoTranscript` | Add the spoken transcript of video posts | `false` |
| `includeReposts` | Keep or drop reshares | `true` |
| `minReactions`, `minComments` | Skip low-engagement posts | `0` |
| `mediaTypes` | Restrict to text / image / video / repost (and other legacy categories) | all |
| `language` | Language hint for localized content | `en` |
| `scrapeInteractors` | Optional cookie-only extra: add `commenters` (with profile URLs/headlines) | `false` |
| `scrapeReactions` | With `scrapeInteractors`, also add the first page of `likers` | `false` |
| `maxInteractors` | Cap per likers list and per commenters list | `50` |
| `cookie` | Optional. Unlocks feed pagination + reaction breakdowns/likers/commenters | empty |
| `cookies` | Optional. Same as `cookie`, as a browser cookie-export JSON array | – |

### Comments and limits, honestly

- **Public posts only.** Posts that LinkedIn reserves for signed-in members, or that were deleted, are skipped and the run still finishes with the posts it could read.
- **Profile feeds show a preview, not an archive — unless you bring a cookie.** Without one, LinkedIn's logged-out activity page lists only the newest few public posts (usually 8). There is no pagination for visitors who are not signed in. With your own session cookie the actor paginates the profile feed up to `maxPosts`.
- **Comments are the visible pageful.** Logged-out post pages embed roughly the ten most recent comments, and the cookie path adds commenter profile URLs to those same first ~10. LinkedIn's "more comments" pagination is not available to visitors.
- **Likers and reaction-type breakdowns are account-scoped.** LinkedIn shows those lists only to signed-in members. If you paste a session cookie from your own browser, the actor adds the first visible page of likers, the reaction-type breakdown, reposts/views counts and commenter profiles. LinkedIn often rejects sessions coming from a server IP, so treat cookie extras as best-effort. Everything in the output still works with no cookie at all.
- **Repost flags survive both page versions.** Reshares are detected from the full-page `sharedContent` block or from the lighter page's "reposted this" header, whichever LinkedIn serves.

### FAQ

**Do I need a LinkedIn account or cookie?** No. The actor reads the same public pages a logged-out visitor sees.

**How current is the data?** Every run fetches the pages live. `scrapedAt` tells you when each row was captured.

**Which post link formats are accepted?** `linkedin.com/posts/...` share links, `/feed/update/urn:li:activity:...` and `urn:li:ugcPost:...` links, bare activity IDs, and country subdomains such as `uk.linkedin.com`.

**Can it scrape company pages or keyword-search LinkedIn?** Those surfaces are login-gated at the publicly visible layer, so this actor focuses on profiles and individual posts.

**Why did a specific URL return nothing?** Either the post is member-only/removed, or it does not exist. The run log lists each URL with the reason.

**Do I need a proxy?** No. The actor selects its own connection and escalates only when a page request is challenged.

# Actor input Schema

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

What to scrape. "Auto" uses the URLs you provide; the actor picks the right pipeline automatically.

## `profileUrl` (type: `string`):

(mode=profilePosts or auto) LinkedIn profile URL, e.g. https://www.linkedin.com/in/williamhgates, or just the username.

## `postUrl` (type: `string`):

(mode=postUrls or auto) A LinkedIn post link, feed-update link, activity URN or bare activity ID. No login needed.

## `postUrls` (type: `array`):

(mode=postUrls) A list of LinkedIn post links, feed-update links, activity URNs or bare activity IDs. Combined with Post URL if both are set.

## `maxPosts` (type: `integer`):

Maximum number of posts to return. Cookieless profile feeds are capped by LinkedIn at the newest ~8 public posts; with the optional cookie the feed paginates up to this limit.

## `postedLimit` (type: `string`):

Keep only posts published within this window. "Any time" keeps everything.

## `postedAfter` (type: `string`):

Optional. Keep posts published on or after this date. Format: 2026-01-31 or full ISO 8601.

## `postedBefore` (type: `string`):

Optional. Keep posts published on or before this date. Format: 2026-01-31 or full ISO 8601.

## `maxComments` (type: `integer`):

How many top comments to include per post. LinkedIn shows ~10 comments to logged-out visitors and the cookie path adds commenter profile URLs to those same first ~10 - a documented source ceiling either way.

## `includeVideoTranscript` (type: `boolean`):

When on, video posts include the full spoken transcript (can make rows large).

## `scrapeInteractors` (type: `boolean`):

Optional extra. Requires the LinkedIn Cookie field and adds the first page of commenters with profile URLs/headlines. Cookieless runs always include engagement counts and the top comments.

## `scrapeReactions` (type: `boolean`):

With Scrape Likers & Commenters on, also include the first page of likers (name/headline/profile URL). Requires the optional cookie. LinkedIn's liker pagination endpoint is not available to visitors, so this is the visible first page only.

## `maxInteractors` (type: `integer`):

Cap applied separately to the likers list and the commenters list of each post when interactor scraping is enabled.

## `cookie` (type: `string`):

Optional and never required - the actor works without any login. If supplied, it unlocks extra data: profile feeds paginate past the ~10-post cookieless ceiling up to Max Posts, and every post gains reaction-type breakdowns, reposts/views counts and the first page of likers/commenters. Accepts the li_at value, a raw cookie header, or a full cookies JSON array.

## `cookies` (type: `array`):

Full browser cookie export for linkedin.com as a JSON array of {name, value} objects (Cookie-Editor extension -> Export -> JSON). Same effect as the Cookie field - merged with it when both are set. Optional and never required.

## `language` (type: `string`):

Language hint sent to LinkedIn. Affects localized content where available.

## `includeReposts` (type: `boolean`):

When off, reposts/reshared posts are excluded from the output.

## `minReactions` (type: `integer`):

Skip posts that received fewer than this many reactions. 0 keeps everything.

## `minComments` (type: `integer`):

Skip posts that received fewer than this many comments. 0 keeps everything.

## `mediaTypes` (type: `array`):

Restrict output to specific post media types. Leave empty to keep all. Cookieless runs detect text, image, video and repost posts.

## Actor input object example

```json
{
  "mode": "postUrls",
  "profileUrl": "https://www.linkedin.com/in/satyanadella",
  "postUrl": "https://www.linkedin.com/posts/nvidia_ai-is-technology-that-is-built-and-improved-activity-7508569677040893954-sffp",
  "maxPosts": 1,
  "postedLimit": "",
  "maxComments": 10,
  "includeVideoTranscript": false,
  "scrapeInteractors": false,
  "scrapeReactions": false,
  "maxInteractors": 50,
  "language": "en",
  "includeReposts": true,
  "minReactions": 0,
  "minComments": 0,
  "mediaTypes": []
}
```

# Actor output Schema

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

Dataset with scraped LinkedIn posts

# 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 = {
    "mode": "postUrls",
    "profileUrl": "https://www.linkedin.com/in/satyanadella",
    "postUrl": "https://www.linkedin.com/posts/nvidia_ai-is-technology-that-is-built-and-improved-activity-7508569677040893954-sffp",
    "maxPosts": 1,
    "postedLimit": "",
    "maxComments": 10,
    "includeVideoTranscript": false,
    "scrapeInteractors": false,
    "scrapeReactions": false,
    "maxInteractors": 50,
    "language": "en",
    "includeReposts": true,
    "minReactions": 0,
    "minComments": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("vexaloom-labs/linkedin-profile-feed-scraper-with-likers").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 = {
    "mode": "postUrls",
    "profileUrl": "https://www.linkedin.com/in/satyanadella",
    "postUrl": "https://www.linkedin.com/posts/nvidia_ai-is-technology-that-is-built-and-improved-activity-7508569677040893954-sffp",
    "maxPosts": 1,
    "postedLimit": "",
    "maxComments": 10,
    "includeVideoTranscript": False,
    "scrapeInteractors": False,
    "scrapeReactions": False,
    "maxInteractors": 50,
    "language": "en",
    "includeReposts": True,
    "minReactions": 0,
    "minComments": 0,
}

# Run the Actor and wait for it to finish
run = client.actor("vexaloom-labs/linkedin-profile-feed-scraper-with-likers").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 '{
  "mode": "postUrls",
  "profileUrl": "https://www.linkedin.com/in/satyanadella",
  "postUrl": "https://www.linkedin.com/posts/nvidia_ai-is-technology-that-is-built-and-improved-activity-7508569677040893954-sffp",
  "maxPosts": 1,
  "postedLimit": "",
  "maxComments": 10,
  "includeVideoTranscript": false,
  "scrapeInteractors": false,
  "scrapeReactions": false,
  "maxInteractors": 50,
  "language": "en",
  "includeReposts": true,
  "minReactions": 0,
  "minComments": 0
}' |
apify call vexaloom-labs/linkedin-profile-feed-scraper-with-likers --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vexaloom-labs/linkedin-profile-feed-scraper-with-likers"
        }
    }
}
```

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/I4oTw7vyuPTBhJ8UF/builds/PMjjgrE6QguMnaiyI/openapi.json
