# LinkedIn Company Posts Scraper & API — No Cookies (`gauravlabs/linkedin-company-posts-api`) Actor

Scrape LinkedIn company posts, text, reactions, comments counts and media links. Bulk URLs, automatic pagination and JSON/CSV export. No cookies needed. $2 per 1,000 posts; no startup fee.

- **URL**: https://apify.com/gauravlabs/linkedin-company-posts-api.md
- **Developed by:** [Gaurav Kumar Choudhary](https://apify.com/gauravlabs) (community)
- **Categories:** Social media, Marketing, Automation
- **Stats:** 1 total users, 1 monthly users, 94.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 company post results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## LinkedIn Company Posts Scraper & API

### At a glance

- Collect: Paginated company-feed posts with available text, engagement and media links.
- Input: use the runnable example below or the prefilled Input form.
- Output: the default dataset supports JSON/CSV/Excel export; see output modes below.
- Billing: $2 per 1,000 unique delivered posts. Monitoring history suppresses previously delivered IDs when enabled. No startup fee. Platform usage may be additional.
- Limits: No full company profiles, individual commenters/reactors or guaranteed complete feed history.

Extract LinkedIn company posts for competitor research, hiring intelligence and content analysis. Paste company page URLs to collect post text, available reaction and comment counts, posting dates and image/video links. Export JSON, CSV or Excel, or call the API from your own application. No LinkedIn account or cookies are required in the input. This independent tool is not affiliated with LinkedIn.

### Quick start

1. Open Input and paste your company page URLs.
2. Set the maximum posts per company and global page-request budget.
3. Start the Actor. Open the completed run's dataset to export JSON, CSV or Excel.

```json
{
  "companyUrls": ["https://www.linkedin.com/company/amazon/"],
  "maxPostsPerCompany": 100,
  "maxRequests": 2,
  "sortBy": "recent"
}
```

Each page can contain up to 50 posts. The Actor follows the next-page token and increments the offset by 50 automatically. Two requests can retrieve up to 100 posts from a sufficiently populated feed. Limits are not delivery guarantees. Pinned posts and reposts can affect ordering.

For five companies and up to 100 posts each, start with a ten-request budget. The budget applies to the entire run, not each company. Failed requests consume this operational budget. Companies are processed in input order; increase the budget if later companies are not reached.

### Popular use cases

- Competitor research: collect updates from several companies and compare topics, posting activity and engagement.
- Content planning: identify company posts that receive reactions, comments and reposts.
- Hiring and market intelligence: search the exported text for hiring updates, product launches and partnerships.
- Reporting workflows: export structured records to a spreadsheet or feed them into your existing analysis tools.

Need to discover posts by keyword instead of company URL? Use our [LinkedIn Post Search API](https://apify.com/gauravlabs/linkedin-post-search-api).

### Pricing: $2 per 1,000 delivered posts

One unique delivered post costs $0.002 on every Apify plan. There is no startup fee or charge for an empty search. Fifty posts cost $0.10; 100 cost $0.20 in Actor result charges. Apify platform usage may be additional, depending on your plan. Check the pricing panel before starting.

Duplicate post IDs within a run and posts in `excludePostIds` are not delivered or charged again in that run. Repeating a run can deliver and charge for previously collected posts unless you maintain exclusions or enable monitoring history. Requests that fail produce no new post-result charges; previously delivered posts remain charged and available.

### What you receive

Every row contains `postId`, `postUrl`, `text`, `sourceCompanyUrl`, `recordType` and `fetchedAt`. Available optional fields include `authorName`, `authorUrl`, `postedAt`, `postedAgo`, `isRepost`, `totalReactions`, `comments`, `reposts`, `reactionBreakdown`, `images`, `video` and `document`.

`totalReactions` preserves the source's aggregate reaction count; it is not presented as the number of LIKE-only reactions. A reaction breakdown is included only for categories actually supplied. Missing counts are omitted, not replaced with zero. Posting dates preserve source text without assuming a timezone. Collection timestamps are UTC.

Media fields contain available links and metadata, not downloaded files. Signed media links may expire. Documents and reaction categories are not guaranteed for every post. Reposts can be attributed to a different author than the requested company. Empty-text posts may still contain useful media and are retained.

#### Example result

Abbreviated illustration based on a supplied Amazon post. Text is shortened here for readability; `fetchedAt` is generated when your run collects the post.

```json
{
  "postId": "7204492333600440320",
  "postUrl": "https://www.linkedin.com/posts/amazon_meet-amazons-very-own-strongman-activity-7204492333600440320-wHUk",
  "text": "Meet Amazon's very own strongman! ...",
  "sourceCompanyUrl": "https://www.linkedin.com/company/amazon/",
  "recordType": "post",
  "authorName": "Amazon",
  "authorUrl": "https://www.linkedin.com/company/amazon/",
  "postedAt": "2024-06-06 14:40:25",
  "totalReactions": 4084,
  "comments": 173,
  "reposts": 68,
  "isRepost": false
}
```

### Input reference

| Field | Default | Purpose |
| --- | --- | --- |
| `companyUrls` | Required | 1–20 company page URLs. |
| `maxPostsPerCompany` | 50 | Save up to 1–500 posts per company. |
| `maxRequests` | 2 | Total page-request budget, 1–100 across the run. |
| `sortBy` | `recent` | Choose `recent` or `top`. |
| `excludePostIds` | Empty | Skip up to 5,000 activity IDs you already collected. |
| `requestTimeoutSecs` | 60 | Timeout per page request, 10–120 seconds. |

### Why choose this Actor?

- Clear per-result pricing with no startup fee.
- Multiple company URLs in one run with automatic pagination.
- Global request and per-company result limits for predictable collection scope.
- Deduplicated post IDs and optional exclusions for repeat research.
- Available media links and engagement data in an export-friendly structure.

This is a company-feed extractor, not full profile enrichment. It does not retrieve individual commenters, people who reacted, complete company profiles, newsletters or guaranteed complete history. It does not claim to be the cheapest, most accurate or fastest competing Actor.

### Use from Python

Install `requests` and store your own Apify token in `APIFY_TOKEN`:

```python
import os
import requests

response = requests.post(
    "https://api.apify.com/v2/acts/gauravlabs~linkedin-company-posts-api/run-sync-get-dataset-items",
    headers={"Authorization": f"Bearer {os.environ['APIFY_TOKEN']}"},
    json={
        "companyUrls": ["https://www.linkedin.com/company/amazon/"],
        "maxPostsPerCompany": 50,
        "maxRequests": 1,
        "sortBy": "recent",
    },
    timeout=200,
)
response.raise_for_status()
print(response.json())
```

For larger runs, use Apify's asynchronous Actor start API and retrieve the default dataset after completion. Scheduled runs, n8n and Make integrations are Apify platform features. Private builds require access; the API example works only when your account has access.

### Frequently asked questions

**Can I get more than 50 posts?** Yes. Raise `maxPostsPerCompany` and `maxRequests` to allow additional pages. A pre-publication test on Amazon returned 100 unique posts across two pages; other companies can return fewer.

**Does this include actual comments or a list of people who reacted?** It includes available counts. Individual comment records and reactor profiles are not included.

**Why did my run return fewer posts?** The company may have fewer available posts, an exclusion may remove posts, or a result/request/charge limit may have been reached. Check the per-company stop reason in SUMMARY.

**Can I retrieve all company history?** No complete-history guarantee is offered. Available pages and the configured limits determine how much can be collected.

### Limits, monitoring and support

Maximum 20 company URLs, 500 saved posts per company and 100 page requests per run. Collection stops at the first applicable limit, empty page, missing cursor or repeated cursor. There are no automatic retries. Persistent cross-run history is opt-in through monitoringKey. Exclusions can require additional pages to reach the saved-post limit, still bounded by `maxRequests`.

To monitor repeatedly, enable `monitoringKey` and schedule sequential runs using the same key, or supply caller-maintained `excludePostIds`. A run with service errors is marked failed even if earlier company results were delivered; inspect SUMMARY for sanitized error codes and per-company stop reasons before re-running.

Use appropriate access and redistribution permissions. Source availability, engagement and media URLs can change. For support, provide a run ID and non-sensitive input through the Actor's Issues tab. Never send credentials or tokens. Validate the output before production use; there is no complete-history or accuracy guarantee.

### Minimal API example

Store your own Apify token in `APIFY_TOKEN`; never paste it into public input or code. This example uses the same small input as the prefilled form.

```python
import os
import requests

response = requests.post(
    "https://api.apify.com/v2/acts/gauravlabs~linkedin-company-posts-api/run-sync-get-dataset-items",
    headers={"Authorization": "Bearer " + os.environ["APIFY_TOKEN"]},
    json={"companyUrls":["https://www.linkedin.com/company/amazon/"]},
    timeout=300,
)
response.raise_for_status()
print(response.json())
```

For large batches, start an asynchronous run with `/runs`, wait for its final status, and retrieve its default dataset. HTTP success when starting a run does not prove the extraction succeeded.

#### Minimal output shape (illustrative)

The following shows one documented field, not a fresh result or a promised yield. Inspect the output reference above for the complete schema.

```json
{
  "recordType": "post"
}
```

### Practical workflow and accuracy notes

Optional persistent monitoring: add `"monitoringKey":"amazon-weekly"` and use `sortBy: "recent"`. The first run establishes history while delivering results; later runs with the same key skip previously delivered IDs. Storage is scoped to this Actor and your authenticated Apify account. A different key starts separate history. Keep the same company inputs for a monitoring key and do not overlap runs using that key: history updates are not a transactional exactly-once guarantee. History retains the most recent 50,000 delivered IDs; older IDs can be collected again after eviction. History is saved after each completed page, so interrupted writes can allow repeats. Excluded or historical posts are not charged again when skipped. This is new-post monitoring, not engagement-refresh mode or an exhaustive backfill.

# Actor input Schema

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

1–20 HTTPS LinkedIn company URLs. Repeated company URLs are requested once.

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

Saved-result cap, not guaranteed delivery. Pages contain up to 50 posts. Increase maxRequests for more companies/pages.

## `maxRequests` (type: `integer`):

Global safety limit across all companies, including failed requests. Companies are processed in input order; later ones may receive no request if this budget is exhausted.

## `sortBy` (type: `string`):

Requests source ordering. Pinned posts and reposts can affect chronological order.

## `excludePostIds` (type: `array`):

Up to 5000 caller-maintained numeric activity IDs. Use monitoringKey instead for optional account-scoped persistent history.

## `requestTimeoutSecs` (type: `integer`):

Requests are not automatically retried.

## `monitoringKey` (type: `string`):

Letters, numbers, underscores or hyphens (1–80). Reuse the same key to skip IDs previously delivered by this Actor in your account. Keeps the last 50,000 delivered IDs. Leave empty for independent searches. Do not run the same key concurrently.

## Actor input object example

```json
{
  "companyUrls": [
    "https://www.linkedin.com/company/amazon/"
  ],
  "maxPostsPerCompany": 50,
  "maxRequests": 2,
  "sortBy": "recent",
  "excludePostIds": [],
  "requestTimeoutSecs": 60
}
```

# Actor output Schema

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

No description

## `summary` (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/amazon/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("gauravlabs/linkedin-company-posts-api").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/amazon/"] }

# Run the Actor and wait for it to finish
run = client.actor("gauravlabs/linkedin-company-posts-api").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/amazon/"
  ]
}' |
apify call gauravlabs/linkedin-company-posts-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gauravlabs/linkedin-company-posts-api"
        }
    }
}
```

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/lGYoDPLLbrh4OsmuN/builds/I8qPl9kQBL1pacnZP/openapi.json
