LinkedIn Company Posts Lookup: posts scraper from $3/1k avatar

LinkedIn Company Posts Lookup: posts scraper from $3/1k

Pricing

from $2.28 / 1,000 post returneds

Go to Apify Store
LinkedIn Company Posts Lookup: posts scraper from $3/1k

LinkedIn Company Posts Lookup: posts scraper from $3/1k

LinkedIn company posts scraper with no cookies and no account. Give it public LinkedIn company page links and get one flat row per post: link, exact timestamp, text, reaction and comment counts, media type and who posted it. Nothing found, nothing charged.

Pricing

from $2.28 / 1,000 post returneds

Rating

0.0

(0)

Developer

Adrian Voss

Adrian Voss

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

LinkedIn Company Posts Lookup: Company Page Posts Scraper

Give it public LinkedIn company page links and get one flat row per post: the permalink, an exact timestamp, the post text, reaction and comment counts, what media it carried, whether it links out, and who actually wrote it when the page is amplifying somebody else. No account, no cookies, no session token. You pay per post that came back, and a page that returns nothing costs nothing.

Who it's for

  • Competitive marketers. You want to know what four rivals shipped, announced and boasted about this quarter, in a table you can read in ten minutes rather than four browser tabs and a scroll. Exact dates mean you can line their announcements up against your own release calendar.
  • Account teams working named-account outbound. A company's last three posts are the cheapest source of a first line that is not a merge field. maxPosts: 3 across two hundred accounts is a small bill and a very different email.
  • Partner and ecosystem teams. The repost rows are the interesting ones: they show which partners, customers and employees a company chooses to amplify, and the authorName column names them.
  • Content and social benchmarking. Reactions and comments per post, with the media type alongside, tells you what actually works on a page you are trying to learn from.
  • Anyone feeding an agent or an LLM. Field names are stable, one post is one row, and the timestamp is ISO 8601, so a model gets a table it can reason over instead of "2w ago".

Why this one

  • Exact post times, not "2w". LinkedIn prints a relative age on every update and that is all most scrapers pass on. A post's activity id is a Snowflake-style integer whose top bits are the millisecond it was created, so this actor decodes the real timestamp and returns it as ISO 8601 in postedAt. It agreed with LinkedIn's own label on every card in the page this actor was built from. postedAtText keeps the page's wording next to it. "Everything this company posted since the funding round" becomes a filter you can write.
  • It tells you when a post is not the company's. LinkedIn's Updates section mixes the company's own posts with posts it reposted from partners, customers and employees. Read carelessly, those become "things this company said", which is wrong. Here isRepost flags them and authorName and authorUrl name whoever wrote them.
  • A quote-post is one row, not two. When a company writes commentary around somebody else's post, LinkedIn nests the quoted post inside the card. A naive reader emits both and bills you twice for one post. This one emits the outer post and marks it as the company's own.
  • No login, no cookies, no session token, and the actor has no field to put one in. It reads the same public page a signed-out browser gets. When LinkedIn decides a request needs an account, the row comes back BLOCKED and free.
  • You are billed per post, and you can cap it. maxPosts sets the most any one page can return and therefore the most it can cost. A page that returns nothing is a free row.

What you get

One row per post, with the company-level fields repeated on each row so the table joins cleanly.

FieldWhat it is
companyUrl, companySlug, companyNameThe page the posts came from, echoed on every row
postCountHow many posts this run returned for that page, which is also what it billed
postsAvailableHow many the page actually carried, before maxPosts capped it
postUrl, postIdThe post permalink and its numeric activity id
postedAtExact ISO 8601 timestamp, decoded from the activity id
postedAtTextLinkedIn's own wording: 6h, 1d, 2w
editedTrue when the post carries LinkedIn's "Edited" marker
textThe commentary, line breaks kept, cut at 1000 characters
textTruncatedTrue when the cut happened, so you know the text is partial
reactionCount, commentCountExact counts off the page markup, or null when the page published none (a post with no comments yet)
mediaTypevideo, image, document, article or none, read from LinkedIn's own label
hasLink, linkUrlWhether the post sends people somewhere, and where, unwrapped out of LinkedIn's redirect
isRepost, authorName, authorUrlWhether the page is amplifying someone else, and who
query, found, status, message, scrapedAtThe standard result columns on every actor here

Two things the public page does not publish, and this actor therefore does not invent:

  • There is no repost or share counter anywhere in the markup. Reaction and comment counts are the only numbers LinkedIn emits. Rather than ship a column that is empty on every row, there is no repost-count column at all.
  • There is no full archive. The Updates section carries a recent window, ten posts on the page this was built against, and there is no next page a signed-out visitor can request.

Pricing

Misses are free. A page that is blocked, gone, or has no public updates produces a row with found: false and is never charged.

Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

curl "https://api.apify.com/v2/acts/accountable_eel~linkedin-company-posts-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
-X POST \
-H "Content-Type: application/json" \
-d '{"companies":["https://www.linkedin.com/company/stripe","shopify"]}'

n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~linkedin-company-posts-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"companies":["https://www.linkedin.com/company/stripe","shopify"]} (swap in an expression from an earlier node for a real value).

Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~linkedin-company-posts-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"companies":["{{company page}}"]}, mapping the row's company page into the companies array.

MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "LinkedIn Company Posts Scraper | Apify" — the agent will find and run this actor.

How to use

  1. In the Apify Console. Open the actor page and click Start — the companies field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
  2. Via the API. Call it directly with a POST request — no Console needed once you have an API token:
    curl "https://api.apify.com/v2/acts/accountable_eel~linkedin-company-posts-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"companies":["https://www.linkedin.com/company/stripe","shopify"]}'
  3. On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.

Input

{
"companies": [
"https://www.linkedin.com/company/stripe",
"shopify"
]
}

One company per line. Paste the full company page link, the /posts/ link you copied while looking at their updates, or just the part after /company/. School and showcase pages work too. Accepted formats: https://www.linkedin.com/company/stripe, https://www.linkedin.com/company/shopify/posts/, stripe.

Useful options, all optional:

OptionWhat it does
maxPostsThe most posts one page may return, newest first. This is also the most it can cost you for that page.
testRunProcess only the first five companies, so you can check the shape before spending on the whole list.
onlyFoundDrop the rows that came back with nothing. Misses are free either way.
includeKeywords / excludeKeywordsKeep or drop posts by the words in them. Filtered-out posts are not billed.
columnsChoose which fields land in the table.

School pages (/school/...) and showcase pages (/showcase/...) are accepted too, because a pasted CRM column has all three mixed in. A member profile link is rejected as a free BAD_FORMAT row without spending a request.

Output

queryfoundstatuscompanyUrlcompanySlugcompanyNamepostCountpostsAvailablepostspostUrlpostIdpostedAtpostedAtTexteditedtexttextTruncatedreactionCountcommentCountmediaTypehasLinklinkUrlisRepostauthorNameauthorUrlscrapedAt
https://www.linkedin.com/company/stripetrueOK<all posts found (full list)><posted at (exact)><posted (as linkedin shows it)><text was cut at 1000 characters><poster's page>1970-01-01T00:00:00.000Z

Tips

  • Filter on isRepost before you quote anything. A reposted row is somebody else's words on the company's page. authorName tells you whose.
  • Sort on postedAt, never on postedAtText. The relative label is what the page said at fetch time and it ages the moment you store it. The ISO timestamp does not.
  • excludeKeywords is the cheap way to drop noise. A post filtered out by your keywords is not billed, so a run that only wants posts mentioning a product name costs less than the same run unfiltered.
  • Set maxPosts to 3 for a wide sweep. If you are checking two hundred companies for "posted anything recently", three posts each answers it at a fraction of the cost of twenty.
  • Leave the residential proxy on and concurrency low. LinkedIn's sign-in wall fires on IP reputation rather than on rate, so a datacenter address is not a saving. Two at a time is the default for a reason.

vs. alternatives

What it costsWhat you getTrade-off
This actor (linkedin-company-posts-lookup)$0.003 per post returned, $0.00005 actor start, nothing for a missOne row per post with an exact ISO timestamp, text, reaction and comment counts, media type, outbound link, and the real author behind every repostIt reads the recent window the public page serves, roughly the last ten posts. There is no way to page back through a page's history without an account, and this actor will not try.
harvestapi/linkedin-company-posts$2 per 1,000 postsThe highest-rated actor in this niche, 4.97 across 3,270 monthly users, with deeper post historyCheaper per post and it goes back further. Pick this one when you need the exact publish time, reposts separated from the company's own words, or a per-page cost cap.
Clay$0.08 to $0.40 per enriched row in credits, on top of a seatA whole enrichment workspace, waterfalls across dozens of providers, plus the table and the sequencing around itIf you want one place that does everything and you are not counting rows, that is Clay. This is one column, priced per column, callable from Clay via its HTTP step.
Doing it yourselfYour time, plus a sign-in wall that fires on reputation rather than on rate, and markup that nests a quoted post inside its own containerThe same postsThis absorbs the wall handling, the session rotation, the quote-post de-duplication and the timestamp decoding, and it stops charging the moment a page comes back empty.

Prices for third-party tools are their published list prices as of September 2026 and are not tracked here. Check the vendor before relying on the comparison.

FAQ

Do I need a LinkedIn account, a cookie, or a li_at token? No, and there is nowhere to put one. The actor requests the public company page a signed-out browser gets. If LinkedIn decides that request needs an account, the row comes back BLOCKED and free.

Why does the /company/stripe/posts/ URL not work? It does work as input, and the actor strips it. What it cannot do is fetch it: LinkedIn redirects that tab to a login form for anyone who is not signed in. The plain company page carries the same recent updates and is served to guests, so that is what gets fetched.

How far back does it go? As far as the Updates section carries, which was ten posts on the page this was built against and varies by company. There is no page-two for a signed-out visitor, so maxPosts can lower what you get but never raise it above what the page served. postsAvailable tells you what was there.

Some rows have another company's name in authorName. Why? Because the page reposted that company's post. isRepost is true on those rows. Filter it out if you only want the company's own words, or keep it if you are studying who they amplify.

Why is there no repost count? Because LinkedIn's public page does not emit one. The only social numbers in the markup are reactions and comments. A column that is empty on every row is worse than no column.

Why is commentCount sometimes empty? Because the page published no number for that post, which is normal on a post nobody has commented on yet. It is reported as null rather than 0, because "nobody has commented" and "LinkedIn did not say" are different facts.

What does edited mean? LinkedIn shows an "Edited" marker next to the age of a post that was changed after publishing. That marker is reported as its own boolean rather than glued onto the date, so postedAtText stays a clean 6h or 2w.

Does it work for member profiles? No. Feed it an /in/ link and it returns a free BAD_FORMAT row without spending a request. Member profiles have their own actor, linkedin-profile-posts-lookup.

What happens to a page with no public updates? One free row, found: false, with a message saying the page loaded but published no posts a signed-out visitor can read. Nothing is charged.

Personal data, and your responsibility

This actor reads public LinkedIn company pages only. It never signs in, never sends a cookie or a session token, and never requests anything behind the sign-in wall.

Most of what comes back is organisation content rather than personal data, but not all of it: a repost row names the person who wrote the original post, and a small company's page can identify individuals on its own. Where the GDPR, the UK GDPR, the CCPA or a comparable law applies to you, you need your own lawful basis for collecting and using that, and your own answer on retention and notice. LinkedIn's User Agreement also restricts automated collection from its services, and that agreement is between you and LinkedIn.

None of this is legal advice, and nothing here says that any particular use is lawful. That call is yours.