# LinkedIn Company Scraper - Details, No Login (`automation_craft/linkedin-company-scraper`) Actor

Get LinkedIn company details from public pages by URL, name or ID, with no login or cookies. Website, industry, company size, employees on LinkedIn, followers, headquarters and offices, founded, specialties, up to 10 latest posts and open jobs. Misses are free. Pay per company, JSON or CSV.

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

## Pricing

from $1.85 / 1,000 companies

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

### LinkedIn Company Scraper - Details, No Login

**LinkedIn Company Scraper** turns a list of LinkedIn company URLs, company names or company IDs into complete LinkedIn company details from the public company page, with no LinkedIn login, no cookies and no API key. Paste 1 or 20,000 companies: every value gets exactly one row, in the order you gave, and anything LinkedIn cannot serve gets a free status row that says why. You pay per company delivered plus a small start fee per run; status rows are free.

Each company row carries the website and its domain, industry, company size band with its bounds, employees on LinkedIn, followers, headquarters (text and structured address), every office the page lists, organization type, founded year, specialties, tagline, description, logo and cover image, affiliated pages, similar pages, products, up to 10 latest posts with their exact publish time, and the number of jobs the company has open on LinkedIn worldwide. Use it as the LinkedIn company data source for CRM enrichment and account lists, or call it as a LinkedIn company API from your own code (curl, Node and Python examples below); in n8n and Make the Apify module runs this Actor with the same input JSON.

#### Why this one

- **Every input gets a row, in order.** Not found, ambiguous, duplicate, school page and blocked values get a free status row in their place. Nothing is dropped silently and nothing missing is billed. The one exception is a list that is mostly misses: after 200 values in a row without a company the run stops and one free row says how many values were not processed (see "What this Actor does NOT do").
- **Names are never guessed.** A company name goes through LinkedIn's own company lookup and is delivered only when exactly one company matches and the fetched page's own ID confirms it. Two pages that share a name up to capitals ("Nio" and "NIO", "Ikea" and "IKEA") are two companies: you get a free `ambiguous` row listing both, never a pick. On 290 saved lookups (2026-09-30) this rule delivered 150 of 220 exact company names, every one of them the right company, and answered the other 70 with a free `ambiguous` row listing the candidates.
- **The open job count**, worldwide, read from LinkedIn's public job search filtered by the company: the number LinkedIn's search holds for it (its `totalResults`), also above 1,000 where the page shows only "1,000+" (Stripe 1,212, Google 5,502 on 2026-09-30).
- **Posts with real dates.** Up to the 10 latest posts on the page with an exact ISO publish time, full text, likes, comments and media type; reposts of other people's text are left out unless you ask for them.
- **The real website**, decoded from LinkedIn's redirect link, never a `linkedin.com/redir` URL.
- **No proxy bill.** One public page per company through the Apify datacenter pool, which is included in the price. In a test run of 2,199 distinct company pages on 2026-09-30 the pool delivered 2,189 of the 2,189 pages that exist (the other 10 were LinkedIn "page not found" answers).

### Quick start

1. Paste companies into **LinkedIn company URLs, names or ids**, one per line. Any of these work: `https://www.linkedin.com/company/stripe`, a URL with a tab or tracking such as `https://www.linkedin.com/company/stripe/about/?trk=x`, a regional URL such as `de.linkedin.com/company/zalando`, a showcase page `https://www.linkedin.com/showcase/stripe-partner-ecosystem`, a company name such as `Twilio` (a name shared by two pages up to capitals, such as `Stripe` and `STRIPE`, comes back as a free `ambiguous` row listing both), a numeric ID such as `1441`, `urn:li:organization:1441`, or a LinkedIn job search URL filtered by company (`f_C=1441`).
2. Leave **Recent posts**, **Open job count** and **Similar pages** on for the full row, or turn them off for a slimmer one.
3. Click **Start**. Rows appear in the Dataset tab in input order; export JSON, CSV or Excel, or read them through the API.

### What you get

Fill rates measured on 2,230 real company pages fetched signed out on 2026-09-30 (they are what LinkedIn publishes, not what the Actor chooses to return):

| Field | What it is | Filled |
|---|---|---|
| `companyId`, `name`, `slug`, `pageType`, `url` | LinkedIn's numeric company ID (a string), name, page slug, `company` or `showcase`, canonical URL | 100% |
| `website`, `websiteDomain` | The company's own website and its host | 97.9% |
| `industry` | Industry from the About block | 99.9% |
| `companySize`, `companySizeMin` | Size band as shown ("5,001-10,000 employees") and its lower bound | 99.6% |
| `companySizeMax` | Upper bound of the band (null for 10,001+) | 76.2% |
| `employeesOnLinkedIn` | LinkedIn members who list the company as employer | 99.1% |
| `followers` | Follower count of the page | 100% |
| `headquarters` | Headquarters text from the About block | 95% |
| `headquartersAddress` | street, city, region, postalCode, country | 94.5% |
| `locations`, `locationCount` | Every office listed: isPrimary, line1, line2, city, region, postalCode, country, mapQuery | 96.5% (locationCount 100%) |
| `organizationType` | Privately Held, Public Company and the like | 99.2% |
| `foundedYear` | Founding year | 63.9% |
| `specialties` | List of specialties | 70.2% |
| `tagline`, `description` | Tagline and About text | 69.4%, 98.5% |
| `logoUrl`, `coverImageUrl` | Logo and cover image | 99.4%, 96% |
| `similarPages` (option) | Up to 10 companies LinkedIn lists as similar: name, slug, pageType, url, industry, location | 100% |
| `affiliatedPages` | Affiliated and showcase pages, same shape | 43% |
| `products` | Products listed on the page: name, url, category | 7% |
| `recentPosts`, `recentPostCount`, `repostsOnPage` (option) | Up to 10 latest posts: url, activityId, postedAt, postedAtSource, text, headline, likes, comments, isReshare (the company's own post that quotes another post), isRepost (a plain share of someone else's post), mediaType. Reposts (someone else's text the company shared, about 9% of feed cards) are left out unless **Include reposts** is on; `repostsOnPage` counts them; `feedOnPage` says whether the page carried a posts section at all (about 10% of pages have none) | 88.6% of pages have at least one post with the defaults |
| `openJobs`, `openJobsSource` (option) | Open jobs worldwide and where the number came from (`jobs_search`, `no_jobs_button`, `lookup_failed`, `showcase_page`) | 83.5% of pages show a See jobs button and are counted; the rest get 0 without a request; a showcase page gets null (its jobs sit under the parent company) |
| `jobsSearchUrl` | LinkedIn's public job search for the company | 100% |
| `position`, `input`, `inputType`, `matchedBy`, `matchEvidence`, `scrapedAt` | Where the row sits in your list, what you gave, and how it was matched to the page | 100% |

With the default settings (reposts left out) 88.6% of the 2,230 pages return at least one post, 17,272 posts in all (1,716 reposts left out); 10.4% of the pages carry no posts section at all (`feedOnPage` false). Inside `recentPosts`: `postedAt` 100% (from the post's structured data, or its activity ID when LinkedIn gives none), `text` 99.3%, `likes` 99.9%, `comments` 99.8%, `mediaType` 99.8% (image, video, document, article, job, text, external_video, live_video). Inside `locations` (12,818 offices): `country` 99.4%, `city` 82.4%, `region` and `postalCode` 65.1%.

`matchedBy` says how the input reached the page: `url`, `url_redirect` (LinkedIn's own redirect to a renamed slug), `name_jobs` or `name_guess` (a name resolved through LinkedIn's lookup), `id_jobs` or `id_guess` (a numeric ID), each verified on the page's own ID.

Example company row (platform run errtwRkSpkhuF06Wd on 2026-10-01, build 0.1.14 of this Actor; the company row, its parser and its fields are unchanged in the build this README ships with, whose later changes are listed in the changelog; shortened: one item per list, the description and the post text cut):

```json
{
  "type": "company",
  "status": "ok",
  "position": 1,
  "input": "https://www.linkedin.com/company/stripe",
  "inputType": "url",
  "matchedBy": "url",
  "matchEvidence": {
    "requestedUrl": "https://www.linkedin.com/company/stripe"
  },
  "companyId": "2135371",
  "name": "Stripe",
  "slug": "stripe",
  "pageType": "company",
  "url": "https://www.linkedin.com/company/stripe",
  "tagline": "Help increase the GDP of the internet.",
  "description": "Stripe builds programmable financial services. Millions of ...",
  "website": "https://stripe.com",
  "websiteDomain": "stripe.com",
  "industry": "Technology, Information and Internet",
  "companySize": "5,001-10,000 employees",
  "companySizeMin": 5001,
  "companySizeMax": 10000,
  "employeesOnLinkedIn": 16622,
  "followers": 1742544,
  "headquarters": "South San Francisco, California",
  "headquartersAddress": {
    "street": "354 Oyster Point Blvd",
    "city": "South San Francisco",
    "region": "California",
    "postalCode": "94080",
    "country": "US"
  },
  "locations": [
    {
      "isPrimary": true,
      "line1": "354 Oyster Point Blvd",
      "line2": "South San Francisco, California 94080, US",
      "mapQuery": "354 Oyster Point Blvd South San Francisco 94080 California US",
      "city": "South San Francisco",
      "region": "California",
      "postalCode": "94080",
      "country": "US"
    }
  ],
  "locationCount": 14,
  "organizationType": "Privately Held",
  "foundedYear": 2010,
  "specialties": [],
  "logoUrl": "https://media.licdn.com/dms/image/v2/D560BAQE2ZfJyfn-VCg/company-logo_200_200/B56ZlyKwpUKIAI-/0/1758557047806/stripe_logo?e=2147483647&v=beta&t=En4Hm6NDGbDTYCoOQ0Ko5Ne2gylx0WRb0yL2GlOeXBQ",
  "coverImageUrl": "https://media.licdn.com/dms/image/v2/D563DAQFt98MykXcktg/image-scale_191_1128/B56Z352EMMKIAY-/0/1778013193531/stripe_cover?e=2147483647&v=beta&t=UwiZWbPrYkD77DpQmZIjVuuqKMCfyZ-e-YcHE336MlY",
  "products": [
    {
      "name": "Stripe",
      "url": "https://www.linkedin.com/products/stripe/",
      "category": "Payment Processing Software"
    }
  ],
  "affiliatedPages": [
    {
      "name": "Stripe Partner Ecosystem",
      "slug": "stripe-partner-ecosystem",
      "pageType": "showcase",
      "url": "https://www.linkedin.com/showcase/stripe-partner-ecosystem",
      "industry": "Internet Publishing",
      "location": "South San Francisco, California"
    }
  ],
  "similarPages": [
    {
      "name": "Atlassian",
      "slug": "atlassian",
      "pageType": "company",
      "url": "https://www.linkedin.com/company/atlassian",
      "industry": "Software Development",
      "location": "Sydney, NSW"
    }
  ],
  "recentPosts": [
    {
      "url": "https://www.linkedin.com/posts/stripe_were-welcoming-parafin-to-stripe-together-activity-7511095253190246400-rDs4",
      "activityId": "7511095253190246400",
      "postedAt": "2026-09-30T16:10:57.761Z",
      "postedAtSource": "structured_data",
      "text": "We’re welcoming Parafin to Stripe. Together, ...",
      "headline": null,
      "likes": 629,
      "comments": 9,
      "isReshare": false,
      "isRepost": false,
      "mediaType": "image"
    }
  ],
  "recentPostCount": 7,
  "repostsOnPage": 3,
  "feedOnPage": true,
  "openJobs": 1171,
  "openJobsSource": "jobs_search",
  "jobsSearchUrl": "https://www.linkedin.com/jobs/search?f_C=2135371&location=Worldwide",
  "scrapedAt": "2026-10-01T02:16:14.628Z"
}
```

#### Status rows (free)

Every input that does not give a company gets a `type: "status"` row in its place with `position` (zero based: your first value is position 0), `input`, `inputType`, `status` and a `message`. None of them is charged.

| `status` | When |
|---|---|
| `not_found` | LinkedIn has no page at that URL, no company is named exactly like that (the nearest names are in `candidates`), or the job search knows no company with that ID |
| `ambiguous` | A name matches several companies exactly; `candidates` lists their IDs and names, nothing is guessed |
| `unresolved` | A numeric ID (or a name resolved to an ID) whose page LinkedIn shows only to signed in members; the row names the company (`companyNameOnLinkedIn`) so you can paste its URL |
| `school_page` | A university page: LinkedIn does not serve school pages to signed out visitors |
| `login_required` | LinkedIn sent the page to its login wall (0 such rows in every test run of this build; the path is proven on captured pages) |
| `invalid` | Not a LinkedIn company URL, name or ID: a website domain, a person profile, an `lnkd.in` short link, a jobs URL without a company filter or filtered by several companies |
| `duplicate` | The same company already delivered in this run, in any shape (URL, name or ID); `duplicateOf` points to its row |
| `blocked` | LinkedIn did not serve the page, or the public job search a name or id is resolved through, after several attempts on fresh exits. Rare: 0 such rows in more than 5,000 live requests during testing, then a burst on 2026-10-01 when LinkedIn's job search answered HTTP 500 and 429 for a quarter of an hour. Try the value again later; nothing is charged |
| `failed` | An unexpected error; the message says what |
| `skipped` | Not processed: the run reached **Maximum companies to deliver** or your charge limit (one row per value), or the list had more than 20,000 values (one row for the whole band, with `overflowCount` and the first and last skipped position), or `maxConsecutiveMisses` values in a row produced no company (one row for all remaining values, with `stoppedBy` `consecutive-misses`, `consecutiveMisses`, `skippedCount` and the first and last skipped position) |

The last row of every run is a free `type: "summary"` row with counters: delivered, charged, not found, ambiguous, duplicates, requests and retries.

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

You pay per delivered company. Status rows and the run summary are free, and the posts, the open job count and the similar pages are included in the company price.

| Event | FREE | BRONZE | SILVER | GOLD |
|---|---|---|---|---|
| Company | $2.30 / 1,000 | $2.30 / 1,000 | $2.10 / 1,000 | $1.85 / 1,000 |
| Actor start (once per run, per GB of memory) | $0.0014 | $0.0014 | $0.0014 | $0.0014 |

Platinum and Diamond plans pay the Gold price. The Actor start event has no tier discount; the default 512 MB run counts as one start event.

| Companies in one run | FREE | GOLD |
|---|---|---|
| 1 | $0.0037 | $0.00325 |
| 100 | $0.2314 | $0.1864 |
| 1,000 | $2.3014 | $1.8514 |
| 10,000 | $23.0014 | $18.5014 |

The Store pricing card shows these same prices per 1,000 events: "$2.30 / 1,000" on the Company row means one company costs 0.23 cents.

### Input

| Field | Default | What it does |
|---|---|---|
| `companies` | (three sample companies) | Company URLs, names or IDs, ONE PER LINE, up to 20,000. A line is one value: a comma never separates two companies. A line that holds a second URL or ID after a comma is refused with a free `invalid` row; two names on one line (`Stripe, Notion`) are looked up as ONE name and come back `not_found`; inside a URL's query string a comma belongs to the URL. Paste one company per line. The one exception is a line made only of numeric IDs (`1441, 1035`). A nested list is read one level deep; HTML entities (`&amp;`) are decoded. `companyUrls`, `companyNames`, `companyIds`, `searches`, `identifier`, `profileCompanies`, `companyTargets`, `linkedinUrls`, `urls`, `startUrls`, `url`, `linkedin_url`, `names`, `queries` and `query` are accepted too. An input without any company list runs the three samples; an explicitly empty list returns one free status row. |
| `maxCompanies` | 0 (no limit) | Stop after this many delivered companies; later values get a free skipped row. `maxItems` and `maxResults` are read too. |
| `includeRecentPosts` | true | Add `recentPosts` (same page, no extra request). |
| `includeReposts` | false | Keep reposts in `recentPosts` (another company's or a person's text the company shared). |
| `includeOpenJobCount` | true | Add `openJobs`: one extra public request per company that shows a See jobs button. |
| `includeSimilarPages` | true | Add `similarPages` (no extra request). |
| `maxConcurrency` | 5 | Companies fetched in parallel (1 to 10). |
| `maxConsecutiveMisses` | 200 | Stop the run when this many values in a row produce no company (20 to 20,000; 20,000 never stops a run). One free `skipped` row reports the values not processed. |
| `proxyConfiguration` | Apify Proxy | The datacenter pool is included in the price. The RESIDENTIAL group is replaced by the datacenter pool; your own proxy URLs are used as given. |

How the three input kinds are read:

- **URLs**: any tab, tracking parameter or regional host is read as the company's main page on `www.linkedin.com`. A renamed slug that LinkedIn redirects is delivered and reported as `url_redirect`.
- **Names**: LinkedIn's own company lookup. Case, extra spaces, accents and "&" versus "and" do not matter; a legal form such as Inc, GmbH or SE on YOUR side is tolerated: the lookup is repeated without it, and the company is delivered when exactly one matches once your legal form is removed. A bare name never resolves to a page that merely adds a legal form ("Delta" is not "Delta Corporation"), and a name with one legal form never resolves to a page with another ("Delta Inc" is not "Delta Corporation"): give the name as LinkedIn spells it, or the page URL. Delivered only when exactly one company matches and the page's own ID equals it; pages that differ only in capitals ("Stripe" and "STRIPE") are two companies and come back as a free `ambiguous` row with both. "Square" comes back as Square (`joinsquare`, the payments company), never as the Oslo agency at `/company/square`.
- **IDs**: LinkedIn sends `/company/<id>` links to its login page, so an ID is resolved through LinkedIn's public job search. With open jobs, the page link comes from a job card (94 of 94 in our test); without open jobs, up to four spellings of the company's name are tried, each accepted only when the page's own ID matches (21 of 40). The rest get a free `unresolved` row.

A run keeps a delivery ledger in its own key value store, so a platform restart never delivers or bills a company twice. Runs use 512 MB of memory (the only size: a 256 MB run ran out of memory in testing, and more is not needed); one run counts as one Actor start event. Measured throughput: 1,983 companies with job counts in 790 s at concurrency 10 (run 0NhHYwzzIDIHmvZYm) and 1.23 companies per second at the default concurrency of 5 (a 120 company run); no run of 20,000 companies was made; the default run timeout is 8 hours, and a run that reaches it keeps the rows and charges made so far.

### FAQ

#### Do I need a LinkedIn account, cookies or an API key?

No. The Actor reads the public company page that LinkedIn serves to signed out visitors, through the Apify datacenter proxy that is included in the price. Nothing in the input asks for a credential.

#### Can I look up a LinkedIn company by name instead of its URL?

Yes. Put the name in the same list. It goes through LinkedIn's own company lookup and is delivered only when exactly one company matches and the fetched page's own ID confirms it. When several companies carry the name you get a free `ambiguous` row with their IDs and names in `candidates`; paste the URL or the ID of the one you mean.

#### How do I find a LinkedIn company ID, and can I give an ID as input?

Every company row carries `companyId`, and `jobsSearchUrl` shows it in LinkedIn's `f_C=` form. As input, a numeric ID, a `urn:li:organization:` ID or a job search URL with `f_C=` all work: the ID is resolved through LinkedIn's public job search, always when the company has open jobs and about half the time when it has none. The rest get a free `unresolved` row naming the company.

#### Does it return how many jobs a company has open, even above 1,000?

Yes. `openJobs` is the worldwide count that LinkedIn's public job search holds for the company's own ID (its `totalResults` field), also above 1,000, where the search page shows only a rounded figure such as "1,000+" (Stripe 1,212 and Google 5,502 on 2026-09-30). It costs one extra public request per company and is included in the company price. A page without a See jobs button gets 0 without a request; a showcase page gets null (`showcase_page`), because its jobs sit under the parent company.

#### Does it return funding, phone numbers or employee statistics?

No. The public company page does not show funding, a phone number, a verified badge, a parent company, employee statistics by location or function or headcount growth to signed out visitors, so the Actor does not emit those fields at all rather than return them empty.

#### Why does this Actor run with limited permissions?

It runs with Apify's limited permissions, the least privilege level: it can only read its input and write to its own run's dataset and key value store, where it keeps its restart ledger. It opens no named store and touches nothing else in your account.

### What this Actor does NOT do

- It does not log in, so it does not read the About, Posts, People or Insights tabs (a tab URL is read as the company's main page), posts beyond the 10 on the page, funding, phone numbers, the verified badge, the parent company, employee statistics or headcount growth.
- It does not return employee names: the employee preview on the page is left out on purpose.
- It does not read school pages (universities); they get a free `school_page` row.
- It does not turn a website domain such as `stripe.com` into a LinkedIn page; a domain with a common ending (.com, .io, .ai, .co, .so, .net, .org, .de, .co.uk and about 90 more) gets a free `invalid` row, and one with a rarer ending goes through the name lookup and comes back `not_found`. Give the LinkedIn URL or the company name.
- It does not search companies by keyword, industry or location: it reads the companies you give it.
- It does not follow `lnkd.in` short links or read person profiles.
- It does not resolve every numeric ID: a company without open jobs is found about half the time.
- It does not work through a list that is mostly misses. When 200 values in a row (in input order) produce no company (not found, ambiguous name, unresolved ID, blocked, invalid or any other free status row; a duplicate of a company already delivered does not count, and a delivered company resets the count), the run stops, writes one free `skipped` row saying how many values were not processed and their positions, and finishes normally. Companies delivered before the stop are billed as usual; nothing is charged for the rest. The threshold is the input option `maxConsecutiveMisses` (default 200, minimum 20; 20,000 never stops a run). Fix the list or raise the option, and run the remaining values again.

### API examples

Every run is also a LinkedIn company info lookup over the Apify API: send the list, read the rows.

curl (synchronous run, returns the rows):

```bash
curl -X POST "https://api.apify.com/v2/acts/automation_craft~linkedin-company-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"companies":["https://www.linkedin.com/company/stripe","ClickHouse","1441"],"includeRecentPosts":false}'
```

Node.js with `apify-client`:

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation_craft/linkedin-company-scraper').call({
    companies: ['https://www.linkedin.com/company/stripe', 'ClickHouse', '1441'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const row of items) if (row.type === 'company') console.log(row.name, row.website, row.employeesOnLinkedIn, row.openJobs);
```

Python with `apify-client`:

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("automation_craft/linkedin-company-scraper").call(
    run_input={"companies": ["https://www.linkedin.com/company/stripe", "ClickHouse", "1441"]}
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row["type"] == "company":
        print(row["name"], row.get("website"), row.get("employeesOnLinkedIn"), row.get("openJobs"))
```

### More data tools by Automation Craft

- [LinkedIn Jobs Scraper - No Login, Real Dates](https://apify.com/automation_craft/linkedin-jobs-scraper)
- [LinkedIn Ad Library Scraper: Ads by Company](https://apify.com/automation_craft/linkedin-ad-library-scraper)
- [Bulk WHOIS & RDAP Domain Lookup: DNS, SSL](https://apify.com/automation_craft/domain-whois-rdap-lookup)
- [G2 Reviews Scraper: Ratings, Pros and Cons](https://apify.com/automation_craft/g2-reviews-scraper)
- [US New Business Registrations Scraper - LLC Leads](https://apify.com/automation_craft/us-new-business-registrations-scraper)
- [Meta Ad Library Scraper - All Placements, Filters](https://apify.com/automation_craft/meta-ads-library-scraper)

This Actor is an independent tool and is not affiliated with or endorsed by LinkedIn. It reads only publicly available company pages.

# Changelog

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

# Actor input Schema

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

One company per line. Accepted: company page URLs (https://www.linkedin.com/company/apify, any tab, tracking or regional host such as de.linkedin.com), showcase page URLs (/showcase/...), company NAMES (resolved through LinkedIn's own company lookup and delivered only when exactly one company matches the name; an ambiguous name gets a free row listing the candidates), numeric company ids and urn:li:organization ids (resolved through the public job search: reliable when the company has open jobs). Up to 20,000 values per run. An input with no company list at all (a literal {}) runs these three sample companies so the Actor can be tried with one click; an explicitly empty list returns a free status row.

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

Stop after this many delivered companies. 0 means no limit (every value in the list). Values after the limit get a free skipped row.

## `includeRecentPosts` (type: `boolean`):

Add recentPosts: the up to ten latest posts the public page shows, each with its URL, exact publish time, full text, reactions, comments and media type. Included in the company price (same page, no extra request). Turn off for a slimmer row.

## `includeReposts` (type: `boolean`):

Off by default: a repost is someone else's text (another company's or a person's) that the company shared; about 9 percent of feed cards. Turn on to keep them in recentPosts (isRepost marks them). repostsOnPage always says how many the page held.

## `includeOpenJobCount` (type: `boolean`):

Add openJobs: how many jobs the company has open on LinkedIn worldwide, read from LinkedIn's public job search filtered by the company (LinkedIn's own total, also above 1,000). One extra public request per company that shows a See jobs button; included in the company price.

## `includeSimilarPages` (type: `boolean`):

Add similarPages: the up to ten companies LinkedIn lists as similar (name, slug, URL, industry, location). No extra request. Turn off for a slimmer row.

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

How many companies are fetched at the same time (1 to 10). The default 5 is fast and polite.

## `maxConsecutiveMisses` (type: `integer`):

When this many values in a row produce no company (not found, ambiguous name, unresolved id, blocked, invalid and the other free status rows; a duplicate does not count), the run stops, writes one free row that says how many values were not processed, and finishes. Companies delivered before the stop are billed as usual. A delivered company resets the count. Default 200, minimum 20; 20000 never stops a run.

## `proxyConfiguration` (type: `object`):

Apify Proxy (the automatic datacenter pool) is used by default and is part of the price. A fresh exit is used for every request and every retry. The RESIDENTIAL group is replaced by the datacenter pool (it costs more than a company earns and is not needed).

## Actor input object example

```json
{
  "companies": [
    "https://www.linkedin.com/company/apify",
    "https://www.linkedin.com/company/stripe",
    "https://www.linkedin.com/company/notionhq"
  ],
  "maxCompanies": 0,
  "includeRecentPosts": true,
  "includeReposts": false,
  "includeOpenJobCount": true,
  "includeSimilarPages": true,
  "maxConcurrency": 5,
  "maxConsecutiveMisses": 200,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (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": [
        "https://www.linkedin.com/company/apify",
        "https://www.linkedin.com/company/stripe",
        "https://www.linkedin.com/company/notionhq"
    ],
    "maxCompanies": 0,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation_craft/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": [
        "https://www.linkedin.com/company/apify",
        "https://www.linkedin.com/company/stripe",
        "https://www.linkedin.com/company/notionhq",
    ],
    "maxCompanies": 0,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("automation_craft/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": [
    "https://www.linkedin.com/company/apify",
    "https://www.linkedin.com/company/stripe",
    "https://www.linkedin.com/company/notionhq"
  ],
  "maxCompanies": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call automation_craft/linkedin-company-scraper --silent --output-dataset

```

## MCP server setup

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