LinkedIn Post Search Scraper
Scrape public LinkedIn posts by keyword: author, text, exact date, reactions, comments and post URL. No login or cookies.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
searchQueries,maxPosts,resultsLimit(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Inputs
| Field | What it does | Type |
|---|---|---|
searchQueries | Keywords to search public LinkedIn posts with. One run handles several queries. | array |
maxPosts | How many posts to return for each query. 0 means 'as many as discovery finds', bounded by the total limit. Discovery tops out around 90 posts per query. | integer |
resultsLimit | Hard cap on charged rows for the whole run, across every query. | integer |
sortBy | 'relevance' keeps search ranking order, 'date' puts the newest posts first. | string |
postedLimit | Only keep posts newer than this window. Checked against each post's real publish timestamp. | string |
postedLimitDate | Only keep posts published on or after this date. Accepts '2026-01-31', a full ISO string, or a millisecond timestamp. | string |
authorUrls | LinkedIn profile or company URLs. Results are narrowed to posts written by them, for example https://www.linkedin.com/in/williamhgates. | array |
contentType | Filter by the media in the post. Videos, images and documents are detected from the post page; jobs, live videos and collaborative articles are not detected and behave as 'All'. | string |
includeAuthorDetails | Add the author's profile URL, avatar URL and follower count to every row. Free, no extra request. | boolean |
requestTimeoutSecs | Per-request timeout for search pages and post pages. | integer |
What you get
A structured dataset — each result includes fields like:
authorNametextpostedAtreactionsCountcommentsCountpostUrlqueryExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
Related tools in Social Media Scrapers
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
LinkedIn Profile Search Scraper
Find public LinkedIn profiles by keyword, job title, company, school or location. Get name, headline, location, current role and profile URL.
YouTube Shorts Scraper
Extract YouTube Shorts by channel or keyword: titles, video ids, URLs, exact views and likes, publish dates, durations, thumbnails and channel details.
TikTok Scraper - Profiles, Videos, Hashtags & Search
Keyless TikTok scraper for profiles, videos, hashtags & search. Get views, likes, comments & video URLs as JSON/CSV. Cheaper, no API key, failed runs free.
Instagram Scraper - Profiles, Posts & Reels (No Login)
Keyless Instagram scraper: profiles, posts and reels in one run. Likes, comments, views, media, hashtags. No login or API key. From $0.45/1k results.
Tweet Scraper - X / Twitter, No Login, Cheapest
No-login X/Twitter scraper: tweets, profiles, search, likes, retweets, views and media to JSON/CSV. No minimums, no caps, failed runs free. ~$0.14/1k.
Twitter (X) User Scraper - Profiles & Followers, No Login
Keyless X (Twitter) profile scraper: followers, bio, verified status & more by username. No login or API key, pay per profile, failed lookups free.
Where this tool sits
- Categories
- Social Media Scrapers
LinkedIn Post Search Scraper
Type keywords, get public LinkedIn posts back as rows: who wrote it, the full post text, the exact timestamp it was published, how many reactions and comments it has, and the link to the post.
No LinkedIn account. No cookies. No session token to paste in. No proxy of your own to buy.
Price
$0.90 per 1,000 posts ($0.0009 per post), plus $0.003 to start a run.
That per-post rate is the lowest on the Apify store for LinkedIn post search. It is flat: the same $0.0009 per post on the free plan as on any paid plan, with no volume tiers, no minimum spend and no monthly fee.
| Posts returned | What you pay |
|---|---|
| 10 | $0.012 |
| 100 | $0.093 |
| 1,000 | $0.903 |
| 10,000 | $9.003 |
What actually bills
- $0.0009 per post row. Charged once, immediately after a real post is written to the dataset.
The event is called post-found.
- $0.003 per started run. One charge per run at the default 1 GB of memory. The start fee is
billed per gigabyte, so if you raise the memory in the run options you raise the start fee with it. There is no reason to: this Actor is built for 1 GB.
- Free: the sample row. Start a run with empty input and you get one labelled row showing the
output shape, marked "_sample": true, "charged": false. Nothing is billed for it.
- Free: diagnostic rows. If a query finds nothing, or an input field cannot be honoured, the
Actor writes a row explaining why, marked "_diagnostic": true, "charged": false, and finishes
successfully. Those rows are never charged.
- Free: everything the Actor fetched and then discarded. A run with a date, author or media
filter reads more post pages than it returns, and a search engine sometimes answers with posts that have nothing to do with your keywords. You are billed for the rows you keep, never for the work it took to find them.
There is no free trial run. The list above is exactly what is charged, and nothing else is.
Input
| Field | What it does |
|---|---|
searchQueries | Keywords to search public posts with. Several queries per run is fine, up to 20. |
maxPosts | Posts per query. 0 means "as many as discovery finds", bounded by resultsLimit. |
resultsLimit | Hard cap on charged rows for the whole run. Max 1000. |
sortBy | relevance keeps search ranking order, date puts the newest first. |
postedLimit | any, 1h, 24h, week, month, 3months, 6months, year. Checked against each post's real publish timestamp. |
postedLimitDate | Keep only posts published on or after this date. Accepts 2026-01-31, a full ISO string, or a millisecond timestamp. |
authorUrls | Profile or company URLs. Narrows results to posts written by those accounts. Works with or without keywords. |
contentType | all, videos, images, documents. |
includeAuthorDetails | Adds profile URL, avatar URL and follower count. Free, no extra request. |
requestTimeoutSecs | Per-request timeout. Default 25. |
{
"searchQueries": ["b2b sales", "hiring software engineer"],
"maxPosts": 25,
"resultsLimit": 50,
"sortBy": "date",
"postedLimit": "month",
"includeAuthorDetails": true
}
Run it with empty input and nothing is charged — you get one labelled sample row that shows every field, so you can wire up your pipeline before spending anything.
Searching one person's or one company's posts
Put the profile or company URL in authorUrls and leave searchQueries empty to get that account's
recent public posts, or fill in both to get only their posts about a topic:
{
"authorUrls": ["https://www.linkedin.com/in/williamhgates"],
"searchQueries": ["climate"],
"maxPosts": 20
}
Output
One row per post. This is a real row, trimmed only in the text field:
{
"ok": true,
"_sample": false,
"charged": true,
"postUrl": "https://www.linkedin.com/posts/coquinn_b2bsales-saleswisdom-thoughtleadership-activity-7378846497251106816-cw7k",
"activityId": "7378846497251106816",
"authorName": "Corey Quinn",
"authorType": "Person",
"text": "What B2B Sales Taught Me About B2B Sales:\n\nI've been in B2B sales for literally years. Here's what I learned...",
"headline": "B2B Sales: What I Learned",
"postedAt": "2025-09-30T17:41:37.263Z",
"reactionsCount": 151,
"commentsCount": 41,
"postType": "SocialMediaPosting",
"mediaType": "text",
"videoUrl": null,
"imageUrl": null,
"query": "b2b sales",
"retrievedAt": "2026-08-15T13:12:44.907Z",
"authorUrl": "https://www.linkedin.com/in/coquinn",
"authorImageUrl": "https://media.licdn.com/dms/image/v2/D5603AQFJV5OVNEHgbQ/profile-displayphoto-shrink_400_400/0/1711075880570",
"authorFollowers": null
}
| Field | Notes |
|---|---|
postUrl | The canonical post URL. A repost resolves to the original post here. |
activityId | LinkedIn's numeric id for the post. Stable, good as a primary key for deduplication. |
authorName, authorType | authorType is Person or Organization. |
text | The full public post body, newlines and emoji intact. |
headline | LinkedIn's own short title for the post. Often the first line. |
postedAt | Exact ISO timestamp, to the millisecond. Not "3d ago". |
reactionsCount, commentsCount | The public counters at the moment the post was read. |
mediaType | text, images, videos or documents. |
videoUrl, imageUrl | Direct media URLs when the post carries them, otherwise null. |
query | Which of your searchQueries produced this row. |
authorUrl, authorImageUrl, authorFollowers | Only when includeAuthorDetails is true. authorFollowers is frequently null — LinkedIn does not publish it on every post page. |
Rows that are not posts are clearly labelled and never billed: _sample: true for the empty-input
example row, _diagnostic: true with an errorCode and a plain-English details string for
anything that went wrong.
How it works, briefly
LinkedIn's own content search redirects a logged-out visitor to the login page, so this Actor does
not use it. What it uses is the fact that every individual linkedin.com/posts/... page is public
and indexed: it finds the post URLs through public web indexes, then reads each post page directly
and pulls the structured record LinkedIn publishes on it. That record is where the author, the exact
timestamp, the body text and the reaction and comment counters come from — they are not guessed from
a search snippet.
Two consequences worth knowing about. First, the date on every row is exact, and the date filter is applied before a post page is ever downloaded, so a "past week" run does not waste your run time opening four-year-old posts. Second, if a search engine cannot match your keywords it will sometimes answer with real but unrelated LinkedIn posts. The Actor checks that each post actually mentions something you searched for and drops the ones that do not, uncharged, rather than billing you for them.
Requests go out over rotating datacenter addresses. There is no browser anywhere in this Actor, which is a large part of why the price is what it is.
Limits, honestly
- About 90 posts per query is the ceiling. The public indexes hand back roughly that many
distinct post URLs for a given phrase, and asking for more does not produce more. If you need
thousands of posts on a topic, split it into several narrower queries — maxPosts applies per
query, resultsLimit caps the run.
- Very fresh posts take time to appear. A post published in the last hour is often not indexed
yet. postedLimit: "1h" is supported and filtered exactly, but expect thin results; 24h and
week are much more productive.
- Coverage is what the public web has indexed, not LinkedIn's internal search. Well-discussed
topics, hashtags and named people are covered well. Very obscure phrases are not.
- Some posts cannot be read. Members-only updates, deleted posts and a small number of pages
return no public record. Those are skipped silently and never billed.
contentTypevaluesjobs,live_videosandcollaborative_articlesare not detectable on
a public post page. They are accepted so an existing input file still runs, and the Actor writes a free diagnostic row saying the filter was not applied instead of pretending it was.
authorFollowersis often null. LinkedIn only publishes it on some post pages.- Counts are a snapshot.
reactionsCountandcommentsCountare the numbers at the moment of
reading, not a running total.
- Reactions are a total, not a breakdown. You get how many, not how many of each type, and not
who reacted.
- Comment bodies are not returned. You get
commentsCount. The comments themselves are a
different job.
- The author filter is applied to the post's own identifier, which is reliable, but a company
that posts under several pages needs each page URL listed.
- A run has a page budget, and a very selective filter can hit it. Each run starts with an
allowance of pages it may read and earns more as it delivers posts, so a request that needs a
hundred pages to produce three matches stops early rather than burning your run time. It writes a
free PAGE_BUDGET_REACHED row when that happens, and you are charged only for the posts you got.
In practice only heavy contentType or multi-author runs reach it; a normal keyword run does not.
- If every public index is rate-limiting at that moment, the run finishes with a free
SEARCH_ENGINES_REFUSED row and no charge beyond the start fee. Running again a few minutes later
normally works — the Actor reads three independent indexes and only one has to be up.
FAQ
Do I need a LinkedIn account, cookies or a session token? No. Nothing is logged in and nothing is stored. Only pages LinkedIn serves publicly are read.
Is this legal / is it scraping private data? It reads only what LinkedIn publishes to anyone without an account, the same pages a search engine indexes. No private profiles, no connections, no email addresses, no member-only content.
What is the cheapest way to run it?
Ask for what you need. Charging is per returned post, so maxPosts: 20 costs $0.018 plus the
$0.003 start fee. There is no penalty for many small runs beyond the start fee, and no discount for
one big one.
What happens if my keywords return nothing? The run finishes as SUCCEEDED with one free diagnostic row explaining why, and you are charged only the start fee. A failed or empty run never bills for results. If the first three queries in a run all come back empty, the Actor stops early and says so rather than spending the rest of your run time on the same outcome.
Can I get posts from a specific person or company?
Yes — authorUrls. Leave searchQueries empty for everything recent from them, or combine both to
filter by topic.
Can I filter by date?
Yes, two ways, and they stack. postedLimit is a rolling window (24h, week, month and so on)
and postedLimitDate is a fixed date. Both are checked against the post's real publish timestamp,
not against a relative "2w" label.
How do I get more than 90 posts on a topic?
Use several queries in one run. ["b2b sales", "b2b sales prospecting", "b2b sales pipeline"] will
find substantially more distinct posts than any single phrase, because each phrase reaches a
different slice of the index.
Does it work in languages other than English? Yes. The post text is returned exactly as published, in any script, and non-English keywords work.
Can I schedule it?
Yes, like any Actor. sortBy: "date" with postedLimit: "24h" is a good daily monitor. Use
activityId to deduplicate against what you already stored.
What do I do about duplicates across runs?
Key on activityId. It is LinkedIn's own id for the post and it does not change.
Can I use my own proxies? The Actor manages its own egress and does not need any input from you. It never routes traffic through metered per-gigabyte proxies, which is what keeps the per-post price this low.
Will it ever fail a run? Only on a genuine crash. Blocks, empty results and bad input all finish as SUCCEEDED with a free diagnostic row, because a failed run still costs you a start fee and being told "you forgot a field" is not worth paying for.
Integration
The dataset is available as JSON, CSV, Excel, XML and RSS through the standard Apify dataset API, so it drops into Make, Zapier, n8n, Google Sheets or a plain HTTP call. To use it from the API:
POST https://api.apify.com/v2/acts/dami_studio~linkedin-post-search-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>
Content-Type: application/json
{"searchQueries":["b2b sales"],"maxPosts":25}
That returns the rows directly in the response body.