# Linkedin Profile Posts Scraper ($1/1000 results) (`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)
- **Features:** Limited permissions
- **Stats:** 139 total users, 61 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: 5.00 out of 5 stars

## 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?

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 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 LinkedIn profile URLs, post URLs, or `https://lnkd.in/...` short links. When you provide a post URL, the Actor identifies its author and collects that author's profile posts.
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, post URLs, or `lnkd.in` short links. Post URLs identify the author whose posts will be scraped. 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.

Accepted inputs are HTTPS LinkedIn member profile URLs under `/in/`, post URLs under `/posts/` or `/feed/update/`, and `lnkd.in` short links. Short links are expanded first, following up to five redirects within LinkedIn. A post URL triggers a post-details lookup to identify the author's member profile ID, which is then used to scrape their posts with the same limits and pagination as a profile URL. Tracking parameters in post URLs are preserved.

The logs show short-link expansion, post-author matching, and the start of profile posts scraping. Links that cannot resolve to a supported profile or post, or posts without a member author profile ID, are reported as errors. The dataset's `requestedProfileUrl` retains the original profile URL, post URL, or short link you supplied; `requestedProfileId` contains the matched profile ID.

### 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?

This Actor uses **pay-per-event pricing** with a **$0.10 minimum total charge per run**.

| Charge | Free plan | Bronze-Diamond plans |
| --- | ---: | ---: |
| Actor start | $0.01 | $0.01 |
| Result saved to the default dataset | $0.01 per result | $0.001 per result |

The Actor start event is charged once per GB of memory, with at least one event per run. The final cost depends mainly on how many profile-post records are saved. Begin with one profile and a small `maxPosts` value, and enable **Parse all posts** only when you need the complete available history. Check the Actor's **Pricing** tab for the latest rates before starting a large run.

### 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.

### Other LinkedIn Scraping Tools

If you like this Actor, you might also find these LinkedIn tools useful:

- 👤 **[LinkedIn Profile Scraper](https://apify.com/api-ninja/linkedin-profile-scraper)**: Collect profile posts, reactions, comments, images, videos, documents, and events in one workflow.
- 💡 **[LinkedIn Post Reactions Scraper](https://apify.com/api-ninja/linkedin-post-reactions-scraper)**: Collect people who reacted to a post and their reaction types.
- 💼 **[LinkedIn Jobs Scraper](https://apify.com/api-ninja/linkedin-jobs-scraper)**: Search and extract structured LinkedIn job listings.
- 🏢 **[LinkedIn Company Posts Scraper](https://apify.com/api-ninja/linkedin-company-posts-scraper)**: Collect posts, media, authors, and engagement from company pages.
- 💬 **[LinkedIn Post Comments Scraper](https://apify.com/api-ninja/linkedin-post-comments-scraper)**: Extract comments and optional replies from public posts.
- 🔁 **[LinkedIn Post Reposters Scraper](https://apify.com/api-ninja/linkedin-post-reposters-scraper)**: Find people and companies that reposted a public post.
- 🔎 **[LinkedIn Post Search Scraper](https://apify.com/api-ninja/linkedin-post-search-scraper)**: Discover public posts by keyword and advanced filters.

### 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 public LinkedIn member profile under `/in/`, a post under `/posts/` or `/feed/update/`, or a short link that resolves to one of these. Post URLs must identify a member author; company-authored posts do not supply a supported member profile ID. Renamed, removed, restricted, or malformed profiles and posts 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/clhH3x9pKxtOrqdbH/openapi.json
