LinkedIn Headcount Monitor
Pricing
from $2.50 / 1,000 headcount snapshots
LinkedIn Headcount Monitor
Employee-count time series for LinkedIn company pages: anonymous snapshots with deltas, open-jobs count as hiring signal, persistent per-watchlist history (up to 400 snapshots), typed values, provenance block. No cookies, no login. Error items never charged.
Pricing
from $2.50 / 1,000 headcount snapshots
Rating
0.0
(0)
Developer
Torchtechnology LTD
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
12 days ago
Last modified
Categories
Share
What does LinkedIn Headcount Monitor do?
LinkedIn Headcount Monitor turns the employee count of any public LinkedIn company page into a time series. Give it a watchlist of company URLs or slugs, run it on a schedule, and every check stores a snapshot and reports the delta against your previous check — headcount grew, shrank, or held — plus the company's open jobs count as a complementary hiring signal. All data comes from anonymous, public LinkedIn pages: no cookies, no login, no LinkedIn account, with a typed JSON output, a per-field coverage status, and an audit-proof provenance block (URL, HTTP status, SHA-256 of the page) on every item.
History is kept in a persistent per-watchlist store (up to 400 snapshots per company) and can be attached to results on demand. History starts with your first check — there is no backfill, and we don't pretend otherwise.
The actor runs on the Apify platform, so you get scheduling, API access, integrations, and proxy rotation out of the box — schedule a daily run and the deltas build themselves. Errors are pushed as transparency items and never charged.
What makes this LinkedIn headcount monitor different?
Most LinkedIn company scrapers sell you a one-off snapshot. The signal is in the change — and that's what this actor is built around.
| Capability | LinkedIn Headcount Monitor | ramsford/linkedin-company-monitor | freshdata/linkedin-company-custom-headcount | riceman/linkedin-company-data-insights-scraper |
|---|---|---|---|---|
| Employee-count time series with deltas (delta + delta %) | ✅ built in, persistent per-watchlist history (up to 400 snapshots) | ⚠️ delta vs. last run only, no history export | ❌ one-off counts | ⚠️ advertised, not verified |
| Open jobs count as complementary signal | ✅ included in the same event | ✅ (bundled in a $0.75 report) | ❌ | ✅ separate charged event |
| Typed values + provenance block (HTTP status, SHA-256 page hash) | ✅ on every item | ❌ | ❌ | ❌ |
Per-field coverage status (obtained/absent/unknown) | ✅ never invents a value | ❌ | ❌ | ❌ |
| Honest about login-only data (headcount by function/location) | ✅ documented limitation | ❌ silent | ❌ | ⚠️ markets "insights" heavily |
| No cookies / no LinkedIn account | ✅ | ✅ | ⚠️ unclear | ✅ |
| Errors never charged | ✅ | — | — | — |
| Price per 1,000 company checks | $2.50 | $750 ($0.75/report) | $8.00 | per-event, multiple charges |
(Competitor data from the public Apify Store API, August 2026.)
How much does it cost to monitor LinkedIn headcounts?
The actor uses pay-per-event pricing — you pay only for delivered snapshots:
snapshot— $2.50 per 1,000 companies checked ($0.0025 each), charged once per successfully checked company. Includes the company fields, the open-jobs signal, the delta computation, and the snapshot store.history-read(opt-in) — $0.50 per 1,000 history snapshots returned ($0.0005 each), charged only whenincludeHistoryis on and past snapshots are actually attached.apify-actor-start— a one-time $0.01 per run.
Errors are never charged. Invalid slugs, deleted company pages (404), blocked requests, and transport failures produce transparency items in the dataset at zero cost.
Cost by volume (snapshots + $0.01 per run)
| Companies per run | Per run | Daily for 30 days |
|---|---|---|
| 10 companies | $0.04 | $1.05 |
| 100 companies | $0.26 | $7.80 |
| 1,000 companies | $2.51 | $75.30 |
The Apify free tier is enough to try the actor on a handful of companies.
Who is this actor for?
| Audience | What they use it for |
|---|---|
| Sales / BD teams | Growth-signal triggers: alert when a target account's headcount or open-jobs count jumps — the classic "they're scaling, time to call" moment. |
| Recruiters & talent intelligence | Layoff detection and hiring-velocity tracking across a competitor watchlist. |
| Investors / VCs | Portfolio and pipeline benchmarking: weekly headcount deltas without a data subscription. |
| Competitive intelligence | Longitudinal headcount series on competitors, with SHA-256 provenance for every data point. |
| Data teams | Clean, typed, honest time series via API — null means verifiably absent, "unknown" means not observable anonymously. |
How to monitor LinkedIn headcount with LinkedIn Headcount Monitor
- Open the actor in Apify Store and click Try for free.
- On the Input tab, add your watchlist: company slugs (
google,apify) and/or company URLs (https://www.linkedin.com/company/google/). - Keep the Watchlist ID as
default, or set your own to keep separate histories for separate lists. - Click Start, then download results from the Output tab — or pull them via the Apify API.
- Schedule it (daily or weekly) in Apify Console — from the second run on, every item carries the delta vs. your previous check.
Using the Apify API (JavaScript)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('CyprusAPI/linkedin-headcount-monitor').call({companySlugs: ['google', 'microsoft', 'apify'],watchlistId: 'competitors-q3',includeJobsSignal: true,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Using the Apify API (Python)
from apify_client import ApifyClientclient = ApifyClient('<YOUR_APIFY_TOKEN>')run = client.actor('CyprusAPI/linkedin-headcount-monitor').call(run_input={'companySlugs': ['google', 'microsoft', 'apify'],'watchlistId': 'competitors-q3','includeJobsSignal': True,})for item in client.dataset(run['defaultDatasetId']).iterate_items():print(item)
Input
The actor accepts the following parameters (see the Input tab for the full form). At least one of companySlugs or companyUrls is required.
| Field | Type | Description |
|---|---|---|
companySlugs | array | LinkedIn company slugs — the part after linkedin.com/company/ (e.g. ["google", "apify"]). One dataset item per company. |
companyUrls | array | LinkedIn company page URLs; the slug is extracted from each URL. |
watchlistId | string | History namespace. Snapshots are stored per watchlist in a persistent key-value store (headcount-history-<watchlistId>). Default default. |
includeJobsSignal | boolean | Also count open jobs per company via LinkedIn's public jobs search (worldwide scope). Default true. |
includeHistory | boolean | Attach past snapshots to each result item (newest first, current check excluded). Charged as history-read per returned snapshot. Default false. |
historyLimit | integer | Max past snapshots attached per company when includeHistory is on (0 = all stored, up to 400). Default 10. |
country | string | ISO alpha-2 proxy exit country (default US) — selects geo-matched proxies. |
requestDelayMs | integer | Optional politeness delay between company checks. Default 0. |
proxyConfiguration | object | Optional Apify proxy settings, used as fallback tiers after your own / the bundled proxy pool. Residential recommended and preselected. |
proxiesByCountry | object | Optional geo-pinned custom proxy URLs per ISO country code — always tried first. |
Output
One dataset item per company check. Core metrics (employeeCount, employeeCountRange, openJobsCount) sit next to the delta block (previousEmployeeCount, employeeCountDelta, employeeCountDeltaPct, openJobsCountDelta, changeSummary), the history metadata (firstSeenAt, checksCount, historyCount), company profile fields, the coverage status, and the capture provenance block. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.
{"companySlug": "apify","companyUrl": "https://www.linkedin.com/company/apify/","name": "Apify","employeeCount": 256,"employeeCountRange": "201-500","companySizeMin": 201,"companySizeMax": 500,"headquarters": "Prague","industry": "Technology, Information and Internet","website": "https://apify.com","openJobsCount": 19,"openJobsCountApprox": false,"previousEmployeeCount": 256,"employeeCountDelta": null,"employeeCountDeltaPct": null,"previousOpenJobsCount": 17,"openJobsCountDelta": 2,"changeDetected": true,"changeSummary": "Open jobs rose from 17 to 19.","isFirstCheck": false,"firstSeenAt": "2026-08-20T15:34:53+00:00","checksCount": 2,"historyCount": 1,"coverage": { "company": "obtained", "jobs": "obtained" },"capture": {"captured_at_utc": "2026-08-20T15:35:49+00:00","url": "https://www.linkedin.com/company/apify/","http_status": 200,"content_hash": "sha256:9f2c…"},"scrapedAt": "2026-08-20T15:35:50+00:00"}
First checks carry isFirstCheck: true and no delta fields — the time series starts with your first check. On later runs, deltas compare against the most recent stored snapshot of the same watchlist. With includeHistory: true, each item also carries a history array of past snapshots (newest first).
Fields follow a three-state discipline: a value means observed, null means verifiably absent, and "unknown" in the coverage block means not observable anonymously right now. Failed companies appear as transparency items with error and errorDescription and are never charged.
Data table
| Field | Description |
|---|---|
companySlug, companyUrl, name | Company identity and canonical page URL |
employeeCount | Employees on LinkedIn — member profiles associated with the company page, as a typed integer from the page's structured data |
employeeCountRange | LinkedIn's company size band (e.g. 201-500, 10001+), plus companySizeMin / companySizeMax |
openJobsCount | Open roles from LinkedIn's public jobs search, worldwide scope. Capped display values ("5,000+") are lower bounds and flagged with openJobsCountApprox: true |
previousEmployeeCount, employeeCountDelta, employeeCountDeltaPct | Delta vs. your previous check of this watchlist (null on first check or when no numeric change) |
previousOpenJobsCount, openJobsCountDelta | Same for the jobs signal |
changeDetected, changes, changeSummary | Human-readable change report (e.g. "Employee count grew from 315,495 to 316,102 (+0.19%)") |
firstSeenAt, checksCount, historyCount | When this company entered the watchlist, how often it was checked, how many snapshots are stored |
history | Past snapshots (opt-in via includeHistory, charged as history-read) |
headquarters, industry, organizationType, website, specialties, companyId | Public company profile fields |
coverage | Per-field-group status: obtained / absent / unknown |
capture | Provenance: capture timestamp, final URL, HTTP status, SHA-256 content hash |
scrapedAt | Item timestamp (ISO 8601, UTC) |
Known limitations
We'd rather you know these up front:
- Headcount by function, location, or seniority (LinkedIn's "Insights" tab) is login-only. We verified this anonymously on 2026-08-20: the insights subpage redirects to LinkedIn's login wall. This actor deliberately does not offer it — no LinkedIn account, no cookies, no exceptions. What you get is the public total (
employeeCount) plus the open-jobs signal. employeeCountis "employees on LinkedIn" — the count of member profiles associated with the company page — not the company's payroll headcount. It is the same figure LinkedIn displays on the public page, and it is exactly what makes a longitudinal signal: the definition is stable, so deltas are meaningful.- The open-jobs count can be rounded. LinkedIn caps large counts at display values like "5,000+" — we store the parsed number as a lower bound and set
openJobsCountApprox: true. - History starts with your first check. There is no backfill of past headcounts — anyone selling you historical LinkedIn headcount series is reselling someone else's stored observations, not scraping history.
- LinkedIn guest endpoints are volatile. Anonymous access is sometimes throttled or auth-walled for specific exit IPs; the actor retries through a proxy fallback chain and, if all tiers fail, pushes an uncharged error item instead of a guess.
Tips and advanced options
- Schedule daily runs in Apify Console — the actor is designed for it: snapshots accumulate per
watchlistId, and from the second run on you get deltas for free. - Separate watchlists, separate histories: use
watchlistIdper segment (e.g.competitors,pipeline,portfolio) — histories never mix. - Alerting: filter runs on
changeDetected: true, or set thresholds onemployeeCountDeltaPct/openJobsCountDeltain your integration (Zapier, Make, Slack webhook). - Proxy fallback chain: each company is attempted through your
proxiesByCountryentries or the bundled pool first, then Apify datacenter, then Apify residential (geo-pinned tocountry). Retries happen only on bot-detection/transport — a 404 is final. - Keep watchlists batched: one run with 100 companies is far cheaper per snapshot than 100 single-company runs (each run carries the fixed start cost).
FAQ
Where does the employee count come from?
From the public company page's structured data (schema.org Organization.numberOfEmployees) — the same "employees on LinkedIn" figure LinkedIn renders on the page. It is scraped live at run time; capture.captured_at_utc records the exact moment.
Do I need a LinkedIn account or cookies?
No. The actor only reads pages LinkedIn serves anonymously. That's a deliberate design constraint: it is also why headcount-by-function/location (the login-only Insights tab) is documented as a limitation instead of being advertised.
Will LinkedIn block the actor?
LinkedIn rate-limits anonymous traffic harder than most sites, which is why residential proxies are preselected and every check retries through a tiered fallback chain (your proxies → the bundled pool → Apify datacenter → Apify residential). Blocked checks surface as transparency items with error / errorDescription and are never charged.
How do I build a real time series?
Run the actor on a schedule (daily or weekly) with a fixed watchlistId. Every run appends one snapshot per company (up to 400 are kept) and reports the delta. Use includeHistory when you want the stored series returned with the results.
Is scraping LinkedIn company data legal?
Web scraping is legal when you extract publicly available data that is not behind a login — a position supported by the hiQ v. LinkedIn precedent in the US. This actor scrapes only anonymous, public pages and never touches login-only data. Note that regulations such as the GDPR in the EU can still apply when company data relates to identifiable individuals; you should have a legitimate reason to process such data. If you are unsure, consult a lawyer. Also review LinkedIn's Terms of Service before scraping. Apify is not liable for how you use the extracted data.
Why did a field come back as null or the coverage as "unknown"?
That is the honest-data design, not a bug: null means the field is verifiably absent on the page, "unknown" means it could not be observed anonymously in this run (e.g. the jobs endpoint auth-walled). The coverage block tells you which case applies — no invented values.
Something isn't working — where do I report it?
Open the Issues tab on the actor's page in Apify Console and describe the problem, ideally with the failing company slug and the run ID. Error items in the dataset (error / errorDescription) already tell you what went wrong for individual companies.
Can you build a custom LinkedIn data solution?
Yes — if you need different fields, company search, or a fully managed monitoring pipeline, reach out via the Issues tab and ask about a custom solution.