# LinkedIn Profile Posts Scraper (`arisma_tech/linkedin-profile-posts-scraper`) Actor

Scrape posts from any LinkedIn profile: text, date, reactions by type, comments, reposts, images, videos, shared articles, mentions and quoted posts. Works without login for recent posts, or add your session cookie to get all posts. Export to JSON, CSV or Excel.

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

## Pricing

from $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/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

### What does LinkedIn Profile Posts Scraper do?

**LinkedIn Profile Posts Scraper** returns the posts of any LinkedIn profile as clean, structured data: text, publication date, reactions (split by type), comments, reposts, images, videos, shared articles and job posts, quoted and reposted posts, and the people and companies mentioned in each post.

It works in two modes:

| | Without a cookie | With your session cookie |
| --- | --- | --- |
| Posts per profile | The few recent posts LinkedIn shows logged-out visitors (usually 3-6) | All posts, with paging |
| Text, date, total reactions, comments | ✅ | ✅ |
| Reactions by type (like, celebrate, love, ...) and repost count | ❌ | ✅ |
| Images, videos, shared articles | ✅ | ✅ |
| Job post details | ❌ | ✅ |
| Mentions | Names and profile/company usernames | Names and LinkedIn ids |
| Author headline | ❌ (hidden by LinkedIn) | ✅ |
| Risk to a LinkedIn account | None | See [the cookie section](#how-do-i-get-my-linkedin-cookie) |

### How do I use it?

1. Enter a **LinkedIn profile URL or username**, for example `https://www.linkedin.com/in/steffanhaas/`.
2. Set **Posts per profile** and, to page through a long history, **Page number**.
3. Optionally paste your **LinkedIn session cookie** to get all posts with full details.
4. Click **Start** and download the posts as JSON, CSV or Excel, or read them through the API.

### How much does it cost?

**$5.00 per 1,000 posts**, with platform usage and proxies included. You pay only for posts returned; rows for profiles that fail are free. To control costs, set **Posts per profile**, or set a maximum cost per run in the run options; the Actor stops as soon as that limit is reached.

Example input:

```json
{
    "username": "https://www.linkedin.com/in/steffanhaas/",
    "total_posts": 25,
    "page_number": 1,
    "proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

| Field | Description |
| --- | --- |
| `username` | Profile URL or username. |
| `usernames` | More profiles for the same run. |
| `total_posts` | Posts per profile (default 50). |
| `page_number` | Page of `total_posts` posts to return. Page 2 with 25 posts returns posts 26-50. |
| `limit` | Alternative cap on posts per profile; the smaller of `limit` and `total_posts` applies. |
| `cookie` | Optional `li_at` session cookie. Stored encrypted; never logged. |
| `proxy` | Proxy settings. Residential proxies work best. |

### Output

One item per post:

```json
{
    "urn": { "activity_urn": "7511765195523014656", "share_urn": "7511765194520567808", "ugcPost_urn": null },
    "full_urn": "urn:li:activity:7511765195523014656",
    "posted_at": { "date": "2026-10-02 12:33:04", "relative": "2 days ago • Visible to anyone on or off LinkedIn", "timestamp": 1790944384461 },
    "text": "🌍 Help define the future workplace architecture of a global technology organization...",
    "url": "https://www.linkedin.com/posts/steffanhaas_ssischaefer-architecture-digitalworkplace-activity-7511765195523014656-aqNK",
    "post_type": "regular",
    "author": {
        "first_name": "Steffan",
        "last_name": "Haas",
        "headline": "IT Transformation | Enterprise Infrastructure | Executive Leadership",
        "username": "steffanhaas",
        "profile_url": "https://www.linkedin.com/in/steffanhaas",
        "profile_picture": "https://media.licdn.com/dms/image/...",
        "actor_type": "member"
    },
    "stats": { "total_reactions": 22, "like": 22, "support": 0, "love": 0, "insight": 0, "celebrate": 0, "funny": 0, "curious": 0, "comments": 0, "reposts": 3 },
    "job_data": { "id": "4474149762", "title": "Digital Workplace Architect", "company": "SSI SCHÄFER", "location": "Riga, Latvia (Hybrid)", "workplace_type": "Hybrid", "url": "https://www.linkedin.com/jobs/view/4474149762/" },
    "text_annotations": [{ "start": 268, "length": 11, "text": "SSI SCHÄFER", "type": "company", "company_urn": "106330" }],
    "pagination_token": "dXJuOmxpOmFjdGl2aXR5..."
}
```

- `post_type` is `regular`, `quote` (a reshare with the member's own text) or `repost` (a plain reshare). Quotes and reposts have the original post under `reshared_post`.
- Depending on the post there is also `media` (images or video), `article` and `attachment` (shared links), `job_data` or `document`.
- `posted_at.date` is in UTC. `text_annotations` positions count Unicode characters, so an emoji counts as one.
- Without a cookie, fields LinkedIn does not show logged-out visitors are `null`: the per-reaction split, `reposts`, `author.headline` and `pagination_token`.

Profiles that fail (not found, cookie expired, ...) are added as rows with `error` and `errorDescription`, which are free. A run summary is saved as `RUN_SUMMARY` in the key-value store.

### How do I get my LinkedIn cookie?

1. Log in to LinkedIn in Chrome.
2. Open DevTools (F12) → **Application** → **Cookies** → `https://www.linkedin.com`.
3. Copy the value of the `li_at` cookie and paste it into the **LinkedIn session cookie** field.

LinkedIn may restrict accounts it believes are automated. The Actor keeps one IP for the whole run and paces its requests like a person browsing, but use an account you can afford to lose and avoid very large runs. For the fewest security checks, set the proxy country to the account's country. The cookie stops working when you log out of LinkedIn in that browser.

### FAQ

#### Why do I get only a few posts without a cookie?

LinkedIn shows logged-out visitors only a handful of each member's recent posts. Everything else requires a logged-in session.

#### Is it legal to scrape LinkedIn?

The Actor reads data that is visible to the account or visitor it runs as. Posts contain personal data, which is protected by regulations such as the GDPR. Only collect personal data you have a legitimate reason to process, and check LinkedIn's terms for your use case. If unsure, consult a lawyer.

# Actor input Schema

## `username` (type: `string`):

Profile to scrape, e.g. <code>https://www.linkedin.com/in/steffanhaas/</code> or <code>steffanhaas</code>.

## `usernames` (type: `array`):

Optional: more profile URLs or usernames to scrape in the same run.

## `total_posts` (type: `integer`):

Maximum number of posts to return per profile (default 50). You are charged per post.

## `page_number` (type: `integer`):

Which page of posts to return, counting pages of <code>total_posts</code> posts. Page 2 with 25 posts per page returns posts 26-50.

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

Alternative cap on posts per profile. When both this and <code>total_posts</code> are set, the smaller one applies.

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

Optional. The value of the <code>li_at</code> cookie from a browser where you are logged in to LinkedIn. With it the Actor returns all posts with full details; without it, only the few posts LinkedIn shows logged-out visitors. Use an account you are willing to risk: LinkedIn may restrict accounts used for automated access.

## `proxy` (type: `object`):

Residential proxies work best. With a cookie, pick the proxy country of the account to avoid LinkedIn security checks.

## Actor input object example

```json
{
  "username": "https://www.linkedin.com/in/steffanhaas/",
  "total_posts": 25,
  "page_number": 1,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `posts` (type: `string`):

Scraped posts with text, date, reactions, comments, reposts, media and mentions.

## `runSummary` (type: `string`):

Which profiles succeeded, failed or were skipped, and why.

# 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 = {
    "username": "https://www.linkedin.com/in/steffanhaas/",
    "total_posts": 25,
    "page_number": 1,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("arisma_tech/linkedin-profile-posts-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 = {
    "username": "https://www.linkedin.com/in/steffanhaas/",
    "total_posts": 25,
    "page_number": 1,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("arisma_tech/linkedin-profile-posts-scraper").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 '{
  "username": "https://www.linkedin.com/in/steffanhaas/",
  "total_posts": 25,
  "page_number": 1,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call arisma_tech/linkedin-profile-posts-scraper --silent --output-dataset

```

## MCP server setup

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

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/pUBxRdYDDUYLiraPc/builds/bVlVyvvZ2YtlIbg5v/openapi.json
