LinkedIn Profile Posts Scraper
Scrape LinkedIn profile posts with no login: post text, author, image, publish time and URL. $0.90 per 1,000 posts, flat on every plan.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
profileUrls,postUrls,maxPostsPerProfile(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.
Pricing
$0.0009 per validated public post = $0.9 per 1,000
| You are charged for | When | Price |
|---|---|---|
| Validated public post | A canonical public LinkedIn post row written to the dataset. | $0.0009 |
Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-08-04, and they are what you are actually charged.
Inputs
| Field | What it does | Type |
|---|---|---|
profileUrls | Public /in/ profile URLs. The actor reads only public post links that LinkedIn includes in that profile response. | array |
postUrls | Optional direct public /posts/...activity-... URLs. This does not discover or access private posts. | array |
maxPostsPerProfile | Bounded number of public post pages to fetch from each supplied public profile. | integer |
maxPosts | Overall cap for direct post URLs and post links discovered from profiles. | integer |
requestTimeoutSecs | Timeout for each public LinkedIn page request. | integer |
What you get
A structured dataset — each result includes fields like:
authorNamecontentpostUrlactivityIdtransportExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
1 ready-to-run use cases
LinkedIn Profile Posts by Person
Get a LinkedIn profile's recent posts: text, date and link. Paste the profile URL and run. No login needed.
Related tools in Social Media Scrapers
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
LinkedIn Company Posts Scraper
Scrape public posts from any LinkedIn company page: post text, reactions, comments and URLs. No login or cookies. $0.90 per 1,000 posts.
LinkedIn Post Comments Scraper
Scrape public LinkedIn post comments: text, author name, profile URL, reactions. No login or cookie. Up to 10 per post. $0.60 per 1,000 comments.
RedNote Scraper
Scrape public RedNote (Xiaohongshu) notes: description, author, likes, collects, comments, shares and images. No login. $0.90 per 1,000 notes.
RedNote (Xiaohongshu) Profile Scraper
Scrape RedNote (Xiaohongshu) profiles: nickname, RedNote ID, followers, likes, verified badge, IP location and recent notes. $2.90 per 1,000.
Douyin Hot Search Scraper
Get Douyin trending topics: rank, hot value, views, video count, badge and cover image. Hot, entertainment and society boards. No login. $0.40/1,000.
Facebook Comments Scraper
Scrape comments from any public Facebook post or reel: author, text, date, likes and replies. No login needed from you. $0.25 per 1,000 comments.
Where this tool sits
- Categories
- Social Media Scrapers
- Platforms
LinkedIn Profile Posts Scraper: recent public posts from a person's profile
Give it a public /in/ profile URL and get back the posts LinkedIn links from that page: the post URL, the activity id, the author, the headline text of the post, the image and the publish time when the page states one. You can also hand it post URLs directly and skip the discovery step.
The honest part first. This reads the logged-out version of a profile, and LinkedIn only links a handful of recent posts there. It is a window on what somebody has been posting lately, not an archive of everything they have ever written.
| Input | Public /in/ profile URLs, public /posts/ URLs, or both |
| Output | One row per post |
| Ceiling | 100 posts per run, 25 per profile |
| Account needed | None |
| Price | $0.90 per 1,000 posts, flat on every plan |
📰 What LinkedIn Profile Posts Scraper does
The LinkedIn feed needs an account. Individual post pages do not: LinkedIn publishes them for search engines, and links some of them from the public profile page.
So the run works in two steps. It opens each profile you gave it and collects the post links on that page, keeping only posts by that person. Then it opens each post page and reads what the page publishes about itself: the title line, the preview text, the image and, if the page states one, the publish time. Post URLs you supplied yourself are fetched first, before anything discovered from a profile.
Every post page has to agree that it is the post you asked for, checked on the canonical URL and the activity id in it. A repost or a redirect that lands on a different activity is reported rather than written as a row, so you never get one post's text filed under another post's id.
📥 What you give it
{
"profileUrls": ["https://www.linkedin.com/in/reidhoffman/"],
"maxPostsPerProfile": 10,
"maxPosts": 25
}
| Field | Default | What it is |
|---|---|---|
profileUrls | empty | Up to 20 public /in/ URLs. The run reads the posts linked from each one. |
postUrls | empty | Up to 100 direct /posts/...activity-... URLs, when you already know the posts you want. A feed/update/urn:li:activity link is refused, so convert it to the /posts/ form first. |
maxPostsPerProfile | 10 | 1 to 25. How many posts to take from each profile. |
maxPosts | 25 | 1 to 100. The ceiling for the whole run, direct URLs and discovered posts together. |
requestTimeoutSecs | 20 | 5 to 60 seconds. How long to wait for one page. |
Leave both URL fields empty and you get a single labelled sample row, free.
Two caps, and the lower one wins. Ten profiles at maxPostsPerProfile: 25 is 250 candidate posts, but maxPosts: 25 stops the run at 25. Raise both if you want more.
Watch the clock on big runs. Profiles and posts are fetched one at a time, and the run ends at the timeout on the actor's Settings tab, 180 seconds unless you raise it. Twenty profiles plus a hundred posts will not fit in that.
📤 What you get back
A real row from a recent run, with the image link cut short:
{
"ok": true,
"_sample": false,
"sourceType": "public_linkedin_post",
"postUrl": "https://www.linkedin.com/posts/reidhoffman_your-family-needs-a-cybersecurity-plan-activity-7503529382813143041--ub-",
"activityId": "7503529382813143041",
"sourceProfileUrl": "https://www.linkedin.com/in/reidhoffman",
"authorPublicIdentifier": "reidhoffman",
"authorName": "Reid Hoffman",
"title": "Your family needs a cybersecurity plan. | Reid Hoffman | 111 comments",
"content": "Open-source tools can now turn a single image into a live face swap on consumer hardware, while agents are lowering the cost of far more sophisticated attacks. ... | 111 comments on LinkedIn",
"imageUrl": "https://media.licdn.com/dms/image/v2/D5612AQFZNnO9R5UHvQ/article-cover_image-shrink_720_1280/...",
"publishedAt": null,
"transport": "direct_http",
"retrievedAt": "2026-09-14T05:45:38.560Z"
}
| Field | What it is | |
|---|---|---|
activityId | The digits at the end of the post URL. The stable key for a post, and the right thing to dedupe on. | |
content | The page's own preview text. Look at the row above: it is the post, but LinkedIn trims long ones and glues `\ | N comments on LinkedIn` onto the end. Strip that tail yourself if it gets in the way. |
title | The page title line. Author and comment count are usually part of it. | |
authorName | Split out of that title line, so a post whose own text contains a vertical bar can put a fragment of the text here instead of the name. authorPublicIdentifier comes from the URL and is the safer field. | |
sourceProfileUrl | The profile this post was found on, or null when you supplied the post URL yourself. | |
publishedAt | The publish time when the page states one, null when it does not. It often does not, as in the row above. |
🧾 Reading the output
Three kinds of row, and only real posts cost anything.
| Row | How to spot it | Charged |
|---|---|---|
| A post | sourceType: "public_linkedin_post" | yes |
| The sample row | _sample: true, and it only appears when you run with empty input | no |
| A diagnostic | ok: false and _diagnostic: true | no |
There is no charged field on these rows. sourceType is what separates a real post from a sample or a diagnostic.
A diagnostic row carries an errorCode:
| Code | What it means |
|---|---|
BAD_INPUT | Not a public /in/ or /posts/...activity-... URL. Nothing was requested for it. |
NO_RESULTS | For a profile: LinkedIn linked no posts of that person's own on the public page. For a post: the page that answered was a different activity, usually a repost or a redirect. |
BLOCKED | LinkedIn answered with a challenge page instead of the content. Other URLs in the same run still go ahead. |
RATE_LIMITED | Too many pages too close together. Space your runs out. |
SERVER_ERROR | LinkedIn returned an error of its own. |
NETWORK | The page did not arrive inside requestTimeoutSecs, or LinkedIn answered with something unusable. A deleted post shows up here rather than under a "not found" code. |
Neither a sample nor a diagnostic row fails the run.
▶️ How to run it
1. Open LinkedIn Profile Posts Scraper and click Try for free. 2. Paste profile URLs into Public LinkedIn profile URLs, or post URLs into Public LinkedIn post URLs. 3. Set Maximum posts per profile and Maximum total posts. 4. Click Start. 5. Download the dataset as JSON, CSV or Excel, or read it from the Apify API.
💰 How much does it cost?
$0.90 per 1,000 posts. Flat on every Apify plan, no volume tiers.
One charge per post row. Sample rows and diagnostic rows are never charged, and a profile that turns out to have no public posts costs you nothing for results.
One thing to know about duplicates: the run skips a post URL it has already queued, matched on the URL text. Two different spellings of the same post, which LinkedIn does produce, read as two posts and are fetched and charged twice. Dedupe your input list on activity-<digits> and you will not hit it.
💡 What people use it for
- Seeing what a prospect has posted recently before writing to them.
- Watching a handful of people in your market and picking up the themes they keep returning to.
- Collecting your own posts for a report, without exporting anything from LinkedIn.
- Pulling the post text and image behind a link somebody shared with you.
🚧 What it does not do
- No post archive. Only the posts LinkedIn links from the logged-out profile page, which is a
recent handful. There is no paging back through someone's history.
- No reaction or comment counts as numbers. The count is sometimes inside the
titletext, but
there is no field to sort on.
- No comments. Use the comments actor below for those.
- No private, connection-only or deleted posts, and no posts from a profile that is not public.
- The text can be a preview.
contentis what the page publishes about itself, so a long post
arrives trimmed by LinkedIn, not by this actor.
- No video files or document attachments. One image link at most.
- No retries. A page that fails, fails for that run.
🧭 Which LinkedIn scraper do you need?
| If you want | Use |
|---|---|
| Recent posts from a person's profile | This one |
| Posts matching a keyword, from anyone | LinkedIn Post Search Scraper |
| Posts from a company page | LinkedIn Company Posts Scraper |
| The comments under a post | LinkedIn Post Comments Scraper |
| The person's profile details | LinkedIn Profiles Scraper |
❓ Questions people ask
Do I need a LinkedIn account? No, and there is no cookie field. Nothing to paste, nothing to renew.
Why did I only get a few posts from a profile? Because that is how many LinkedIn links on the public page. Raising maxPostsPerProfile does not make more of them appear.
Can I get posts from a date range? Not from here. Dates are missing on many public post pages, so there is nothing reliable to filter on.
Can I give it a feed/update/urn:li:activity link? Not directly. Open the post, copy the /posts/... URL from the address bar and use that.
Is scraping LinkedIn legal? This reads only pages LinkedIn publishes to the open web for search engines. Posts can contain personal data, which GDPR and similar laws cover, so have a lawful reason for collecting it. Apify's write-up on scraping and the law is a reasonable starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the run ID and the profile or post URL that went wrong. The errorCode on the diagnostic row usually explains it on its own.