The Mine Works
← All posts
tutorial October 8, 2026 · 7 min read Updated October 8, 2026

Monitor Competitor LinkedIn Company Posts on a Schedule

Get every new post from competitor LinkedIn company pages each day or week, with only-new mode and an Apify schedule. No LinkedIn login or cookies.

Try the scraper

The actor referenced in this article. Pay only for results delivered.

View the scraper →

Teams that watch a handful of competitors want the same thing from LinkedIn every week: tell me when one of them posts, and what it said. Opening five company pages each morning to scroll for anything new is a chore that rarely survives the second week, and it leaves no record of what was posted when.

Try it live: LinkedIn Company Posts Scraper: No Login, No Cookies. Pay per result delivered. Failed and empty results are never charged.

The LinkedIn Company Posts Scraper reads public company pages without a login and returns one row per post. Put it on a schedule with only-new mode switched on and each run hands you just the posts that appeared since the last one.

What you get and who it is for

Every row is one post, with the company’s details copied on. These are the fields that matter for monitoring:

FieldWhat it tells you
company_name, company_followersWhich competitor, and its follower count at run time
post_url, activity_idThe link for your alert, and the id to dedupe on
activity_atWhen the item appeared on the company feed (published or reposted)
posted_at, posted_agoPublish time to the second, plus LinkedIn’s own label such as 17h
is_repost, author_typeWhether the company wrote it or reposted a person, partner or showcase page
textThe full post text with its line breaks
media_typenone, image, video, document or article
reactions_count, comments_countExact counts at the moment of the run
mentions, linksTagged companies and people, and the links in the post

Product marketers use it to catch launches and pricing posts the day they go out. Communications teams track announcements and hiring news. Sales teams point it at target accounts and read mentions for the partners and customers those accounts are naming. Hiring news on a page is a summary, and the job ads behind it say more about where a competitor is heading.

The input

{
  "companies": [
    "https://www.linkedin.com/company/stripe/",
    "openai",
    "nvidia",
    "hubspot"
  ],
  "maxPostsPerCompany": 20,
  "postedWithinDays": 7,
  "includeReposts": true,
  "onlyNewPosts": true
}
  • companies takes company page links, showcase page links (/showcase/...) or bare vanity names, up to 500 per run. Numeric ids such as /company/1035/ are refused, because LinkedIn sends logged-out visitors who open them to its sign-in page.
  • onlyNewPosts skips posts an earlier run of yours already delivered, so a scheduled run returns and charges only new ones.
  • postedWithinDays set to 7 keeps the first run to the last week. The actor stops reading a company as soon as its feed goes past that date.
  • maxPostsPerCompany (10 to 70) caps each company per run. 20 is plenty for a daily or weekly check.
  • includeReposts stays on here, because the staff and partner posts a competitor chooses to amplify are part of what it is saying. Untick it to keep only the company’s own posts; skipped reposts are not charged.

What the output looks like

[
  {
    "company_name": "Stripe",
    "company_followers": 1754153,
    "post_url": "https://www.linkedin.com/posts/stripe_introducing-personal-agent-protocol-activity-7513299438086332416-zrLF",
    "activity_id": "7513299438086332416",
    "position": 2,
    "author_type": "company",
    "is_repost": false,
    "text": "We're working with Meta, Sierra, Genesys, Instinct, Rocket, Shopify, and Walmart as founding partners for the Personal Agent Protocol...",
    "posted_ago": "17h",
    "posted_at": "2026-10-06T18:09:36Z",
    "activity_at": "2026-10-06T18:09:36Z",
    "reactions_count": 341,
    "comments_count": 30,
    "media_type": "article",
    "article_title": "Introducing Personal Agent Protocol"
  },
  {
    "company_name": "OpenAI",
    "company_followers": 11878447,
    "post_url": "https://www.linkedin.com/posts/openai_advancing-computer-use-with-ironclad-activity-7513327719082930176-eaol",
    "activity_id": "7513327719082930176",
    "position": 1,
    "author_type": "company",
    "is_repost": false,
    "text": "We’re working with Ironclad to help AI agents get better at complex professional work...",
    "posted_ago": "15h",
    "posted_at": "2026-10-06T20:01:59Z",
    "activity_at": "2026-10-06T20:01:59Z",
    "reactions_count": 427,
    "comments_count": 69,
    "media_type": "article",
    "mentions": [
      {"name": "Ironclad", "url": "https://www.linkedin.com/company/ironclad-inc-", "type": "company"}
    ]
  }
]

These rows come from our run on Stripe and OpenAI on October 7, 2026, with 20 posts per company and only-new mode off. Comparing it with our run 24 hours earlier, 4 feed items were new: 3 on Stripe (one of them a repost) and 1 on OpenAI, which is the set an only-new run would have delivered that morning. The pace differs a lot even between two large pages: in the 7 days before that run, Stripe’s feed had 7 items and OpenAI’s had 2. Counts also keep moving after capture. The Stripe post above had 329 reactions at 09:06 UTC and 341 two hours later.

Run it in Apify Console

  1. Open https://apify.com/themineworks/linkedin-company-posts-scraper and click Try for free (or Start if you already use it).
  2. In Company pages, enter one competitor per line, as a page link or a vanity name.
  3. Set Max posts per company to 20 and Posted within the last N days to 7.
  4. Tick Only new posts (for schedules). Leave Include reposts ticked, or untick it for own posts only.
  5. Click Start and watch the Output tab fill with one row per post.
  6. Use the Export button to download the rows as CSV, JSON or Excel.

Run it from Python

pip install apify-client
import csv
import json
import os
import urllib.request

from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("themineworks/linkedin-company-posts-scraper").call(run_input={
    "companies": ["https://www.linkedin.com/company/stripe/", "openai", "nvidia", "hubspot"],
    "maxPostsPerCompany": 20,
    "postedWithinDays": 7,
    "includeReposts": True,
    "onlyNewPosts": True,
})

new_posts = []
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item.get("_type") == "info":
        continue  # the run summary row, never billed
    new_posts.append(item)

new_posts.sort(key=lambda p: p["activity_at"])

# Append to a running log so you keep a history of everything competitors posted.
fields = ["company_name", "activity_at", "is_repost", "media_type",
          "reactions_count", "comments_count", "post_url", "text"]
log_exists = os.path.exists("competitor_posts.csv")
with open("competitor_posts.csv", "a", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=fields, extrasaction="ignore")
    if not log_exists:
        writer.writeheader()
    writer.writerows(new_posts)

# One alert per new post, to a Slack incoming webhook if you set one.
webhook = os.environ.get("SLACK_WEBHOOK_URL")
for p in new_posts:
    verb = "reposted" if p["is_repost"] else "posted"
    message = f"{p['company_name']} {verb} ({p['media_type']}): {p['text'][:140]}\n{p['post_url']}"
    print(message)
    if webhook:
        body = json.dumps({"text": message}).encode("utf-8")
        request = urllib.request.Request(webhook, data=body, headers={"Content-Type": "application/json"})
        urllib.request.urlopen(request)

print(f"{len(new_posts)} new posts")

The script keeps no state of its own. The actor remembers what it already delivered to your account, so every run’s dataset is the alert list, and the CSV grows into a dated record of what each competitor published and reposted.

Run it on a schedule

Save the input above as a task, open Schedules, create a schedule with a cron expression such as 0 8 * * * (every morning at 8:00) or 0 7 * * 1 (Mondays at 7:00), and pick the task. The first run returns the last 7 days of posts; every later run returns only what appeared since. In our own test of only-new mode, a repeat run delivered 0 posts and stopped after one request.

Where the rows go is up to you. Apify’s Google Sheets integration adds each run’s posts to a sheet, the Make, Zapier and n8n apps can forward new rows to Slack or email, and a webhook can call your own URL when a run finishes so a script like the one above can fetch the dataset.

What it costs

You pay per post delivered: $1.49 per 1,000 posts on the Bronze plan, $1.29 on Silver, and $0.99 on Gold, Platinum and Diamond, plus a flat $0.005 run start fee per run. Posts an earlier run delivered, reposts you switch off, posts outside your date window and company pages that do not exist are never charged.

A worked example: four competitors that each post at Stripe’s pace in our data (7 feed items a week) give about 28 new posts a week, roughly 120 a month. On Bronze that is about $0.18 for the posts plus $0.15 for 30 daily start fees, about $0.33 a month.

Limits worth knowing

  • LinkedIn shows a logged-out visitor about 70 recent items per company page, so one run can never reach further back than that. The first run is a starting point, not a full history.
  • Counts are a snapshot. With only-new mode each post is delivered once, at whatever reaction count it had then. Run without onlyNewPosts when you want refreshed numbers.
  • You get exact reaction and comment counts, not comment texts or the names of people who reacted. Repost counts are not shown to logged-out visitors, so there are none.
  • Personal profiles, school pages and numeric ids are skipped with a warning. Use the company or showcase page’s vanity name.
  • Image and video links are LinkedIn’s signed CDN links, which LinkedIn may rotate. Save any media you need soon after the run.
Related Actor

Explore the scraper referenced in this article: inputs, outputs, and pricing, then run it on Apify.

Frequently asked questions

Do I need a LinkedIn account or cookies? +

No. The actor reads company pages the way a logged-out visitor sees them. It never logs in and never asks for your li_at cookie, so there is no account of yours to restrict.

How does only-new mode decide what is new? +

With onlyNewPosts on, a run skips every post that an earlier run in your Apify account already delivered. It also stops reading a company as soon as it reaches a post you already have, so a quiet page costs one request.

What does a run cost when nobody posted anything? +

Only the $0.005 run start fee. Posts an earlier run delivered, posts older than your postedWithinDays window and skipped reposts are never charged.

How far back does the first scheduled run go? +

As far as postedWithinDays allows, up to maxPostsPerCompany posts per company. LinkedIn shows a logged-out visitor about 70 recent items per page, so that is the ceiling for any single run.

Apify Store

Find a ready-made scraper for your job

Apify has over 80,000 scrapers and automations, ours included. Start free with $5 of platform credit every month.