LinkedIn Post Scraper By Keyword avatar

LinkedIn Post Scraper By Keyword

Pricing

$14.99/month + usage

Go to Apify Store
LinkedIn Post Scraper By Keyword

LinkedIn Post Scraper By Keyword

Scrapes posts from any public LinkedIn profile or company page, capturing text, images, videos, authors, timestamps, reactions, comments, hashtags, and post URLs. Ideal for content research, competitor tracking, engagement analysis, and large-scale LinkedIn data extraction

Pricing

$14.99/month + usage

Rating

0.0

(0)

Developer

Scrapio

Scrapio

Maintained by Community

Actor stats

0

Bookmarked

78

Total users

8

Monthly active users

3 days ago

Last modified

Share

LinkedIn Post Scraper — Keyword Posts, Authors and Engagement

LinkedIn Post Scraper By Keyword watches public LinkedIn company pages, personal profiles, and their post graph for brand, product, and hashtag mentions, returning every matching post as one JSON row with its author profile fields and public engagement counts attached. It runs fully logged-out — no cookies, no session — and flags which posts are new since your last run through a persistent named store. Unlike scraping frameworks that return raw HTML, LinkedIn Post Scraper By Keyword returns typed JSON — ready for your model, your database, or your pipeline without any parsing. This guide covers every input field, every output key, and how monitoring teams deploy it long-term.

🧭 What Does LinkedIn Post Scraper By Keyword Do?

LinkedIn Post Scraper By Keyword crawls public LinkedIn company pages, personal profile pages, and — when deepCrawl is on — the surrounding post-URN graph, then matches your keywords, brand terms, and hashtags against each post's text. No LinkedIn account or login is required: every request hits LinkedIn's public, server-rendered, logged-out pages directly. Every returned row bundles three layers of data in one place: the post itself, the author's public profile fields, and the post's publicly visible engagement counts. A persistent named key-value store lets the actor flag which posts are new since the previous run of the same watchlist, turning a one-off scrape into an ongoing keyword monitor.

Key capabilities:

  • Post discovery from company pages and personal profiles, with optional BFS deep-crawl across the post-URN graph (deepCrawl) to surface more posts per source than the first page alone.
  • Keyword and hashtag matching against post text and hashtags → matchedTerms, matchedHashtags, hashtags, isKeywordMatch.
  • Exclude-keyword filtering to drop noise (webinars, giveaways, etc.) before it reaches the dataset (excludeKeywords).
  • Cross-run new-post detection via a named tracking store → newSinceLastRun, firstSeenAt, lastSeenAt.
  • Author profile fields on every post → authorFullName, authorType, authorHeadline, authorProfileId, and a nested author{} object.
  • Public engagement counts on every post, when LinkedIn's logged-out page renders them → numLikes, numComments.
  • Optional AI sentiment classification of the post body across seven selectable models (OFF by default; never fabricated when no key is supplied).

⚡ Features & Capabilities

The feature set splits into what gets matched and tracked, and where this actor sits inside the rest of Scrapio's LinkedIn lineup.

Core features

  • Sources accepted: LinkedIn company page URLs, personal profile URLs, and bare company slugs — normalized automatically to https://www.linkedin.com/... (postSources, base key urls also accepted).
  • Per-source post cap via postsPerSource (default 10), with deepCrawl following the post-URN graph breadth-first to collect more than the first page renders.
  • Text and hashtag matching against keywords/hashtagsToMatch, writing matchedTerms[], matchedHashtags[], hashtags[], mentionHandles[], and a boolean isKeywordMatch on every row.
  • Output filters that are enforced before a row is ever pushed: excludeKeywords, onlyMatchingPosts (keep only keyword/hashtag hits), onlyNewPosts (keep only posts flagged new).
  • Cross-run change detection: trackNewPosts persists each post's activityId into the named key-value store trackingStoreName (default linkedin-keyword-monitor-state), and stamps newSinceLastRun, firstSeenAt, lastSeenAt on every subsequent run against that same store name.
  • Exact post-creation timestamp decoded from the activity URN itself (activityCreatedAt), not just the relative timeSincePosted label LinkedIn shows.
  • Optional aiSentiment classification of text into postSentiment (positive/negative/neutral), across claude-haiku-4-5, claude-sonnet-5, claude-opus-4-8, gpt-4o-mini, gpt-4o, gpt-4.1-mini, and o3-mini — OFF by default, and it returns null rather than a guess if no aiApiKey is supplied or the call fails.
  • proxyConfiguration support for reliability against LinkedIn's rate limiting.

LinkedIn Post Scraper By Keyword within the Scrapio data stack

LinkedIn Post Scraper By Keyword covers cross-company, cross-profile post discovery matched by keyword. For a single company's firmographics plus its similar/affiliated pages, use linkedin-company-about-scraper-with-similar-companies-affiliates. For a company's employee list and public contact info, use linkedin-company-employees-scraper-public-contact-info. For one company's own posts enriched with reaction/comment counts and derived engagement analytics, use LinkedIn-Company-Scraper-Post-Reactions-Comments-And-Engagement-Analytics. For individual profile data and network expansion, see linkedin-profile-scraper-by-similar-profile-finder; for B2B contact emails and phone numbers, linkedin-b2b-emails-scraper-by-phone-email-finder.

Why do developers and data teams scrape LinkedIn?

Teams that pull LinkedIn post data by keyword tend to fall into a handful of recurring workflows — commercial monitoring, AI data pipelines, and research.

🏢 Brand monitoring, social listening and sales-trigger teams

Brand and PR teams add their own company's page plus a watchlist of partner and competitor pages to postSources, set keywords to their brand and product names, and read matchedTerms, isKeywordMatch, and newSinceLastRun to catch every public mention without manually refreshing LinkedIn. Social-listening teams do the same with hashtagsToMatch against a campaign hashtag to measure organic pickup. Sales and recruiting teams watch a target-account list for posts containing "hiring", "we're growing", or a competitor's product name — matchedTerms on a fresh, newSinceLastRun: true row is a live trigger to act on, not a stale weekly report.

📊 AI training data and RAG indexing

The highest-information text field here is text (mirrored in postContent) — the post's actual body copy — paired with hashtags[] and authorHeadline for context. For RAG enrichment, indexing text alongside activityCreatedAt, url, and authorFullName lets an agent answer "who said what about X, and when" with a citable post and exact timestamp. For training data, matchedTerms/isKeywordMatch give a ready-made keyword-hit label without hand-tagging, and every field returns as a stable typed primitive across every post and every run.

📱 Competitive and market intelligence

Competitive-intelligence teams point postSources at a list of competitor company pages, leave keywords broad (product names, feature launches, hiring terms), and track newSinceLastRun plus numLikes/numComments over successive scheduled runs to see which competitor announcements are actually gaining traction, not just which ones exist.

🔬 Research and academic use

Academic and social-media researchers use this actor to build datasets of public keyword or hashtag prevalence across a set of LinkedIn company and profile pages — for studies on corporate communication, professional discourse, or campaign spread. It returns only what LinkedIn's public, logged-out page renders; it does not authenticate and does not access private profiles, groups, or connections-only content.

🎥 Product and SaaS development

Teams building brand-monitoring dashboards, media-intelligence tools, or lead-alert products can run this actor on a schedule against a customer's watchlist and merge matchedTerms, newSinceLastRun, and postSentiment directly into their own alerting logic. Because every field is a stable JSON key rather than parsed HTML, it maps straight into a product's schema without an HTML-parsing layer to maintain.

🍚 Input Parameters

None of the 16 parameters are required — the schema defaults to scraping nothing if postSources is left empty, so it must be supplied for a run to do anything.

ParameterRequiredTypeDescriptionExample Value
postSourcesNoarray of stringsLinkedIn company, profile or post-permalink URLs to monitor — one per line. Runs fully logged-out (no cookies). Base key urls is also accepted.["https://www.linkedin.com/company/microsoft/", "https://www.linkedin.com/company/openai/"]
postsPerSourceNointeger (min 1, default 10)How many posts to collect from each source. Base key limitPerSource is also accepted.25
keywordsNoarray of stringsCase-insensitive terms to match in the post body and its hashtags → matchedTerms[]. Empty = no matching (all posts pass unless a filter is on).["acme", "product launch", "openai"]
hashtagsToMatchNoarray of stringsSpecific hashtags to flag (with or without #) → matchedHashtags[]. All hashtags found are always emitted in hashtags[] regardless.["#hiring", "#ai"]
excludeKeywordsNoarray of stringsDrop any post whose text/hashtags contain one of these terms (case-insensitive).["webinar", "giveaway"]
onlyMatchingPostsNoboolean (default false)When ON and at least one keyword/hashtag is set, only posts that matched are written to the output table.false
trackNewPostsNoboolean (default true)Enable cross-run change detection. Run 1 seeds the store (newSinceLastRun=null). From run 2 onward, first-seen posts are newSinceLastRun=true.true
trackingStoreNameNostring (default "linkedin-keyword-monitor-state")Name of the persistent named key-value store that remembers seen activityIds between runs. Keep it the same across runs of one watchlist."acme-brand-watch"
onlyNewPostsNoboolean (default false)When ON, only posts flagged newSinceLastRun=true are written (requires tracking ON and a prior baseline run).false
publishedAfterNostring (datepicker, nullable)Only include posts published on/after this date. Base key scrapeUntil is also accepted."2026-06-01"
deepCrawlNoboolean (default true)Follow the post-URN graph (BFS) to gather more posts per source instead of only the first page. Base key deepScrape is also accepted.true
includeRawHtmlNoboolean (default false)Attach the raw source HTML to each row for debugging. Base key rawData is also accepted.false
aiSentimentNoboolean (default false)When ON and an API key is supplied, adds postSentiment to each row.false
aiModelNostring enum (default "claude-haiku-4-5")Provider auto-detected from the name: claude-*=Anthropic, gpt-*/o3=OpenAI. Cheaper models are recommended for classification. Accepts: claude-haiku-4-5, claude-sonnet-5, claude-opus-4-8, gpt-4o-mini, gpt-4o, gpt-4.1-mini, o3-mini."claude-haiku-4-5"
aiApiKeyNostring (secret)API key for the selected provider. Falls back to the ANTHROPIC_API_KEY/OPENAI_API_KEY environment variable. Kept private to your run."sk-ant-xxxxx"
proxyConfigurationNoobject (proxy editor, nullable)Optional proxy for reliability and to avoid rate limits.{"useApifyProxy": true}

JSON input example:

{
"postSources": ["https://www.linkedin.com/company/openai/"],
"postsPerSource": 20,
"keywords": ["gpt", "api", "hiring"],
"hashtagsToMatch": ["#ai"],
"excludeKeywords": ["webinar"],
"onlyMatchingPosts": false,
"trackNewPosts": true,
"trackingStoreName": "openai-watch",
"onlyNewPosts": false,
"deepCrawl": true,
"includeRawHtml": false,
"aiSentiment": false,
"proxyConfiguration": { "useApifyProxy": true }
}

Supported URL types and input formats

postSources is normalized automatically: full URLs are rewritten to https://www.linkedin.com/... if needed, and a bare word with no linkedin.com in it (e.g. openai) is treated as a company slug and expanded to https://www.linkedin.com/company/openai. Two source types work end to end today — company pages (/company/<slug>/) and personal profiles (/in/<handle>/) — and deepCrawl then expands each one across the post-URN graph internally (fetching linkedin.com/feed/update/<urn> pages on your behalf, so you never need to supply those directly). One honest limitation: although the field description also mentions "post-permalink URLs," a direct post URL (/posts/...-activity-.../ or any URL containing /activity-) is currently routed to an "Unsupported URL type" error by the actor's own URL-type check rather than being scraped — point postSources at the company or profile page instead and let deepCrawl surface the individual posts.

Example inputs:

  1. Company watchlist: {"postSources": ["https://www.linkedin.com/company/microsoft/", "https://www.linkedin.com/company/openai/"], "keywords": ["copilot", "gpt"]}
  2. Bare-slug shorthand (auto-resolved to a company page): {"postSources": ["openai", "anthropic"]}
  3. Personal profile with hashtag tracking only: {"postSources": ["https://www.linkedin.com/in/satyanadella/"], "hashtagsToMatch": ["#ai", "#leadership"]}

📦 Output Format

Every kept post is pushed as one typed, normalized JSON row, charged as a row_result event. Posts dropped by excludeKeywords, onlyMatchingPosts, onlyNewPosts, a fetch error, or a detected login-wall placeholder card are never pushed to the dataset and are never charged. Results can be exported as JSON, CSV, Excel/XLSX, or XML directly from the Apify Console or API, and browsed live in the dataset's default table view.

Output for posts

{
"urn": "urn:li:activity:7480375037418565632",
"activityId": "7480375037418565632",
"text": "Meet Wei, a Forward Deployed Engineer at Google Cloud who is helping enterprise customers build with our latest AI models. #ai #hiring",
"postContent": "Meet Wei, a Forward Deployed Engineer at Google Cloud who is helping enterprise customers build with our latest AI models. #ai #hiring",
"url": "https://www.linkedin.com/posts/google_forward-deployed-engineer-activity-7480375037418565632-abcd",
"postedAtTimestamp": 1751479452000,
"postedAtISO": "2026-07-02T18:14:12.000000Z",
"timeSincePosted": "3w",
"isRepost": false,
"authorType": "Company",
"authorProfileUrl": "https://www.linkedin.com/company/google/",
"authorProfileId": "google",
"authorHeadline": "Google's mission is to organize the world's information...",
"authorFullName": "Google",
"image": "https://media.licdn.com/dms/image/example-post-image.jpg",
"type": "image",
"images": ["https://media.licdn.com/dms/image/example-post-image.jpg"],
"author": {
"firstName": null,
"lastName": null,
"occupation": "Google's mission is to organize the world's information...",
"id": "google",
"publicId": "google",
"trackingId": null,
"profileId": null,
"picture": "https://media.licdn.com/dms/image/company-logo/google.png",
"backgroundImage": null
},
"authorName": "Google",
"authorTitle": "Google's mission is to organize the world's information...",
"attributes": [],
"comments": [],
"reactions": [],
"numShares": null,
"numLikes": 177,
"numComments": 20,
"activityCreatedAt": "2026-07-02T18:14:12Z",
"hashtags": ["ai", "hiring"],
"mentionHandles": [],
"matchedTerms": ["ai", "google"],
"matchedHashtags": ["ai", "hiring"],
"isKeywordMatch": true,
"newSinceLastRun": true,
"firstSeenAt": "2026-07-11T05:39:11Z",
"lastSeenAt": "2026-07-25T09:12:44Z",
"sourceUrl": "https://www.linkedin.com/company/google/",
"scrapedAt": "2026-07-25T09:12:44Z",
"postSentiment": null
}

comments[], reactions[], attributes[], and numShares are structural placeholders that stay empty/null on every row: LinkedIn does not expose individual comment bodies, reactor identities, or share counts to a logged-out request, so the actor returns honest empty values rather than fabricating them. numLikes/numComments are populated only when LinkedIn's public page itself renders a count; otherwise they are null.

Schema stability and export options

Field names stay stable when LinkedIn updates its front end because extraction targets the page's own JSON-LD SocialMediaPosting/Organization blocks and Open Graph meta tags rather than fragile CSS class names, with a same-shape fallback post built from og:description/og:title when JSON-LD is missing. If a data point LinkedIn removes was never guaranteed, the corresponding field returns null/[] rather than breaking the row. Delivery is the standard Apify dataset: browse it live in the default table view, or export to JSON, CSV, Excel, or XML from the Console or the Apify API.

💡 LinkedIn Post Scraper By Keyword Strategy Guide

🎯 Strategy 1: Real-time enrichment pipeline

Trigger a run whenever a new account, lead, or partner is added to your CRM: pass that account's LinkedIn company URL as postSources, set keywords to your product and campaign terms, and cap postsPerSource low (e.g. 5) for a fast pass. Read back matchedTerms, isKeywordMatch, and numLikes/numComments and append them to the CRM record as enrichment fields — a rep sees, at a glance, whether an account has recently posted about a relevant topic before making contact, with no manual LinkedIn lookup.

🎯 Strategy 2: Scheduled monitoring and alerting

Use an Apify Schedule to run the same postSources list on a recurring cadence — daily for a fast-moving watchlist, weekly for a slower one — keeping trackNewPosts on and trackingStoreName identical across every run so the named store accumulates state instead of resetting. Diff each run against the last on newSinceLastRun and matchedTerms — a post with newSinceLastRun: true and a non-empty matchedTerms[] is exactly the delta worth alerting a Slack channel or ticket queue about, without re-processing posts already seen in a prior run. Setting onlyNewPosts on once the baseline run has completed keeps every subsequent scheduled run's dataset limited to genuinely new activity, which is what an alerting rule should actually fire on.

🎯 Strategy 3: Bulk dataset build

To build a research or brand-mention dataset, feed a full list of company and profile URLs into postSources in one run, leave keywords/hashtagsToMatch broad to capture volume rather than filter it, and set postsPerSource and deepCrawl high enough to pull deep post history from each source. Export the finished dataset directly to CSV or Excel from the Apify Console, or pull it via the API into a database for further analysis. Turning aiSentiment on at build time adds postSentiment to every row in the same pass, so the exported dataset carries a sentiment label per post without a separate labeling step run afterward.

Strategy comparison at a glance

StrategyBest forRun patternOutput format
Real-time enrichmentScoring one account/lead on contactOn-demand, triggered per record, low postsPerSourceFields merged back into CRM/enrichment record
Scheduled monitoringOngoing brand/keyword watchRecurring Apify Schedule, fixed trackingStoreNameDataset diffed run-over-run on newSinceLastRun
Bulk dataset buildResearch or mention-volume datasetsOne run, many postSources, broad keywordsCSV/Excel/API export of the full dataset
Scraper NameWhat it extracts
linkedin-company-about-scraper-with-similar-companies-affiliatesCompany firmographics plus similar/affiliated company pages
linkedin-company-employees-scraper-public-contact-infoPublic employee listings and contact info for a company page
LinkedIn-Company-Scraper-Post-Reactions-Comments-And-Engagement-AnalyticsOne company's posts with reaction/comment counts and derived engagement analytics
linkedin-profile-scraper-by-similar-profile-finderIndividual LinkedIn profile data plus similar-profile network expansion
linkedin-b2b-emails-scraper-by-phone-email-finderB2B contact emails/phone numbers linked to LinkedIn profiles
facebook-posts-search-comments-scraperFacebook posts matched by keyword, with engagement data and comments
reddit-comment-scraper-sentiment-lead-scoringReddit comments matched by keyword, sentiment-scored and lead-scored
twitter-profile-scraper-sentiment-analyzerTwitter/X posts with AI sentiment, topic, and entity tagging

How to integrate LinkedIn Post Scraper By Keyword with your stack

LinkedIn Post Scraper By Keyword works with any language or tool that can make an HTTP request to the Apify API.

Python

import csv
from apify_client import ApifyClient
client = ApifyClient("<APIFY_API_TOKEN>")
post_sources = [
"https://www.linkedin.com/company/openai/",
"https://www.linkedin.com/company/anthropic/",
]
run_input = {
"postSources": post_sources,
"postsPerSource": 20,
"keywords": ["api", "launch", "hiring"],
"trackNewPosts": True,
"trackingStoreName": "ai-brand-watch",
}
run = client.actor("YOUR_USERNAME/linkedin-post-scraper-by-keyword").call(run_input=run_input)
rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
with open("linkedin_keyword_posts.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["authorFullName", "matchedTerms", "newSinceLastRun", "numLikes", "url"])
for row in rows:
writer.writerow([
row.get("authorFullName"),
row.get("matchedTerms"),
row.get("newSinceLastRun"),
row.get("numLikes"),
row.get("url"),
])
print(f"Wrote {len(rows)} matched posts to linkedin_keyword_posts.csv")

Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_API_TOKEN' });
const run = await client.actor('YOUR_USERNAME/linkedin-post-scraper-by-keyword').call({
postSources: ['https://www.linkedin.com/company/openai/'],
keywords: ['gpt', 'api'],
trackNewPosts: true,
trackingStoreName: 'openai-watch',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const row of items) {
console.log(row.authorFullName, row.matchedTerms, row.newSinceLastRun, row.url);
}

Async and scheduled pipelines

For fire-and-forget large watchlists, call .start() instead of .call() to kick off a run without blocking, then poll client.run(runId).get() for its status or list the dataset once it reaches SUCCEEDED. For an ongoing monitor, set up an Apify Schedule (cron expression) in the Apify Console or via the Schedules API so the same postSources/trackingStoreName pair runs automatically on a timer — no server of your own required.

🎯 Who Needs LinkedIn Post Scraper By Keyword? (Use Cases & Industries)

🏢 Brand, PR and social-listening teams

Brand and PR teams keep their own page plus partner and competitor pages in postSources, matching their brand and product names as keywords, and pull matchedTerms/newSinceLastRun/numLikes into a weekly mention report without manually refreshing LinkedIn feeds one page at a time.

📊 Sales and recruiting teams

Sales development reps and recruiters watch a target-account list for posts containing "hiring," "we're growing," or a competitor's product name — a fresh row with isKeywordMatch: true and newSinceLastRun: true is a live outreach trigger, surfaced automatically instead of found by chance while scrolling a feed.

📱 Competitive and market-intelligence teams

Competitive-intelligence teams run a broad-keyword watch across a list of competitor company pages and diff newSinceLastRun and numLikes/numComments run over run to see which competitor announcements are actually gaining traction versus which ones quietly underperform.

🔬 Researchers

Academic and social-media researchers use this actor to build datasets on public keyword or hashtag prevalence across a set of LinkedIn company and profile pages, for studies on corporate communication or campaign spread. It returns only what LinkedIn's public, logged-out page renders — public data only.

🎥 Media-intelligence and monitoring product builders

Teams building brand-monitoring dashboards or lead-alert products run this actor as a backend enrichment step on a customer's watchlist, merging matchedTerms, newSinceLastRun, and optional postSentiment directly into their own alerting logic, with every field a stable typed JSON key rather than parsed HTML.

Scraping publicly accessible data from LinkedIn is generally lawful. In hiQ Labs, Inc. v. LinkedIn Corp. (9th Circuit, 2019, reaffirmed on remand in 2022), the U.S. Court of Appeals for the Ninth Circuit held that scraping data LinkedIn makes publicly available, without logging in, does not violate the Computer Fraud and Abuse Act. This actor only fetches LinkedIn's public, logged-out company and profile pages — it does not authenticate, bypass a login wall, or access private data.

That said, scraping can still violate LinkedIn's own Terms of Service, which is a civil contract matter between the scraper and LinkedIn, separate from CFAA exposure — running this actor against LinkedIn may still put you in breach of those terms.

This actor's authorFullName, authorHeadline, and nested author{} fields surface names and professional details of individuals whose posts appear publicly, which is personal data under GDPR/CCPA-style frameworks when the author is a person rather than a company page. Storing or using that data beyond simply reading it is your responsibility as the data controller.

LinkedIn Post Scraper By Keyword returns only publicly accessible data. What you do with that data is your responsibility — consult legal counsel for commercial applications involving personal data.

❓ Frequently asked questions

Does LinkedIn Post Scraper By Keyword work without a LinkedIn account?

No login is needed. It fetches LinkedIn's public, logged-out company and profile pages directly — no cookie or session is required or used.

How does it handle LinkedIn's anti-scraping measures?

Requests retry with exponential backoff on HTTP 429 and transient errors (bounded by an internal retry count), and a login-wall placeholder card (LinkedIn's "Sign in or join now to see…" stub, occasionally served to logged-out crawlers) is detected and dropped rather than saved as a fake post. proxyConfiguration is available for additional reliability against rate limiting.

Can I run it at scale without getting blocked?

Deep-crawl requests fan out with bounded concurrency (an internal default of 16 concurrent connections). No uptime or block-rate figure is published for this actor — scale postsPerSource and your postSources list up gradually and watch for error rows in the output.

How fresh is the data it returns?

Live. Every run fetches each source page fresh over HTTP at request time; nothing is cached or pre-scraped, and scrapedAt reflects the actual moment of that run's fetch.

Which LinkedIn fields work best for AI training and RAG indexing?

text (mirrored in postContent) is the highest-information field for both RAG (paired with activityCreatedAt, url, and authorFullName as a citable source and exact date) and training data (paired with matchedTerms/isKeywordMatch as a ready keyword-hit label, or postSentiment when AI sentiment is enabled). Every field returns as a typed primitive — string, number, boolean, or array — requiring no normalization before use.

Does the output include personal data, and who is responsible for it?

Yes, when the author is a person rather than a company: authorFullName, authorHeadline, and the nested author{} object surface names and professional details tied to a real individual's public post. The actor returns only publicly available data; the lawful basis for storing and using any personal data sits with you.

Does LinkedIn Post Scraper By Keyword work with Claude, ChatGPT, and other AI agent tools?

Yes, as an HTTP endpoint callable by any agent framework through the Apify API — it is not currently exposed through an MCP server. Every response is typed JSON, so an agent can consume it directly without parsing HTML.

Why are comments, reactions, and share counts always empty or null?

LinkedIn does not expose individual comment bodies, reactor identities, or share counts to a logged-out request. Rather than fabricate them, the actor always returns comments: [], reactions: [], and numShares: null; only numLikes/numComments are populated, and only when LinkedIn's own public page renders a count.

What happens if aiSentiment is enabled without an API key?

The run logs a warning and proceeds with the full non-AI output — postSentiment simply comes back null on every row instead of blocking the run or fabricating a label.

How is "new since last run" actually determined?

By comparing each post's activityId against a snapshot saved in the named key-value store trackingStoreName from the previous run. The very first run against a given store name is always a baseline (newSinceLastRun: null — there is no prior run to diff against); genuine true/false values appear from the second run onward, provided the same trackingStoreName is reused.

ℹ️ Disclaimer

LinkedIn Post Scraper By Keyword extracts only publicly available data from LinkedIn. This tool is intended for lawful use cases only. Users are responsible for complying with LinkedIn's terms of service and applicable data protection laws in their jurisdiction.