# LinkedIn Company Insights Scraper (`automation-lab/linkedin-company-insights-scraper`) Actor

Extract public LinkedIn company profiles and visible workforce metrics for recurring enrichment and employee or follower snapshot comparisons.

- **URL**: https://apify.com/automation-lab/linkedin-company-insights-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Social media
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#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 Company Insights Scraper

Create structured snapshots of public LinkedIn company pages for recurring company enrichment and visible workforce analysis.

LinkedIn Company Insights Scraper accepts company URLs or slugs and returns profile fields, current employee and follower counts, a metric fingerprint, and optional deltas against an earlier snapshot. It works without a LinkedIn login or cookie.

### What does LinkedIn Company Insights Scraper do?

The Actor turns public company pages into one normalized row per company.

It extracts:

- company name and LinkedIn identifier;
- canonical company URL and slug;
- website and public description;
- industry, company type, and employee range;
- visible employee and follower counts;
- headquarters, founding year, and specialties;
- logo URL;
- snapshot timestamp and metric fingerprint;
- employee and follower deltas when an earlier snapshot is supplied.

The default dataset contains the primary results, ready for CSV, Excel, JSON, API, webhook, or automation-platform export.

### Who is it for?

#### Market and competitive intelligence teams

Take repeated snapshots of a known company list and identify visible workforce or audience changes.

#### Sales operations teams

Enrich account records with public LinkedIn company identity, size, industry, website, and headquarters fields.

#### Investors and analysts

Compare visible employee and follower signals across a watchlist without manually opening every company page.

#### Data engineers

Send normalized rows to a warehouse, spreadsheet, CRM, or monitoring pipeline on an Apify schedule.

### Why use it?

- **No LinkedIn cookie:** the supported workflow uses public company pages.
- **Real company URLs:** provide slugs or full `linkedin.com/company/...` URLs.
- **Batch input:** process up to 500 unique companies per run.
- **Duplicate control:** repeated URLs normalize to one company request.
- **Change-ready output:** timestamps and `snapshotKey` make repeated runs easy to compare.
- **Built-in deltas:** pass selected earlier metrics back through `previousSnapshots`.
- **Fail-closed behavior:** challenge pages are not reported as valid empty companies.
- **Efficient HTTP extraction:** no browser is launched for the supported fields.

### What data does it extract?

| Field | Type | Meaning |
| --- | --- | --- |
| `companyId` | string | Numeric LinkedIn identifier when public, otherwise the slug |
| `universalName` | string | Company slug from the canonical URL |
| `name` | string | Public company display name |
| `linkedinUrl` | string | Normalized LinkedIn company URL |
| `website` | string or null | Public company website |
| `description` | string or null | Public company description |
| `industry` | string or null | Public industry label |
| `companyType` | string or null | Public organization type |
| `employeeRange` | string or null | Visible company-size range |
| `employeeCount` | integer or null | Current visible employee count |
| `followerCount` | integer or null | Current visible follower count |
| `foundedYear` | integer or null | Public founding year |
| `headquarters` | string or null | Public headquarters text |
| `specialties` | string\[] | Public specialty labels |
| `logoUrl` | string or null | Public logo image URL |
| `snapshotAt` | ISO timestamp | Time the row was produced |
| `snapshotKey` | string | Hash of employee and follower metrics |
| `previousSnapshotAt` | string or null | Timestamp supplied for the matched earlier row |
| `changes` | object or null | Comparable metric deltas and changed field names |

LinkedIn controls which optional fields are public. Nullable fields are expected, not parser errors.

### How to run the scraper

1. Open the Actor in Apify Console.
2. Add one or more company slugs or URLs under **LinkedIn company URLs or slugs**.
3. Set **Maximum companies** to a safe test limit.
4. Leave `previousSnapshots` empty for a current snapshot.
5. Click **Start**.
6. Inspect the default dataset or export it in your preferred format.
7. For monitoring, schedule the task and compare its dataset with an earlier run.

A useful first input is:

```json
{
  "companyUrls": [
    "microsoft",
    "https://www.linkedin.com/company/apifytech/"
  ],
  "maxCompanies": 2
}
```

### Input parameters

| Input | Required | Default | Description |
| --- | --- | --- | --- |
| `companyUrls` | yes | — | LinkedIn company URLs or slugs; up to 500 entries |
| `maxCompanies` | no | `25` | Maximum unique companies processed, from 1 to 500 |
| `previousSnapshots` | no | `[]` | Earlier URL, timestamp, employee count, and follower count values for delta calculation |

The Actor automatically uses a US residential proxy because direct LinkedIn company-page requests commonly return anti-bot status 999.

No user-supplied credentials or LinkedIn session cookies are accepted.

### Output example

This shape is based on a real current run; counts naturally change over time:

```json
{
  "companyId": "1035",
  "universalName": "microsoft",
  "name": "Microsoft",
  "linkedinUrl": "https://www.linkedin.com/company/microsoft/",
  "website": "https://news.microsoft.com/",
  "industry": "Software Development",
  "companyType": "Public Company",
  "employeeRange": "10,001+ employees",
  "employeeCount": 233229,
  "followerCount": 28806103,
  "headquarters": "Redmond, Washington",
  "snapshotAt": "2026-08-07T20:22:40.000Z",
  "snapshotKey": "80ed764994cc82da",
  "previousSnapshotAt": null,
  "changes": null
}
```

Long descriptions, specialty arrays, and logo URLs are included in the actual dataset when exposed publicly.

### Compare repeated company snapshots

Run once to collect baseline rows. On a later run, pass the relevant baseline metrics back in `previousSnapshots`:

```json
{
  "companyUrls": ["microsoft"],
  "maxCompanies": 1,
  "previousSnapshots": [
    {
      "linkedinUrl": "https://www.linkedin.com/company/microsoft/",
      "snapshotAt": "2026-08-01T12:00:00.000Z",
      "employeeCount": 233228,
      "followerCount": 28806091
    }
  ]
}
```

The output can then contain:

```json
{
  "previousSnapshotAt": "2026-08-01T12:00:00.000Z",
  "changes": {
    "employeeCountDelta": 1,
    "followerCountDelta": 12,
    "changedFields": ["employeeCount", "followerCount"]
  }
}
```

A delta is `null` when either the earlier or current value is unavailable. `changedFields` contains only non-zero comparable metrics.

### How much does it cost to scrape LinkedIn company insights?

The Actor uses pay-per-event pricing:

- a one-time **$0.005 start fee** per run;
- a provisional Bronze price of **$0.003596 per saved company snapshot**;
- no charge for duplicates, failed pages, or rejected responses.

At the Bronze rate, calculate an estimated Actor charge as the **$0.005 start fee plus the number of saved snapshots multiplied by $0.003596**. Subscription tiers may have lower per-snapshot event rates. Apify platform usage and proxy consumption are accounted for in the Actor's measured pricing process. The live Console price is authoritative.

### Scheduling and workforce monitoring

Use an Apify Task when you monitor the same companies repeatedly:

1. Save the company list as a Task.
2. Add a daily, weekly, or monthly schedule.
3. Send run-finished webhooks to your workflow.
4. Store each dataset with its `snapshotAt` value.
5. Join records on `linkedinUrl`.
6. Compare `employeeCount`, `followerCount`, or `snapshotKey`.
7. Alert only when a threshold important to your analysis changes.

The Actor does not persist a hidden cross-run history. This keeps every result reproducible and lets you choose your own retention policy.

### Export and integration workflows

#### Spreadsheet tracking

Export each dataset to CSV or Excel, then join snapshots by `linkedinUrl`.

#### CRM enrichment

Map `website`, `industry`, `employeeRange`, and `headquarters` to account fields. Keep `snapshotAt` as the source freshness timestamp.

#### Data warehouse

Append each run to a partitioned snapshot table. Use `snapshotKey` to identify unchanged metrics before expensive downstream processing.

#### Webhooks and automation

Trigger Make, Zapier, n8n, Airtable, Slack, or a custom endpoint when a scheduled run finishes.

### Use the Actor through the API

Replace `<APIFY_TOKEN>` with your Apify API token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~linkedin-company-insights-scraper/runs?token=<APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"companyUrls":["microsoft","apifytech"],"maxCompanies":2}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/linkedin-company-insights-scraper').call({
  companyUrls: ['microsoft', 'apifytech'],
  maxCompanies: 2,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("automation-lab/linkedin-company-insights-scraper").call(
    run_input={"companyUrls": ["microsoft", "apifytech"], "maxCompanies": 2}
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with Apify MCP

#### Claude Code setup

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/linkedin-company-insights-scraper"
```

#### Claude Desktop setup

Use this JSON in Claude Desktop:

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

#### Cursor setup

Add the same `mcpServers.apify.url` value to Cursor's MCP configuration.

#### VS Code setup

Add the same HTTP MCP server URL to your VS Code MCP configuration.

Example prompts:

- “Create current public company snapshots for Microsoft and Apify.”
- “Run this company watchlist and return employee and follower counts as a table.”
- “Compare these prior employee and follower values with the latest public snapshots.”

### Limits

- Only public LinkedIn company pages are supported.
- Personal profiles, employees, private contact data, and authenticated Sales Navigator analytics are not extracted.
- LinkedIn may omit optional fields or change public markup.
- Direct requests are frequently blocked, so the Actor uses residential proxy routing.
- A deleted, renamed, private, or invalid company page may fail.
- Processing is sequential and conservative to reduce source blocking.
- `maxCompanies` is capped at 500 per run.
- Results are snapshots, not audited financial or employment records.

### Legality and responsible use

Use the data lawfully. Follow LinkedIn's terms, applicable privacy and database laws, and your organization's policies. Do not use output for harassment, discrimination, or unlawful profiling.

### Troubleshooting

#### Why is a field null?

LinkedIn does not expose every profile field for every company. Null means the field was not visible in the accepted public response.

#### Why did the run fail with no snapshots?

The Actor fails when every requested page is invalid or blocked. Verify each URL, lower the batch size, and retry later rather than treating an anti-bot page as an empty company.

#### Why did two identical inputs produce different counts?

Employee and follower counts are live public signals. They may change between requests, and LinkedIn can update them independently.

#### Why are there no automatic historical rows?

Each run writes current results to its own default dataset. Use schedules, dataset retention, a warehouse, or `previousSnapshots` for the history policy you need.

### FAQ

#### Does it require a LinkedIn account?

No. The Actor does not accept a LinkedIn login or session cookie.

#### Can I provide only a company slug?

Yes. `microsoft` normalizes to `https://www.linkedin.com/company/microsoft/`.

#### Does it return employee profiles?

No. It returns company-level public metrics, not people records.

#### Does it return Sales Navigator headcount history?

No. It does not claim authenticated or private Sales Navigator analytics.

#### Are failed companies charged?

No per-company event is emitted unless a useful normalized snapshot is saved.

#### Can I detect no-change runs?

Yes. Compare `snapshotKey` values or provide an earlier snapshot and inspect `changes.changedFields`.

### Related automation-lab Actors

- [LinkedIn Company Scraper](https://apify.com/automation-lab/linkedin-company-scraper) for straightforward company profile enrichment.
- [LinkedIn Company Search Scraper](https://apify.com/automation-lab/linkedin-company-search-scraper) to discover company URLs before creating snapshots.
- [LinkedIn Company Employees Scraper](https://apify.com/automation-lab/linkedin-company-employees-scraper) when the separate buyer job requires public employee profile discovery.
- [LinkedIn Jobs Scraper](https://apify.com/automation-lab/linkedin-jobs-scraper) for job-listing records rather than company-level snapshot metrics.

Start with a small real company list, inspect the current dataset, and then turn the tested input into a scheduled Task.

# Actor input Schema

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

Public LinkedIn company page URLs or slugs. Duplicate companies are processed once.

## `maxCompanies` (type: `integer`):

Maximum number of unique companies to process in this run.

## `previousSnapshots` (type: `array`):

Optional earlier metrics. Match rows by linkedinUrl to calculate employee and follower deltas in the current output.

## Actor input object example

```json
{
  "companyUrls": [
    "microsoft",
    "https://www.linkedin.com/company/apifytech/"
  ],
  "maxCompanies": 2,
  "previousSnapshots": []
}
```

# Actor output Schema

## `dataset` (type: `string`):

Open all normalized company snapshots in the default dataset.

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

Open the table view for current metrics and changes.

# 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": [
        "microsoft",
        "https://www.linkedin.com/company/apifytech/"
    ],
    "maxCompanies": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/linkedin-company-insights-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": [
        "microsoft",
        "https://www.linkedin.com/company/apifytech/",
    ],
    "maxCompanies": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/linkedin-company-insights-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": [
    "microsoft",
    "https://www.linkedin.com/company/apifytech/"
  ],
  "maxCompanies": 2
}' |
apify call automation-lab/linkedin-company-insights-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/linkedin-company-insights-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/D9dtmxgnVpYorjEN3/builds/eD2BAfBryOuZhFdxi/openapi.json
