Back to guides
/Linked API

LinkedIn Social Listening: Monitor Mentions and Competitors with AI

What people say about your brand, your competitors and your category on LinkedIn is useful – if you can see it without reading the feed all day.

The short version. LinkedIn social listening means watching three things: posts that mention your company, what your competitors and their people publish, and the conversations in your category. LinkedIn's own tools cover a slice – your Page sees posts that tag it, and Page competitor analytics compares you with one competitor on a free Page or up to nine on Premium. Beyond that, the data comes by one of three routes: official-API Page connectors (your own Page and its comments), public-web keyword samples that monitoring tools collect, or LinkedIn's own post search run from a logged-in account. The last route is what an AI agent can run on your account every week, turning keyword searches into a digest of themes, objections and who is engaging. Every route is a sample, not every post on LinkedIn.

What LinkedIn social listening covers – and what it can't see

Listening on LinkedIn has three jobs:

  • Your brand – who mentions your company, tagged or not.
  • Your competitors – what their Pages publish, and what their people post.
  • Your category – what buyers and peers say about the problem you solve.

The data reaches you by different routes, and a product may use more than one:

RouteWhat it seesLimits
LinkedIn's native Page toolsPosts that @-tag your Page, under the Page's Activity tab (LinkedIn Help). Competitor analytics for 1 competitor on a free Page or up to 9 on Premium – followers, organic content metrics, trending competitor posts from the last 30 days (LinkedIn Help)Untagged mentions; people rather than Pages
Official-API Page connectorsYour own Business Page's posts, comments and insights, inside a listening suite. Mentionlytics, for example, notes that commenters come through anonymizedNot a keyword search across LinkedIn
Public-web keyword samplesPublic LinkedIn posts with your keywords that appear on the web – the keyword monitoring some suites offer, such as Mentionlytics and Brand24A sample; Mentionlytics states it cannot retrieve every public post with your keywords
LinkedIn post search from a logged-in accountThe posts LinkedIn's own content search returns for your keyword, as that account sees them – what an agent on your account runsEach search needs a keyword; results are bounded per call; LinkedIn widens narrow queries; no private content

Whichever route you use, treat the result as a sample. It tells you what is being said and by whom, not how many times your brand came up across all of LinkedIn.

Native tools, listening suites, keyword monitors or your own agent

OptionBest forWatch out for
LinkedIn Page analyticsA free baseline for your own Page: tagged mentions and a competitor comparisonCompetitor tracking depends on your Page tier; untagged mentions do not show
Listening suites (Sprout, Brand24, Mentionlytics)Reporting across several social networks in one dashboardOn LinkedIn they combine Page connectors with public-web keyword samples, depending on the product
LinkedIn keyword monitors (Octolens, OutX, Buska)Ready-made alerts on keywords, people and companiesTheir coverage and sources vary; OutX is also listed as an MCP server for AI agents
An agent or script on your own account (Linked API)A custom weekly digest with your own searches, LLM analysis and routing into your toolsYou run and schedule it; it sees what your account's search returns

Agent access is not unique to any one route. What an agent on your own account adds is control: you choose the searches, the digest format and where the results go.

The weekly listening digest: what to watch

Four watches, each one search. "Past week" and "latest" keep each run to new posts.

WatchWhat to searchLinked API callCaveat
Brand mentions (baseline, untagged included)Your brand name as the keywordsearchPosts with term: "<brand>", sort: latest, datePosted: pastWeek – then keep only posts whose text contains the brandLinkedIn widens narrow queries, so check each hit
Tagged mentions (optional)The same keyword, limited to posts that tag your companyThe same search plus mentioningCompanies: ["<brand>"]This filter is a company-mention facet combined with the keyword, so it narrows to tagged posts. Never use it as the only brand watch
Competitors' PagesWhat each competitor publishesfetchCompany with retrievePosts and postsRetrievalConfig: { limit, since }Page posts only
Competitors' peopleWhat their employees post about your categorysearchPosts with your category keyword plus authorCompanies: ["<competitor>"]Matches the author's current company as LinkedIn shows it
Category conversationsPosts about the problem you solvesearchPosts with a problem phrase, past week, latestPick phrases buyers use, not your product's vocabulary

Then, for the few hits worth it, see who engages: fetchPost with retrieveComments and retrieveReactions. Comments carry LinkedIn's relative time, such as 3d; reactions carry no time.

Company and person filters accept a name, or a name with an identifier that pins the exact company. If LinkedIn's filter panel does not offer a match for the name, the search fails with filterNotApplied rather than returning unfiltered results. Details are in the post search reference.

Run it with an AI agent

The digest runs from a plain-language instruction. Give an assistant such as Claude access to your account through the MCP server – tools search_posts, fetch_company and fetch_post – the agent-friendly CLI, or a ready-made skill. Setup is covered in giving an AI agent access to LinkedIn.

A runnable instruction. It is a starting point, not a record of an observed run:

Run my weekly LinkedIn listening digest for the past week.

Brand: "Acme Analytics". Competitors: "Example Rival", "Other Rival".
Category phrase: "pipeline forecasting".

1. Search posts for "Acme Analytics" (latest, past week). Keep only posts whose text
   actually mentions Acme Analytics. Do not use the mentioning-company filter for this.
2. Fetch each competitor's company page with its posts from the last 7 days.
3. Search posts for "pipeline forecasting" from people who work at each competitor.
4. Search posts for "pipeline forecasting" (latest, past week).
5. For the three most-engaged hits, fetch the comments.

Write the digest in this format:
- Themes: 3–5 recurring themes, each with 1–2 post links.
- Objections and questions people raised, with links.
- Competitors: what each one published and what got engagement.
- Notable authors and commenters worth following.
- Share of the observed sample by watch (counts of the posts you kept, not LinkedIn-wide).
- Items for sales: posts from people asking about the problem we solve.

From the terminal, the same searches look like this:

bash
linkedin post search --term "Acme Analytics" --sort latest --date-posted pastWeek --json
linkedin post search --term "pipeline forecasting" --author-companies "Example Rival" --date-posted pastWeek --json

Use --mentioning-companies only for a separate tagged-mentions watch. Scheduling is yours: a weekly agent session, cron, n8n or Make.

Or schedule it in code

The same digest as a script. It runs the watches and writes the new posts to digest-input.json for whichever LLM you use for the summary. Posts already sent in an earlier week are skipped.

typescript
import LinkedApi, { type TSearchPostsParams } from '@linkedapi/node';
import { existsSync, readFileSync, writeFileSync } from 'node:fs';

const linkedapi = new LinkedApi({
  linkedApiToken: 'your-linked-api-token',
  identificationToken: 'your-identification-token',
});

const BRAND = 'Acme Analytics';
const COMPETITORS = [{ name: 'Example Rival', pageUrl: 'https://www.linkedin.com/company/example-rival' }];
const CATEGORY_TERM = 'pipeline forecasting';
const SEEN_FILE = 'listening-seen.json';
const OUTPUT_FILE = 'digest-input.json';
const ONE_WEEK_MS = 7 * 24 * 60 * 60 * 1000;
const PAST_WEEK = { sort: 'latest', datePosted: 'pastWeek' } as const;

interface THit {
  watch: string;
  url: string;
  author: string | null;
  time: string;
  text: string;
  reactions: number;
  comments: number;
}

async function searchWatch(watch: string, params: TSearchPostsParams): Promise<Array<THit>> {
  const workflow = await linkedapi.searchPosts.execute({ limit: 50, ...params });
  const { data, errors } = await linkedapi.searchPosts.result(workflow.workflowId);
  if (errors.length > 0) console.warn(watch, errors.map((error) => error.type));
  return (data ?? []).map((post) => ({
    watch,
    url: post.url,
    author: post.author?.name ?? null,
    time: post.time,
    text: post.text ?? '',
    reactions: post.reactionsCount,
    comments: post.commentsCount,
  }));
}

async function competitorPagePosts(competitor: { name: string; pageUrl: string }): Promise<Array<THit>> {
  const workflow = await linkedapi.fetchCompany.execute({
    companyUrl: competitor.pageUrl,
    retrievePosts: true,
    postsRetrievalConfig: { limit: 20, since: new Date(Date.now() - ONE_WEEK_MS).toISOString() },
  });
  const { data, errors } = await linkedapi.fetchCompany.result(workflow.workflowId);
  if (errors.length > 0) console.warn(competitor.name, errors.map((error) => error.type));
  return (data?.posts ?? []).map((post) => ({
    watch: `competitor page: ${competitor.name}`,
    url: post.url,
    author: competitor.name,
    time: post.time,
    text: post.text ?? '',
    reactions: post.reactionsCount,
    comments: post.commentsCount,
  }));
}

async function collectDigestInput() {
  const seen = new Set<string>(existsSync(SEEN_FILE) ? JSON.parse(readFileSync(SEEN_FILE, 'utf8')) : []);

  const brandHits = await searchWatch('brand', { term: BRAND, filter: PAST_WEEK });
  const hits = brandHits.filter((hit) => hit.text.toLowerCase().includes(BRAND.toLowerCase()));

  for (const competitor of COMPETITORS) {
    hits.push(...(await competitorPagePosts(competitor)));
    hits.push(...(await searchWatch(`competitor people: ${competitor.name}`, {
      term: CATEGORY_TERM,
      filter: { ...PAST_WEEK, authorCompanies: [competitor.name] },
    })));
  }
  hits.push(...(await searchWatch('category', { term: CATEGORY_TERM, filter: PAST_WEEK })));

  const fresh = hits.filter((hit) => !seen.has(hit.url));
  const excerpts = fresh.map((hit) => ({ ...hit, text: hit.text.slice(0, 500) }));
  writeFileSync(OUTPUT_FILE, JSON.stringify(excerpts, null, 2));
  writeFileSync(SEEN_FILE, JSON.stringify([...seen, ...fresh.map((hit) => hit.url)]));
}

collectDigestInput();

Every call is asynchronous – execute starts the work and returns a workflow ID, result waits for it – and action failures come back in errors, not as exceptions. A failed watch is logged and the rest of the digest still runs. Feed digest-input.json to your model with the same digest format as the agent instruction above. To pin a competitor exactly, pass { name, id } with its company URN or numeric ID instead of the bare name.

Turning the digest into decisions

A digest is only worth the time if someone acts on it:

  • Themes feed your content plan – what your category argues about this week.
  • Objections and questions go to sales enablement and to the FAQ on your site.
  • Competitors' launches and messaging shape your counter-positioning before your buyers ask about them.
  • People asking about the problem you solve are sales-relevant; route them the way LinkedIn buying signals describes, with a person reviewing before any outreach.

Report shares as the share of your observed sample – "most of the competitor posts we saw were about pricing" – never as LinkedIn-wide share of voice.

Limits and guardrails

  • A sample, not a firehose. You see what your account's search returns, bounded per call.
  • A keyword is required. Every post search needs a term, and LinkedIn widens narrow queries, so check each hit.
  • No private content, and no posts the search does not surface.
  • No streaming or alerts. You schedule the run; Linked API has no post-mention webhook.
  • The analysis is the LLM's, not LinkedIn's. Themes and sentiment are interpretations – keep the post links next to every claim.
  • Pace and limits. Searches count toward per-action limits by category and period, which you can see and set with the limits API. The account runs in a dedicated cloud browser at a human pace.

Need the post data itself – full text, engagers, a CSV – rather than a digest? That is the job of the LinkedIn post scraper guide.

Frequently Asked Questions (FAQ)

Watching what is said on LinkedIn about your brand, your competitors and your category, then turning it into decisions – content, positioning, sales enablement.

Posts that tag your Page show in the Page's Activity tab. Untagged mentions only appear through keyword search – a monitoring tool's public-web sample, or LinkedIn's own post search run from an account.

Start with Page competitor analytics – one competitor on a free Page, up to nine on Premium. For more, collect their Page posts and their employees' posts each week by search, as in the digest above.

LinkedIn's official APIs centre on your own Page's content, and access to them is gated – see LinkedIn API access. Linked API runs LinkedIn's post search and company pages on your own account, so a script or an agent can collect the digest.

It depends on the job. A suite fits multi-network reporting, a keyword monitor fits ready-made alerts, and an agent on your own account fits a custom digest that feeds your own tools.

Build it in, or hand it to an agent

Build the digest into your own tools with the REST API, the Node and Python SDKs or the CLI. Or have an AI agent run it out of the box through the MCP server, the agent-friendly CLI or a ready-made skill. Plans start at $49 a seat a month billed annually – see pricing.

Facts verified October 9, 2026 – LinkedIn Page mentions and competitor analytics against LinkedIn Help; Mentionlytics' LinkedIn monitoring routes against its help center; Brand24, Octolens, OutX and Buska descriptions against their live pages on that date.