LinkedIn Post Scraper API
Our LinkedIn post scraper takes a public /posts/ URL and returns structured JSON: the full post text, engagement counts, hashtags, attached media, the author with their profile link, the post ID, and the published timestamp, all in one request.
Why it is hard
LinkedIn wraps the logged-out post page in the same authwall as the rest of the member surface, so a datacenter request usually gets a "Sign in to view" shell. On a clean residential egress the guest render does carry the post as structured data, and our endpoint reads that; use /posts/ URLs, since /feed/update/ links wall for guests.
Quickstart
curl "https://api.linkedinscraperapi.com/api/v1/linkedin/post?url=https://www.linkedin.com/posts/maryam-asim_i-studied-500-linkedin-posts-this-year-activity-7457771025557061633-pza0&api_key=$API_KEY" import requests
BASE = "https://api.linkedinscraperapi.com"
API_KEY = "YOUR_API_KEY"
# Pass a public /posts/ URL (use /posts/, not /feed/update/).
data = requests.get(
f"{BASE}/api/v1/linkedin/post",
params={
"url": "https://www.linkedin.com/posts/maryam-asim_i-studied-500-linkedin-posts-this-year-activity-7457771025557061633-pza0",
"api_key": API_KEY,
},
timeout=30,
).json()
print(data["postAuthor"]["authorName"], "-", data["postedAt"])
print("likes:", data["engagement"]["likes"], "comments:", data["engagement"]["comments"])
print(data["content"][:200]) Params
| Parameter | Required | Default | Notes |
|---|---|---|---|
url | required | - | A public /posts/{slug} post URL. Required. Use /posts/ links; /feed/update/ URLs wall for guests. |
add_html | optional | - | Pass true or 1 to include the post's raw HTML alongside the parsed content. |
api_key | required | - | Your API key, passed as a query parameter. Get one free at signup. |
Response
{
"content": "I studied 500+ LinkedIn posts this year. The viral ones all follow the same 14 hook patterns. The dead ones all make the same 14 mistakes. Here's what I found: Viral hooks name something specific. Dead hooks stay vague on purpose...",
"content_markdown": null,
"engagement": {
"likes": 517,
"comments": 97,
"shares": null,
"views": null
},
"hashtags": [],
"media": [
{
"mediaType": "image",
"mediaUrl": "https://media.licdn.com/dms/image/v2/D4D22AQHjxZGfkH6JwQ/feedshare-shrink_800/B4DZ39TOQZKkAc-/0/1778071169119?e=2147483647&v=beta&t=6aE81_-uEvV7Pj_4Q_wcWkH70JOttnoxvJRnqT4psCU",
"mediaDescription": "image"
}
],
"mentions": [],
"comments": [],
"postAuthor": {
"authorId": null,
"authorName": "Maryam Asim",
"authorProfileLink": "https://www.linkedin.com/in/maryam-asim",
"authorUsername": "maryam-asim"
},
"postId": "7457771025557061633",
"postLink": "https://www.linkedin.com/posts/maryam-asim_i-studied-500-linkedin-posts-this-year-activity-7457771025557061633-pza0",
"postedAt": "2026-05-06T12:39:31.157Z",
"socialPlatform": "linkedin"
} | Field | Type | Description |
|---|---|---|
content | string | The full post text, from the post's structured data. |
engagement | object | Engagement counts: { likes, comments, shares, views }. Each is an integer when exposed, otherwise null. |
engagement.likes | integer | Reaction count when the render exposes it, e.g. 517. |
engagement.comments | integer | Comment count when the render exposes it, e.g. 97. |
hashtags | array | Hashtags parsed from the post text, without the # prefix. Empty when the post has none. |
media | array | Attached media as { mediaType, mediaUrl, mediaDescription }, e.g. the post's image. |
mentions | array | Mentions parsed from the post. Empty when none are exposed. |
postAuthor | object | The author: { authorId, authorName, authorProfileLink, authorUsername }. |
Use it for
Content and engagement analytics
Creator and thought-leader tracking
Social listening
Swipe files and research
Under the hood
- Full post text The complete post copy comes back in content, parsed from the post's structured data rather than a truncated preview.
- Engagement counts Likes and comments return as integers when the guest render exposes them, with shares and views null when LinkedIn omits them.
- Author and media The author (name, profile link, username) and any attached media come back alongside the text, so a post is one call.
- Consistent social shape Output matches the shape our other social endpoints use, so posts across platforms share one schema in your code.
How it compares
| Our API | DIY (requests / headless) | Official LinkedIn API | |
|---|---|---|---|
| Input by URL | Yes, a /posts/ URL | Manual fetch and parse | No public post-by-URL endpoint |
| Post text and engagement | Parsed content plus counts | Parse the guest render yourself | Only your own or authorized content |
| Setup | API key only | Residential proxies, headless browser, parsers | Marketing Developer Platform approval |
| Author and media | Returned in one call | Extra selectors per field | Limited to authorized scopes |
| Anti-bot and proxies | Residential-first, built in | You build and maintain it | Not applicable |
| Consistent shape | Same schema as other socials | You normalize it yourself | Platform-specific payloads |
| Behavior when walled | Reports the authwall honestly | Silent partial or empty record | Returns only authorized fields |
Pricing
| Plan | Price | Best for |
|---|---|---|
| Free | 1,000 requests | Testing and small jobs |
| Pro | $0.60 / 1k | Production workloads |
| Pay-as-you-go | $0.90 / 1k | Spiky or one-off volume |
Median response 2.6s. You only pay for successful requests.
FAQ
What is a LinkedIn post scraper?
A LinkedIn post scraper is a tool that reads a public post and returns it in a structured format. Our LinkedIn post scraper API takes a /posts/ URL and returns the post text, engagement counts (likes, comments, shares, views), hashtags, attached media, the author with a profile link, the post ID, and the published timestamp as JSON from a single request.
How do I scrape a LinkedIn post?
Send one GET request to our linkedin/post endpoint with the post url and your API key. We route through residential proxies, handle anti-bot checks, and parse the guest render's structured data, so you get clean JSON back without a LinkedIn login or a headless browser of your own.
Should I use a /posts/ or a /feed/update/ URL?
Use the /posts/ URL. LinkedIn's /feed/update/ links wall for logged-out visitors, so they return an authwall rather than the post. The /posts/{slug} share URL is the one that renders public post data, and that is the input this endpoint expects.
Why are shares or views null?
The guest render exposes reaction and comment counts on most public posts, but share and view counts are frequently omitted. When a count is not present we return null for that field rather than guessing, so likes and comments come through as integers while shares and views may be null on a given post.
What happens if the post is private or removed?
On a challenged egress, or for a removed post, LinkedIn serves an authwall or a generic "Top Content" landing with no post data. Our endpoint detects that and returns an error naming the wall and the markers it matched, so a block is distinguishable from a real post. We never emit a post assembled from a landing page.
Do I need a LinkedIn login or the official API?
No. You only need a linkedinscraperapi key, passed as the api_key query parameter. There is no LinkedIn login, no cookies, and no Marketing Developer Platform approval. We read the public logged-out post page. The free tier includes 1,000 requests per month.