# LinkedIn Posts Scraper \[$0.99💰 No Cookies] Profile + Companies (`memo23/linkedin-posts-scraper`) Actor

\[Only $0.99💰]  Track any LinkedIn creator or company's posts — no login, no cookies. Get text, author, reactions with types, comment counts and media, plus a unique 0–100 engagement-quality score and a monitoring mode that returns only new posts on a schedule. Profiles, companies, post URLs

- **URL**: https://apify.com/memo23/linkedin-posts-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Social media, Agents, AI
- **Stats:** 112 total users, 35 monthly users, 100.0% runs succeeded, 13 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.99 / 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.

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 (No Cookies)

![How It Works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-linkedin-posts.png)

Turn any LinkedIn **profile URL, company URL, post URL, or activity id** into clean, structured post rows — **no LinkedIn account, no cookie, no login**.
Each post comes back as one tidy row: post text, author (name + profile + headline + photo), reactions (with types), comment counts, media, post type — plus an **exact post date** you can filter by range and a **0–100 engagement-quality score** nobody else surfaces. Add **monitoring mode** to get only-new posts on a schedule. JSON or CSV out.

### Why Use This Scraper?

- ✅ Cookie-free — no LinkedIn login, no account, nothing to paste
- ✅ Clean structured rows — 18 fields per post, ready for a spreadsheet or a model
- ✅ Author included — name, profile URL, headline, and photo on every post
- ✅ Engagement — reaction count, reaction **types** (LIKE/EMPATHY/PRAISE/…), and comment count
- ✅ **Engagement-quality score** — a 0–100 score + tier (viral / high / solid / low / quiet) computed from reactions, comment ratio, and reaction depth — rank posts at a glance
- ✅ **Date-range filter** — `dateFrom` / `dateTo` keep only posts published in a window; dates are derived from the post id, so out-of-range posts are skipped *before* fetching (you don't pay for them)
- ✅ **Monitoring mode** — schedule it and get **only new posts** each run (de-dupes against what it already returned)
- ✅ **Company posts too** — paste a company URL for its recent posts
- ✅ Flexible input — profile URLs, company URLs, post URLs, or raw activity ids
- ✅ Cheap to run — built to use the lightest egress tier first

### Overview

The LinkedIn Posts Scraper is built for marketers, founders, researchers, and analysts who need a quick, structured pull of someone's recent LinkedIn posts without managing logins or accounts.

The output is **post-shaped rows** — one row per post.

- Paste a **post URL or activity id** → you get that post. **Works for any public post.**
- Paste a **profile URL** → you get that person's recent public posts — **but only for profiles that expose their activity publicly** (creators, influencers, and active public posters). Many regular profiles keep their post feed behind login; cookie-free, those return no posts, and you'd pass the individual post URLs instead.
- Paste a **company URL** → you get that company's ~12–15 most recent posts (a small share of company posts are partially login-gated and may come back with engagement but truncated text).

The author (name, profile, headline, photo) and engagement counts ride along on every row.

This is the **lightweight, cookie-free** option. It reads only LinkedIn's public surfaces, so it's honest about its limits (below) rather than pretending to do everything. If you need *unlimited* post history, full comment threads, company feeds, or keyword search, those require logged-in scraping — out of scope here by design.

### Supported Inputs

| Input type | Pattern | Example |
|---|---|---|
| **Keyword / phrase** | any topic, brand or competitor | `SaaS pricing strategy` |
| Profile URL | `https://www.linkedin.com/in/{slug}` | `https://www.linkedin.com/in/williamhgates` |
| Company URL | `https://www.linkedin.com/company/{slug}` | `https://www.linkedin.com/company/microsoft` |
| Post URL | `.../feed/update/urn:li:activity:{id}` or `.../posts/...-activity-{id}-{hash}` | `https://www.linkedin.com/feed/update/urn:li:activity:7469496437156925441` |
| Activity id / URN | `{id}` or `urn:li:activity:{id}` | `7469496437156925441` |

#### Copy-pasteable startUrls

```json
{
  "startUrls": [
    "https://www.linkedin.com/in/williamhgates",
    "https://www.linkedin.com/feed/update/urn:li:activity:7469496437156925441",
    "7468855929338310656"
  ]
}
```

#### Unsupported inputs

- ❌ Keyword / content search — requires a logged-in session
- ❌ Person *search* or connection data
- ❌ Any host outside `linkedin.com`

### Use Cases

| Audience | Use case |
|---|---|
| **Marketers / ghostwriters** | Pull a creator's recent posts to study format, hooks, and engagement |
| **Founders / sales** | Watch a prospect's or competitor's recent posts for timely outreach angles |
| **Researchers / analysts** | Bulk-export public posts from a list of profiles for content analysis |
| **Social teams** | Track a roster of voices and benchmark reactions/comments over time |

### How It Works

![How It Works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-linkedin-posts.png)

1. **Input** — give keywords, LinkedIn profile URLs, post URLs, or activity ids
2. **Search (keywords)** — each keyword runs as `site:linkedin.com/posts "your keyword"` against Google's index of public posts, which returns post ids. **LinkedIn is never contacted during this step**, so there is no session to flag
3. **List posts (profiles)** — for a profile, the actor reads its public page and collects up to ~15 recent post ids
4. **Fetch each post** — it pulls each post's public embed widget (a small ~24 KB page), cookie-free
5. **Structure** — author, text, engagement counts, media, and type are parsed into one clean row
6. **Output** — export as JSON or CSV

### Input Configuration

| Field | Type | Required | Notes |
|---|---|---|---|
| `searchQueries` | `array<string>` | one of | Keywords or phrases to find posts by, e.g. `SaaS pricing strategy`. Each is quoted and site-scoped for you; a query that already contains `site:` or a quote is passed to the search engine verbatim so you can use its operators |
| `maxPostsPerQuery` | `integer` | optional | Cap on posts discovered per keyword. Default `50` |
| `startUrls` | `array<string>` | one of | Profile URLs, post URLs, or activity ids/URNs. Scraped in addition to any keyword results |
| `maxPostsPerProfile` | `integer` | optional | Posts to pull per profile. LinkedIn's cookie-free limit is **15**, so higher values are capped. Default `15` |
| `maxItems` | `integer` | optional | Hard cap on total post rows. Default `1000` |
| `maxConcurrency` | `integer` | optional | Parallel requests. Default `3` |
| `maxRequestRetries` | `integer` | optional | Retries per request before giving up. Default `2` |
| `dateFrom` | `string` | optional | Keep only posts published **on/after** this date (YYYY-MM-DD). Derived from the post id, so filtering happens before fetch. |
| `dateTo` | `string` | optional | Keep only posts published **on/before** this date (YYYY-MM-DD, inclusive). |
| `onlyNewPosts` | `boolean` | optional | **Monitoring mode.** Remembers the posts it has already returned and, on each re-run, emits **only posts it hasn't seen before** — so a schedule pays only for genuinely new content. Default `false` |
| `dedupeStoreName` | `string` | optional | Monitoring only: the named storage holding the "already-seen" ids. Give each independent monitor its own name (e.g. `seen-microsoft`). Default `linkedin-posts-seen` |
| `sdoKey` | `string` (secret) | optional | Leave blank — built-in egress is used by default. Advanced: paste your own scrape.do token to bill unblocker usage to your own account |

#### Example input

Search by keyword:

```json
{
  "searchQueries": ["SaaS pricing strategy", "product led growth"],
  "maxPostsPerQuery": 50,
  "dateFrom": "2026-01-01"
}
```

Or scrape specific profiles:

```json
{
  "startUrls": ["https://www.linkedin.com/in/williamhgates"],
  "maxPostsPerProfile": 10,
  "maxConcurrency": 3
}
```

### Output Overview

Each dataset item is one post:

- **Identity** — `urn`, `activityId`, `postUrl`
- **Content** — `postText`, `postType` (article / video / image / text), `mediaUrl`, `articleUrl` (for published LinkedIn articles)
- **Author** — `author.name`, `author.profileUrl`, `author.headline`, `author.image`, `author.isInfluencer`
- **Engagement** — `reactions`, `comments` (counts), `reactionTypes` (e.g. `["LIKE","EMPATHY","PRAISE"]`)
- **Engagement score** — `engagement.score` (0–100), `engagement.tier` (`viral`/`high`/`solid`/`low`/`quiet`), `engagement.total`, `engagement.commentRatio`, `engagement.reactionDepth`
- **Meta** — `postedAt` (exact ISO date, derived from the activity id), `postedRelative` (e.g. "1d", "3w"), `sourceProfile`, `scrapedAt`

### Output Sample

#### Profile start (`linkedin.com/in/williamhgates`)

```jsonc
{
  "urn": "urn:li:activity:7469496437156925441",
  "activityId": "7469496437156925441",
  "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:7469496437156925441",
  "postText": "Alzheimer's research has historically faced problems with scale: not enough people diagnosed early enough…",
  "postType": "article",
  "author": {
    "name": "Bill Gates",
    "profileUrl": "https://www.linkedin.com/in/williamhgates",
    "headline": "Chair, Gates Foundation and Founder, Breakthrough Energy"
  },
  "reactions": 5332,
  "comments": 692,
  "reactionTypes": ["LIKE", "EMPATHY", "PRAISE", "INTEREST"],
  "engagement": {
    "total": 6024,
    "commentRatio": 0.11,
    "reactionDepth": 3,
    "score": 71,
    "tier": "high"
  },
  "mediaUrl": "https://dms.licdn.com/playlist/vid/v2/%E2%80%A6",
  "postedRelative": "1d",
  "postedAt": "2026-06-08T14:20:11.000Z",
  "sourceProfile": "https://www.linkedin.com/in/williamhgates",
  "scrapedAt": "2026-06-09T16:32:00.000Z"
}
```

### Key Output Fields

#### Post

- `urn`, `activityId`, `postUrl`, `postText`, `postType`, `mediaUrl`, `postedAt`, `postedRelative`

#### Author

- `author.name`, `author.profileUrl`, `author.headline`

#### Engagement

- `reactions`, `comments` (counts), `reactionTypes`
- `engagement.score` (0–100), `engagement.tier` (viral / high / solid / low / quiet), plus the raw `total`, `commentRatio`, and `reactionDepth` inputs

### FAQ

#### Do I need a LinkedIn account or cookie?

No. This actor reads only LinkedIn's public surfaces, so you provide nothing but a keyword or a URL.

#### Why did a profile return 0 posts?

Cookie-free, LinkedIn only exposes a profile's post feed publicly for **creator / influencer-style profiles** (and people who've made their activity public). Many regular profiles keep their feed behind login, so they come back empty. **Post URLs and activity ids always work for any public post** — so for those profiles, pass the individual post links directly.

#### How many posts do I get per profile?

For profiles that do expose activity, up to about **15 most-recent posts** — LinkedIn's hard cap for cookie-free access (no deeper pagination without login).

#### Do I get the comment text?

No — you get the **comment count**, not the comment bodies. Comment threads and reaction lists are only available to logged-in sessions, which this actor deliberately doesn't use.

#### Can I scrape company pages?

Yes — paste a company URL (`linkedin.com/company/{name}`) and you get its ~12–15 most recent posts. A small share of company posts are partially login-gated; those rows come back with engagement counts but truncated text.

#### Can I search by keyword?

Yes — put your terms in `searchQueries`. LinkedIn's own content search is login-walled, so the actor discovers posts through Google's index of public `linkedin.com/posts/…` pages instead, then fetches each match through the normal pipeline. That means your rows carry the **full post text, engagement counts, media and post type**, not just a search snippet, and LinkedIn is never contacted during discovery.

Two things follow from using an index rather than LinkedIn's live search: reach is limited to posts Google has crawled (a post published today may take days to appear), and a broad keyword typically yields 40–120 distinct posts before results start repeating, at which point the crawl stops on its own. Pair it with `dateFrom` / `dateTo` to keep only a date range — that filter runs before any post is fetched, so out-of-range matches cost nothing.

#### Is the posted date exact?

Yes. `postedAt` is an **exact ISO timestamp derived from the post's activity id** — LinkedIn encodes the creation time in the id itself, so you get a precise date cookie-free. `postedRelative` ("1d", "3w") is included too, as LinkedIn displays it. Use **`dateFrom` / `dateTo`** to keep only posts published in a date range — they're filtered before fetching, so out-of-range posts cost nothing.

#### What if a profile or post is private?

Only publicly visible posts are returned. Private/connections-only content is out of scope.

#### What is the engagement score?

A transparent **0–100 quality score** computed per post from public signals only — no extra requests, no guessing. It blends three things: **volume** (reactions + comments, log-scaled so a 5k-reaction post isn't 100× a 50-reaction one), **comment ratio** (comments are higher-effort than reactions, so a real conversation scores higher), and **reaction depth** (how many reaction *types* beyond a plain LIKE — praise/empathy/insightful/funny/support signal stronger sentiment). The score maps to a `tier`: `viral` (80+), `high` (60+), `solid` (40+), `low` (20+), `quiet` (<20). The raw inputs (`total`, `commentRatio`, `reactionDepth`) ride along so you can re-rank with your own weights.

#### How do I monitor a profile or company for new posts?

Turn on **`onlyNewPosts`** and put the actor on an **Apify Schedule** (e.g. every 6 hours). On each run it remembers the post ids it already returned (in a named storage) and emits **only posts it hasn't seen before** — so your dataset and your bill only grow with genuinely new content. Running several independent monitors? Give each its own `dedupeStoreName` (e.g. `seen-microsoft`, `seen-billgates`) so they don't share state. A monitoring run that finds nothing new simply returns 0 rows — that's the expected "all quiet" result, not an error.

### Support

- Issues or feature requests: the [Issues tab](https://apify.com/memo23/linkedin-posts-scraper/issues) of this actor.
- Custom work / questions: <muhamed.didovic@gmail.com> · all actors at [apify.com/memo23](https://apify.com/memo23).

### Additional Services

Need deeper LinkedIn data (full comments, reactions lists, company feeds, search)? That requires a logged-in approach — email <muhamed.didovic@gmail.com> to discuss a custom build.

### Explore More Scrapers

- [**Crunchbase Company Scraper**](https://apify.com/memo23/crunchbase-scraper) — clean structured company + funding data
- [**More by memo23**](https://apify.com/memo23) — directory, jobs, real-estate, and social scrapers

***

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/linkedin-posts-scraper`).

**Purpose:** Turn LinkedIn profile, company, or post URLs (or raw activity ids) into structured post rows — cookie-free, no login — with author, engagement counts, an exact post date, and a 0–100 engagement-quality score.

**Minimal input:**

```json
{
  "startUrls": ["https://www.linkedin.com/in/williamhgates"],
  "maxPostsPerProfile": 10,
  "maxItems": 20
}
```

**Output:** one row per post with urn, activityId, postUrl, postText, postType, mediaUrl, author {name, profileUrl, headline, image, isInfluencer}, reactions, comments (counts), reactionTypes\[], engagement {score, tier, total, commentRatio, reactionDepth}, postedAt (exact ISO), postedRelative, sourceProfile, scrapedAt.

**Behaviors an agent should know:**

- Set `maxItems` and `maxPostsPerProfile` — cookie-free access is hard-capped at ~15 posts per profile.
- Profile URLs return posts only for creator/influencer profiles that expose activity publicly; regular profiles return 0 posts — pass individual post URLs or activity ids, which work for any public post. Company URLs return ~12–15 recent posts.
- `dateFrom`/`dateTo` (YYYY-MM-DD) filter by post date, derived from the activity id, so out-of-range posts are skipped before fetching and cost nothing.
- `onlyNewPosts` monitoring mode emits only unseen posts across re-runs, deduping against a named store (`dedupeStoreName`); pair with an Apify Schedule.
- Comment bodies, reaction lists, and keyword search are not available cookie-free.
- Pay-per-event billing — see the Pricing tab on the actor page.

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by LinkedIn Corporation or Microsoft Corporation. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available LinkedIn pages — no authenticated endpoints, no login, and no content behind LinkedIn's login wall. Users are responsible for ensuring their use complies with LinkedIn's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization. Scrape responsibly and respect the rights of the individuals whose public posts you collect.

***

### SEO Keywords

linkedin posts scraper, scrape linkedin posts, linkedin post scraper, linkedin scraper no cookies, cookie-free linkedin scraper, linkedin profile posts, linkedin activity scraper, linkedin post data, linkedin content scraper, linkedin engagement data, linkedin engagement score, linkedin post monitoring, linkedin new posts alert, linkedin post tracker, social media scraper, linkedin api alternative, linkedin posts export, linkedin author data, linkedin post extractor, Apify linkedin, linkedin marketing data, creator content analysis, linkedin posts json, linkedin posts csv

# Actor input Schema

## `searchQueries` (type: `array`):

One keyword or phrase per line, e.g. `SaaS pricing strategy`, `lab grown diamond`. Each is quoted and site-scoped for you. If you type a query that already contains `site:` or a quote, it is sent to the search engine exactly as written so you can use its operators (`OR`, `-`, quoted phrases) yourself.

## `maxPostsPerQuery` (type: `integer`):

Cap on how many posts each keyword may discover. Search results thin out after a few pages — a broad keyword typically yields 40–120 distinct posts before the engine starts repeating itself, and the crawl stops on its own at that point.

## `startUrls` (type: `array`):

Paste any combination of:

- **Post URL** — `https://www.linkedin.com/feed/update/urn:li:activity:7469496437156925441` or a `.../posts/...-activity-…` link (works for ANY public post)
- **Activity id / URN** — `7469496437156925441` or `urn:li:activity:7469496437156925441`
- **Profile URL** — `https://www.linkedin.com/in/williamhgates` (up to ~15 recent posts — only for profiles that expose activity publicly: creators, influencers, public posters. Regular profiles keep their feed behind login and return no posts — use the post URLs instead.)
- **Company URL** — `https://www.linkedin.com/company/microsoft` (up to ~12-15 recent company posts)

Cookie-free: no LinkedIn account needed. Keyword search is not supported. Optional when you are searching by keyword above — anything listed here is scraped in addition to the search results.

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

How many recent posts to pull from each profile. LinkedIn's cookie-free limit is 15, so values above 15 are capped.

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

Hard cap on total post rows emitted across the whole run.

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

Parallel unblocker requests. Keep low (2–4) — the premium pool is metered per success.

## `maxRequestRetries` (type: `integer`):

Retries on transient unblocker errors before giving up.

## `dateFrom` (type: `string`):

Only keep posts published on or after this date (YYYY-MM-DD). Post dates are derived from the activity id, so out-of-range posts are skipped before fetching — you don't pay for them. Leave blank for no lower bound.

## `dateTo` (type: `string`):

Only keep posts published on or before this date (YYYY-MM-DD, inclusive). Leave blank for no upper bound.

## `onlyNewPosts` (type: `boolean`):

Turn this ON for a scheduled monitor. The actor remembers the posts it has already emitted (in a named storage) and, on each re-run, returns ONLY posts it hasn't seen before — so you pay only for genuinely new content. Pair it with an Apify Schedule (e.g. every 6h) to track a profile's or company's latest posts. Leave OFF for a normal one-off scrape.

## `dedupeStoreName` (type: `string`):

Advanced (monitoring mode only): the named key-value store that holds the 'already-seen' post ids. Give each independent monitor its own name so they don't share state — e.g. `seen-microsoft`, `seen-billgates`. Leave blank to use the default shared store.

## `sdoKey` (type: `string`):

Leave blank — the actor uses its built-in unblocker by default. Advanced: paste your own scrape.do API token to bill unblocker requests to your own account.

## Actor input object example

```json
{
  "searchQueries": [
    "AI agents"
  ],
  "maxPostsPerQuery": 50,
  "startUrls": [
    "https://www.linkedin.com/in/williamhgates",
    "https://www.linkedin.com/company/microsoft"
  ],
  "maxPostsPerProfile": 15,
  "maxItems": 1000,
  "maxConcurrency": 3,
  "maxRequestRetries": 2,
  "onlyNewPosts": false,
  "dedupeStoreName": "linkedin-posts-seen"
}
```

# Actor output Schema

## `posts` (type: `string`):

One row per post with full text, author name/headline/profile, reaction and comment counts, an engagement score, media URL and an exact publish timestamp.

# 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 = {
    "searchQueries": [
        "AI agents"
    ],
    "startUrls": [
        "https://www.linkedin.com/in/williamhgates",
        "https://www.linkedin.com/company/microsoft"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/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 = {
    "searchQueries": ["AI agents"],
    "startUrls": [
        "https://www.linkedin.com/in/williamhgates",
        "https://www.linkedin.com/company/microsoft",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/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 '{
  "searchQueries": [
    "AI agents"
  ],
  "startUrls": [
    "https://www.linkedin.com/in/williamhgates",
    "https://www.linkedin.com/company/microsoft"
  ]
}' |
apify call memo23/linkedin-posts-scraper --silent --output-dataset

```

## MCP server setup

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