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

Scrape public posts from LinkedIn personal profiles - text, dates, reactions, comments, reposts, quote posts, hashtags, mentions, images, videos and articles. Multiple profiles, date and engagement filters. No LinkedIn login or cookies.

- **URL**: https://apify.com/coregent/linkedin-profile-posts-scraper.md
- **Developed by:** [Delowar Munna](https://apify.com/coregent) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.25 / 1,000 post 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

## LinkedIn Profile Posts Scraper — Posts, Reposts, Reactions, Media & Mentions

![LinkedIn Profile Posts Scraper](https://raw.githubusercontent.com/coregentdevspace/linkedin-profile-posts-scraper-assets/main/thumbnail-linkedin-profile-posts-scraper.png "LinkedIn Profile Posts Scraper")

Scrape public posts from LinkedIn **personal profiles**. Extract post text, timestamps, reactions, comment counts, reposts, quote posts, hashtags, mentions, images, videos, documents and linked articles. Process many profiles in one run, filter by date and engagement, and export clean JSON, CSV or Excel.

**No LinkedIn login or cookies required.** The actor reads LinkedIn's public profile and post pages — the same pages anyone sees without signing in.

### ✨ What you get

- **One row per post**, newest first per profile, with a stable `postId` / `urn` and canonical `postUrl`
- **Post types normalized**: `POST`, `REPOST`, `QUOTE_POST`, `ARTICLE`
- **Reposts are never credited to the wrong person** — the row belongs to the profile that reposted; the original post, its author, text, media and engagement sit in `originalPost`
- **Quote posts keep both sides** — the profile's commentary in `text`, the quoted post in `originalPost`
- **Engagement**: reactions, comments, and the most common reaction types LinkedIn displays (`LIKE`, `CELEBRATE`, `SUPPORT`, `LOVE`, `INSIGHTFUL`, `FUNNY`)
- **Media**: images, native video (URL, thumbnail, duration, size), document carousels (page count, cover), article / link cards (URL, title, publisher, thumbnail)
- **Hashtags** (without `#`), **mentions** of people and companies, **external links**
- **Source lineage on every row** — `sourceProfileUrl`, `sourceProfileName`, `input`
- **Optional top-comments preview** (up to 5 per post)
- **Free error rows** for profiles that could not be read, and a `RETRY_INPUT` you can re-run

### 🚀 Quick start

#### Minimal input

```json
{
    "profiles": ["https://www.linkedin.com/in/satyanadella/"],
    "maxPostsPerProfile": 20
}
```

#### Bulk monitoring

```json
{
    "profiles": ["satyanadella", "justinwelsh", "williamhgates"],
    "maxPostsPerProfile": 20,
    "postsNewerThan": "30 days",
    "includeReposts": true,
    "includeQuotePosts": true
}
```

#### Date window

```json
{
    "profiles": ["https://www.linkedin.com/in/williamhgates/"],
    "postsNewerThan": "2026-09-01",
    "postsOlderThan": "2026-10-01"
}
```

#### Engagement filter (only high-performing original posts)

```json
{
    "profiles": ["justinwelsh"],
    "postsNewerThan": "90 days",
    "minReactions": 100,
    "minComments": 10,
    "includeReposts": false
}
```

### ⚙️ Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `profiles` | array | `["https://www.linkedin.com/in/satyanadella/"]` | Profile URLs (`/in/<slug>`) or bare slugs. Company, job and post URLs are rejected with a free error row. |
| `maxPostsPerProfile` | integer | `20` | Max posts saved per profile, newest first (1–1,000). |
| `postsNewerThan` | string | `""` | `24 hours`, `7 days`, `2 weeks`, `3 months`, `2026-09-01` or ISO timestamp. |
| `postsOlderThan` | string | `""` | Same formats. |
| `minReactions` | integer | `0` | Skip posts with fewer reactions. |
| `minComments` | integer | `0` | Skip posts with fewer comments. |
| `includeReposts` | boolean | `true` | Include plain reposts. |
| `includeQuotePosts` | boolean | `true` | Include quote posts (repost + commentary). |
| `includeMedia` | boolean | `true` | Include image / video / document / article-card details. Media is linked, never downloaded. |
| `includeReactionBreakdown` | boolean | `true` | Include `engagement.topReactionTypes`. |
| `includeTopComments` | boolean | `false` | Add a preview of up to 5 top comments per post. |
| `proxyConfiguration` | object | Apify Proxy | See the proxy policy below. |

### 📦 Output

The dataset has two views (tabs) in the Apify Console, plus a run summary record:

| Tab | What it shows |
| --- | --- |
| **Posts** | Every field of every post — text, type, author, engagement, media, article card, original post, lineage |
| **Engagement** | A compact per-post engagement table for benchmarking and monitoring |
| **Run summary** | Per-run counts and a per-profile status table (`RUN_SUMMARY` in the key-value store) |

![LinkedIn Profile Posts Scraper — Posts table view](https://raw.githubusercontent.com/coregentdevspace/linkedin-profile-posts-scraper-assets/main/linkedin-profile-posts-scraper-output-posts-table-view.png "LinkedIn Profile Posts Scraper — Posts table view")

#### Posts tab — sample record

A real record from a run on `satyanadella` and `williamhgates` (all fields):

```json
{
    "rowType": "post",
    "postId": "urn:li:activity:7514393874887270401",
    "urn": "urn:li:activity:7514393874887270401",
    "activityId": "7514393874887270401",
    "postUrl": "https://www.linkedin.com/posts/satyanadella_introducing-microsoft-decision-1-our-new-activity-7514393874887270401-thi6",
    "postType": "POST",
    "text": "Introducing Microsoft-Decision-1, our new model for fast decision-making.\n\nIt delivers top performance on structured decision tasks, outperforming both LLMs and other decision models in latency and quality.\n\nWe’re already testing it across Microsoft for everything from incident response and quality control to scientific discovery.\n\nAvailable now in Foundry and soon through OpenRouter: https://lnkd.in/gNh5aW8b",
    "publishedAt": "2026-10-09T18:38:30.459Z",
    "publishedAtSource": "post",
    "isEdited": false,
    "author": {
        "name": "Satya Nadella",
        "headline": "Chairman and CEO at Microsoft",
        "profileUrl": "https://www.linkedin.com/in/satyanadella/",
        "publicIdentifier": "satyanadella",
        "profileId": "urn:li:member:19186432",
        "profilePictureUrl": "https://media.licdn.com/dms/image/v2/C5603AQHHUuOSlRVA1w/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1579726625398?e=2147483647&v=beta&t=Rr7WT9uBM0byOij0oT_KirejIMVE4HK4r8NGIp0zjdI"
    },
    "engagement": {
        "reactionsCount": 5273,
        "commentsCount": 241,
        "repostsCount": null,
        "reactionBreakdown": null,
        "topReactionTypes": [
            "LIKE",
            "CELEBRATE",
            "LOVE"
        ]
    },
    "hashtags": [],
    "mentions": [],
    "media": [
        {
            "type": "VIDEO",
            "url": "https://dms.licdn.com/playlist/vid/v2/D5605AQEGTbLwnI83Fg/mp4-640p-30fp-crf28/B56aEh9ZGNIABk-/0/1791571105798?e=2147483647&v=beta&t=6JrwMMNQcRErvoTGvMWx8RrTtVFr4rsRE3AcPTj4iIo",
            "thumbnailUrl": "https://media.licdn.com/dms/image/v2/D5605AQEGTbLwnI83Fg/videocover-high/B56aEh9ZGNIABM-/0/1791571105315?e=2147483647&v=beta&t=o9-L0_x4GTPEhiSuF_BIiqVx7p3xV7wt975UjUgtLDg",
            "title": null,
            "description": null,
            "width": 1280,
            "height": 720,
            "durationSeconds": 10
        }
    ],
    "article": null,
    "externalLinks": [
        "https://lnkd.in/gNh5aW8b"
    ],
    "isRepost": false,
    "isQuotePost": false,
    "originalPost": null,
    "topComments": [],
    "dataQuality": "FULL",
    "positionInFeed": 1,
    "discoveredVia": "public_profile",
    "sourceProfileUrl": "https://www.linkedin.com/in/satyanadella/",
    "sourceProfileName": "Satya Nadella",
    "input": "https://www.linkedin.com/in/satyanadella/",
    "scrapedAt": "2026-10-10T12:22:24.460Z"
}
```

#### Engagement tab — sample record

```json
{
    "sourceProfileName": "Bill Gates",
    "postType": "POST",
    "publishedAt": "2026-10-07T23:11:00.403Z",
    "engagement.reactionsCount": 1355,
    "engagement.commentsCount": 223,
    "engagement.topReactionTypes": [
        "LIKE",
        "INSIGHTFUL",
        "LOVE"
    ],
    "hashtags": [],
    "postUrl": "https://www.linkedin.com/posts/williamhgates_preventing-contrails-those-white-lines-activity-7513737675791646720-T3Y1"
}
```

#### Run summary — sample

From the same 2-profile run. Each profile carries its own status, so one failed profile never fails the run:

```json
{
    "inputProfiles": 2,
    "successfulProfiles": 2,
    "failedProfiles": 0,
    "invalidProfiles": 0,
    "postsSaved": 17,
    "duplicatesSkipped": 0,
    "repostsSaved": 2,
    "quotePostsSaved": 4,
    "articlesSaved": 1,
    "postsFound": 17,
    "filteredOut": 0,
    "filteredByDate": 0,
    "filteredByEngagement": 0,
    "filteredByType": 0,
    "cappedByMaxPostsPerProfile": 0,
    "postPagesFetched": 17,
    "postPagesFailed": 0,
    "partialPosts": 0,
    "mediaAvailabilityRate": 88.24,
    "reactionTypesAvailabilityRate": 100,
    "extendedHistoryUsed": false,
    "chargedEvents": 17,
    "unchargedEvents": 0,
    "blockedRequests": 0,
    "rateLimitedRequests": 0,
    "retryCount": 0,
    "runtimeSeconds": 15,
    "scrapedAt": "2026-10-10T12:22:32.383Z",
    "profiles": [
        {
            "input": "https://www.linkedin.com/in/satyanadella/",
            "profileUrl": "https://www.linkedin.com/in/satyanadella/",
            "name": "Satya Nadella",
            "status": "SUCCESS",
            "postCardsFound": 9,
            "postsSaved": 9,
            "postPagesFailed": 0,
            "message": null
        },
        {
            "input": "williamhgates",
            "profileUrl": "https://www.linkedin.com/in/williamhgates/",
            "name": "Bill Gates",
            "status": "SUCCESS",
            "postCardsFound": 8,
            "postsSaved": 8,
            "postPagesFailed": 0,
            "message": null
        }
    ]
}
```

When some profiles fail with a retryable status, `RETRY_INPUT` holds the same input narrowed to just those profiles — run it again later.

#### Repost example

The row is credited to the profile that reposted. The content and its engagement belong to the original post (long fields shortened):

```json
{
    "rowType": "post",
    "postId": "urn:li:activity:7509282507121512449",
    "postUrl": "https://www.linkedin.com/posts/deirdre-bosa-05374518_the-first-db-live-interview-is-live-activity-7509282507121512449-RkPY",
    "postType": "REPOST",
    "text": null,
    "publishedAt": "2026-09-25T16:07:45.419Z",
    "publishedAtSource": "original_post",
    "author": {
        "name": "Satya Nadella",
        "publicIdentifier": "satyanadella"
    },
    "engagement": {
        "reactionsCount": null,
        "commentsCount": null,
        "repostsCount": null,
        "reactionBreakdown": null,
        "topReactionTypes": []
    },
    "isRepost": true,
    "isQuotePost": false,
    "originalPost": {
        "postId": "urn:li:activity:7509282507121512449",
        "postUrl": "https://www.linkedin.com/posts/deirdre-bosa-05374518_the-first-db-live-interview-is-live-activity-7509282507121512449-RkPY",
        "author": {
            "name": "Deirdre Bosa",
            "headline": null,
            "profileUrl": "https://www.linkedin.com/in/deirdre-bosa-05374518/",
            "publicIdentifier": "deirdre-bosa-05374518",
            "profileId": null,
            "profilePictureUrl": "https://media.licdn.com/dms/image/…",
            "type": "PERSON"
        },
        "text": "The first DB Live interview is.... live.\n\nI sat down with Satya Nadella at Microsoft this week around the launch of the new Copilot.\nThe takeaway: Microsoft is …",
        "publishedAt": "2026-09-25T16:07:45.419Z",
        "hashtags": [],
        "mentions": [
            {
                "name": "Microsoft",
                "type": "COMPANY",
                "url": "https://www.linkedin.com/company/microsoft/",
                "publicIdentifier": "microsoft",
                "id": null
            }
        ],
        "media": [
            {
                "type": "VIDEO",
                "url": "https://dms.licdn.com/playlist/vid/v2/D5605AQEIxwTaGN7vYg/mp…",
                "thumbnailUrl": "https://media.licdn.com/dms/image/…",
                "title": null,
                "description": null,
                "width": 1280,
                "height": 720,
                "durationSeconds": 30
            }
        ],
        "article": null,
        "externalLinks": [
            "https://lnkd.in/gzwJK6AC",
            "https://lnkd.in/gn_Gd_KW"
        ],
        "engagement": {
            "reactionsCount": 1204,
            "commentsCount": 129,
            "repostsCount": null,
            "reactionBreakdown": null,
            "topReactionTypes": [
                "LIKE",
                "CELEBRATE",
                "LOVE"
            ]
        }
    },
    "sourceProfileUrl": "https://www.linkedin.com/in/satyanadella/"
}
```

#### Quote post example

The profile's commentary stays in `text`; the quoted post goes in `originalPost` (shortened):

```json
{
    "postId": "urn:li:activity:7510854041028108288",
    "postType": "QUOTE_POST",
    "text": "Looking forward to seeing how recruiters use our new Hiring Assistant to help connect the right people with the right opportunities!",
    "engagement": {
        "reactionsCount": 918,
        "commentsCount": 147
    },
    "isQuotePost": true,
    "originalPost": {
        "author": {
            "name": "Dan Reid",
            "publicIdentifier": "reiddan",
            "type": "PERSON"
        },
        "text": "At LinkedIn, every day we talk to recruiters around the world, and what we know for certain is that hiring has become more complex. More applications, pressure …",
        "media": [
            {
                "type": "ARTICLE",
                "url": "https://www.linkedin.com/pulse/introducing-hiring-assistant-2-more-advanced-ffdyf",
                "title": "Introducing Hiring Assistant 2: More Advanced Reasoning, Memory and Personalization to Deliver Better Candidate Results",
                "publisher": "LinkedIn Talent Solutions"
            }
        ]
    }
}
```

#### Article example

A post publishing the profile's own LinkedIn article (shortened):

```json
{
    "postId": "urn:li:activity:7513980032831078400",
    "postType": "ARTICLE",
    "text": "Our opportunity is to reinvent systems of record for an agentic world, not just build new experiences on top of them, while giving every business an entirely ne …",
    "article": {
        "url": "https://www.linkedin.com/pulse/infinite-saas-factory-satya-nadella-1vwte",
        "title": "The Infinite SaaS Factory",
        "description": null,
        "thumbnailUrl": "https://media.licdn.com/dms/image/…",
        "publisher": "Satya Nadella"
    }
}
```

#### Error row (free)

```json
{
    "rowType": "error",
    "status": "INVALID_PROFILE",
    "message": "company / school pages are not supported (personal profiles only)",
    "retryable": false,
    "input": "https://www.linkedin.com/company/microsoft/",
    "sourceProfileUrl": null,
    "scrapedAt": "2026-10-10T11:38:53.554Z"
}
```

Statuses: `SUCCESS`, `INVALID_PROFILE`, `PROFILE_NOT_FOUND`, `PROFILE_UNAVAILABLE`, `NO_POSTS`, `RATE_LIMITED`, `BLOCKED`, `PARTIAL_RESULT`, `TEMPORARY_LINKEDIN_ERROR`, `PROVIDER_ERROR`. Error rows are pushed after the posts and are **never charged**.

### ❓ FAQ

**Which profile inputs are supported?** Personal profile URLs (`https://www.linkedin.com/in/<slug>/`, any country subdomain) and bare slugs (`satyanadella`). Tracking parameters and fragments are stripped. Duplicates are merged.

**Do I need a LinkedIn login or cookies?** No. Nothing you enter is a credential, and the actor never signs in.

**Can I scrape multiple profiles?** Yes — up to 500 per run, processed in parallel.

**How far back can posts be retrieved?** LinkedIn's public profile view shows each profile's **most recent posts — typically 8 to 10**. That is what this actor reliably returns today. When the actor's extended-history source is enabled, higher `maxPostsPerProfile` values reach further back; each row's `discoveredVia` says which source found it. The actor never invents posts it could not see.

**Are reposts included?** Yes (toggle `includeReposts`). They are typed `REPOST`, credited to the profile that reposted, with the original in `originalPost`. LinkedIn does not publish *when* a repost happened, so `publishedAt` is the original post's date (`publishedAtSource: "original_post"`).

**Are quote posts included?** Yes (toggle `includeQuotePosts`). Commentary stays in `text`, the quoted post in `originalPost`.

**Are reaction types included?** LinkedIn's public pages show the total reaction count and the top (up to three) reaction types, not per-type counts. You get `reactionsCount` and `topReactionTypes`; `reactionBreakdown` and `repostsCount` are `null` because they are not public — they are never estimated.

**Are images and videos included?** Yes — images, native video (direct MP4 URL, thumbnail, duration, size), document carousels and article/link cards. Media is linked, not downloaded.

**Are hashtags and mentions included?** Yes. Hashtags are returned without `#`; mentions include name, type (`PERSON` / `COMPANY`), URL and public identifier.

**Can I filter by date?** Yes — `postsNewerThan` / `postsOlderThan`, relative or absolute. Posts outside the window are skipped before their page is even fetched (the post ID carries its own timestamp), and are never charged.

**Can I filter by engagement?** Yes — `minReactions` / `minComments`. Filtered posts are never charged.

**Are comments included?** Only a preview: `includeTopComments` adds up to 5 top public comments per post. The total comment count is always included.

**How do I get all comments?** Full comment threads are out of scope here; use a dedicated LinkedIn post-comments scraper.

**How is pricing calculated?** Pay per result: one charge per **unique post saved to the dataset** after all filters. You are never charged for profile lookups, retries, duplicates, filtered-out posts, error rows or failed profiles. Your per-run spending limit is respected — the actor stops before exceeding it. See the **Pricing** tab for current rates (this README deliberately doesn't quote figures, since prices can change).

**Can I schedule it for monitoring?** Yes. Schedule daily or weekly with `postsNewerThan` set to the schedule interval (e.g. `"7 days"` for a weekly run) to collect just the new posts.

**Can I use it via API or MCP?** Yes — like any Apify Actor, through the Apify API, client libraries, integrations (Make, Zapier, n8n) and the Apify MCP server.

### 🚦 Proxy policy

Use **Apify Datacenter** proxy (the default) or **no proxy** for normal runs.

**Apify Residential proxy is not supported.** The actor fails at startup if `apifyProxyGroups` includes `RESIDENTIAL`. Reason: in pay-per-event actors, residential bandwidth is billed to the developer, not the run user, so a single bandwidth-heavy run could exceed the per-result revenue.

If you genuinely need residential routing, supply your own residential provider via the proxy editor's **Custom proxy URLs** field — that traffic goes through your provider, not Apify:

```
http://user:pass@proxy.iproyal.com:12321
http://user:pass@proxy.brightdata.com:22225
http://user:pass@proxy.oxylabs.io:7777
```

### ⚠️ Limitations

- Personal profiles only — no company-page posts and no keyword post search.
- Depth is limited to what LinkedIn shows publicly (see FAQ).
- Per-reaction-type counts and repost counts are not public and are returned as `null`.
- A repost's `publishedAt` is the original post's date.
- LinkedIn answers a non-existent profile and a blocked request with the same response, so such profiles are reported as `PROFILE_UNAVAILABLE` (or `BLOCKED` when nothing in the run could be read). Re-run `RETRY_INPUT` later.
- If a post page cannot be read after retries, the post is still delivered from the profile card with `dataQuality: "PARTIAL"` (ID, URL, date, counts).

### 🔗 Related actors

- **LinkedIn Profile Scraper** (`coregent/linkedin-profile-scraper`) — full profile data for the authors you track. Use it for profile enrichment; this actor returns lightweight author context only.

### ⚖️ Compliance & privacy

This is an unofficial tool and is not affiliated with, endorsed by, or connected to LinkedIn. It processes only publicly available professional content that LinkedIn shows to signed-out visitors. Public posts can still contain personal information: collect only what your use case needs, and you are responsible for lawful downstream processing (e.g. GDPR / CCPA). The actor does not collect credentials, harvest cookies, automate accounts, access private content or infer sensitive attributes.

# Actor input Schema

## `profiles` (type: `array`):

Personal LinkedIn profiles to collect posts from. Paste profile URLs (`https://www.linkedin.com/in/satyanadella/`) or just the public slug (`satyanadella`). Tracking parameters are stripped. Company pages, job URLs and post URLs are rejected with a free error row - this actor covers personal profiles only.

## `maxPostsPerProfile` (type: `integer`):

Maximum number of posts saved (and charged) per profile, newest first. LinkedIn's public profile view shows each profile's most recent posts - typically 8-10 - so higher values only return more when the extended-history source is enabled for this actor.

## `postsNewerThan` (type: `string`):

Keep only posts published after this point. Relative (`24 hours`, `7 days`, `2 weeks`, `3 months`) or a date (`2026-09-01`, `2026-09-01T00:00:00Z`). Leave empty for no limit. Note: a plain repost carries the original post's date, because LinkedIn does not publish when the repost happened.

## `postsOlderThan` (type: `string`):

Keep only posts published before this point. Same formats as above. Leave empty for no limit.

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

Skip posts with fewer reactions. For a plain repost, the original post's reactions are compared. 0 = no filter.

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

Skip posts with fewer comments. 0 = no filter.

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

Include plain reposts of other people's posts. The row is credited to the profile that reposted; the original post, its author, text, media and engagement are kept separately in `originalPost`.

## `includeQuotePosts` (type: `boolean`):

Include posts where the profile added their own commentary to someone else's post. The commentary stays in `text`; the quoted post goes in `originalPost`.

## `includeMedia` (type: `boolean`):

Return image, video, document and article/link-card details (URLs, thumbnails, titles). Media is linked, never downloaded.

## `includeReactionBreakdown` (type: `boolean`):

Return the most common reaction types LinkedIn shows for each post (e.g. LIKE, CELEBRATE, LOVE) in `engagement.topReactionTypes`. Per-type counts are not public, so `engagement.reactionBreakdown` is always null rather than estimated.

## `includeTopComments` (type: `boolean`):

Add up to 5 of the top public comments on each post (author, text, date, reactions). This is a preview only - it does not page through all comments.

## `proxyConfiguration` (type: `object`):

Apify Proxy configuration. Defaults to Apify Proxy (datacenter). Apify Residential proxy is not supported - supply your own residential provider via Custom proxy URLs if you need one.

## Actor input object example

```json
{
  "profiles": [
    "https://www.linkedin.com/in/satyanadella/",
    "williamhgates"
  ],
  "maxPostsPerProfile": 20,
  "postsNewerThan": "",
  "postsOlderThan": "",
  "minReactions": 0,
  "minComments": 0,
  "includeReposts": true,
  "includeQuotePosts": true,
  "includeMedia": true,
  "includeReactionBreakdown": true,
  "includeTopComments": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

One row per public post from the requested LinkedIn profiles: text, publish time, post type (post / repost / quote post / article), author, engagement, top reaction types, hashtags, mentions, media, article cards, original-post context and source-profile lineage.

## `engagement` (type: `string`):

Compact per-post engagement table.

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

Per-run counts, per-profile statuses and cost diagnostics.

# 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 = {
    "profiles": [
        "https://www.linkedin.com/in/satyanadella/",
        "williamhgates"
    ],
    "maxPostsPerProfile": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("coregent/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 = {
    "profiles": [
        "https://www.linkedin.com/in/satyanadella/",
        "williamhgates",
    ],
    "maxPostsPerProfile": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("coregent/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 '{
  "profiles": [
    "https://www.linkedin.com/in/satyanadella/",
    "williamhgates"
  ],
  "maxPostsPerProfile": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call coregent/linkedin-profile-posts-scraper --silent --output-dataset

```

## MCP server setup

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