# LinkedIn Keyword Posts Monitor (`coregent/linkedin-keyword-posts-monitor`) Actor

Monitor LinkedIn posts by keyword, hashtag, brand, or topic. Extract matching public posts with text, author, URL, date, engagement counts, matched keywords, and a monitoring score. Built for B2B content research, social listening, competitor tracking, and market intelligence.

- **URL**: https://apify.com/coregent/linkedin-keyword-posts-monitor.md
- **Developed by:** [Delowar Munna](https://apify.com/coregent) (community)
- **Categories:** Social media, Lead generation, Other
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 post-results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## LinkedIn Keyword Posts Monitor

![LinkedIn Keyword Posts Monitor](https://raw.githubusercontent.com/coregentdevspace/linkedin-keyword-posts-monitor-assets/main/thumbnail-linkedin-keyword-posts-monitor.jpg)

Monitor **LinkedIn posts by keyword, hashtag, brand, or topic** and export matching public posts as clean, flat, CSV-ready rows — with author, engagement counts, matched-keyword context, and a lightweight **monitoring score**. Built for **B2B marketers, sales intelligence teams, content researchers, agencies, and competitor monitoring**.

**No LinkedIn login, no cookies, no session IDs.** Discovery runs through Google (`site:linkedin.com/posts "<keyword>"` via Apify's [`apify/google-search-scraper`](https://apify.com/apify/google-search-scraper)); each LinkedIn post URL is then fetched as a public page. You pay one flat event per saved unique post row.

### ✨ Why this scraper

- **Keyword-and-hashtag first, monitoring focused** — not a generic LinkedIn scraper. Each row carries the keyword that found it, every keyword that matched it (`matched_keywords`), and a `monitoring_score` so you can rank what to read.
- **Hashtag inputs in the same field** — `#fintech` and `AI agents` mix freely in one run.
- **30 flat fields** — post identity, author, company (when visible), engagement counts, match context, derived signals. CSV/Sheets/CRM friendly.
- **Pay-Per-Event** — one flat `post-result` event per saved unique post. Duplicates and filtered rows are never charged.
- **No login / cookies / session IDs** — uses public surfaces only.
- **Transparent monitoring score** — rule-based (no AI), explained below.

---

### 🚀 Quick start — sample inputs

#### Example 1 — multi-keyword + hashtag, fresh + high-engagement

```json
{
    "keywords": ["AI agents", "SOC 2", "#fintech"],
    "maxResults": 100,
    "sortBy": "recent",
    "dateFilter": "pastWeek",
    "authorType": "any",
    "minReactions": 10,
    "minComments": 0,
    "includeReposts": false,
    "companyOrProfileUrls": [],
    "dedupe": true,
    "proxyConfiguration": { "useApifyProxy": true }
}
````

#### Example 2 — company-scoped monitoring

```json
{
    "keywords": ["hiring", "we are hiring", "series a", "launch"],
    "maxResults": 50,
    "sortBy": "recent",
    "dateFilter": "pastMonth",
    "authorType": "company",
    "minReactions": 0,
    "minComments": 0,
    "includeReposts": true,
    "companyOrProfileUrls": ["https://www.linkedin.com/company/openai/", "https://www.linkedin.com/company/anthropic/"],
    "dedupe": true,
    "proxyConfiguration": { "useApifyProxy": true }
}
```

> Discovery delegates to `apify/google-search-scraper` via `Actor.call(...)`. Local runs need `APIFY_TOKEN` set (or `apify login` once); platform runs use the run user's token automatically.

***

### 📦 Output

One dataset view: **LinkedIn posts** — a 30-column flat table.

![LinkedIn Keyword Posts Monitor — LinkedIn posts table view](https://raw.githubusercontent.com/coregentdevspace/linkedin-keyword-posts-monitor-assets/main/linkedin-keyword-posts-monitor-output-linked-posts-table-view.png)

#### Output fields (30)

`search_keyword`, `matched_keywords`, `source_constraint_url`, `post_id`, `post_url`, `post_text`, `post_text_preview`, `posted_at_text`, `posted_at_iso`, `author_name`, `author_type`, `author_profile_url`, `author_headline`, `company_name`, `company_url`, `reactions_count`, `comments_count`, `reposts_count`, `engagement_total`, `post_type`, `contains_external_link`, `external_link_domain`, `keyword_match_in_text`, `keyword_match_location`, `monitoring_score`, `monitoring_label`, `reason_tags`, `scrape_status`, `source_url`, `scraped_at`.

#### Sample record — person-authored post

(Real run output; `post_text` truncated for readability.)

```json
{
    "search_keyword": "SOC 2",
    "matched_keywords": "SOC 2",
    "source_constraint_url": null,
    "post_id": "urn:li:activity:7399469516180738049",
    "post_url": "https://www.linkedin.com/posts/mycroftmike_soc-2-auditors-be-like-its-actually-soc-activity-7399469516180738049-KPkH",
    "post_text": "SOC 2 auditors be like: \"It's actually SOC 2, not SOC2\" Meanwhile, every startup founder: Types \"HIPPA compliance\" into ChatGPT or Google · Writes \"SOC2 certifications\" in their pitch deck · Says \"We're ISO certified\" (Which one? There's a lot)...",
    "post_text_preview": "SOC 2 auditors be like: \"It's actually SOC 2, not SOC2\" Meanwhile, every startup founder: Types \"HIPPA compliance\" into ChatGPT or Google · Writes \"SOC2 certifications\" in their pitch deck...",
    "posted_at_text": "6mo",
    "posted_at_iso": "2025-11-26T15:30:08.126Z",
    "author_name": "Mike Kim",
    "author_type": "person",
    "author_profile_url": "https://www.linkedin.com/in/mycroftmike",
    "author_headline": "Compliance & security at Mycroft · ex-auditor",
    "company_name": null,
    "company_url": null,
    "reactions_count": 408,
    "comments_count": 99,
    "reposts_count": 0,
    "engagement_total": 507,
    "post_type": "external_link",
    "contains_external_link": true,
    "external_link_domain": "lnkd.in",
    "keyword_match_in_text": true,
    "keyword_match_location": "text",
    "monitoring_score": 60,
    "monitoring_label": "Medium",
    "reason_tags": "keyword_in_text,high_engagement,has_comments,external_link",
    "scrape_status": "ok",
    "source_url": "http://www.google.com/search?q=site%3Alinkedin.com%2Fposts+%22SOC+2%22&hl=en",
    "scraped_at": "2026-05-28T01:37:45.672Z"
}
```

#### Sample record — company-authored post

```json
{
    "search_keyword": "SOC 2",
    "matched_keywords": "SOC 2",
    "source_constraint_url": null,
    "post_id": "urn:li:activity:7424327031087120384",
    "post_url": "https://www.linkedin.com/posts/hrvcertpro_soc-2-audit-checklist-evidence-controls-activity-7424327031087120384-Y3at",
    "post_text": "SOC 2 audits reward preparation, not last-minute fixes. A well-defined checklist ensures your policies, controls, and audit evidence align with Trust Services Criteria — before auditors ask. Read more: https://lnkd.in/g9RawZD3 #SOC2Compliance #ComplianceChecklist #RiskManagement #DataProtection",
    "post_text_preview": "SOC 2 audits reward preparation, not last-minute fixes. A well-defined checklist ensures your policies, controls, and audit evidence align with Trust Services Criteria...",
    "posted_at_text": "3mo",
    "posted_at_iso": "2026-02-03T05:45:01.511Z",
    "author_name": "CertPro",
    "author_type": "company",
    "author_profile_url": "https://www.linkedin.com/company/hrvcertpro",
    "author_headline": null,
    "company_name": "CertPro",
    "company_url": "https://www.linkedin.com/company/hrvcertpro",
    "reactions_count": 2,
    "comments_count": 0,
    "reposts_count": 0,
    "engagement_total": 2,
    "post_type": "article_share",
    "contains_external_link": true,
    "external_link_domain": "lnkd.in",
    "keyword_match_in_text": true,
    "keyword_match_location": "text",
    "monitoring_score": 40,
    "monitoring_label": "Low",
    "reason_tags": "keyword_in_text,company_author,external_link",
    "scrape_status": "ok",
    "source_url": "http://www.google.com/search?q=site%3Alinkedin.com%2Fposts+%22SOC+2%22&hl=en",
    "scraped_at": "2026-05-28T01:37:45.281Z"
}
```

***

### 🎯 Monitoring score

Transparent rule-based score (0–100). No AI, no external enrichment.

| Signal                                             | Points |
| -------------------------------------------------- | -----: |
| Keyword found directly in `post_text`              |    +25 |
| Keyword found in a hashtag                         |    +15 |
| `engagement_total >= 100`                          |    +20 |
| `engagement_total >= 25` (and < 100)               |    +15 |
| `comments_count >= 5`                              |    +10 |
| Author is a company / page                         |    +10 |
| Post falls inside the selected `dateFilter` window |    +10 |
| Post includes an external link                     |     +5 |

Score capped at 100.

**Labels**: `High` (80–100) · `Medium` (50–79) · `Low` (0–49).

`reason_tags` is a comma-separated list explaining the score — e.g. `keyword_in_text`, `keyword_in_hashtag`, `high_engagement`, `moderate_engagement`, `has_comments`, `company_author`, `recent_post`, `external_link`, `repost`.

***

### 💰 Pricing

**Pay-Per-Event**. One flat event per saved row (per-event price configured on the Apify console):

| Event         | Charged when                                                                                  |
| ------------- | --------------------------------------------------------------------------------------------- |
| `post-result` | Once per unique post row that passed all filters and was successfully written to the dataset. |

So your bill is simply `results_saved × price_per_event`. The actor honours the user-configured per-run spending cap (Apify `eventChargeLimitReached`): it caps how many results it discovers up-front to what the limit can pay for, and stops cleanly the moment the cap is reached during charging.

**Not charged:**

- Duplicates (deduped by `post_id`, canonical `post_url`, and author+text keys; see PRD §9).
- Rows filtered out by author / engagement / repost / date filters.
- Failed or authwalled requests.
- Rows missing a `post_url`, `post_id`, and `(post_text + author_name)`.

#### 🚦 Proxy policy

Use **Apify Datacenter** proxy or **no proxy** for normal runs — both work reliably for the public LinkedIn post pages at this actor's conservative concurrency.

**Apify Residential proxy is not supported.** The actor will fail at startup if `proxyConfiguration.apifyProxyGroups` includes `RESIDENTIAL`. Reason: in pay-per-event actors, residential bandwidth (~/GB) is billed to the developer, not the run user, so a single bandwidth-heavy run could exceed the per-result event revenue.

If you genuinely need residential routing, supply your own provider via the proxy editor's **Custom proxy URLs** field — that traffic goes through your provider, not Apify, and is unaffected:

```
http://user:pass@proxy.iproyal.com:12321
http://user:pass@proxy.brightdata.com:22225
http://user:pass@proxy.oxylabs.io:7777
```

***

### 📊 Run summary

After each run, a `RUN_SUMMARY` entry is written to the key-value store:

```json
{
    "inputs_total": 3,
    "successful_inputs": 2,
    "failed_inputs": 1,
    "keywords_total": 3,
    "raw_results_found": 180,
    "results_saved": 100,
    "duplicates_removed": 25,
    "filtered_out": 55,
    "charged_events": 100,
    "charge_failures": 0,
    "blocked_requests": 2,
    "retry_count": 6,
    "empty_result_keywords": 0,
    "runtime_seconds": 148,
    "scraped_at": "2026-05-28T04:00:00.000Z"
}
```

`charged_events` equals the number of successfully saved unique rows.

***

### ⚙️ Filters

| Filter                 | Stage             | Effect                                                                                                                                              |
| ---------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `authorType`           | Pre-extraction    | `any` / `person` / `company`. Rows with a *detected* type the opposite of the filter are dropped. `unknown` is kept (we do not guess by filtering). |
| `minReactions`         | Post-extraction   | Drop rows with `reactions_count < minReactions` (missing counts as 0).                                                                              |
| `minComments`          | Post-extraction   | Drop rows with `comments_count < minComments` (missing counts as 0).                                                                                |
| `includeReposts`       | Post-extraction   | When `false`, drop `post_type = repost`.                                                                                                            |
| `dateFilter`           | Post-extraction   | `any` / `past24h` / `pastWeek` / `pastMonth`. Rows with unparseable dates are kept but marked `scrape_status = partial`.                            |
| `dedupe`               | Per-keyword merge | When `true` (default), duplicate posts found by more than one keyword are saved once with merged `matched_keywords`.                                |
| `companyOrProfileUrls` | Discovery scope   | Optional list of LinkedIn company/profile URLs. Discovery candidates are kept only if the post URL slug matches one. Empty list = no constraint.    |

Filters are applied **before** any dataset push or event charge.

***

### 🚧 Limitations (V1)

- **Public surfaces only.** No login, cookies, or member-only content. LinkedIn does not expose a no-auth post-search endpoint, so discovery runs through Google (`site:linkedin.com/posts "<keyword>"`) via the `apify/google-search-scraper` actor. Coverage depends on Google's index for `linkedin.com/posts`.
- **Page authwall.** Some LinkedIn post pages, when fetched without cookies, return an authwall HTML even for previously-indexed posts. Those rows are counted as `blocked_requests` and retried; persistent failures are skipped, not fatal.
- **Best-effort fields.** Author identity is parsed from JSON-LD when present, then from `og:title` / page slug / `og:image` hints. When LinkedIn returns only minimal authwall metadata, `author_type` may remain `unknown` and `company_name` / `company_url` may be `null`.
- **No comment or reaction-user scraping.** V1 returns post-level rows only.
- **No media download.**
- **`maxResults`** caps **saved unique rows** across the whole run (not per keyword).
- **No `recent` ordering at the LinkedIn level.** `sortBy` influences Google's ranking, not LinkedIn's, so true recency depends on Google's index freshness.

***

### ❓ FAQ

**Do I need a LinkedIn account or cookies?**
No. Discovery uses Google (`site:linkedin.com/posts "<keyword>"`); extraction reads each LinkedIn post page over public HTTP.

**How does discovery work technically?**
For each keyword the actor builds a Google query and calls Apify's `apify/google-search-scraper` actor once per run. Result URLs are filtered to public LinkedIn post URLs, canonicalised, and deduped across keywords. Then each URL is fetched with Crawlee `CheerioCrawler` and parsed.

**Why are some `author_type` values `unknown`?**
LinkedIn's no-cookie response sometimes contains only minimal Open Graph metadata. When neither JSON-LD, the post URL slug, nor the `og:image` give a confident person-vs-company signal, `author_type` is left `unknown` rather than guessed.

**Why is `company_name` sometimes `null` even when the author works at a known company?**
For person-authored posts we only populate `company_name` when the company is clearly visible in the author headline (e.g. "VP Sales at Acme"). We never visit the author's profile page to enrich it in V1.

**Can I scope a run to specific companies or people?**
Yes — list their LinkedIn URLs in `companyOrProfileUrls`. Discovery candidates whose post URL slug matches one of those handles are kept; everything else is skipped. The matched constraint URL is stamped on every kept row as `source_constraint_url`.

**Can I export to CSV?**
Yes — every field is flat. Use Apify's CSV / Excel export, or call the dataset API with `format=csv`.

**Will I get blocked?**
Concurrency is `min=1 / max=5` with retries, session rotation, and randomised user agents. Apify Datacenter Proxy is sufficient for typical runs. For large runs, split keywords across runs or supply your own proxy provider via Custom proxy URLs.

**Hashtag vs keyword — same input?**
Yes. Drop them into the same `keywords` list. Hashtags keep their `#` (e.g. `"#fintech"`); the actor quotes them inside the Google query so they match as literal tokens.

***

### 🛠️ Technical notes

- **Stack**: Node.js 22 · Apify SDK 3 · Crawlee `CheerioCrawler` · Cheerio + native fetch. No browser.
- **Discovery**: `apify/google-search-scraper` via `Actor.call(...)`. Requires `APIFY_TOKEN` for local runs.
- **Extraction**: each LinkedIn post URL is fetched directly. Parsing is layered: JSON-LD (`SocialMediaPosting` / `Article`) → Open Graph meta tags → visible markup fallback.
- **Concurrency**: `min=1`, `max=5` (conservative, LinkedIn is blocking-sensitive).
- **Memory**: 1 GB min · 2 GB default · 4 GB max.
- **Proxy**: Apify Proxy enabled by default; custom configs accepted; Apify Residential rejected at startup.

#### Local run

```bash
cd actor
npm install
## Either: apify login   (writes APIFY_TOKEN to your env), or:
## $env:APIFY_TOKEN = "..."   (PowerShell)   /   export APIFY_TOKEN=...   (bash)
npm start
```

# Actor input Schema

## `keywords` (type: `array`):

Keywords, phrases, hashtags, or brand terms to monitor on LinkedIn (1-50 items, each up to 100 chars). Use a leading # to scope a search to a hashtag, e.g. "#fintech". Each keyword is searched independently and any post that matches more than one is reported once with merged matched\_keywords.

## `maxResults` (type: `integer`):

Maximum number of unique post rows saved across the whole run (not per keyword). Range 1-5000.

## `sortBy` (type: `string`):

Preferred result ordering for the discovery layer where supported. Most recent prioritises freshness over relevance.

## `dateFilter` (type: `string`):

Limit to posts within the chosen recency window. Applied after extraction using the post's visible date text; posts with unparseable dates are kept but marked partial.

## `authorType` (type: `string`):

Filter rows by author type. Posts with an unknown author type are always kept and reported.

## `minReactions` (type: `integer`):

Drop rows whose visible reaction count is below this value. Missing reactions count as 0.

## `minComments` (type: `integer`):

Drop rows whose visible comment count is below this value. Missing comments count as 0.

## `includeReposts` (type: `boolean`):

When false, rows detected as reposts/shares (post\_type = repost) are dropped.

## `companyOrProfileUrls` (type: `array`):

Optional list of LinkedIn company or profile URLs (https://www.linkedin.com/company/... or /in/...) to scope searches when supported. Invalid or non-LinkedIn URLs are logged and skipped, they do not fail the run.

## `dedupe` (type: `boolean`):

When true, posts found by more than one keyword are saved only once with matched\_keywords merged.

## `proxyConfiguration` (type: `object`):

Apify Proxy configuration. Defaults to Apify Proxy enabled. Apify Residential is NOT supported and will fail the run at startup; if you need residential routing, supply your own provider via Custom proxy URLs (proxyUrls).

## Actor input object example

```json
{
  "keywords": [
    "AI agents",
    "SOC 2",
    "#fintech"
  ],
  "maxResults": 100,
  "sortBy": "relevance",
  "dateFilter": "any",
  "authorType": "any",
  "minReactions": 0,
  "minComments": 0,
  "includeReposts": true,
  "companyOrProfileUrls": [],
  "dedupe": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Flat 30-field table view of every post row pushed to the dataset, including post identity, author and company metadata, engagement counts, derived monitoring score, and the keyword(s) that matched.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keywords": [
        "AI agents",
        "SOC 2",
        "#fintech"
    ],
    "companyOrProfileUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("coregent/linkedin-keyword-posts-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "keywords": [
        "AI agents",
        "SOC 2",
        "#fintech",
    ],
    "companyOrProfileUrls": [],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("coregent/linkedin-keyword-posts-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keywords": [
    "AI agents",
    "SOC 2",
    "#fintech"
  ],
  "companyOrProfileUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call coregent/linkedin-keyword-posts-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=coregent/linkedin-keyword-posts-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "LinkedIn Keyword Posts Monitor",
        "description": "Monitor LinkedIn posts by keyword, hashtag, brand, or topic. Extract matching public posts with text, author, URL, date, engagement counts, matched keywords, and a monitoring score. Built for B2B content research, social listening, competitor tracking, and market intelligence.",
        "version": "1.0",
        "x-build-id": "DPVGRs2GpYkjBaFc0"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/coregent~linkedin-keyword-posts-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-coregent-linkedin-keyword-posts-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/coregent~linkedin-keyword-posts-monitor/runs": {
            "post": {
                "operationId": "runs-sync-coregent-linkedin-keyword-posts-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/coregent~linkedin-keyword-posts-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-coregent-linkedin-keyword-posts-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "keywords": {
                        "title": "Keywords or hashtags",
                        "type": "array",
                        "description": "Keywords, phrases, hashtags, or brand terms to monitor on LinkedIn (1-50 items, each up to 100 chars). Use a leading # to scope a search to a hashtag, e.g. \"#fintech\". Each keyword is searched independently and any post that matches more than one is reported once with merged matched_keywords.",
                        "default": [
                            "AI agents"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxResults": {
                        "title": "Max results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of unique post rows saved across the whole run (not per keyword). Range 1-5000.",
                        "default": 100
                    },
                    "sortBy": {
                        "title": "Sort by",
                        "enum": [
                            "relevance",
                            "recent"
                        ],
                        "type": "string",
                        "description": "Preferred result ordering for the discovery layer where supported. Most recent prioritises freshness over relevance.",
                        "default": "relevance"
                    },
                    "dateFilter": {
                        "title": "Date filter",
                        "enum": [
                            "any",
                            "past24h",
                            "pastWeek",
                            "pastMonth"
                        ],
                        "type": "string",
                        "description": "Limit to posts within the chosen recency window. Applied after extraction using the post's visible date text; posts with unparseable dates are kept but marked partial.",
                        "default": "any"
                    },
                    "authorType": {
                        "title": "Author type",
                        "enum": [
                            "any",
                            "person",
                            "company"
                        ],
                        "type": "string",
                        "description": "Filter rows by author type. Posts with an unknown author type are always kept and reported.",
                        "default": "any"
                    },
                    "minReactions": {
                        "title": "Minimum reactions",
                        "minimum": 0,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Drop rows whose visible reaction count is below this value. Missing reactions count as 0.",
                        "default": 0
                    },
                    "minComments": {
                        "title": "Minimum comments",
                        "minimum": 0,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Drop rows whose visible comment count is below this value. Missing comments count as 0.",
                        "default": 0
                    },
                    "includeReposts": {
                        "title": "Include reposts",
                        "type": "boolean",
                        "description": "When false, rows detected as reposts/shares (post_type = repost) are dropped.",
                        "default": true
                    },
                    "companyOrProfileUrls": {
                        "title": "Company or profile URL constraints",
                        "type": "array",
                        "description": "Optional list of LinkedIn company or profile URLs (https://www.linkedin.com/company/... or /in/...) to scope searches when supported. Invalid or non-LinkedIn URLs are logged and skipped, they do not fail the run.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "dedupe": {
                        "title": "Deduplicate posts",
                        "type": "boolean",
                        "description": "When true, posts found by more than one keyword are saved only once with matched_keywords merged.",
                        "default": true
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify Proxy configuration. Defaults to Apify Proxy enabled. Apify Residential is NOT supported and will fail the run at startup; if you need residential routing, supply your own provider via Custom proxy URLs (proxyUrls).",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
