LinkedIn Activity Feed Scraper with Engagement Filters
Pull posts, articles, and reposts from LinkedIn profile activity feeds, with reaction/comment/date filters and a per-reaction-type breakdown. Requires a LinkedIn session cookie.
Input schema
Input fields, types, required flags, descriptions, defaults, and prefills come from the published definition. Prefill examples are distinct from defaults.
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | optional | Choose what to scrape: specific public post URLs, a profile's recent posts, or a company's recent posts. |
postUrls | array | optional | Public LinkedIn post URLs, feed-update URLs, activity URNs or numeric activity IDs. (mode=postUrls) |
profileUrls | array | optional | LinkedIn profile URLs or public identifiers, e.g. https://www.linkedin.com/in/williamhgates/ or williamhgates. (mode=profiles) |
Show all input fields
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | optional | Choose what to scrape: specific public post URLs, a profile's recent posts, or a company's recent posts. |
postUrls | array | optional | Public LinkedIn post URLs, feed-update URLs, activity URNs or numeric activity IDs. (mode=postUrls) |
profileUrls | array | optional | LinkedIn profile URLs or public identifiers, e.g. https://www.linkedin.com/in/williamhgates/ or williamhgates. (mode=profiles) |
companyUrls | array | optional | LinkedIn company URLs or slugs, e.g. https://www.linkedin.com/company/google/ or google. (mode=companies) |
maxPostsPerProfile | integer | optional | Maximum posts to keep per profile or company. Public profile pages expose about 6-8 recent posts and company home pages 2-10, so larger values do not unlock more history. |
mediaType | array | optional | Only keep posts of these media types. Public pages reliably expose text, image, video and article; repost is a pure reshare. Leave empty to keep all. |
postTypes | array | optional | Legacy type filter. Left at its default of six types it changes nothing; any other selection is merged with mediaType. |
datePosted | string | optional | Keep posts published within this window, measured from the run time. |
minReactions | integer | optional | Only keep posts with at least this many reactions. Posts without a readable reaction count are treated as zero. |
minComments | integer | optional | Only keep posts with at least this many comments. Posts without a readable comment count are treated as zero. |
includeReposts | boolean | optional | When enabled, reposts and quote posts are kept with their postType and repostOf fields. When disabled, they are dropped. |
maxItems | integer | optional | Global cap on post records in the dataset. Diagnostic error rows are not counted toward this cap. |
proxyConfiguration | object | optional | Optional. The actor works without a proxy. Supply one only if your runs are consistently blocked. |
Download the published input schema
View complete JSON
{
"properties": {
"companyUrls": {
"description": "LinkedIn company URLs or slugs, e.g. https://www.linkedin.com/company/google/ or google. (mode=companies)",
"editor": "stringList",
"title": "Company URLs",
"type": "array"
},
"datePosted": {
"default": "",
"description": "Keep posts published within this window, measured from the run time.",
"editor": "select",
"enum": [
"",
"r86400",
"r604800",
"r2592000"
],
"enumTitles": [
"Any time",
"Past 24 hours",
"Past week",
"Past month"
],
"title": "Date Posted",
"type": "string"
},
"includeReposts": {
"default": true,
"description": "When enabled, reposts and quote posts are kept with their postType and repostOf fields. When disabled, they are dropped.",
"editor": "checkbox",
"prefill": true,
"title": "Include Reposts & Quotes",
"type": "boolean"
},
"maxItems": {
"default": 1000,
"description": "Global cap on post records in the dataset. Diagnostic error rows are not counted toward this cap.",
"editor": "number",
"maximum": 10000,
"minimum": 1,
"title": "Max Posts",
"type": "integer"
},
"maxPostsPerProfile": {
"default": 50,
"description": "Maximum posts to keep per profile or company. Public profile pages expose about 6-8 recent posts and company home pages 2-10, so larger values do not unlock more history.",
"editor": "number",
"maximum": 500,
"minimum": 1,
"title": "Max Posts Per Target",
"type": "integer"
},
"mediaType": {
"description": "Only keep posts of these media types. Public pages reliably expose text, image, video and article; repost is a pure reshare. Leave empty to keep all.",
"editor": "select",
"items": {
"enum": [
"text",
"image",
"video",
"article",
"document",
"carousel",
"repost",
"poll",
"event"
],
"enumTitles": [
"Text only",
"Image",
"Video",
"Article",
"Document",
"Carousel",
"Repost",
"Poll",
"Event"
],
"type": "string"
},
"title": "Media Type Filter",
"type": "array"
},
"minComments": {
"default": 0,
"description": "Only keep posts with at least this many comments. Posts without a readable comment count are treated as zero.",
"editor": "number",
"maximum": 10000000,
"minimum": 0,
"title": "Minimum Comments",
"type": "integer"
},
"minReactions": {
"default": 0,
"description": "Only keep posts with at least this many reactions. Posts without a readable reaction count are treated as zero.",
"editor": "number",
"maximum": 10000000,
"minimum": 0,
"title": "Minimum Reactions",
"type": "integer"
},
"mode": {
"default": "postUrls",
"description": "Choose what to scrape: specific public post URLs, a profile's recent posts, or a company's recent posts.",
"editor": "select",
"enum": [
"postUrls",
"profiles",
"companies"
],
"enumTitles": [
"Public post URLs",
"Profile recent posts",
"Company recent posts"
],
"prefill": "postUrls",
"title": "Mode",
"type": "string"
},
"postTypes": {
"default": [
"text",
"image",
"video",
"article",
"document",
"repost"
],
"description": "Legacy type filter. Left at its default of six types it changes nothing; any other selection is merged with mediaType.",
"editor": "select",
"items": {
"enum": [
"text",
"image",
"video",
"article",
"document",
"repost"
],
"enumTitles": [
"Text",
"Image",
"Video",
"Article",
"Document",
"Repost"
],
"type": "string"
},
"title": "Post Types (legacy)",
"type": "array"
},
"postUrls": {
"description": "Public LinkedIn post URLs, feed-update URLs, activity URNs or numeric activity IDs. (mode=postUrls)",
"editor": "stringList",
"prefill": [
"https://www.linkedin.com/posts/williamhgates_how-better-data-helped-us-cut-child-mortality-activity-7329207003942125568-_gfJ"
],
"title": "Post URLs",
"type": "array"
},
"profileUrls": {
"description": "LinkedIn profile URLs or public identifiers, e.g. https://www.linkedin.com/in/williamhgates/ or williamhgates. (mode=profiles)",
"editor": "stringList",
"title": "Profile URLs",
"type": "array"
},
"proxyConfiguration": {
"description": "Optional. The actor works without a proxy. Supply one only if your runs are consistently blocked.",
"editor": "proxy",
"title": "Proxy Configuration",
"type": "object"
}
},
"schemaVersion": 1,
"title": "LinkedIn Profile Posts Scraper Input",
"type": "object"
}
Output schema
Published result links and storage locations. This schema is not an exhaustive contract for every field in a dataset record.
| Field | Type | Required | Description |
|---|---|---|---|
posts | string | optional | Dataset containing all scraped LinkedIn posts and any diagnostic error rows. |
Download the published output schema
View complete JSON
{
"actorOutputSchemaVersion": 1,
"description": "One record per LinkedIn post, with full text, author, exact date, reaction and comment totals, top comments, media, post type and repost/quote details.",
"properties": {
"posts": {
"description": "Dataset containing all scraped LinkedIn posts and any diagnostic error rows.",
"template": "{{links.apiDefaultDatasetUrl}}/items",
"title": "LinkedIn posts",
"type": "string"
}
},
"title": "LinkedIn Activity Feed Scraper with Engagement Filters Output"
}
Dataset schema
Published dataset views and any declared field definitions. A view can select only a subset of the returned record fields.
Download the published dataset schema
View complete JSON
{
"actorSpecification": 1,
"title": "LinkedIn Profile Posts",
"views": {
"overview": {
"display": {
"component": "table",
"properties": {
"authorName": {
"format": "text",
"label": "Author"
},
"authorType": {
"format": "text",
"label": "Author Type"
},
"commentsCount": {
"format": "number",
"label": "Comments"
},
"content": {
"format": "text",
"label": "Content"
},
"mediaType": {
"format": "text",
"label": "Media Type"
},
"postType": {
"format": "text",
"label": "Post Type"
},
"postUrl": {
"format": "link",
"label": "Post URL"
},
"postedAt": {
"format": "datetime",
"label": "Posted At"
},
"reactionsCount": {
"format": "number",
"label": "Reactions"
}
}
},
"title": "Posts",
"transformation": {
"fields": [
"authorName",
"authorType",
"postedAt",
"content",
"postType",
"mediaType",
"reactionsCount",
"commentsCount",
"postUrl"
]
}
}
}
}
Key-value schema
Published key-value store definitions, when provided by this build.
This definition is not present in the default published build. See the published README for available documentation.
Published README
Read the full published documentation
LinkedIn Activity Feed Scraper with Engagement Filters
Scrape LinkedIn profile posts, company posts, and individual public post URLs without cookies, logins, or an API key. Get the full post text, author name and profile URL, exact publish date, reaction and comment totals, the visible comments, media, and clear original/quote/repost flags.
What this actor does
- Three modes:
postUrlsfor specific public posts,profilesfor a profile's recent posts, andcompaniesfor a company's recent posts. - Cookieless by design: reads public LinkedIn pages only, so there is no session cookie to export, expire, or leak.
- Exact post data: full text, author identity, ISO publish date, reaction total, comment total, media URLs, and the comments visible on the public page.
- Correct reshare semantics:
postTypeseparatesoriginal,quote, andrepost;repostOfnames the original author and text when LinkedIn exposes them. - Filters: media type, post type, relative date window, minimum reactions, minimum comments, and a global record cap. Empty fields are omitted.
Output per post
postId,postUrl,postedAt— numeric activity ID, canonical post URL, exact ISO publish dateauthorName,authorProfileUrl,authorType,authorAvatar,authorFollowers— author identity;authorTypeisPersonorOrganizationcontent— full post texthashtags— hashtags found in the post textmediaType—text,image,video,article,repost; legacy valuesdocument,carousel,poll, andeventare accepted by the filter but are not exposed on public pagesmediaUrls,mediaItems— image URLs, or a video URL with thumbnail, duration, and embed URLarticleTitle— live article/link title when the post is an article-style or image/link sharecomments— up to 10 visible comments, each withauthorName,text,postedAt, andreactionsCountcommentsCount— total comment count on the postreactionsCount— total reaction count (likes plus other reactions)postType—original,quote, orrepostisRepost,isQuotePost— flags for reshared and quote postsrepostOf— originalauthorName,authorProfileUrl,authorType,content, andpostUrlwhen availableinputUrl— the post or target URL that produced this recordinputProfileUrl— profile URL (mode=profiles)inputCompanyUrl— company URL (mode=companies)dataSource—public-post,public-profile, orpublic-companypartial— present andtruewhen only the discovery stub could be read (for example, the post page was blocked)recordType—postfor post records,errorfor diagnostic rowsscrapedAt— ISO 8601 run timestamp
Legacy compatibility fields remain part of the output contract but are omitted when the public page does not expose them: authorHeadline, articleUrl, linkPreview, documentUrl, pollOptions, mentionedPeople, mentionedCompanies, reactionBreakdown, repostsCount, and viewsCount. See Limitations.
Diagnostic rows have recordType: "error", targetType, inputUrl, status (invalid, not_found, blocked, empty, or fetch_failed), error, optional httpStatus, and scrapedAt. They are not counted toward maxItems.
Input
| Field | Type | Default | Description |
|---|---|---|---|
mode |
string | postUrls |
postUrls, profiles, or companies |
postUrls |
array | – | Public post URLs, feed-update URLs, activity URNs, or numeric activity IDs (mode=postUrls) |
profileUrls |
array | – | Profile URLs or public identifiers, e.g. https://www.linkedin.com/in/williamhgates/ or williamhgates (mode=profiles) |
companyUrls |
array | – | Company URLs or slugs, e.g. https://www.linkedin.com/company/google/ or google (mode=companies) |
maxPostsPerProfile |
integer | 50 |
Maximum posts kept per profile or company (1–500); public pages expose about 6–8 profile posts and 2–10 company posts |
mediaType |
array | – | Keep only text, image, video, article, or repost; empty keeps all |
postTypes |
array | ["text","image","video","article","document","repost"] |
Legacy type filter; left at its default it changes nothing, otherwise it is merged with mediaType |
datePosted |
string | Any time | "" (any time), r86400 (24 hours), r604800 (week), or r2592000 (month) |
minReactions |
integer | 0 |
Minimum reaction count |
minComments |
integer | 0 |
Minimum comment count |
includeReposts |
boolean | true |
Keep quote posts and reposts; set to false to drop them |
maxItems |
integer | 1000 |
Global cap on post records (1–10000); error rows do not count |
proxyConfiguration |
object | – | Optional. The actor works without a proxy |
Example: one public post URL
{
"mode": "postUrls",
"postUrls": [
"https://www.linkedin.com/posts/williamhgates_how-better-data-helped-us-cut-child-mortality-activity-7329207003942125568-_gfJ"
]
}
Example: recent posts from several profiles
{
"mode": "profiles",
"profileUrls": [
"https://www.linkedin.com/in/satyanadella/",
"https://www.linkedin.com/in/adam-grant/"
],
"maxPostsPerProfile": 8
}
Example: company posts with engagement filters
{
"mode": "companies",
"companyUrls": ["https://www.linkedin.com/company/google/"],
"datePosted": "r2592000",
"minReactions": 100,
"includeReposts": false
}
Example: a mixed list of posts, with comments and media
{
"mode": "postUrls",
"postUrls": [
"https://www.linkedin.com/feed/update/urn:li:activity:7518622101692436482/",
"https://www.linkedin.com/posts/nvidia_ai-is-technology-activity-7518633624649252864-9XSo",
"https://www.linkedin.com/feed/update/urn:li:activity:7518239029990023168/"
],
"mediaType": ["image", "video", "article"],
"minComments": 5,
"maxItems": 50
}
Use cases
- Content research — collect full posts and visible comments from experts, creators, and companies you track.
- Competitive intelligence — monitor the latest company posts and compare engagement across peers.
- Lead generation — find active, high-engagement authors and the posts that sparked discussion.
- Influencer vetting — check real reaction and comment counts before a sponsorship or partnership.
- Campaign reporting — export exact dates, post URLs, and engagement totals for a reporting window.
- Dataset building — assemble a clean post corpus for topic modelling, sentiment analysis, or LLM training.
Limitations
- Public surfaces only. Private profiles, member-only posts, and pages that return a login wall or HTTP 999 are reported as diagnostic error rows instead of being bypassed.
- Profile depth is about 6–8 posts. A public profile page shows only its latest posts and has no "load more" for logged-out visitors.
maxPostsPerProfilecannot unlock older history. - Company depth is about 2–10 posts. It comes from the company home page, not the
/posts/tab, which is login-gated. Older company posts are not available. - Comments are the visible subset. The public page exposes up to 10 comments, with text, author name, date, and likes. It does not expose replies, comment permalinks, or commenter profile URLs.
- These fields are not public: shares/reposts counts, views/impressions, per-reaction-type breakdown, reactor or liker identities, and author headlines. They are omitted rather than estimated.
- Some media labels are not public: document, carousel, poll, and event posts are not distinguishable on the public post page, so they are reported as
text,image,video, orarticlebased on what the page exposes. - Date filters apply to what was discovered. In profile and company modes, only the latest page of posts is filtered; the filter does not make older posts appear.
- A failed hydration can produce a
partialrecord. When a profile or company page lists a post but its public post page is blocked, the record keeps the listing text, date, author, and reaction count and is markedpartial: true.
FAQ
Do I need a LinkedIn cookie or login? No. This actor reads public LinkedIn pages only. There is no cookie field to fill and no account risk.
How many posts can I get per profile?
About 6–8 recent posts per profile. That is the public page's own limit; setting maxPostsPerProfile higher does not add pagination.
How many posts can I get per company? About 2–10 recent posts from the company home page. Older company posts are behind a login wall.
Why are shares, views, or the reaction breakdown missing? LinkedIn does not publish those values on public post pages. The actor deliberately omits them instead of returning zeros or guesses.
What is the difference between quote and repost?
A quote adds the sharer's own commentary above the original content. A repost shares the original without new commentary. repostOf carries the original author and text when LinkedIn exposes them.
Are the comments the full thread? No. They are the up-to-10 comments LinkedIn renders on the public page, in the order LinkedIn shows them. Replies and commenter profile URLs are not included.
Why did I get an error row instead of a post?
The post, profile, or company was private, deleted, rate-limited, or returned a login wall. The row's status and error fields say which case occurred; other targets in the same run still return data.
Can I scrape a specific old post?
Yes, if it is public. Put its URL, feed-update URL, activity URN, or numeric ID in postUrls.
Can I run this on a schedule? Yes. A daily run with one public post URL is enough to return data and keep a dataset fresh.
Is this affiliated with LinkedIn? No. This is an independent, third-party actor; it is not operated by or affiliated with LinkedIn.
Python quickstart
Use a schema-derived input and the Python standard library to start a run. An Apify account and token are required for execution.
Source build 2J31IX5LPEdINxWgA. Documentation is regenerated from the default published build; private drafts are not included.