# LinkedIn Posts Scraper (`calm_builder/linkedin-posts-scraper`) Actor

Extract structured data from public LinkedIn post URLs. Collect post text, author, publish date, reaction and comment counts, visible comments, reaction types, and media (images, video, carousels, documents) — ideal for social listening, content research, competitor monitoring, and lead enrichment.

- **URL**: https://apify.com/calm\_builder/linkedin-posts-scraper.md
- **Developed by:** [Coder](https://apify.com/calm_builder) (community)
- **Categories:** Social media, Lead generation, Automation
- **Stats:** 23 total users, 7 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 post scrapeds

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?

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 Posts Scraper

Collect structured data from public [LinkedIn](https://www.linkedin.com) **post** pages using direct post URLs. Add one or more links, start a run, and receive clean JSON records in your Apify dataset — no LinkedIn login required.

Use it for **social listening**, **content research**, **competitor monitoring**, **influencer analysis**, **lead enrichment**, and **marketing intelligence** — without copying posts manually.

***

### What you get

Each saved row is **one LinkedIn post**, organized into clear sections:

| Section        | What it contains                                                                              |
| -------------- | --------------------------------------------------------------------------------------------- |
| **Links**      | The URL you provided (`inputUrl`) and the canonical post link (`postUrl`)                     |
| **Content**    | Post text, headline, and publication timestamp when available                                 |
| **Author**     | Author name, profile or company link, type (`person` or `organization`), and image when shown |
| **Engagement** | Reaction count, comment count, and reaction types when shown                                  |
| **`comments`** | Visible comments with author name and text when LinkedIn exposes them on the public page      |
| **`postType`** | Content type — for example `text`, `image`, `video`, `carousel`, or `document`                |
| **`media`**    | Images, video sources, or other media when present                                            |

Results are saved to the dataset **as each post is processed**, so you can preview progress before the run finishes.

***

### Quick start on Apify

1. Open the Actor in the Apify Console.
2. Under **LinkedIn post URLs**, add one or more public post links (one per line).
3. Click **Start** and open the **Dataset** tab as posts are saved.

**Supported input formats:**

- Activity post: `https://www.linkedin.com/posts/apify_pyconsg-activity-7475096162006646784-txwr/`
- UGC post: `https://www.linkedin.com/posts/jancurn_its-always-great-to-be-back-in-san-francisco-ugcPost-7477224335636680704-LH9L/`
- Company post: `https://www.linkedin.com/posts/apify_two-brothers-scraped-10000-french-bakeries-activity-7477345241553936384-aWdh/`

Tracking parameters in the URL (for example `utm_source`) are ignored. The Actor uses the canonical post address.

**Example input:**

```json
{
  "postUrls": [
    "https://www.linkedin.com/posts/apify_pyconsg-activity-7475096162006646784-txwr/",
    "https://www.linkedin.com/posts/jancurn_its-always-great-to-be-back-in-san-francisco-ugcPost-7477224335636680704-LH9L/",
    "https://www.linkedin.com/posts/charlie-hills_claude-has-375-native-mcp-connectors-how-activity-7473675973541044225-8oQk"
  ]
}
```

***

### Input parameters

#### LinkedIn post URLs

|              |                                                             |
| ------------ | ----------------------------------------------------------- |
| **Field**    | `postUrls`                                                  |
| **Type**     | List of text entries (one URL per line)                     |
| **Required** | Yes — at least one entry                                    |
| **Formats**  | Standard LinkedIn post page URLs (`linkedin.com/posts/...`) |

Invalid entries that cannot be recognized as a LinkedIn post URL are skipped with a warning.

Duplicate URLs in the same run are still processed as separate inputs if listed more than once.

***

### What you will see during a run

The run log is written for end users — messages describe collection progress only.

Typical messages:

- `Starting collection for N post(s).`
- `Progress: 5 post(s) saved.`
- `Could not retrieve: https://www.linkedin.com/posts/...` *(when a single post fails)*
- `Run complete. Saved N post(s).`
- `Run complete. Saved X of Y post(s). Z could not be retrieved.` *(when some posts fail)*

If one post cannot be retrieved, other posts in the same run can still succeed.

On the Apify **free plan**, you may also see a notice when free-tier limits apply (see [Free plan limits](#free-plan-limits)).

***

### Output overview

#### Dataset structure

- Results are saved to a **single Apify dataset**
- Each row is **one post object**
- Only **successfully scraped** posts appear in the dataset — posts that could not be retrieved are not included

Field presence varies by post: not every post shows inline comments, reaction types, or full media on the public view. Missing sections are omitted from the output — not necessarily a scraper error.

***

### Output fields

#### Links and content

| Field         | Description                            |
| ------------- | -------------------------------------- |
| `inputUrl`    | The post URL as provided in your input |
| `postUrl`     | Canonical LinkedIn post link           |
| `text`        | Post body text when available          |
| `headline`    | Post headline or title line when shown |
| `publishedAt` | ISO publish timestamp when available   |

#### Author

| Field               | Description                            |
| ------------------- | -------------------------------------- |
| `author.name`       | Author display name                    |
| `author.profileUrl` | LinkedIn profile or company page URL   |
| `author.type`       | `person` or `organization`             |
| `author.imageUrl`   | Author or company image URL when shown |

#### Engagement

| Field           | Description                                                                    |
| --------------- | ------------------------------------------------------------------------------ |
| `numLikes`      | Total reaction count when shown                                                |
| `numComments`   | Total comment count when shown                                                 |
| `reactionTypes` | Reaction types displayed on the post (for example `LIKE`, `PRAISE`, `EMPATHY`) |

#### `comments` (array)

| Field         | Description                          |
| ------------- | ------------------------------------ |
| `authorName`  | Commenter name when shown            |
| `authorUrl`   | Commenter profile URL when available |
| `text`        | Comment text                         |
| `publishedAt` | Comment timestamp when available     |

#### Media

| Field          | Description                                                                   |
| -------------- | ----------------------------------------------------------------------------- |
| `postType`     | Content type — `text`, `image`, `video`, `carousel`, `document`, or `article` |
| `media.images` | List of image URLs (and optional `alt` text when shown)                       |
| `media.video`  | Video sources and poster image when the post contains video                   |

***

### Example output

The excerpts below come from a real run of public LinkedIn post URLs. Full output is available in the run dataset.

#### Example input

```json
{
  "postUrls": [
    "https://www.linkedin.com/posts/apify_pyconsg-activity-7475096162006646784-txwr/",
    "https://www.linkedin.com/posts/jancurn_its-always-great-to-be-back-in-san-francisco-ugcPost-7477224335636680704-LH9L/",
    "https://www.linkedin.com/posts/apify_the-apify-team-is-heading-to-wearedevelopers-activity-7475503085436534784-8Fhp/"
  ]
}
```

#### Excerpt — company carousel post with comments

```json
{
  "inputUrl": "https://www.linkedin.com/posts/apify_pyconsg-activity-7475096162006646784-txwr/",
  "postUrl": "https://www.linkedin.com/posts/apify_pyconsg-activity-7475096162006646784-txwr/",
  "text": "At PyCon Singapore's PyLadies track, Kateřina Hroníková ran a hands-on workshop with a real output: a Women in Tech Inspiration Feed Actor...",
  "headline": "At PyCon Singapore's PyLadies track, Kateřina Hroníková ran a hands-on workshop with a real output: a Women in Tech Inspiration Feed Actor.",
  "publishedAt": "2026-06-23T08:03:25.574Z",
  "author": {
    "name": "Apify",
    "profileUrl": "https://cz.linkedin.com/company/apify",
    "type": "organization",
    "imageUrl": "https://media.licdn.com/dms/image/v2/D4D0BAQF7OnC-r1njIA/company-logo_100_100/..."
  },
  "postType": "carousel",
  "media": {
    "images": [
      {
        "url": "https://media.licdn.com/dms/image/v2/D4E10AQEomy8zWsZpUw/image-shrink_800/..."
      },
      {
        "url": "https://media.licdn.com/dms/image/v2/D4E10AQH62KvFkG_w9A/image-shrink_800/..."
      },
      {
        "url": "https://media.licdn.com/dms/image/v2/D4E10AQGtyi-2FsHutA/image-shrink_800/..."
      }
    ]
  },
  "numLikes": 48,
  "numComments": 2,
  "reactionTypes": ["LIKE", "EMPATHY", "PRAISE"],
  "comments": [
    {
      "authorName": "Saurav Jain",
      "text": "❤️❤️",
      "publishedAt": "2026-06-23T13:14:52.984Z"
    },
    {
      "authorName": "Sandhu Singh",
      "text": "Hii",
      "publishedAt": "2026-06-23T09:08:57.768Z"
    }
  ]
}
```

#### Excerpt — personal post with carousel images

```json
{
  "inputUrl": "https://www.linkedin.com/posts/jancurn_its-always-great-to-be-back-in-san-francisco-ugcPost-7477224335636680704-LH9L/",
  "postUrl": "https://www.linkedin.com/posts/jancurn_its-always-great-to-be-back-in-san-francisco-activity-7477224336890912768-tZVV/",
  "text": "It’s always great to be back in San Francisco! With a strong crew from Apify, we’re heading to AI Engineer World's Fair next week...",
  "headline": "It’s always great to be back in San Francisco!",
  "publishedAt": "2026-06-29T05:00:02.001Z",
  "author": {
    "name": "Jan Čurn",
    "profileUrl": "https://www.linkedin.com/in/jancurn",
    "type": "person",
    "imageUrl": "https://media.licdn.com/dms/image/v2/D4E03AQGVYzvGHp9zhw/profile-displayphoto-shrink_400_400/..."
  },
  "postType": "carousel",
  "media": {
    "images": [
      {
        "url": "https://media.licdn.com/dms/image/v2/D4D22AQFnPIWsXxWMbQ/feedshare-shrink_800/..."
      },
      {
        "url": "https://media.licdn.com/dms/image/v2/D4D22AQH_EAhX-Hdk0Q/feedshare-shrink_800/..."
      }
    ]
  },
  "numLikes": 219,
  "numComments": 8,
  "reactionTypes": ["LIKE", "EMPATHY", "PRAISE"],
  "comments": [
    {
      "authorName": "Saurav Jain",
      "text": "This sounds like a strong lineup. The “MCP doesn’t suck, your agent does” framing is especially interesting...",
      "publishedAt": "2026-06-29T12:45:44.581Z"
    },
    {
      "authorName": "Petr Smid",
      "text": "Wow. Enjoy SF and with 1,000 people registered, be careful with the rooftop 😉",
      "publishedAt": "2026-06-29T09:08:05.825Z"
    }
  ]
}
```

#### Excerpt — image post with engagement counts

```json
{
  "inputUrl": "https://www.linkedin.com/posts/apify_the-apify-team-is-heading-to-wearedevelopers-activity-7475503085436534784-8Fhp/",
  "postUrl": "https://www.linkedin.com/posts/apify_the-apify-team-is-heading-to-wearedevelopers-activity-7475503085436534784-8Fhp/",
  "text": "The Apify team is heading to WeAreDevelopers World Congress in Berlin, July 9-10...",
  "headline": "The Apify team is heading to WeAreDevelopers World Congress in Berlin, July 9-10.",
  "publishedAt": "2026-06-24T11:00:23.683Z",
  "author": {
    "name": "Apify",
    "profileUrl": "https://cz.linkedin.com/company/apify",
    "type": "organization"
  },
  "postType": "image",
  "media": {
    "images": [
      {
        "url": "https://media.licdn.com/dms/image/v2/D4E10AQELPd6D6SBFBg/image-shrink_1280/..."
      }
    ]
  },
  "numLikes": 27,
  "numComments": 2,
  "reactionTypes": ["LIKE", "PRAISE", "APPRECIATION"]
}
```

#### Excerpt — high-engagement post with many visible comments

```json
{
  "inputUrl": "https://www.linkedin.com/posts/charlie-hills_claude-has-375-native-mcp-connectors-how-activity-7473675973541044225-8oQk/",
  "postUrl": "https://www.linkedin.com/posts/charlie-hills_claude-has-375-native-mcp-connectors-how-activity-7473675973541044225-8oQk/",
  "text": "Claude has 375+ native MCP connectors. How to connect one in under 2 minutes...",
  "headline": "Claude has 375+ native MCP connectors.",
  "publishedAt": "2026-06-19T10:00:06.259Z",
  "author": {
    "name": "Charlie Hills 🦩",
    "profileUrl": "https://uk.linkedin.com/in/charlie-hills",
    "type": "person"
  },
  "postType": "carousel",
  "numLikes": 1004,
  "numComments": 393,
  "reactionTypes": ["LIKE", "EMPATHY", "INTEREST"],
  "comments": [
    {
      "authorName": "Sajad Hussain",
      "text": "100%. Feels like most people are just collecting connectors like Pokemon...",
      "publishedAt": "2026-06-19T12:08:18.065Z"
    },
    {
      "authorName": "Brook Hinton",
      "text": "\"The connectors aren't the magic, chaining them is\" is the line that matters.",
      "publishedAt": "2026-06-19T10:07:14.648Z"
    }
  ]
}
```

Posts that could not be retrieved do not appear in the dataset. Check the run log for a short message per failed URL.

***

### Pricing

This Actor uses **pay-per-result** pricing. You are charged only for posts **successfully saved** to the dataset.

| What you pay for    | When it is charged                       |
| ------------------- | ---------------------------------------- |
| **Each saved post** | Once per post row written to the dataset |

**Examples** (see the **Pricing** tab on the Store listing for current rates):

| Run                        | What you pay for |
| -------------------------- | ---------------- |
| 50 post URLs, 48 succeed   | 48 results       |
| 100 post URLs, all succeed | 100 results      |
| 20 post URLs, 5 fail       | 15 results       |

Failed or skipped URLs are not saved and are not billed as results.

***

### Free plan limits

On the Apify **free plan**, the Actor may automatically apply:

| Limit                       | Value                                       |
| --------------------------- | ------------------------------------------- |
| Post URLs processed per run | **5** (only the first entries in your list) |

Additional URLs in the same run are not processed. Paid Apify plans can use the full input list without this cap. If limits apply, the run log will include a short notice.

***

### Public pages and data coverage

**No LinkedIn login required**\
The Actor reads publicly visible post pages. It does not sign in to LinkedIn and does not use your account or cookies.

**Guest view vs signed-in view**\
Results reflect what LinkedIn shows to visitors who are not logged in. Compared with what you see when signed in, output may include:

- Fewer inline comments or partial comment threads
- Reaction counts without a full list of who reacted
- Missing media on some post types
- Shorter or simplified post text on certain pages

Coverage varies by post, author type, and LinkedIn's own visibility settings.

**Post URL formats**\
Standard `linkedin.com/posts/...` links are supported, including activity, UGC, and share-style slugs.

**High-traffic or restricted posts**\
Some posts may not be retrieved in a given run. Retrying later or processing URLs in a smaller batch can help in some cases.

**Compliance**\
You are responsible for using collected data in line with applicable laws and [LinkedIn's terms of service](https://www.linkedin.com/legal/user-agreement).

***

### Tips for best results

1. **Use the post link from the browser** — Open the post on LinkedIn, copy the address bar URL, and paste it into `postUrls`.
2. **Start with a small batch** — Test with 5–10 posts before large exports.
3. **Expect partial comments** — `numComments` is the total count; the `comments` array contains only comments visible on the public page (often a subset).
4. **Deduplicate on `postUrl`** — Use the canonical post link as a stable key across runs.
5. **Schedule recurring runs** — Use Apify schedules to monitor the same posts or refresh a list over time.
6. **Export flexibly** — Download the dataset as JSON, CSV, Excel, or connect via API to your warehouse or automation tools.

***

### Frequently asked questions

**Can I scrape a profile or company feed?**\
This Actor is built for **individual post URLs**. For company post feeds, use a LinkedIn company scraper with post collection enabled.

**Why is a post missing from my dataset?**\
The post may be unavailable, temporarily busy, restricted, or the URL may be invalid. Check the run log for `Could not retrieve: ...` messages. Other posts in the same run can still succeed.

**Why does `numComments` not match the `comments` array length?**\
`numComments` is the total count shown on the post. The `comments` array includes only comments LinkedIn exposes on the public page — often fewer than the full thread.

**Why is the author a person on a company post?**\
Some posts are published by executives or employees on behalf of an organization. The `author.type` field indicates `person` or `organization` as shown on the page.

**Will failed posts be charged?**\
No. Only posts successfully saved to the dataset are billed as results. See the **Pricing** tab for current rates.

**Can I run hundreds of post URLs at once?**\
Yes on paid plans. Posts are processed in parallel; results appear in the dataset as each one completes.

***

### Support

For Actor-specific issues, use the **Issues** tab on the Apify Store listing or contact the publisher through Apify.

For platform questions (runs, billing, API, schedules), see [Apify documentation](https://docs.apify.com) and Apify support.

# Actor input Schema

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

Enter LinkedIn post URLs, one per line. Supported links include standard post pages (for example, https://www.linkedin.com/posts/username\_activity-1234567890-abcd/ or https://www.linkedin.com/posts/company-name\_keywords-activity-1234567890-abcd/). Tracking parameters in the URL are ignored.

## Actor input object example

```json
{
  "postUrls": [
    "https://www.linkedin.com/posts/apify_two-brothers-scraped-10000-french-bakeries-activity-7477345241553936384-aWdh",
    "https://www.linkedin.com/posts/charlie-hills_claude-has-375-native-mcp-connectors-how-activity-7473675973541044225-8oQk"
  ]
}
```

# Actor output Schema

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

No description

# 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 = {
    "postUrls": [
        "https://www.linkedin.com/posts/apify_two-brothers-scraped-10000-french-bakeries-activity-7477345241553936384-aWdh",
        "https://www.linkedin.com/posts/charlie-hills_claude-has-375-native-mcp-connectors-how-activity-7473675973541044225-8oQk"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("calm_builder/linkedin-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 = { "postUrls": [
        "https://www.linkedin.com/posts/apify_two-brothers-scraped-10000-french-bakeries-activity-7477345241553936384-aWdh",
        "https://www.linkedin.com/posts/charlie-hills_claude-has-375-native-mcp-connectors-how-activity-7473675973541044225-8oQk",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("calm_builder/linkedin-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 '{
  "postUrls": [
    "https://www.linkedin.com/posts/apify_two-brothers-scraped-10000-french-bakeries-activity-7477345241553936384-aWdh",
    "https://www.linkedin.com/posts/charlie-hills_claude-has-375-native-mcp-connectors-how-activity-7473675973541044225-8oQk"
  ]
}' |
apify call calm_builder/linkedin-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,calm_builder/linkedin-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/b4WDgXOj1Sb1J7aiP/builds/7VpTSAEj9jqRyqWJn/openapi.json
