# LinkedIn Post Analytics Scraper (`khadinakbar/linkedin-post-analytics-scraper`) Actor

Scrape public LinkedIn post analytics from post URLs: reactions, comments, engagement rate vs author followers, media type, author, optional transcript. Use for content reporting. For engager identities use linkedin-post-engagers-scraper. One row per post. $0.005/row.

- **URL**: https://apify.com/khadinakbar/linkedin-post-analytics-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (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 $5.00 / 1,000 linkedin post analytics rows

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Post Analytics Scraper

Turn public LinkedIn post URLs into one analytics row per post for content teams, agencies, and competitor-research agents. Each row includes `reactionCount`, `commentCount`, `engagementRatePct` versus the author's public follower count, `mediaType`, author context, and an optional video transcript. No LinkedIn login or cookies.

This Actor scores **posts you already have URLs for** using public reaction and comment totals plus engagement rate versus author followers. For the people commenting on a post, continue with [LinkedIn Post Engagers Scraper](https://apify.com/khadinakbar/linkedin-post-engagers-scraper) after you have the post URL.

### Best fit for this Actor

- Benchmark a competitor's last five posts by reactions, comments, and engagement rate vs follower count.
- Build a weekly client report of owned or industry posts without logging into LinkedIn.
- Compare video vs document vs text formats on the same author's public posts.
- Feed an AI agent a short list of post URLs and get structured JSON for a dashboard or CRM note.

For commenter identities, continue with [LinkedIn Post Engagers Scraper](https://apify.com/khadinakbar/linkedin-post-engagers-scraper). For author firmographics after you have a company URL, use [LinkedIn Company Search Scraper](https://apify.com/khadinakbar/linkedin-company-search-scraper).

### Practical scenario

A social lead pastes a Microsoft video post URL and an Anthropic document post URL. The run returns two `OK` rows: the video post has 379 reactions, 25 comments, media type `video`, and a transcript preview; the document post has 10,889 reactions, 607 comments, and media type `document`. Engagement rate is `(reactions + comments) / author followers`, so a 28-million-follower company page and a 4-million-follower research page are comparable. A deleted URL comes back as `VALID_EMPTY` with no `post-analytics` charge.

### Quick start input

```json
{
  "postUrls": [
    "https://www.linkedin.com/feed/update/urn:li:activity:7468770468041502720/"
  ],
  "maxItems": 20,
  "includeTranscript": false,
  "providerOrder": "scrapecreators-first"
}
```

`postUrls` accepts activity URLs, `/posts/` URLs, and pulse article URLs. Duplicate URLs are deduplicated. Profile and company page URLs are skipped.

### Input reference

| Field | Type | What it controls |
|---|---|---|
| `postUrls` | array | Required post URLs. Example: `https://www.linkedin.com/feed/update/urn:li:activity:7468770468041502720/`. Max 100 unique values. |
| `maxItems` | integer | Cap on unique posts processed. Default 20, max 100. |
| `includeTranscript` | boolean | Include the full public video transcript. Default false keeps a 280-character `transcriptPreview`. |
| `providerOrder` | enum | `scrapecreators-first` (default) or `sociavault-first`. Fallback fires automatically. |
| `maxConcurrency` | integer | Posts processed in parallel. Default 2, max 5. |

### What data you receive

One dataset item is one LinkedIn post.

```json
{
  "outcome": "OK",
  "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:7468770468041502720/",
  "resolvedPostUrl": "https://www.linkedin.com/posts/microsoft_activity-7468770468041502720-mGV1",
  "postId": "7468770468041502720",
  "authorName": "Microsoft",
  "authorUrl": "https://www.linkedin.com/company/microsoft",
  "authorType": "company",
  "authorFollowerCount": 28914824,
  "reactionCount": 379,
  "commentCount": 25,
  "totalEngagements": 404,
  "engagementRatePct": 0.0014,
  "commentsPerReaction": 0.066,
  "mediaType": "video",
  "hasTranscript": true,
  "publishedAt": "2026-06-05T21:07:22.617Z",
  "provider": "scrapecreators",
  "scrapedAt": "2026-08-21T12:00:00.000Z"
}
```

| Field | Meaning |
|---|---|
| `reactionCount` | Public reaction total. LinkedIn often labels this as likes even when it includes all reaction types. |
| `engagementRatePct` | `((reactions + comments) / author followers) * 100`. Null when follower count is missing. |
| `mediaType` | `video`, `document`, `carousel`, `image`, `media`, or `text`. |
| `outcome` | `OK` billed; `VALID_EMPTY` when the post is private, deleted, or not public (no `post-analytics` charge). |

`OUTPUT` and `RUN_SUMMARY` in the default key-value store hold `outcome`, `itemsPushed`, and `chargedEventCounts`.

You can download the dataset as JSON, CSV, Excel, or HTML from the Dataset tab.

### Use through the API

```bash
curl -X POST "https://api.apify.com/v2/acts/khadinakbar~linkedin-post-analytics-scraper/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"postUrls":["https://www.linkedin.com/feed/update/urn:li:activity:7468770468041502720/"]}'
```

Results land in the run's default dataset. Paginate with `offset`/`limit`.

### Use with AI agents through Apify MCP

> Score these LinkedIn post URLs. Return authorName, reactionCount, commentCount, engagementRatePct, mediaType, publishedAt, outcome, and provider.

Connect via <https://mcp.apify.com>. Read `OUTPUT.outcome` and `itemsPushed` to interpret empty datasets. The actor is exposed as `apify--linkedin-post-analytics-scraper`.

### Connect the workflow

- After you have post URLs, extract commenters with [LinkedIn Post Engagers Scraper](https://apify.com/khadinakbar/linkedin-post-engagers-scraper).
- For public profile context on an author handle, use [LinkedIn Profile Details Scraper](https://apify.com/khadinakbar/linkedin-profile-details-scraper).
- For emails on other public websites, use [Contact Details Scraper](https://apify.com/khadinakbar/contact-details-scraper).

### Pricing

Pay per event plus platform usage. Confirm current event prices on the live [Pricing tab](https://apify.com/khadinakbar/linkedin-post-analytics-scraper/pricing); that tab is the source of truth if this page ever lags.

- `apify-actor-start`: $0.00005 per run
- `post-analytics`: **$0.005** per `OK` row

A one-post check is about $0.005 in result events plus a few seconds of Apify platform usage. `VALID_EMPTY` rows have no `post-analytics` charge. Provider credits are paid by the Actor owner.

| Run | Billed rows | Event cost (approx.) |
|---|---|---|
| One post | 1 | ~$0.005 |
| 10-post weekly report | 10 | ~$0.05 |
| 20-post default batch | 20 | ~$0.10 |
| 100-post max batch | 100 | ~$0.50 |

### How it works

1. Normalize and deduplicate post URLs.
2. Fetch public post JSON from ScrapeCreators, then SociaVault.
3. Flatten reaction and comment counts, compute engagement rate vs author followers, and classify media type.
4. Charge `post-analytics` only after a usable `OK` row, then write the row.

Private, deleted, or non-public posts finish as `VALID_EMPTY` with zero fabricated metrics.

### Best results

- Pass post, activity, or pulse URLs. Keep profile and company URLs for the matching scrapers.
- Compare `engagementRatePct` across authors of similar follower size; a 28M-follower page and a 50k-follower person are not the same base.
- Use `mediaType` to split video vs document vs text before ranking posts.
- Leave `includeTranscript` off unless you need the full spoken text. The preview is enough to see that a transcript exists.
- A typo or deleted post finishes `SUCCEEDED` with a `VALID_EMPTY` row and no `post-analytics` charge.

### Best results for recovery and data quality

- **Public metrics.** Reactions, comments, author followers, media, and transcripts that appear without login. Owner-only impression dashboards stay with LinkedIn's native analytics.
- **Single reaction total.** Public provider payloads expose one reaction count covering all visible reaction types.
- **Share counts when present.** The field is written when a provider returns it.
- **People rows.** Continue with LinkedIn Post Engagers Scraper when you need commenter identities.
- **Per-URL resilience.** Provider hiccups retry, then fall back. Mixed success is `PARTIAL`. A fully unavailable URL set is `UPSTREAM_FAILED`.

### Builder's note

I built this after I found that both public providers already return reaction totals, comment totals, author followers, media URLs, and sometimes a transcript — enough to score a post without a browser. In my testing, engagement rate versus follower count was the useful derived metric: it lets you compare a viral document on a mid-size page with a quiet video on a huge company page. Every row still carries `provider` and `scrapedAt` so you can see source and freshness.

### FAQ

**Which metrics are in each row?**
Public reaction and comment totals plus an engagement rate versus the author's public follower count. Owner-only impression dashboards remain in LinkedIn's native analytics.

**Is LinkedIn login or cookies required?**
No. The default path is cookieless providers. You never supply cookies, credentials, or a personal LinkedIn account.

**What happens if a post is deleted or restricted?**
The row is `VALID_EMPTY` with a reason, no `post-analytics` charge. Runs with at least one `OK` post still finish with useful data.

**Can an AI agent use this?**
Yes. One `postUrls` tool call returns schema-valid rows, provenance, and a named `OUTPUT.outcome`.

### Legal

This Actor retrieves publicly available data. You are responsible for complying with LinkedIn's Terms of Service, applicable data-protection laws (GDPR/CCPA), and Apify's [Exclusion Policy](https://apify.com/terms/exclusion-policy) when using the results. This Actor is independent of LinkedIn.

Issues and feature requests: use the Actor Issues tab on Apify.

# Actor input Schema

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

LinkedIn post URLs to score. Accepts activity URLs (https://www.linkedin.com/feed/update/urn:li:activity:7468770468041502720/), posts URLs, and pulse article URLs. Up to 100 unique URLs per run. NOT profile, company, or search URLs — use a profile or company scraper for those.

## `maxItems` (type: `integer`):

Maximum unique post URLs to process in this run. Default 20 keeps a typical reporting batch cheap. Raise to 100 for scheduled competitor monitoring. Does not scrape more posts than you paste; it only caps cost.

## `includeTranscript` (type: `boolean`):

When enabled, video posts include the full public transcript in the row. Default false keeps token-light rows with a 280-character transcriptPreview when a transcript exists. Does not invent a transcript the provider did not return.

## `providerOrder` (type: `string`):

Which public-data provider to try first for each post. Both providers return the same analytics shape; the fallback fires automatically when the primary fails or reports the post as missing. Keep the default unless you have a reason to prefer SociaVault.

## `maxConcurrency` (type: `integer`):

How many post URLs to process in parallel. Default 2 balances speed against provider rate limits. Raise to 5 for large batches; lower to 1 if you see rate-limit errors in the run log.

## Actor input object example

```json
{
  "postUrls": [
    "https://www.linkedin.com/feed/update/urn:li:activity:7468770468041502720/"
  ],
  "maxItems": 20,
  "includeTranscript": false,
  "providerOrder": "scrapecreators-first",
  "maxConcurrency": 2
}
```

# Actor output Schema

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

Dataset items containing reaction counts, comments, engagement rate, author context, media type, and optional transcript.

## `summary` (type: `string`):

Compact OUTPUT record including outcome, itemsPushed, chargedEventCounts, and warnings.

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

Machine-readable RUN\_SUMMARY record with per-post diagnostics and billing counters.

# 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/feed/update/urn:li:activity:7468770468041502720/"
    ],
    "maxItems": 20,
    "includeTranscript": false,
    "maxConcurrency": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/linkedin-post-analytics-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/feed/update/urn:li:activity:7468770468041502720/"],
    "maxItems": 20,
    "includeTranscript": False,
    "maxConcurrency": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/linkedin-post-analytics-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/feed/update/urn:li:activity:7468770468041502720/"
  ],
  "maxItems": 20,
  "includeTranscript": false,
  "maxConcurrency": 2
}' |
apify call khadinakbar/linkedin-post-analytics-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/linkedin-post-analytics-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/3x59JTrM1VJJcur2l/builds/BOLollqDu6Somj0Rb/openapi.json
