# Linkedin Profile Posts Scraper (`api-ninja/linkedin-profile-posts-scraper`) Actor

Scrape structured LinkedIn posts from one or more public profile URLs.

- **URL**: https://apify.com/api-ninja/linkedin-profile-posts-scraper.md
- **Developed by:** [API ninja](https://apify.com/api-ninja) (community)
- **Categories:**
- **Stats:** 11 total users, 11 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.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.
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

### What does LinkedIn Profile Posts Scraper do?

LinkedIn Profile Posts Scraper collects **posts from one or more LinkedIn profiles** and turns the deeply nested response into a clean, analysis-ready dataset. Add a list of [LinkedIn](https://www.linkedin.com/) profile URLs, choose how many posts you need, and start the Actor—no cookies, browser automation, or LinkedIn login input is required.

Use the normalized table for everyday work, or open the complete `rawData` object when you need every field returned by the source. Running on the [Apify platform](https://apify.com/) also gives you API access, scheduling, run monitoring, cloud datasets, webhooks, and integrations with tools such as Google Sheets, Make, and Zapier. Apify proxy rotation is available for Actors that need direct web access; this Actor uses an API-backed workflow and therefore does not expose proxy settings.

The Actor can extract:

- 👤 Author name, headline, LinkedIn URL, profile ID, and public identifier
- ✍️ Complete post text, post URL, visibility, and repost status
- 🕒 Publication timestamp, relative publication text, and edited status
- 👍 Reactions, reaction breakdown, comments, shares, views, and impressions when available
- 🖼️ Images and the highest-resolution media preview available
- 🎬 Video URLs, thumbnails, duration, and caption files when available
- 📄 Article and document titles, descriptions, links, covers, and page counts
- \#️⃣ Hashtags, outbound links, post URNs, and activity URNs
- 🧰 The original unmodified post response under `rawData`

### Why use LinkedIn Profile Posts Scraper?

Manually reviewing profile activity is slow, and raw LinkedIn post responses are difficult to use in spreadsheets or analytics tools. This Actor handles profile-ID resolution, pagination, retries, normalization, and dataset storage for you.

Common use cases include:

- **Content research:** understand which topics and formats a creator publishes.
- **Engagement analysis:** compare reactions, comments, and shares across posts or profiles.
- **Influencer discovery:** evaluate relevant authors before outreach or partnerships.
- **Competitive intelligence:** monitor the public content of founders, executives, and industry experts.
- **Lead enrichment:** add recent public activity to an existing research workflow.
- **Content inspiration:** identify recurring themes, hashtags, articles, videos, and high-performing formats.
- **Automation:** schedule recurring runs and send new datasets to your database, spreadsheet, webhook, or data warehouse.

### How to scrape LinkedIn profile posts

1. Open the Actor in Apify Console and select **Try for free** or **Start**.
2. In the **Input** tab, add one or more LinkedIn profile URLs. Use URLs in the form `https://www.linkedin.com/in/username`.
3. Set **Maximum posts per profile** to the number of posts you want from each profile.
4. To collect every post the source makes available, enable **Parse all posts**. This ignores the numeric limit and may make the run longer.
5. Click **Start** and wait for the run to finish.
6. Open the **Dataset** or **Output** tab. Use the clean LinkedIn profile posts view for the most useful columns, or inspect `rawData` in the All fields view.
7. Download the results or connect the dataset to another service.

The Actor processes profiles independently. If one URL cannot be resolved, it logs the error and continues with the remaining profiles. Failed requests and responses with an unexpected structure are retried up to three times with a one-second delay.

### Input

Configure these fields in the Actor's **Input** tab:

| Field         | Type             | Default             | Description                                                                                             |
| ------------- | ---------------- | ------------------- | ------------------------------------------------------------------------------------------------------- |
| `profileUrls` | Array of strings | Example profile URL | LinkedIn profile URLs to scrape. At least one URL is required. Empty and duplicate entries are removed. |
| `maxPosts`    | Integer          | `100`               | Maximum posts saved for each profile. Must be at least `1`. Ignored when `parseAll` is enabled.         |
| `parseAll`    | Boolean          | `false`             | Continues through all pages made available by the source.                                               |

#### LinkedIn profile scraper input example

```json
{
    "profileUrls": ["https://www.linkedin.com/in/jamesmcmaster", "https://www.linkedin.com/in/linasbeliunas"],
    "maxPosts": 50,
    "parseAll": false
}
```

The limit applies **per profile**, not to the whole run. With two profiles and `maxPosts` set to `50`, the Actor can save up to 100 posts in total.

### Output

Each dataset item represents one LinkedIn post. The default overview emphasizes the fields most useful for review and export, while `rawData` retains the complete source object for advanced use cases.

#### LinkedIn post dataset example

```json
{
    "requestedProfileUrl": "https://www.linkedin.com/in/linasbeliunas",
    "requestedProfileId": "urn:li:fsd_profile:ACoAABbscnUBlKacJbEN5USrYdfhVdH-ffYINJk",
    "authorName": "Linas Beliūnas",
    "authorHeadline": "Daily Intelligence on Finance & AI",
    "authorPublicIdentifier": "linasbeliunas",
    "authorUrl": "https://www.linkedin.com/in/linasbeliunas",
    "postText": "NVIDIA co-founder & CEO Jensen Huang's LinkedIn is a next-level flex...",
    "postUrl": "https://www.linkedin.com/posts/linasbeliunas_example-activity-7503894264981114880",
    "postType": "IMAGE",
    "publishedAt": "2026-09-10T19:16:48.385Z",
    "publishedText": "1 hour ago",
    "isEdited": false,
    "isRepost": false,
    "visibility": "PUBLIC",
    "reactions": 89,
    "reactionBreakdown": {
        "LIKE": 80,
        "EMPATHY": 7,
        "APPRECIATION": 1,
        "INTEREST": 1
    },
    "comments": 15,
    "shares": 2,
    "mediaPreviewUrl": "https://media.licdn.com/example-image.jpg",
    "imageUrls": ["https://media.licdn.com/example-image.jpg"],
    "hashtags": [],
    "contentLinks": [],
    "activityUrn": "urn:li:activity:7503894264981114880",
    "rawData": {
        "actor": {},
        "updateMetadata": {},
        "content": {},
        "commentary": {},
        "socialDetail": {}
    }
}
```

You can download the dataset in various formats such as **JSON, HTML, CSV, or Excel**. You can also access it through the [Apify API](https://docs.apify.com/api/v2), stream it into another Actor, or send it to an integration.

### LinkedIn profile posts data table

| Field                    | Description                                                                    |
| ------------------------ | ------------------------------------------------------------------------------ |
| `authorName`             | Display name of the post author.                                               |
| `authorHeadline`         | Author's professional headline or occupation.                                  |
| `authorUrl`              | Link to the author's LinkedIn profile.                                         |
| `authorPublicIdentifier` | Public LinkedIn profile identifier.                                            |
| `postText`               | Full available text of the post.                                               |
| `postUrl`                | Direct link to the LinkedIn post.                                              |
| `postType`               | Detected type: `TEXT`, `IMAGE`, `VIDEO`, `ARTICLE`, `DOCUMENT`, or `CAROUSEL`. |
| `publishedAt`            | Publication time derived from the LinkedIn activity URN.                       |
| `publishedText`          | Human-readable relative time returned by the source.                           |
| `reactions`              | Total reaction count when available.                                           |
| `reactionBreakdown`      | Counts grouped by LinkedIn reaction type.                                      |
| `comments`               | Total comment count when available.                                            |
| `shares`                 | Total share count when available.                                              |
| `mediaPreviewUrl`        | Best available image, video thumbnail, article image, or document cover.       |
| `mediaUrl`               | Direct media, article, or document URL when available.                         |
| `hashtags`               | Unique hashtags found in the post text.                                        |
| `contentLinks`           | Unique HTTP links found in the post text.                                      |
| `rawData`                | Complete unmodified post object returned by the source API.                    |

Some fields are content-specific. For example, video posts may include `videoUrl`, `videoDurationSeconds`, and `captionUrls`, while article posts may include `articleTitle`, `articleDescription`, and `articleUrl`.

### How much does it cost to scrape LinkedIn profile posts?

The exact run price is shown in the Actor's **Pricing** tab and depends on the pricing model active when you run it. If your Apify plan includes platform credits or a free usage allowance, eligible runs draw from that balance according to the current plan terms.

This Actor uses lightweight HTTP requests rather than a browser, which keeps compute usage low. For each profile, it normally makes one profile lookup request plus approximately one posts request per page of results. Your final cost therefore depends mainly on:

- The number of profile URLs
- The number of posts available for each profile
- Whether **Parse all posts** is enabled
- The current Actor and Apify plan pricing

For predictable test runs, begin with one profile and a small `maxPosts` value. Review the run cost in Apify Console before scaling to larger lists. Avoid enabling `parseAll` unless you genuinely need the complete available history.

### Tips and advanced options

#### Improve LinkedIn scraping reliability

- Use canonical profile URLs such as `https://www.linkedin.com/in/username`.
- Remove unrelated paths such as company pages, posts, jobs, and search-result URLs.
- Test a new workflow with a small post limit before enabling `parseAll`.
- Keep the normalized overview for spreadsheets and dashboards; use `rawData` only when you need advanced fields.
- Media URLs and captions may be temporary signed links. Download required files soon after the run instead of treating those URLs as permanent storage.

#### Schedule profile monitoring

Use [Apify schedules](https://docs.apify.com/platform/schedules) to run the Actor daily, weekly, or at another interval. A downstream task can compare activity URNs or post URLs to identify new posts and prevent duplicates in your own database.

#### Use the LinkedIn profile posts API

Every Actor can be started through the Apify API. You can pass the same JSON input programmatically, wait for the run to finish, and retrieve dataset items through the dataset API. See the [Apify API documentation](https://docs.apify.com/api/v2) and the **API** tab on the Actor page for ready-to-use request examples.

### FAQ, disclaimers, and support

#### Is it legal to scrape LinkedIn profile posts?

Scraping laws and platform rules vary by country and use case. This Actor is intended for collecting publicly accessible professional content. You are responsible for ensuring that your use complies with LinkedIn's terms, applicable laws, privacy rules, and data-protection requirements. Do not collect or use personal data without a valid legal basis.

#### Does the Actor require my LinkedIn login or cookies?

No LinkedIn credentials or session cookies are part of the Actor input. The Actor resolves profile identifiers and retrieves posts through its configured data provider.

#### Why are some fields empty?

LinkedIn posts have different structures. A text post has no image URL, an image post has no video duration, and engagement fields may not always be returned. The normalized dataset leaves unavailable optional fields empty while preserving the complete response in `rawData`.

#### Why did a profile fail?

Confirm that the URL points to a LinkedIn member profile under `/in/` and that the profile is publicly accessible. Renamed, removed, restricted, or malformed profiles may not resolve. The Actor retries temporary request and response-format failures, then continues with the next URL.

#### Does Parse all guarantee every post ever published?

No. It requests every page made available by the upstream source, but LinkedIn or the data provider may limit historical coverage. Deleted, private, restricted, or otherwise unavailable posts cannot be returned.

#### Can I combine this with company post scraping?

Yes. Use the creator's LinkedIn Company Posts Scraper for organization pages, then combine both Actor datasets using post URLs or activity URNs. This profile Actor is specifically designed for LinkedIn member URLs.

#### Where can I get help?

If you find a missing post type, unexpected response shape, or normalization issue, open the **Issues** tab on the Actor page and include a public example URL plus the relevant run ID. Do not post credentials or sensitive personal data. Custom scraping, enrichment, export, and integration solutions can also be built around this Actor—describe your required workflow in the Issues tab to discuss it.

# Actor input Schema

## `profileUrls` (type: `array`):

Add one public LinkedIn profile URL per row, for example https://www.linkedin.com/in/jamesmcmaster.

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

Maximum number of posts to save for each profile. This value is ignored when Parse all posts is enabled.

## `parseAll` (type: `boolean`):

Keep requesting pages for each profile until the API reports that no more posts are available.

## Actor input object example

```json
{
  "profileUrls": [
    "https://www.linkedin.com/in/jamesmcmaster"
  ],
  "maxPosts": 100,
  "parseAll": false
}
```

# Actor output Schema

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

Open the dataset to browse normalized post details or inspect the complete raw API response.

# 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 = {
    "profileUrls": [
        "https://www.linkedin.com/in/jamesmcmaster"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("api-ninja/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 = { "profileUrls": ["https://www.linkedin.com/in/jamesmcmaster"] }

# Run the Actor and wait for it to finish
run = client.actor("api-ninja/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 '{
  "profileUrls": [
    "https://www.linkedin.com/in/jamesmcmaster"
  ]
}' |
apify call api-ninja/linkedin-profile-posts-scraper --silent --output-dataset

```

## MCP server setup

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