LinkedIn Company Posts & Updates Scraper — Likes & Comments
Pricing
from $1.20 / 1,000 posts
LinkedIn Company Posts & Updates Scraper — Likes & Comments
LinkedIn company posts scraper: give it a name, website or LinkedIn URL and get the company's posts and updates with exact reaction and comment counts, plus the real posting date the public page hides. Run it again to see how fast each post is still gaining. No login, no cookies.
Pricing
from $1.20 / 1,000 posts
Rating
0.0
(0)
Developer
Northbell
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
3 hours ago
Last modified
Categories
Share
LinkedIn Company Posts Scraper with Engagement Tracking
Scrape any company's recent LinkedIn posts — the text, whether it carries media, and the exact reaction and comment counts, not the 1K the page displays. Give it the LinkedIn URL, the company website (stripe.com) or just the name.
$1.50 per 1,000 posts — 100 posts cost $0.16 including the run start.
Try it now. The input is already filled in. Press Start: the recent posts of Stripe and Shopify, 20 posts in about 15 seconds, for $0.04. One run reads the ten or so posts LinkedIn shows on a company's public page. Run it daily and it keeps the history, so each post gets its date and its growth.
For marketing and sales teams who follow competitors or accounts: which posts worked, how often a company posts, and when it goes quiet.
Plus the two things the public page will not tell you: when each post went up, and whether it is still gaining.
The page does not show the date. The post id does.
LinkedIn's public company page lists recent posts with no timestamp at all — not a date, not even "3 weeks ago". A post with 95 reactions could be from this morning or from March, and those are opposite facts.
The date is in the post id. LinkedIn ids carry a millisecond timestamp in their high bits, and this Actor recovers it:
urn:li:ugcPost:7496332962540589056 → 2026-08-20T22:30:53Zurn:li:ugcPost:7488672358250233856 → 2026-07-30T19:10:23Z
The bit offset was determined by measurement, not by copying a blog post: across 27 real post ids from one company, a 22-bit shift put every single one inside a three-week window ending on the day they were fetched. A 23-bit shift — the value you would get from "41 bits of 64" — puts them all in 1998.
And when an id does not decode to a plausible date, the Actor returns postedAt: null rather than shipping you a post from the last century.
A post's reaction count is a snapshot of a moving thing
95 reactions on a post published four hours ago is a strong start. 95 reactions on a post published three weeks ago is a post that died quietly.
Reaction counts only climb after publication, and nothing back-fills them. Run this Actor twice and you get what actually happened in between:
stripe · "Kraken is launching Krak Cards in the US..."posted Aug 20 22:30Aug 23 101 reactions + commentsAug 24 441────────────────────────────────+340 in 24h · still climbing
What you get
Every run appends to your dataset. Rows are tagged by type.
post: one row per post.
| field | meaning |
|---|---|
postedAt | recovered from the post id — the page has no date at all |
ageHours | how old the post was when you observed it |
reactions, comments, engagement | exact counts, read from the aria-label, not the rounded 1K on screen |
engagementAdded, engagementPerDay | how fast it is still gaining, across your own observations |
engagementGrowthReliable | false when the figure cannot be trusted — see below |
engagementAddedSinceLastRun | change since you last looked |
postsPerWeek, cadenceChange, cadenceDirection | how often this company publishes, and whether that is rising or falling |
text, hasMedia, postUrl, observations | the post itself |
vanished: a post that was in the company's recent list last run and is not now, with its last known engagement. It was either deleted or pushed out by newer posts, and either way you would otherwise lose the tail of its series.
error: anything that failed, written where you will actually see it.
Three questions this answers that a snapshot cannot
"Which post actually worked?" — not the one with the highest count, the one with the highest count for its age. engagementPerDay ranks them honestly.
"Has this company gone quiet?" — cadenceDirection turns down when a company that was posting five times a week drops to one. Companies go quiet before they announce anything.
"Is this post still alive?" — a post gaining 300 a day is being circulated. One that has been flat for two days is finished, whatever its total says.
Numbers this Actor refuses to give you
- First observation → no rate. One point has no slope, and inventing one would be a lie with a decimal point on it.
- Under 6 hours of observation →
observed-for-less-than-6-hours. Engagement spikes immediately after publication; extrapolating the first hour to a daily rate produces a number that is wrong by an order of magnitude. - Engagement went down →
engagement-went-down. Reactions can be withdrawn and comments deleted; the Actor reports the fact and declines to call it a trend. - Fewer than two dated posts → no cadence. You cannot measure an interval with one point.
- All posts share a timestamp → no cadence, rather than a division by zero dressed up as a number.
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.
If a competing tool asks you to paste your li_at cookie, it is operating your LinkedIn account on your behalf. This one cannot, by construction.
Two more things it gets right
Exact counts, not the rounded ones. The visible text says 1K; the aria-label behind it says 1,234. Diffing rounded numbers produces growth figures that are mostly rounding error, so this Actor reads the precise value.
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 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 so, so a workflow that sends one company per run is not stopped by a typo.
Input
{"companies": ["stripe", "https://www.linkedin.com/company/shopify"],"minEngagement": 0,"onlyTrackedPosts": false,"maxRequestsPerMinute": 20}
One request per company, so 50 companies is 50 requests.
A one-word name is checked against look-alikes. Twilio on LinkedIn is not /company/twilio (a near-empty page) but /company/twilio-inc-. When a one-word name lands on a page that is small or has no posts, the Actor also looks at the usual variants (twilio-inc-, notionhq, mirohq, ...) and takes the biggest page with exactly that name — only if it is at least ten times bigger. The rows carry the slug it settled on; give the LinkedIn URL to skip the guess.
Start from one company. similarPerCompany (0–10, default 0) also reads the posts of the first N companies LinkedIn lists as similar on each company's page — stripe with similarPerCompany: 10 follows Stripe and ten peers. Their posts carry similarTo (the company they came from) and are charged like any other post; added companies are not expanded again. Added 2026-10-24.
Daily runs
Run it on a schedule with the same company list. Each run adds a point to every post's series and to each company's cadence. Set onlyTrackedPosts: true if you would rather keep deepening the history you already have than pick up every new post.
What you pay for
Pay per event, charged only for results actually delivered:
| event | when |
|---|---|
| Actor start | once per run that records a post |
| Post recorded | one post delivered with its counts and growth figures |
A failed fetch is never charged, and neither are posts filtered out by minEngagement. Posts of a page found for a website you gave, whose website and name both differ from it (domainMatch: false), are returned but not charged. You are paying for rows you received. The $0.01 run-start fee is charged together with the first posts recorded; a run that records no post costs nothing.
Limits worth knowing
- About ten recent posts per company. That is what LinkedIn puts on the public company page; the dedicated
/posts/tab redirects to a login wall, so ten is the honest ceiling per run. Running daily accumulates far more than ten over time — which is the point. - Posting cadence is measured across those ten, so it describes recent behaviour, not the company's whole history.
postedAtis derived, not published. It has matched every id tested, and returnsnullrather than a guess when an id does not decode sensibly.- 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 posts published by company pages, not people. It does not read, store or return the identities of the individuals who reacted or commented — reactions and comments are counts and nothing else.
Post text passes through to your dataset but is never written to the Actor's own history. The persistent store holds numbers and identifiers only: post ids, counts, dates.
Images and video are not downloaded or redistributed; hasMedia is a boolean.
Storage
History lives in a named key-value store, linkedin-posts-history, so it survives between runs. Deleting it resets the baselines — every post reports as a first observation again, and momentum goes quiet until it has two samples six hours apart.
Running locally
Our own running cost is about **$0.059 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; nothing is billed on top.npm installnpm test # 30 unit tests, no network, including the no-login guarantees
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:
- scrape a company's LinkedIn posts with exact reaction and comment counts
- track LinkedIn post engagement growth over time
- get real posting dates for LinkedIn company posts
Use it from Claude Code (or another coding agent)
Save this as ~/.claude/skills/linkedin-company-posts/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, for example "What did stripe.com and notion.so post on LinkedIn this week, and which got the most engagement?".
---name: linkedin-company-postsdescription: The latest posts of LinkedIn company pages with reactions, comments and how engagement grew since the last run, from company websites, LinkedIn URLs or names. Runs the Apify Actor northbell/linkedin-company-posts-scraper with the user's APIFY_TOKEN.---Run: curl -s -X POST "https://api.apify.com/v2/acts/northbell~linkedin-company-posts-scraper/run-sync-get-dataset-items?timeout=300" -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" -d '{"companies": ["stripe.com", "notion.so"]}'For long lists start `/runs` instead and read the dataset when the run finishes.Rows of type post carry the text, postedAt, reactions, comments and engagement; vanished rows are posts gone since the last run. Posts of a page whose name and website both differ from the input are returned but not charged.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-posts-scraper as a remote MCP server (in Claude Code: claude mcp add --transport http apify "https://mcp.apify.com?tools=northbell/linkedin-company-posts-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