# LinkedIn Company Posts Scraper (`fetch_cat/linkedin-company-posts-scraper`) Actor

Monitor public LinkedIn company posts, media, timestamps, and engagement metadata without login.

- **URL**: https://apify.com/fetch_cat/linkedin-company-posts-scraper.md
- **Developed by:** [Fetch Cat](https://apify.com/fetch_cat) (community)
- **Categories:** Social media, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 4 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.48 / 1,000 post saveds

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

Monitor public LinkedIn company and showcase-page posts without supplying an account or cookies. Export stable activity IDs, canonical post URLs, company attribution, post text, timestamps, media, and engagement counts LinkedIn exposes publicly.

### Quick start

Supply one known public company URL, a small per-company cap and the intended publication cutoff. Start the Actor, then inspect its dataset and run summary:

```json
{
  "companyUrls": ["https://www.linkedin.com/company/linkedin/"],
  "maxPostsPerCompany": 5,
  "postedAfter": "2026-01-01T00:00:00.000Z"
}
```

Prefer a video guide? This short Apify walkthrough shows you how to set up and run an Actor. It uses a different Actor, but the setup steps are the same.

https://youtu.be/1OW8gOqlZbY?t=25

### What you get

One verified public company-post row with its stable activity ID, canonical post link, exact company attribution, text and available media or engagement values. Publication dates are derived from activity IDs. Public comment counts are included when available. Reaction and repost counts are not currently collected. This is index-based discovery with first-party source verification rather than a complete company activity archive.

### Who is it for?

- **B2B marketers** reviewing public company announcements and campaign posts.
- **Competitive-intelligence analysts** comparing their own known-company exports.
- **Social-listening agencies** keeping source-linked post evidence for client reports.
- **Data teams** maintaining downstream post-ID joins and repeatable engagement snapshots.

### How you can use the data

- **Review one company's public announcements.** Use the existing LinkedIn company URL with five posts. Keep postId, postUrl and companyUrl together before opening the source. The candidate must be verified against LinkedIn's public embed and exact company attribution before saving.
- **Compare a known three-company sample.** Use the preserved LinkedIn/Microsoft/Adobe recipe with three posts per company. Keep company relationships in your report and allow for public search-index gaps rather than treating absent posts as no activity.
- **Apply a publication cutoff deliberately.** Use postedAfter for a bounded recurring export and deduplicate post IDs in your own destination. A future cutoff can complete with explicit empty results. This is not a built-in history database or complete search of every company post.
- **Refresh your own engagement observations.** Retain collection times with whatever public reaction, comment or repost counts are exposed. Missing values are omitted rather than zero, and counts can change between snapshots. Any announcement detection, comparison or alert logic is downstream work.

### Input settings

| Field | Description | Default |
|---|---|---:|
| `companyUrls` | 1–100 public `linkedin.com/company/...` or `linkedin.com/showcase/...` URLs, at most 2048 characters each | required |
| `maxPostsPerCompany` | Maximum rows saved for each company, 1–1000 | `20` |
| `postedAfter` | Optional ISO date/time lower bound for incremental exports | none |

Personal profiles, private groups, messages, and authenticated-only feeds are not supported. Invalid or non-company URLs fail with a clear validation error.

Existing input recipes:

#### Monitor one company's latest announcements

```json
{
  "companyUrls": ["https://www.linkedin.com/company/linkedin/"],
  "maxPostsPerCompany": 5
}
```

#### Compare recent campaigns from three companies

```json
{
  "companyUrls": [
    "https://www.linkedin.com/company/linkedin/",
    "https://www.linkedin.com/company/microsoft/",
    "https://www.linkedin.com/company/adobe/"
  ],
  "maxPostsPerCompany": 3
}
```

#### Refresh an incremental engagement watch

```json
{
  "companyUrls": ["https://www.linkedin.com/company/linkedin/"],
  "maxPostsPerCompany": 10,
  "postedAfter": "2026-09-01T00:00:00.000Z"
}
```

Use these inputs in the Actor UI, API, schedules, webhooks, integrations, or MCP-compatible Apify tools.

### Output data

Each row contains `postId`, `postUrl`, `companyName`, `companyUrl`, `text`, `media`, and `scrapedAt`. `postedAt` is derived from the activity ID, and `commentCount` appears when available. The schema retains optional `reactionCount` and `repostCount` fields, but the current collection route does not populate them. `postId` is the stable LinkedIn activity ID and is suitable for deduplication across scheduled runs.

The `RUN_SUMMARY` key-value-store record reports requested companies, saved rows, per-company failures, and a `complete`, `partial`, `empty`, `failed`, or `budget-limited` status. A future `postedAfter` can therefore complete successfully with an explicit empty result. The summary also reports decompressed download bytes and consumed request allowance (conservative retry/redirect reservations, not a measured request count).

#### Example output

Historical record shape from the prior documentation, not a claim that the post passes every date-filter recipe above:

```json
{
  "postId": "7247998907798978560",
  "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:7247998907798978560",
  "companyName": "LinkedIn",
  "companyUrl": "https://www.linkedin.com/company/linkedin/",
  "text": "No is a complete sentence.",
  "postedAt": "2024-09-27T17:00:00.000Z",
  "commentCount": 359,
  "media": [{ "type": "image", "url": "https://media.licdn.com/dms/image/..." }],
  "scrapedAt": "2026-09-30T00:00:00.000Z"
}
```

Unavailable public engagement values are omitted rather than guessed.

#### Download your results

Open your run's dataset, choose **Export** and select JSON, CSV or Excel. JSON keeps nested fields together. CSV and Excel are useful when you want to review the records in a spreadsheet.

See [Apify's download and export guide](https://docs.apify.com/storage/dataset#apify-console) for the available formats and field options.

### Pricing

The `start` event charges once after input validation, and `post` charges for each saved durable company-post row. Each post charge follows a saved row. Collection stops when the remaining post-event budget cannot cover another row. Company failures are summarized rather than emitted as fabricated post rows.

Begin with a small company list and per-company cap. See the [live Pricing tab](https://apify.com/fetch_cat/linkedin-company-posts-scraper/pricing) for current rates and plan discounts.

### Tips for best results

- **Supply canonical public company or showcase URLs.** Activity-page suffixes are normalized, while personal or non-company targets fail validation.
- **Start with a small per-company cap.** Public discovery coverage does not guarantee the requested count.
- **Keep activity IDs and company attribution in your destination.** They support your own deduplication across scheduled exports.
- **Use source dates and collection times for different purposes.** Engagement can change after the post's publication date.
- **Read company failures in RUN_SUMMARY before interpreting gaps.** Public index or LinkedIn rate limits can prevent discovery or verification.

### Limits and caveats

Only anonymous public company and showcase posts are supported. No account or cookies are supplied, and personal profiles, private groups, messages and authenticated-only feeds are outside scope. Invalid targets and invalid cutoff dates fail validation.

Discovery depends on public search-index coverage. Posts not exposed there can be absent, and every candidate must pass anonymous first-party verification with exact company attribution. Rate limits or source failures are reported rather than replaced with invented posts. A capped export does not guarantee a full company history or the latest available post.

RUN_SUMMARY distinguishes complete, partial, empty, failed and budget-limited collection. A future cutoff can succeed empty. Blocked or unverified posts, unrecognized index responses, and incomplete decoder results are recorded as failures rather than confirmed no matches. Useful rows can remain in mixed results, but essential storage or billing failures fail the run. Same-run restarts are refused after extraction starts to avoid duplicate output or charging. Existing rows and summaries are preserved. Start a new run for a fresh collection.

Index, decoder and post requests share a four-minute deadline from the original run start, even if a longer platform timeout is selected. The shared allowance is 1000 requests including reserved retries/redirects, 1000 discovered links per company, 2 MiB per decompressed response and 50 MiB downloaded per run. Individual requests have a 30-second timeout and at most three redirects. Reaching a processing safeguard fails the run with a truthful summary. Any rows already saved remain accessible. The default and maximum supported memory allocation is 512 MiB. These safety ceilings do not guarantee complete company-history coverage.

The Actor does not automatically compare earlier datasets or configure notifications. Use your own post-ID joins, Apify schedules and integrations for monitoring or reporting.

### Automation and integrations

#### Save your settings for next time

Once you have an input that works for you, [save it as an Apify task](https://docs.apify.com/actors/running/tasks). This keeps your settings together so you can use them again without filling in the form from scratch.

#### Run on a schedule

Need fresh results regularly? You can [schedule the Actor or a saved task](https://docs.apify.com/actors/running/schedules) to run at a time that suits you.

Each scheduled run collects the data again. If you want to compare results or highlight changes, add that step in your own workflow.

#### Send results to your other tools

Use **n8n, Make or Zapier** to connect this scraper to the rest of your workflow. For example, you could pass its results to an AI assistant or add records to a spreadsheet. Follow the [Apify integration guides](https://docs.apify.com/integrations) for your chosen tool.

For a custom connection, an [Apify webhook](https://docs.apify.com/integrations/webhooks) can notify your app when a run finishes or fails. Your app can then fetch the results or handle the failure.

### API usage

The Node.js and Python examples wait for completion before reading saved dataset rows. The original cURL example starts an asynchronous run. Wait for completion and retrieve its defaultDatasetId to read results.

For setup instructions, see Apify's [JavaScript client guide](https://docs.apify.com/api/client/js), [Python client guide](https://docs.apify.com/api/client/python) and [Actor runs API reference](https://docs.apify.com/api/v2/acts-runs-post).

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/fetch_cat~linkedin-company-posts-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"companyUrls":["https://www.linkedin.com/company/linkedin/"],"maxPostsPerCompany":5}'
```

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/linkedin-company-posts-scraper').call({
  companyUrls: ['https://www.linkedin.com/company/linkedin/'],
  maxPostsPerCompany: 5
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('fetch_cat/linkedin-company-posts-scraper').call(run_input={
    'companyUrls': ['https://www.linkedin.com/company/linkedin/'],
    'maxPostsPerCompany': 5,
})
print(client.dataset(run['defaultDatasetId']).list_items().items)
```

### MCP and AI agents

You can ask your AI assistant to collect data with **LinkedIn Company Posts Scraper** and help you work with the results. The scraper returns the data, and your assistant can then summarize it, compare records or prepare notes.

Connect your assistant through the [Apify MCP server](https://mcp.apify.com/). MCP gives your assistant a way to find this scraper, run it and read the results. Follow the [official setup and sign-in guide](https://docs.apify.com/mcp) for your app.

#### Easier setup with an Apify plugin

If you use a supported coding assistant, the [official Apify plugin](https://docs.apify.com/agents/plugins) can set up the connection for you. It connects your assistant to Apify and includes instructions for common tasks. Follow the guide for your particular app.

#### Use Apify AI in Console

Prefer to keep everything in Apify? Open [Apify AI in Console](https://docs.apify.com/account/apify-ai) and ask it to find Fetch Cat's **LinkedIn Company Posts Scraper**. You can describe the data you want and ask questions about the results.

Apify AI is currently in beta. It asks for confirmation before starting an Actor, and normal run charges apply.

#### Choose your assistant

- **Claude and Claude Code (Anthropic):** [Apify setup guide](https://docs.apify.com/integrations/claude).
- **ChatGPT and Codex (OpenAI):** [Apify setup guides](https://docs.apify.com/integrations/openai).
- **Grok Bot (xAI):** [Apify plugin guide](https://docs.apify.com/integrations/grok-bot).
- **Gemini CLI (Google):** [MCP server setup guide](https://geminicli.com/docs/tools/mcp-server/). Use the server URL below with the HTTP configuration supported by Gemini CLI.

#### Connect just this scraper

To keep your setup focused on this scraper, add this server configuration to a compatible MCP client:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=fetch_cat/linkedin-company-posts-scraper"
    }
  }
}
```

Sign in to Apify when your client asks. If your client uses a Bearer token instead, follow its setup guide and keep the token in its secure configuration. Configuration formats vary by app, so use the linked guide if your client needs a different format.

#### Use Apify's general server

Already connected to the general Apify MCP server at `https://mcp.apify.com`? You can use it to find this scraper without adding another server. Ask your assistant to use **LinkedIn Company Posts Scraper** by Fetch Cat, or give it the identifier `fetch_cat/linkedin-company-posts-scraper`.

Your assistant can check the available settings and retrieve the results from the returned run. If the run is still working, it should follow that run rather than start it again. Both connection options use Apify's hosted service.

#### Example requests

- “Use Fetch Cat’s LinkedIn Company Posts Scraper to collect up to 3 public posts for https://www.linkedin.com/company/linkedin/. Keep stable post IDs, exact company attribution and available text and engagement fields without claiming a complete archive.”
- “Collect up to 2 public posts per company for LinkedIn, Microsoft and Adobe using the company URLs in the preserved input recipe. Keep source post links and company attribution, and check company failures before comparing campaign activity.”
- “Retrieve up to 3 public LinkedIn-company posts from https://www.linkedin.com/company/linkedin/ published after 1 September 2026 at 00:00 UTC. Keep post IDs and collection times for my own later comparison and explain empty or partial outcomes from RUN_SUMMARY.”

Normal Apify charges apply. Check the [live Pricing tab](https://apify.com/fetch_cat/linkedin-company-posts-scraper/pricing) before asking your assistant to run a larger batch.

### Pay with x402

If your AI agent has a funded wallet, it can pay for Apify usage through [x402](https://docs.apify.com/integrations/x402). This experimental option lets an agent use Apify without a conventional account.

[Apify AGI](https://agi.apify.com/) provides a prepaid API token with a spending cap after payment. Your agent can use that token to run this scraper through the Apify API or an authenticated MCP connection.

Some MCP setups also support paying for each request directly. That is a different payment option, so check the official guide for its availability.

Follow the official guide for wallet setup, supported payment options and current terms. Apify handles the payments. Keep wallet keys and payment tokens in your agent's secure configuration.

#### Other ways for agents to pay

Apify also supports **MPP** for prepaid access through AGI and **Skyfire** for eligible Actors. If your agent already uses one of these, see the [agentic payment guide](https://docs.apify.com/agents/payments) to choose the right setup.

### FAQ

#### Does this require a LinkedIn account or cookies?

No. It uses anonymous public company and showcase content, without authenticated feeds or private data.

#### Does it collect every company post?

No. Discovery depends on public search-index coverage and first-party verification. Limits are ceilings rather than archive completeness.

#### How should I compare repeated exports?

Keep postId and company attribution with collection times, then compare saved files in your own workflow. Public engagement counts can change and missing values are not zero.

#### Can a date-filtered search return no rows?

Yes. A future postedAfter cutoff can complete empty. Read RUN_SUMMARY for company failures rather than interpreting empty output as confirmed inactivity.

### Related Actors

- [LinkedIn Company Profiles Scraper](https://apify.com/fetch_cat/linkedin-company-profiles-scraper) — export public company profile details
- [LinkedIn Posts Scraper](https://apify.com/fetch_cat/linkedin-posts-scraper) — refresh known post URLs or activity URNs
- [LinkedIn Post Comments Scraper](https://apify.com/fetch_cat/linkedin-post-comments-scraper) — collect comments from public posts
- [LinkedIn Ad Library Scraper](https://apify.com/fetch_cat/linkedin-ad-library-scraper) — research public LinkedIn ads
- [LinkedIn Jobs Scraper](https://apify.com/fetch_cat/linkedin-jobs-scraper) — export public job listings

### Support and feedback

For custom additions or integrations, email <hello@fetchcat.dev>.

Found an error or have a feature request? [Open an issue](https://apify.com/fetch_cat/linkedin-company-posts-scraper/issues) with the run URL, a non-sensitive input example and what you expected.

Need help sharing it? See [Apify’s guide to sharing a run when reporting an issue](https://docs.apify.com/account/collaboration/general-resource-access#automatically-sharing-runs-via-actor-issues). Sharing a run can give the developer access to its input, logs and results, so use a run that contains no sensitive data. Please leave out API tokens, passwords, cookies, private documents and personal data. Use a public sample URL or a redacted example instead.

Tried this scraper? We'd love to hear how it worked for you. [Leave a review](https://apify.com/fetch_cat/linkedin-company-posts-scraper/reviews) to help others choose the right tool and help us improve it. Your feedback means a lot to us.

Made with care for curious people, AI agents and the possibilities in data. ♥

# Changelog

This Actor's version history is a separate document: https://apify.com/fetch_cat/linkedin-company-posts-scraper/changelog.md

# Actor input Schema

## `companyUrls` (type: `array`):

Provide 1–100 public LinkedIn company or showcase page URLs (at most 2048 characters each).

## `maxPostsPerCompany` (type: `integer`):

Maximum number of public post rows saved for each supplied company.

## `postedAfter` (type: `string`):

Optional ISO date/time lower bound for incremental monitoring.

## Actor input object example

```json
{
  "companyUrls": [
    "https://www.linkedin.com/company/linkedin/"
  ],
  "maxPostsPerCompany": 20
}
```

# Actor output Schema

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

No description

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

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

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fetch_cat/linkedin-company-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/TQJUBfDCGkyc6qvX6/builds/3AcCYWc7nHsj1BHc2/openapi.json
