# LinkedIn Company Scraper $1.50/1K | Websites & Firmographics (`apivault_labs/linkedin-company-scraper`) Actor

Enrich exact LinkedIn company URLs with source-reported websites, industry, size, headquarters and specialties. Public guest data with field provenance and explicit missing values.

- **URL**: https://apify.com/apivault_labs/linkedin-company-scraper.md
- **Developed by:** [Apivault Labs](https://apify.com/apivault_labs) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 useful company delivereds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

![LinkedIn company research — generated illustrative artwork](https://raw.githubusercontent.com/apivault-labs/apivault-labs/8899b6f135e472785b77d49204fee8dfe0d2bc2f/assets/linkedin-company-scraper/readme-cover-generated-v2.png)

### LinkedIn company data for account research and CRM enrichment

Turn a large, explicit list of LinkedIn company URLs into structured company records. Collect the website LinkedIn reports, industry, company-size range, headquarters, company type, founding year and specialties when those fields are publicly available. Every row includes its canonical company URL, observation time and field-level provenance.

Use it to fill firmographic columns in a CRM, compare a known list of suppliers, prepare an account-research sheet or refresh an existing company directory. It is designed for **company lookup**, not global company discovery. Start with an exact slug such as `apify`, or a company URL you already know. No LinkedIn login, user cookies, employee-profile collection or external provider key is required. This independent tool is not affiliated with LinkedIn or Microsoft.

#### First useful run

```json
{"companies":["apify"],"maxCompanies":1}
```

Open **Output → Companies** after the run. Download JSON, CSV or Excel using Apify Dataset exports. Check **SUMMARY** and **ERRORS** before importing the data. A successful run with partial results can still contain unpaid source failures; an inaccessible source is never represented as a successful empty company profile.

For two known companies:

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

The website is exactly the source-reported website, not a guessed home page. For example, a company may publish a newsroom subdomain; the Actor preserves that URL and does not silently substitute a brand's main domain.

#### What this company scraper delivers

| Need | Output | Boundary |
|---|---|---|
| CRM account enrichment | Company name, URL, website and industry | Explicit URLs/slugs; no domain-to-LinkedIn resolver |
| Firmographic segmentation | Company-size range, type and headquarters | Public self-reported LinkedIn observations |
| Company research | Description, specialties and founding year | Missing source fields stay null |
| Audience observations | Followers and LinkedIn-associated employee count | Not verified payroll headcount; no employee identities |
| Data quality review | Canonical URL, collectedAt and fieldSources | Provenance identifies where a field came from, not independent truth |
| Bulk company-list processing | One deduplicated record per accessible company | Up to 10,000 inputs and delivered records; bounded concurrency and deadline |

#### Output reference

| Field | Meaning |
|---|---|
| `id`, `companyUrl` | Normalized source company slug and canonical LinkedIn company URL |
| `name`, `description` | Organization name and description from the matching public Organization node |
| `website`, `websiteDomain` | Source-reported external URL and its hostname, without guessing domain ownership |
| `industry`, `companyType` | Public Industry and Type labels |
| `companySize` | Source display range such as 51–200 employees; not an exact measured staff count |
| `companySizeMin`, `companySizeMax` | Parsed bounds; an open-ended upper bound is null |
| `headquarters`, `address` | Reported HQ label and available structured address; not all office locations |
| `foundedYear` | Published founding year, otherwise null |
| `specialties` | Public specialties text, preserved as text |
| `employeesOnLinkedIn` | Number reported by LinkedIn's public Organization data; not verified employed headcount |
| `followers` | Count explicitly present in the English public page description, otherwise null |
| `logoUrl` | Source image URL when present; availability may expire |
| `collectedAt`, `coverage` | UTC observation time and `public_company_profile` scope |
| `fieldSources` | Map from populated fields to their JSON-LD, About or metadata source |

Unknown metrics are `null`, not zero. A reported zero remains zero. A name alone is insufficient: the page's canonical company identity and matching Organization node must agree, and at least one substantive company field must be present. Related-company cards and social-post authors are not used to fill another company's data.

#### Complete input reference

| Setting | Default | Meaning |
|---|---|---|
| `companies` | `["apify"]` when omitted | 1–10,000 exact ASCII slugs or HTTPS LinkedIn company URLs. Country subdomains and tracking parameters normalize to the canonical www route. Person URLs, arbitrary hosts and credentials are rejected |
| `maxCompanies` | 1,000 | Global delivered-company cap, 1–10,000. Stops further requests once reached |
| `sourceTimeoutSeconds` | 3,600 | Overall source collection budget, 10–7,200 seconds. Each request uses at most 25 seconds and the remaining budget |
| `requireWebsite` |false|Skip records without a usable source-reported website; see filteredOut |
| `maxConcurrency` | 5 | Concurrent requests, 1–10. More parallelism can increase rate limits |
| `proxyMode` |`"direct"`|`direct` or explicit `residential`; no automatic paid-proxy fallback |

Inputs are deduplicated before collection and processed in ordered waves, with up to 10 concurrent requests. Results are delivered and checkpointed after every wave. Repeated slugs, URL aliases differing only by country host or tracking query and case variations are deduplicated. An invalid item in a mixed list becomes a separate unpaid diagnostic; valid companies can still be delivered. Unknown input settings are rejected to avoid silently pretending to support search or other unimplemented options.

#### Large company lists and continuation

Supply up to 10,000 known company URLs/slugs, set `maxCompanies` and `maxConcurrency` (1–10, default 5), and allow enough run time. The configured input ceiling is not a promise of 10,000 accessible companies. Requests can fail or be rate-limited; only useful delivered records are billed as results. Lower concurrency if the source restricts access.

```json
{"companies":["apify","microsoft","openai"],"maxCompanies":1000,"maxConcurrency":5,"sourceTimeoutSeconds":3600}
```

Results are saved after each wave rather than kept until the whole list finishes. `CHECKPOINT.remainingCompanies` contains unattempted inputs, while `inFlightCompanies` marks a reserved wave whose delivery may be uncertain after interruption. There is no automatic restart or retry: reconcile Dataset before retrying in-flight companies. For an explicit next run, copy only remainingCompanies into a new input; historical failures are in ERRORS and are not silently repeated. A charge cap stops delivery and returns undelivered rows to remainingCompanies.

#### Useful input examples

Deduplicate several references to the same company:

```json
{"companies":["Apify","https://www.linkedin.com/company/apify/?trk=public_profile","microsoft"],"maxCompanies":2}
```

Build a company-to-website sheet:

```json
{"companies":["apify","microsoft","openai"],"maxCompanies":3,"requireWebsite":true}
```

Use a small delivered-record cap:

```json
{"companies":["apify","microsoft","openai"],"maxCompanies":1}
```

Opt into Apify Residential Proxy if Direct is blocked:

```json
{"companies":["apify"],"maxCompanies":1,"proxyMode":"residential","sourceTimeoutSeconds":45}
```

Residential traffic is charged separately by Apify, in addition to platform usage and result events. It does not guarantee source access. The Actor does not collect or require your LinkedIn credentials or session cookies and does not switch routes without your input.

#### Price and cost controls

The result tariff is **$1.50 per 1,000 delivered company records on Free**, **$1.20 on Starter**, **$1.00 on Scale** and **$0.80 on Business and current higher tiers**. There is **no startup event**. Platform resources are paid separately by the user; Residential adds proxy usage when explicitly selected. A filtered-out profile, invalid URL, source error or diagnostic is not a result event.

This is a per-delivered-company event rate, not an all-inclusive promise. A one-company run has startup compute overhead even without a startup event. Use `maxCompanies` for an output cap, `sourceTimeoutSeconds` for a collection deadline and Apify's maximum charge setting to constrain a run. A charge cap does not guarantee the total of every separately billed resource. Compare total costs and coverage, not only the advertised per-record event.

#### Failures, partial results and completeness

`SUMMARY` reports requested inputs, unique valid companies, duplicate inputs skipped, attempted and not-attempted counts, filtered-out profiles and delivered records. `ERRORS` contains source or input codes without billing them as useful companies. Completed records survive a later source error or deadline. When no useful result is produced because all pages failed, the Actor fails explicitly. A legitimate website-filtered empty result is distinguished by filteredOut and no source errors.

HTTP403/429/999, redirects to authentication, missing structured company data or an identity mismatch can prevent delivery. Availability varies by region, route and time. No retry storm, third-party data provider, inferred replacement record or paid proxy fallback is hidden behind a successful status. This version does not search the entire LinkedIn company network, resolve arbitrary company names/domains, paginate employees, collect personal profiles, gather all office locations or return a complete archive of company posts.

#### API, Python and agent workflows

Use the Apify Actor API with your own token. Save that token in an environment variable, not in a copied input. The permanent Actor ID is `9OI0iq6qu1BQXQSoy`; use it in generic Apify clients.

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("9OI0iq6qu1BQXQSoy").call(
    run_input={"companies": ["apify"], "maxCompanies": 1},
    max_total_charge_usd=0.03,
)
if run["status"] != "SUCCEEDED":
    raise RuntimeError("Inspect SUMMARY and ERRORS before importing results")
for company in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(company)
```

The standard Apify API/client and an appropriately configured Apify MCP connection are the integration paths. No dedicated npm/n8n, PyPI or public GitHub wrapper is claimed for this new product; do not confuse it with LinkedIn Jobs or the individual-profile scraper. Use the small editable JSON examples above or create your own saved Apify Task for repeated account-list enrichment.

#### FAQ

**Can I enter a company name or a website domain?** No. Provide the exact LinkedIn company slug or URL. Guessing a similarly named company could silently corrupt a CRM.

**Are employee counts exact company headcounts?** No. `employeesOnLinkedIn` is the public source's associated-profile count; `companySize` is its displayed size band. Neither is independently verified payroll data.

**Why did Microsoft return a newsroom website?** That is what the company page reports. The Actor preserves source evidence rather than replacing it with an assumed corporate domain.

**Why is a field null?** It was absent or could not be parsed with sufficient evidence. Null must not be interpreted as zero followers, no employees or no company history.

**Does Residential guarantee every company?** No. It is an optional paid route and can still encounter source restrictions. Inspect errors before treating missing records as missing businesses.

**Can I monitor changes?** You can schedule runs and compare exports in your own store using companyUrl/id and collectedAt. Built-in cross-run history and change notifications are not implemented.

# Changelog

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

# Actor input Schema

## `companies` (type: `array`):

Enter 1–10,000 exact company URLs or slugs. Deduplicated before requests. Use CHECKPOINT.remainingCompanies for explicit continuation; no automatic retries.

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

Delivered-record cap, 1–10,000. Large output depends on source access and available time; the configured ceiling is not a throughput guarantee.

## `sourceTimeoutSeconds` (type: `integer`):

Global collection budget 10–7,200 seconds. Each request uses at most25seconds. Results are delivered after every wave of at most10companies.

## `requireWebsite` (type: `boolean`):

Skip profiles without a usable source-reported website. This is not independent ownership verification. Skipped companies are not billed as results; see SUMMARY.filteredOut.

## `proxyMode` (type: `string`):

No automatic paid fallback. Direct may be blocked. Residential uses separately billed Apify proxy traffic and is used only when selected. Neither route guarantees access.

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

1–10parallel public-page requests. Higher concurrency may increase blocking. Default5; no automatic paid fallback.

## Actor input object example

```json
{
  "companies": [
    "apify"
  ],
  "maxCompanies": 1000,
  "sourceTimeoutSeconds": 3600,
  "requireWebsite": false,
  "proxyMode": "direct",
  "maxConcurrency": 5
}
```

# Actor output Schema

## `companies` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `errors` (type: `string`):

No description

## `checkpoint` (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 = {
    "companies": [
        "apify"
    ]
};

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

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,apivault_labs/linkedin-company-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/9OI0iq6qu1BQXQSoy/builds/5FyaTnJXh8JahA3nb/openapi.json
