LinkedIn Company Scraper — Employee Count & Headcount Growth
Pricing
from $3.20 / 1,000 company records
LinkedIn Company Scraper — Employee Count & Headcount Growth
LinkedIn company scraper: employee count (headcount), industry, HQ, website, founding year and followers from public company pages - then keep the series, so you also see how fast each company is growing. Optional open jobs count and hiring signals. Company info in bulk. No login, no cookies.
Pricing
from $3.20 / 1,000 company records
Rating
0.0
(0)
Developer
Northbell
Maintained by CommunityActor stats
0
Bookmarked
17
Total users
10
Monthly active users
2 hours ago
Last modified
Categories
Share
LinkedIn Company Scraper with Headcount Growth
Paste a list of companies — LinkedIn URLs, websites (stripe.com) or plain names — and get each one's real headcount (the number LinkedIn counts, not the size band the company typed in), industry, HQ, website, followers and the 10 similar companies LinkedIn lists, in a few seconds (3 companies in 6 s on 17 Oct 2026). Put the same list on a weekly schedule: from the second run every row adds employeesAddedSinceLastRun and the growth rates. $4 per 1,000 companies, no login, no cookies.
For exact matches, give the LinkedIn URL or the company's website rather than a bare name. A name is matched by guessing, and every row says how it was found (resolvedBy) and how sure that is (matchConfidence: high, medium, low); low matches are never charged: the row is still returned, marked low, so you can check it; turn on Only confident matches to get a short free unconfirmed row instead.
What the filled-in input returned on 17 Oct 2026 (7 s, $0.022), on an account that had run the same list before:
| company | employees today | stated size | since the first run | per month |
|---|---|---|---|---|
| Shopify | 30,331 | 10,001+ | +474 in 54 days | +265 (+0.89 %) |
| Booking.com | 17,357 | 10,001+ | +41 in 9 days | +132 (+0.76 %) |
| Stripe | 16,694 | 5,001–10,000 | −454 in 54 days | employeeGrowthReliable: false (count-went-down): from outside, a real cut and a LinkedIn profile cleanup look the same, so the fall is reported but not called a trend |
The first column is what any company scraper gives you. The other columns exist only because the earlier runs were recorded; on your first run they are empty, and they fill in from your second.
Hiring signals, two switches: tick Add open jobs count to get each company's open jobs on LinkedIn too (Shopify 138, Booking.com 96 on 17 Oct 2026), or set Only companies that moved to 5 to get back only the companies whose headcount or open jobs moved 5% or more since your last run — a hiring signal list for a weekly schedule. Both are off unless you turn them on, at no extra charge.
Same list, next step: paste it unchanged into LinkedIn Company Jobs Scraper for every role those companies have open. Need more companies like these? LinkedIn Lookalike Companies returns the companies LinkedIn lists as similar to each one (10 for Stripe in about 5 seconds); paste their url column back here for their headcount.
Call it from a script or a schedule
curl -X POST "https://api.apify.com/v2/acts/northbell~linkedin-company-growth-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"companies":["stripe.com","https://www.linkedin.com/company/shopify"]}'
The response is the rows themselves (a JSON array). To run it on a timetable instead, save the input as a task in Apify Console and add a Schedule; n8n, Make and Zapier run it through their Apify app with the same input.
Start from whatever list you have. Company websites (stripe.com) and LinkedIn URLs are matched exactly. Plain names (Scale AI, McDonald's, Nestlé) are tried as a LinkedIn handle first and, when that does not give the company, looked up on Wikidata, which records many companies' LinkedIn page and official website; a page found that way is returned only when its website agrees with the one Wikidata lists. A website is matched to the right LinkedIn page and checked against the company's own website — domainMatch tells you whether it matched — so booking.com returns Booking.com, not a café called Booking. $4 per 1,000 companies, no login, no cookies.
Coming from LinkedIn job posts? The free LinkedIn Job Details Actor returns each job's companyUrl (and the run's companyUrls list in OUTPUT); paste those here as they are.
Then keep running it, and you get the thing a single scrape cannot give you: how fast each company is growing.
The first run records today; the second run is where growth starts. On 9 October 2026 a first run of 16 companies had employeesAddedSinceLastRun empty on every row, and the next run filled it on all 16. Put your list on a weekly schedule from day one.
Anthropic says 501–1,000. LinkedIn counts 6,163.
Every company page carries two different numbers for the same thing:
| source | when it was last true | |
|---|---|---|
501-1,000 employees | the size band an admin picked from a dropdown | whenever they last thought about it |
6,163 employees | LinkedIn counting profiles that list this employer | today |
Measured live on 9 October 2026 (headcounts move every day, so your run will differ a little). The top of the stated band is less than a fifth of the real number — and it will keep pointing there until somebody remembers to change it. Stripe states 5,001–10,000 and counts 16,618. OpenAI states 1,001–5,000 and counts 11,258.
This Actor hands you both numbers, plus bandDrifted, bandDriftDirection and bandDriftRatio so you can find the companies whose own description of themselves has gone stale. Those are usually the ones that grew.
Run it again and again
- On a schedule — save your input as a task and add a Schedule: the same company list every day. Send each run to Google Sheets, Slack or email with an integration on the task.
- Watch for changes — Nothing to switch on: from the second run each row compares with the last one (
employeesAddedSinceLastRunand the growth rates), and the series sharpens as the days add up. - In bulk — Put every company in Companies — websites, LinkedIn links or names — in one run.
The number that only means something twice
17,148 employees is a fact. 17,148, up from 16,148 a month ago is a signal — that a company is hiring hard, that a competitor is scaling, that a prospect just raised.
Headcount cannot be back-filled. There is no endpoint that tells you what a company's headcount was last month. If you did not record it then, that month is gone. This Actor records it and keeps the series (illustrative numbers):
stripeJul 25 16,148 employees 1,553,570 followersAug 24 17,148 employees 1,653,570 followers─────────────────────────────────────+1,000 / month +6.19 % / month
What you get
Every run appends to your dataset. Rows are tagged by type.
company — one row per company.
| field | meaning |
|---|---|
employees | the real headcount LinkedIn counts today |
followers | follower count today |
sizeBand, sizeBandMin, sizeBandMax | what the company says about itself |
bandDrifted, bandDriftDirection, bandDriftRatio | how far the stated band is from reality, and which way |
employeesChanged, employeesPerMonth, employeesPercentPerMonth | growth, measured across your own observations — or, on a company's first run, from a Web archive copy of its page |
employeesFromDate, employeesFromSource, archiveUrl | where the growth starts: the date, your-runs or web-archive, and the archived copy it was read from |
employeeGrowthReliable | false when the figure cannot be trusted — see below |
employeesAddedSinceLastRun | change since you last looked |
followersChanged, followersPerMonth, followersPercentPerMonth, followerGrowthReliable | the same for followers |
observedDays, observations, firstSeenAt | how long you have been watching and how many samples you have |
industry, headquarters, founded, website, companyType, specialties, tagline | the profile itself |
locations, locationCount, locationCountries | the company's offices as its page lists them: [{address, country, isPrimary}] (the primary one is the headquarters), how many, and the countries they are in |
guessedFrom | what you typed, when it was a name or a website rather than a LinkedIn handle |
resolvedBy | how the company was found: linkedin-url (the URL or handle you gave), website (its website is the domain you gave), company-website-link (the LinkedIn link on the company's own site), wikidata-website, wikidata-owner (the page of the company Wikidata says owns or makes the product at that website: line.me → LINE's operator, medium), wikidata, similar-companies, website-same-name, largest-same-name, name-without-legal-suffix, name (guessed from the name), website-other-site (no page with your domain; the first same-name page) |
matchConfidence | high (the URL you gave, or a page whose website or Wikidata record matches), medium (guessed from the name and the page carries that name), low (neither the name nor the website matches what you gave, or a page under 1,000 followers whose website only shares the name). With Only confident matches, low matches come back as free unconfirmed rows |
matchedBy | how a name was matched: name-without-legal-suffix (Siemens AG → siemens), wikidata (see below) or largest-same-name (a one-word name whose guessed page was small, replaced by the same-name page at a usual LinkedIn variant such as okta-inc- or gong-io with at least ten times the followers). Absent when the handle was used as typed |
wikidataId | the Wikidata item (for example Q38076) a wikidata match came from. Only on those rows |
domainMatch | for a website input: true, "same-name" or false - whether the page's own website matched |
similarTo | on companies added by similarPerCompany: the listed company they are similar to |
similarCompanies | the companies LinkedIn lists as similar (usually 10): name, slug, url, industry, location — ready to feed back in as the next input |
affiliatedPages | subsidiaries and showcase pages the company links to |
error — anything that failed, written where you will actually see it.
Three questions this answers that a snapshot cannot
"Is this prospect actually growing?" — a company adding 6% headcount a month is spending. One that has been flat for six months is not, whatever its funding announcement said.
"Is my competitor scaling or bleeding?" — employeesChanged goes negative on contraction, and the Actor reports that rather than hiding it.
"Which companies have outgrown their own description?" — bandDrifted finds them. A company still claiming 51–200 while LinkedIn counts 600 is a company that has been too busy to update its profile.
Numbers this Actor refuses to give you
A growth rate computed over three days is mostly noise multiplied by ten. So:
- Fewer than 7 days of observation →
employeeGrowthReliable: false, noteobserved-for-less-than-7-days. The figure is still returned; it is just labelled. - First observation → the Actor looks for an Internet Archive (Wayback Machine) copy of the same LinkedIn page, 60 days to a year old, and measures from it (
employeesFromSource: "web-archive", with the date and a link to the copy). No copy → no rate at all. One point has no slope, and inventing one would be a lie with a decimal point on it. - Headcount went down →
count-went-down. Real contraction and a LinkedIn profile cleanup look identical from outside, so the Actor reports the fact and declines to call it a trend. - No count on the page →
no-value, rather than a zero that would poison an average.
A rate without that flag is a rate that will eventually lie to you.
No login. Not as a policy — as a property of the code.
This Actor never signs in, never asks you for a session cookie, and never sends one. It reads the public company page, the same one an anonymous visitor sees.
That is enforced, not promised:
- The request headers are a frozen object with no
Cookieand noAuthorizationfield, and nothing can add one at runtime. - A guard rejects any attempt to attach a credential header, and the input schema refuses any field whose name looks like
cookie,session,token,authorpassword. - Unit tests assert all of the above.
There is no field in which a li_at cookie or any other session could be passed, and nothing in the code that could send one.
Two more things it gets right
A page that parses to nothing fails loudly. If neither the follower count nor the headcount can be read, the Actor raises rather than emitting a row full of nulls. A silently empty result is indistinguishable from a company that shrank to zero, and you would not notice for months.
A failed fetch becomes a row, not a log line. Nobody reads run logs. Failures land in the dataset as error rows, and the run is marked failed when nothing at all came back because LinkedIn refused or did not answer. A company page that does not exist is an answer, not a failure: the run succeeds with a free error row saying how to enter that company, so a workflow that sends one company per run is not stopped by a typo.
Input
{"companies": ["stripe", "https://www.linkedin.com/company/shopify", "booking.com", "Scale AI", "McDonald's"],"lookUpNames": true,"maxRequestsPerMinute": 20}
lookUpNames (default true) turns the Wikidata lookup for names on or off. Leave it on for lists of company names; switch it off if your list is only LinkedIn URLs, handles and websites.
includeOpenJobs (default off) adds openJobs — the company's open jobs on LinkedIn, worldwide; LinkedIn shows at most "1,000+" for big employers (openJobsIsLowerBound: true) — and openJobsAddedSinceLastRun; one more request per company, no extra charge. Added 2026-10-17.
Start from one company. similarPerCompany (0–10, default 0) also records the first N companies LinkedIn lists as similar on each company's page — type stripe with similarPerCompany: 10 and you are tracking Stripe and ten of its peers. Added companies are ordinary rows with similarTo (the company they came from), charged like any other; they are not expanded again. Added 2026-10-24.
minChangePercent (default empty = every company) returns only the companies whose headcount (or open jobs, when added) moved by at least that many percent since your last run, plus companies seen for the first time; the others are still checked and billed like any returned company and added to your history, and are named in one free notice row. Added 2026-10-17. Each returned row then says why, as flat columns that read the same in JSON and CSV: the change as a count and as a percent (employeesAddedSinceLastRun, employeesPercentSinceLastRun — so +2 at a 20-person company and +200 at a 2,000-person one are told apart), previousEmployees, previousObservedAt, comparedDays, observations and one sentence, changeReason — for example Employees +15% (+180, 1,200 → 1,380) in 90 days: at or above your 5% threshold. With open jobs added, previousOpenJobs too. Added 2026-10-18.
Handles, full LinkedIn URLs, company websites and company names all work:
| you give | it reads | row says |
|---|---|---|
stripe or linkedin.com/company/stripe | linkedin.com/company/stripe | — |
stripe.com, https://www.notion.so/product | the LinkedIn page whose website is that domain (tries stripe, stripe.com, stripehq, stripeinc…) | guessedFrom, domainMatch: true, "same-name" (notion.so ↔ notion.com) or false |
Scale AI, Snowflake Inc., McDonald's | scale-ai, then scaleai; for a name with a legal ending, also the name without it (siemens for Siemens AG), used only when that page's name matches; then the LinkedIn page and website that Wikidata lists for a company of that name (see below) | guessedFrom, matchedBy (name-without-legal-suffix or wikidata), wikidataId |
Entries that cannot be read become a free error row; the rest of the run carries on. The error row says what was tried and how to enter the company instead. Two entries that end on the same LinkedIn page (for example Nestlé and Nestlé S.A.) are recorded and charged once; the second gets a free error row that says so.
How a name is matched
- The handle you would expect -
Scale AI→scale-ai,scaleai; accents and apostrophes dropped (L'Oréal→loreal). - Without the legal ending -
Siemens AG→siemens, used only if that page's company name matches yours. - Wikidata - the name is searched on Wikidata (public, no key). Wikidata often records a company's LinkedIn page (
mcdonald's-corporation,nestle-s-a-) and its official website. The page is fetched and used only if its website is on the same domain as the website Wikidata lists (or, when Wikidata lists no website, if the page's company name matches yours). If Wikidata names only a website, the usual handles for that website are tried the same way. At most six extra LinkedIn pages are fetched per name. - One-word names that were found in step 1 (
anthropic,Klarna,Shopify Inc) are also checked against Wikidata, because a one-word handle can belong to a different, smaller company. The page is replaced only when exactly one Wikidata company has that name and a LinkedIn page, the page you got has none of that company's websites, and the page Wikidata points to has the company's main website. Otherwise you keep the page you got, as before.
A row matched through Wikidata says matchedBy: "wikidata" and carries the wikidataId. A row that was not matched is never returned and never charged. Wikidata is asked at most once a second, and what it answered is remembered for 30 days in your history store, so a daily run over the same list does not ask again.
LinkedIn URLs are the exact input; names and websites depend on the company. LinkedIn's page address often differs from the legal name. Measured on 9 October 2026 from our own machine, with 16 real company names (Zoom Video Communications, Procter & Gamble, McDonald's, L'Oréal, Nestlé, Siemens AG, Toyota Motor Corporation, Rakuten, Klarna, Revolut, Canva, datadog, Snowflake Inc., anthropic, Scale AI, Shopify Inc):
| right page | a different page | not found | |
|---|---|---|---|
| handle guesses only | 9 | 1 (anthropic gave a smaller company with 18 people; Anthropic's own page is anthropicresearch) | 6 (Zoom Video Communications, McDonald's, L'Oréal, Nestlé, Toyota Motor Corporation, Snowflake Inc.) |
| with Wikidata (this version) | 16 | 0 | 0 |
Names are looked up only for companies Wikidata knows; see the notes below. Re-measured on 28 October 2026 on the live Actor: 11 company websites from 7 countries (stripe.com, klarna.com, personio.com, booking.com, gitlab.com, mercari.com, freee.co.jp, zalando.de, doctolib.fr, rakuten.co.jp, spotify.com) all returned the right page, 7 with matchConfidence: high and 4 medium (the page lists a careers or regional site); 10 one-word names (Grab, Wise, Square, Bolt, Monzo, Figma, Linear, Ramp, Brex, Deel) all did too. squareup.com was missed at first and now finds Square (/company/joinsquare, which lists squareup.com). Check matchConfidence, and use the LinkedIn URL when it matters.
Sizing a run
One request per company. 100 companies is 100 requests, about five minutes at the default rate.
A plain name costs more the first time you run it: two requests to Wikidata (the search, then the company's record, at least a second apart) and sometimes up to six more LinkedIn pages. On 9 October 2026 those 16 names took 36 LinkedIn requests (27 without Wikidata) and 28 Wikidata requests: about 70 seconds in total, against about 17 without Wikidata. The answers are remembered for 30 days, so running the same list again made no Wikidata requests at all. Scale AI and Procter & Gamble were found by their handles and did not ask Wikidata.
Daily runs
Just run it on a schedule with the same company list. Every run adds a point to each company's series, and the growth figures sharpen as the history deepens. Seven days in, the rates become reliable.
What you pay for
Pay per event, charged only for results actually delivered:
| event | price | when |
|---|---|---|
| Actor start | $0.01 | once per run that records a company |
| Company recorded | $0.004 ($4 per 1,000) | one company's profile, counts and growth figures delivered |
100 companies cost $0.41. A daily run over 50 companies costs about $6 a month.
Our own running cost is about **$0.254 per 1,000 rows** of Apify platform usage at 512 MB (22-run measurement, Sept 2026 — [how it was measured](https://dev.to/apify/i-measured-what-my-11-actors-cost-to-run-the-96x-spread-was-mostly-one-config-field-hoj)) — already included in the price above; nothing is billed on top.A failed fetch is never charged. A dead handle produces an error row and no charge. You are paying for data, not attempts. The $0.01 run-start fee is charged together with the first company recorded; a run that finds no company costs nothing.
Limits worth knowing
- Headcount counts LinkedIn profiles, not payroll. It undercounts companies whose staff are not on LinkedIn and overcounts stale profiles. It is a consistent proxy, tracked over time — which is exactly what makes the change meaningful even when the absolute number is not.
- Some pages carry no headcount at all (very small or new companies). Those rows report
employees: nullrather than a guess, andemployeesSource: "none"so you can tell that apart from a parsing failure. - Need the payroll figure the state publishes instead (supplier checks, KYC, small companies with no LinkedIn headcount)? Official Company Headcount returns it from the business registers and tax boards of France, Norway, the UK, Latvia, Estonia, Czechia, Slovakia, Romania and Japan, and from the Form 5500 filings of US employers (by EIN or name), with its date and source. The two answer different questions: payroll as declared, against people on LinkedIn today.
headquarters,foundedandspecialtiesare not on every page — on 9 October 2026, 15, 8 and 15 of 16 large companies had them.employees,followers,sizeBand,industry,websiteandcompanyTypecame back on all 16.sizeBandMaxis empty for the10,001+band, which has no upper limit (9 of the 16), andbandDriftRatiois empty for companies inside their stated band (10 of the 16).- Names found through Wikidata need Wikidata to know the company. It lists a LinkedIn page or a website for many large and mid-size companies and for few small ones; a name it does not know, or knows without either, ends as a free
errorrow. Spelling matters: the name must equal the company's Wikidata label or one of its aliases (legal endings and accents are ignored). On 9 October 2026L'Oréal,NestleandUberwere found andLorealandUber Technologieswere not; for the last one, the alias Wikidata matches is "Uber Technologies, Inc. (San Francisco, CA)". When a name fails, enter the LinkedIn URL or the name Wikidata uses. - Big groups list many regional pages (Wikidata lists eight LinkedIn pages for McDonald's, thirty-six for Toyota). The page closest to the name is tried first and used only if its website matches the group's main website; a country page is not returned for the group's name.
- If a name now resolves to a different page than before (
anthropicgave a different company until this version), its history starts again under the new handle. The rows already in your dataset are not changed. - On a company's first row, growth needs a Web archive copy of its page (60 days to a year old). On 21 October all four companies new to our account (Canva, Monzo, Vercel, Datadog) had one, 61 to 111 days old, and growth was filled on the first run; small companies are archived less often, and without a copy growth starts on your second run.
employeesAddedSinceLastRunalways compares with your own previous run, so it is empty on the first one. - The rate-limit budget persists in a key-value store, so overlapping runs of this Actor share one budget rather than stacking up.
On data and privacy
This Actor collects company pages, not people. It does not read, store or return employee identities, profiles, names or contact details — the headcount is a count and nothing else.
Taglines pass through to your dataset but are never written to the Actor's own history. The persistent store holds numbers and identifiers only: handles, counts, dates, and the remembered Wikidata lookups for names (the company's name, its Wikidata item, LinkedIn handle and website). Wikidata is asked about company names only, and only its company facts are read - nothing about people.
Company logos are not redistributed.
Storage
History lives in a named key-value store, linkedin-company-history, so it survives between runs. It also keeps the Wikidata lookups for names (keys starting wikidata/, valid for 30 days). Deleting it resets the baselines — every company reports as a first observation again, and growth goes quiet until it has two samples a week apart.
Running locally
npm installnpm test # 66 unit tests, no network, including the no-login guarantees and the Wikidata matching
For AI agents
This Actor works well as an agent tool: the input schema is small and fully described, every run returns structured rows, and failures come back as data rather than silent gaps. Use it when you need to:
- get a LinkedIn company's real employee count and headcount growth
- scrape LinkedIn company pages: industry, HQ, founding year, follower count, without login
- turn company names like McDonald's or Nestlé into the right LinkedIn company page (via Wikidata, checked against the company's website)
- compare stated company size band vs actual headcount on LinkedIn
Use it from Claude Code (or another coding agent)
Save this as ~/.claude/skills/linkedin-company-growth/SKILL.md (other agents that read SKILL.md files: their skills folder), put your Apify API token in the APIFY_TOKEN environment variable, and ask the agent in plain words — "Get the real LinkedIn headcount and growth for these companies: stripe.com, monzo.com".
---name: linkedin-company-growthdescription: Real LinkedIn headcount, followers, industry, HQ and headcount growth for a list of company websites, LinkedIn URLs or names. Runs the Apify Actor northbell/linkedin-company-growth-scraper with the user's APIFY_TOKEN.---Run: curl -s -X POST "https://api.apify.com/v2/acts/northbell~linkedin-company-growth-scraper/run-sync-get-dataset-items?timeout=300" -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" -d '{"companies": ["stripe.com", "monzo.com"]}'For long lists start `/runs` instead and read the dataset when the run finishes.Read matchConfidence on every row: show low rows as unconfirmed (they are not charged). Growth figures appear from the second run of the same list.Never print the token. Tell the user the price on the Actor's Store page before a large run.
Prefer MCP? Add https://mcp.apify.com?tools=northbell/linkedin-company-growth-scraper as a remote MCP server — in Claude Code: claude mcp add --transport http apify "https://mcp.apify.com?tools=northbell/linkedin-company-growth-scraper" — and sign in to Apify when asked; the Actor then shows up as a tool.
More no-login scrapers by northbell
Every one of these reads only public pages — no login, no cookies — and most of them record the numbers that cannot be back-filled if you don't capture them today.
LinkedIn jobs
- LinkedIn Jobs Scraper with Applicant Counts — jobs plus how fast applicants are arriving
- LinkedIn Jobs Scraper — Filters That Actually Work — the experience/workplace filters LinkedIn silently ignores, applied for real
- LinkedIn Jobs Salary Data — Filter by Pay — salary parsed into numbers so you can filter by yearly pay
- Fast LinkedIn Jobs Scraper — bulk job listings, cheap and quick
- LinkedIn Company Jobs Scraper — every open role at a company you name
LinkedIn companies
- LinkedIn Company Scraper with Headcount Growth — the real headcount and how fast it's growing
- LinkedIn Company Posts + Engagement — a company's posts with exact reaction and comment counts
- Official Company Headcount — the headcount from business registers and tax boards (8 European countries, Japan and the US), with source and date
App stores
- App Store Rank & Rating Scraper — iOS keyword rank and rating changes over time
- Shopify App Reviews Scraper — Filter & Sort by Rating — exact per-star review counts, filter and sort
- Google Play Rating & Review Tracker — an Android app's rating tracked day by day