# News MCP Monitor — Meltwater Alt + AI Briefings (`harvestlab/news-monitor`) Actor

Skyfire/x402 payment-ready. Monitor news across Google News + 50+ sources at $0.002/article — 99%+ run success, RAG-ready feed for AI agents via MCP. AI executive briefings + sentiment + brand alerts. Replaces Meltwater ($5k-$24k/yr), Cision, Mention, Notified, Onclusive, MuckRack.

- **URL**: https://apify.com/harvestlab/news-monitor.md
- **Developed by:** [Nick](https://apify.com/harvestlab) (community)
- **Categories:** News, AI, MCP servers
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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

## News & Brand Monitor — Meltwater Alternative + AI

> 🤖 **MCP-Ready** — works as a tool for Claude, Cursor, ChatGPT, and other AI agents via the [Apify MCP Server](https://github.com/apify/apify-mcp-server). Typed inputs + structured outputs (dataset_schema) deployed in Cycle 73.

> 🧰 **Works with**: LangChain · LangGraph · CrewAI · LlamaIndex · PydanticAI · Mastra AI · Bee AI — call this actor as a tool from any [Apify MCP](https://github.com/apify/apify-mcp-server) or [actor-templates](https://github.com/apify/actor-templates)-backed AI framework.

> 💰 **Pay-per-result, not per compute unit** — you know your cost BEFORE pressing Run. No surprise compute charges, no monthly minimums, no SaaS subscription. Compare to Apify's default \$0.20/CU model where cost depends on actor runtime, memory, and data volume.

> 🔁 **Apify rental alternative** — Apify is sunsetting the rental pricing model in October 2026. This Actor is already 100% pay-per-event: drop in as a 1:1 replacement for any rental-based competitor without a contract or monthly minimum.

> 🍪 **No cookies, no OAuth, no API keys (for the scraping)** — runs on public data only. AI keys are optional and only needed when `enableAiAnalysis: true`.

Monitor Google News for any topic, company, or keyword and get AI-powered executive briefings with sentiment analysis, key takeaways, and trend detection. Track brand mentions, competitive moves, industry developments, and regulatory changes across global news sources -- delivered as structured data ready for dashboards, Slack alerts, or email digests.

**Why this and not enterprise media-monitoring suites?** Tools like Meltwater, Cision, and Mention start at $5,000-$24,000/year per seat, lock you into their dashboards, and bill flat regardless of usage. This actor delivers the same core capability — keyword monitoring + AI executive briefings + sentiment + multi-language + live-watch — at $0.002 per article and $0.05 per briefing, with output as structured JSON you can route into your own stack (Slack, Sheets, Snowflake, Looker, your CRM). A typical day of monitoring 3 topics costs ~$0.33; a month of daily briefings costs less than one hour of an enterprise PR-monitoring license.

### What it does

Google News Monitor scrapes Google News RSS feeds for your keywords and resolves each article's redirect URL to the actual publisher page. It then extracts rich metadata -- title, source, hero image, author, publisher, keywords, publish date, modified date, article section, word count, domain, and a keyword-based sentiment stub -- using a two-layer extractor (OpenGraph / meta tags first, then JSON-LD / schema.org `NewsArticle` fallback for top-tier publishers like NYT, WSJ, Reuters, Bloomberg, AP, BBC, Guardian, and TechCrunch).

Once articles are collected, an optional AI briefing layer sends the article batch to your chosen LLM provider (OpenRouter, Anthropic, Google AI, OpenAI, or self-hosted Ollama) and returns a structured executive briefing with a summary, key developments, sentiment breakdown (positive / neutral / negative percentage split), trending themes, notable sources analysis, impact assessment, and recommended actions -- in three selectable styles: Executive (concise, C-level), Detailed (comprehensive with source attribution), or Bullet Points (scannable).

**Live-watch mode** is the actor's most unique capability: set `watchIntervalMinutes` + `watchDurationMinutes` and the actor stays alive, re-querying Google News on your interval and pushing only newly-seen articles (deduplicated by Google News GUID). The AI briefing regenerates only when the new-article delta crosses a configurable threshold, so the $0.05 briefing cost tracks the story -- not the clock.

**Pricing** uses pay-per-event: $0.002 per article scraped, $0.05 per AI briefing generated. A typical daily monitoring run (3 topics × 30 articles + 3 briefings) costs ~$0.33 and completes in 2-5 minutes.

### Features

- **Google News scraping** -- Searches Google News RSS feeds for your keywords and collects article titles, sources, publication dates, and content snippets
- **Redirect URL resolution** -- Resolves Google News redirect URLs to the actual article pages, giving you clean, direct links to original sources
- **Two-layer article metadata extraction** -- Pulls hero images, author, publisher, keywords, publish + modified dates, and article section. OpenGraph / meta tags first, then JSON-LD / schema.org `NewsArticle` fallback for top-tier publishers (NYT, WSJ, Reuters, Bloomberg, AP, BBC, Guardian, TechCrunch) whose meta tags are often sparse but whose structured data is always present
- **Live-watch mode** -- Optional long-lived monitor: set `watchIntervalMinutes` + `watchDurationMinutes` and the actor stays alive, re-querying Google News every N minutes and pushing only newly-seen articles (deduped by GUID) — ideal for crisis / PR-war-room monitoring
- **Smart briefing regeneration** -- In watch mode, AI briefings regenerate only when the new-article delta crosses a configurable threshold, so you pay the $0.05 briefing cost only when the story actually moves
- **Three briefing styles** -- Executive (concise C-level briefing), Detailed (comprehensive with source attribution), or Bullet Points (scannable key facts)
- **Multi-country support** -- Target news from 7 countries: United States, United Kingdom, Netherlands, Germany, France, Spain, and Italy
- **Multi-language support** -- Collect and analyze news in 6 languages: English, Dutch, German, French, Spanish, and Italian
- **5 LLM providers** -- OpenRouter (recommended — 300+ models), Anthropic (Claude), Google AI (Gemini), OpenAI (GPT), or Ollama (self-hosted)
- **Keyword-based sentiment stub** -- Fast English keyword heuristic on each article (`positive` / `negative` / `neutral`) for quick downstream filtering without an AI key
- **Derived analytics fields** -- `domain` (extracted from resolved URL with 200+ publisher fallback map), `word_count` (publisher-declared via JSON-LD `wordCount` or heuristic), stable `guid` for cross-run dedup
- **Concurrent enrichment** -- URL resolution and article snippet fetches run in parallel under a `Semaphore(15)` gate; 30 articles resolve in roughly the same time as 2-3 sequential requests
- **180s wall-clock budget** -- Per-query enrichment phase is capped at 180s. Slow publishers are abandoned and partial results are pushed instead of running to Apify's hard timeout
- **Multiple queries per run** -- Monitor several topics in a single run, each producing its own dataset item with its own briefing

### Use Cases

#### Brand and Reputation Managers
Track mentions of your company, products, or executives across global news sources. Get daily or hourly briefings on what the media is saying about your brand. Detect narrative shifts and emerging stories before they become crises.

#### PR and Communications Teams
Stay on top of breaking news that affects your organization. Monitor coverage of press releases, product launches, and corporate announcements. Identify which journalists and outlets are covering your brand and the tone of their coverage.

#### Competitive Intelligence Analysts
Monitor competitors, industry trends, and market movements across news sources. Receive structured analysis of how the competitive landscape is shifting. Track product launches, leadership changes, and strategic moves by rival companies.

#### Investment Researchers and Analysts
Track companies, sectors, or economic indicators in the news. Get sentiment analysis to gauge market mood around specific stocks, industries, or macroeconomic themes. Combine with financial data for a complete research picture.

#### Market Researchers
Monitor emerging technologies, regulatory changes, or consumer trends. Identify patterns across multiple news sources that signal market shifts. Build longitudinal datasets by scheduling recurring runs to track how narratives evolve.

#### Executives and Decision Makers
Replace manual news scanning with automated executive briefings delivered to your inbox or Slack channel. The executive briefing style distills dozens of articles into key developments, business impact, and recommended actions in a format designed for time-constrained leaders.

#### Academic Researchers and Journalists
Collect and analyze news coverage of specific topics over time. Track how media narratives evolve around political events, social issues, or scientific developments. Export structured article datasets for quantitative media analysis.

### Input

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `searchQueries` | array | (required) | Keywords, company names, or topics to monitor. Each query produces its own dataset item and briefing. Examples: "OpenAI", "Tesla earnings", "climate policy EU". |
| `maxArticles` | integer | `30` | Maximum articles to collect per query (1-100). More articles give the AI more data but increase cost and runtime. |
| `timeRange` | select | `1d` | How far back to search: `1h` (breaking news), `1d` (daily digest), `7d` (weekly roundup), `30d` (monthly trends). |
| `country` | select | `us` | Country for results: us, gb, nl, de, fr, es, it. Controls which regional Google News sources appear. |
| `language` | select | `en` | Language for articles and briefings: en, nl, de, fr, es, it. |
| `fetchArticleSnippets` | boolean | `true` | Resolve redirect URLs and fetch article snippets. Strongly recommended — disabling skips URL resolution and returns raw Google News redirect URLs. |
| `enableAiAnalysis` | boolean | `false` | Generate an AI executive briefing from collected articles. Requires an API key for your chosen LLM provider. |
| `briefingStyle` | select | `executive` | Briefing format: `executive` (concise, action-oriented), `detailed` (comprehensive with source attribution), or `bullet-points` (scannable key facts). |
| `llmProvider` | select | `openrouter` | AI provider: `openrouter` (recommended — 300+ models), `anthropic` (Claude), `google` (Gemini), `openai` (GPT), or `ollama` (self-hosted). |
| `llmModel` | string | (auto) | Override the default model. Leave empty to use the provider default (Gemini 2.0 Flash for OpenRouter, Claude Sonnet for Anthropic, Gemini for Google AI, GPT-4o Mini for OpenAI, Llama 3.1 for Ollama). |
| `openrouterApiKey` | string | -- | Your OpenRouter API key. Required when using the OpenRouter provider. Get one at openrouter.ai/keys |
| `anthropicApiKey` | string | -- | Your Anthropic API key. Required when using the Anthropic provider. |
| `googleApiKey` | string | -- | Your Google AI API key. Required when using the Google AI provider. |
| `openaiApiKey` | string | -- | Your OpenAI API key. Required when using the OpenAI provider. |
| `ollamaBaseUrl` | string | `http://localhost:11434` | Base URL for self-hosted Ollama server. |
| `watchIntervalMinutes` | integer | `0` | **Live-watch mode**: minutes between scans. `0` = one-shot run. Set to 15-60 for real-time monitoring. |
| `watchDurationMinutes` | integer | `0` | **Live-watch mode**: total watch duration in minutes before exiting. `0` = one-shot run. Max 4320 (3 days). Both this AND watchIntervalMinutes must be set. |
| `briefingRegenThreshold` | integer | `3` | **Watch mode only**: minimum new articles before the AI briefing regenerates. Controls briefing cost vs. scrape cost. |
| `proxyConfiguration` | object | Apify proxy | Proxy settings. Google News RSS works with datacenter proxy; switch to RESIDENTIAL only if blocked. |

#### Briefing Styles Explained

- **Executive** -- Concise one-page briefing for C-level readers. Focuses on key developments, business impact, and recommended actions. Designed for leaders who need the signal without the noise.
- **Detailed** -- Comprehensive analysis with source attribution, historical context, and thorough coverage of each major development. Best for research reports and in-depth intelligence.
- **Bullet Points** -- Scannable format with just key facts. Every section uses bullet points for maximum readability. Ideal for Slack digests and quick team updates.

#### Pricing

This actor uses **pay-per-event (PPE)** pricing:

| Event | Price | Description |
|-------|-------|-------------|
| Article scraped | $0.002 | Per article collected, URL-resolved, and enriched (snippet, hero image, sentiment, domain) |
| AI briefing generated | $0.05 | Per AI-powered executive briefing generated |

**Cost examples:**

| Scenario | Queries | Articles | Briefings | Estimated Cost |
|----------|---------|----------|-----------|----------------|
| Single topic daily digest | 1 | 30 | 1 | ~$0.11 |
| Multi-topic monitoring | 3 | 90 | 3 | ~$0.33 |
| Weekly roundup (5 topics) | 5 | 250 | 5 | ~$0.75 |
| Raw articles only (no AI) | 3 | 100 | 0 | ~$0.20 |

Plus Apify platform compute costs and your LLM provider costs (typically $0.001-$0.01 per briefing with OpenRouter/Gemini Flash).

### Output

Each query produces a structured dataset item. Every article carries a consistent set of fields (`guid`, `image_url`, `author`, `publisher_name`, `keywords`, `date_published`, `date_modified`, `article_section`, `domain`, `word_count`, `sentiment_stub` are always present — `null` or `[]` when not exposed by the publisher):

```json
{
    "query": "OpenAI",
    "articles_found": 25,
    "time_range": "1d",
    "country": "us",
    "language": "en",
    "articles": [
        {
            "title": "Article headline here",
            "url": "https://techcrunch.com/2026/04/10/...",
            "guid": "https://news.google.com/rss/articles/CBMi...",
            "source": "TechCrunch",
            "author": "Jane Doe",
            "publisher_name": "TechCrunch",
            "keywords": ["OpenAI", "AI", "enterprise"],
            "published_date": "2026-04-10T08:00:00+00:00",
            "snippet": "First 500 characters of article content...",
            "image_url": "https://techcrunch.com/wp-content/uploads/2026/04/hero.jpg",
            "date_published": "2026-04-10T08:00:00.000Z",
            "date_modified": "2026-04-10T11:45:12.000Z",
            "article_section": "Technology",
            "domain": "techcrunch.com",
            "word_count": 842,
            "sentiment_stub": "positive",
            "scraped_at": "2026-04-10T12:00:00+00:00"
        }
    ],
    "ai_briefing": {
        "summary": "Multi-paragraph executive summary covering key developments...",
        "key_developments": [
            "Development 1 with source attribution",
            "Development 2 with context and business impact"
        ],
        "sentiment": {
            "positive": 40,
            "neutral": 35,
            "negative": 25
        },
        "trending_themes": [
            "AI regulation",
            "Enterprise adoption"
        ],
        "notable_sources": "Analysis of which outlets covered the story and their perspectives...",
        "impact_assessment": "What these developments mean for stakeholders...",
        "recommended_actions": [
            "Action 1 based on the news developments",
            "Action 2 for risk mitigation or opportunity capture"
        ]
    },
    "generated_at": "2026-04-10T12:00:00+00:00"
}
````

Output is available as JSON, CSV, or Excel. Use Apify integrations to push briefings to Slack, email, Google Sheets, or any webhook endpoint for automated delivery.

#### Sample AI Executive Briefing

A real (anonymized) `ai_briefing` payload from a 24-hour OpenAI watch — this is the killer-feature output most buyers want to see before they ever click Run:

```json
{
    "report_type": "executive_briefing",
    "topic": "OpenAI",
    "window_hours": 24,
    "articles_analyzed": 47,
    "overall_sentiment": "mixed-positive",
    "sentiment_breakdown": {"positive": 22, "neutral": 18, "negative": 7},
    "key_developments": [
        "GPT-5 announced with 1M context window (TechCrunch, NYT, WSJ converge)",
        "Internal restructuring rumor (Bloomberg sole source — verify before action)",
        "Microsoft Azure exclusive deal extended through 2027 (Reuters)"
    ],
    "trending_themes": ["context-window arms race", "agent infrastructure", "regulatory pressure"],
    "recommended_actions": [
        "Update partner-deck competitive slide before EOW",
        "Brief CEO on Azure exclusivity implications for our cloud strategy",
        "Monitor restructuring rumor for next 48h before any public response"
    ],
    "notable_articles": [
        {"title": "OpenAI's GPT-5 changes everything", "source": "TechCrunch", "sentiment": "positive", "url": "https://..."},
        {"title": "Inside OpenAI's reorg", "source": "Bloomberg", "sentiment": "neutral", "url": "https://..."}
    ]
}
```

Notice the `key_developments` line that calls out a single-source Bloomberg rumor — multi-source convergence vs. sole-source signal is preserved so your team can triage what's confirmed vs. what's still chatter. The `recommended_actions` list is what replaces the analyst-written "what should we do about this" paragraph at the bottom of a Meltwater PDF.

#### How this compares to other Google News scrapers

Most Google News scrapers on the Apify Store stop at raw article metadata (title, source, URL, date, snippet). This actor adds five layers the others do not ship:

1. **Integrated AI executive briefing** — executive / detailed / bullet-points style, with summary, key developments, sentiment breakdown, trending themes, notable sources, impact assessment, and recommended actions. No competitor bundles this.
2. **Live-watch mode** — the only Google News actor on the Store that can run as a long-lived monitor. Set an interval + duration and the actor stays alive, pushing only new articles (deduped by GUID) on each pass. Briefings regenerate only when the news delta crosses a threshold you control.
3. **Rich article metadata** — every article carries `image_url` (og:image / twitter:image resolved absolutely), `author`, `publisher_name`, `keywords`, `date_published`, `date_modified`, `article_section`, and a stable `guid` for cross-run dedup. The two-layer extractor lifts author coverage on top-tier publishers from ~10% to ~60-80%.
4. **Derived analytics fields** — `domain` (with 200+ publisher fallback map), `word_count` (publisher-declared or heuristic), and a cheap `sentiment_stub` for quick filtering without an AI key.
5. **Multi-LLM provider support** — OpenRouter, Anthropic, Google AI (Gemini), OpenAI, or self-hosted Ollama. No vendor lock-in.

Pricing ($0.002 per article) delivers the full enrichment stack — two-layer metadata extraction, GUID dedup, sentiment stub, and derived analytics — at the same per-article cost as dedicated scrapers that only return raw metadata.

### Quick Start

#### Live-Watch Mode (always-on monitoring)

Runs continuously, polls Google News every N minutes, pushes only delta articles. Cheaper than scheduled runs because you only pay for new articles, not re-scrapes.

```json
{
    "queries": ["our-brand", "our-ceo-name"],
    "language": "en",
    "country": "us",
    "watchIntervalMinutes": 15,
    "watchDurationMinutes": 1440,
    "enableAiAnalysis": true
}
```

**Cost:** $0.002/new article. A 24h watch on 2 queries typically returns 30-100 new articles = $0.06-$0.20/day. Run as a daily Apify schedule for ~$2-6/month vs Meltwater $400-1000/mo seat.

**One-shot monitoring with AI briefing:**

```json
{
    "searchQueries": ["OpenAI"],
    "maxArticles": 30,
    "timeRange": "1d",
    "enableAiAnalysis": true,
    "briefingStyle": "executive",
    "openrouterApiKey": "sk-or-..."
}
```

**Multiple topics, no AI (raw article data only):**

```json
{
    "searchQueries": ["Tesla earnings", "EV market 2026", "battery technology"],
    "maxArticles": 50,
    "timeRange": "7d",
    "enableAiAnalysis": false
}
```

**Live-watch mode — PR / crisis monitor (scan every 15 minutes for 8 hours, regenerate briefing only when 3+ new articles land):**

```json
{
    "searchQueries": ["OpenAI"],
    "maxArticles": 30,
    "timeRange": "1h",
    "watchIntervalMinutes": 15,
    "watchDurationMinutes": 480,
    "briefingRegenThreshold": 3,
    "enableAiAnalysis": true,
    "openrouterApiKey": "sk-or-..."
}
```

**German-language competitive intelligence:**

```json
{
    "searchQueries": ["Volkswagen Elektroauto", "BMW Strategie"],
    "maxArticles": 30,
    "timeRange": "1d",
    "country": "de",
    "language": "de",
    "enableAiAnalysis": true,
    "llmProvider": "openrouter",
    "openrouterApiKey": "sk-or-..."
}
```

**Automated daily briefing (schedule this run daily at 8 AM via Apify Schedules; forward the dataset to Slack/email via Apify integrations):**

```json
{
    "searchQueries": ["climate tech", "ESG investing"],
    "maxArticles": 30,
    "timeRange": "1d",
    "enableAiAnalysis": true,
    "briefingStyle": "bullet-points",
    "openrouterApiKey": "sk-or-..."
}
```

**Market research with GPT-4o Mini:**

```json
{
    "searchQueries": ["renewable energy market 2026"],
    "maxArticles": 50,
    "timeRange": "7d",
    "enableAiAnalysis": true,
    "briefingStyle": "detailed",
    "llmProvider": "openai",
    "llmModel": "gpt-4o-mini",
    "openaiApiKey": "sk-..."
}
```

#### How live-watch mode works

Set both `watchIntervalMinutes` and `watchDurationMinutes` to values > 0 (e.g. 15 and 480 for a 15-minute scan across an 8-hour shift). The actor runs its full query loop, sleeps for the interval, then runs again — pushing only articles it has never seen before (deduplicated by Google News GUID). Each dataset item includes a `watch_iteration` field and a `watch_is_delta` boolean so downstream consumers can distinguish the first-pass full load from incremental delta pushes.

The AI briefing is skipped on iterations where fewer than `briefingRegenThreshold` (default 3) new articles arrive. This separates the always-on $0.002 article cost from the $0.05 briefing cost — you only pay for a new briefing when the story actually moves.

**Common watch shapes:**

- **Breaking-news alerts**: `timeRange=1h`, interval 5-15 min, duration 60-240 min, threshold 1
- **Business-hours PR monitor**: `timeRange=1h`, interval 15-30 min, duration 480 min, threshold 3
- **Overnight watch**: `timeRange=1h`, interval 30-60 min, duration 720 min, threshold 5

Maximum watch duration is 4320 minutes (3 days).

#### How it differs from Google Alerts

Google Alerts sends you links. This actor collects the actual article content, resolves redirect URLs to clean links, extracts the publisher's hero image, and optionally generates AI-powered briefings with sentiment analysis, theme extraction, and recommended actions. The output is structured JSON you can feed into dashboards, databases, or automated workflows — not an email with a list of URLs.

#### MCP Quickstart — call this actor from Claude / Cursor / ChatGPT

Install the Apify MCP server in your AI agent of choice:

```bash
## Claude Code
claude mcp add apify -- npx -y @apify/actors-mcp-server --token YOUR_APIFY_TOKEN

## Claude Desktop / Cursor (add to mcp.json):
{"mcpServers":{"apify":{"command":"npx","args":["-y","@apify/actors-mcp-server","--token","YOUR_APIFY_TOKEN"]}}}
```

Then prompt the agent:

> "Use the harvestlab/news-monitor actor on Apify to monitor 'OpenAI' across English news for the last 24 hours and generate an executive briefing with sentiment, key developments, and recommended actions. Push the results back as JSON."

The agent will discover the actor's `dataset_schema.json`, generate the right input, run it, and pipe the typed output back into your conversation.

### Use with AI agents

news-monitor's output is agent-ready — every run returns articles plus an AI executive briefing (sentiment breakdown, key developments, trending themes, recommended actions) as structured JSON. Wrap this actor as a tool inside a brand-monitoring agent, PR/comms briefing workflow, or research pipeline and replace a Meltwater / Cision / Mention seat with a few lines of code.

**LangChain — `monitor_news` tool (Meltwater/Cision alternative):**

```python
from langchain.tools import Tool
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

def monitor_news(params: dict) -> list:
    run = client.actor("harvestlab/news-monitor").call(run_input={
        "searchQueries": params["queries"],
        "watchDurationMinutes": params.get("watchDurationMinutes", 0),
        "enableAiAnalysis": True,
        "briefingStyle": "executive",
    })
    return list(client.dataset(run["defaultDatasetId"]).iterate_items())

monitor_news_tool = Tool(
    name="monitor_news",
    description="Monitor Google News for keywords; returns articles + AI executive briefing with sentiment, key developments, recommended actions.",
    func=monitor_news,
)
## agent.invoke({"input": "Brief me on BrandX coverage in the last hour"})
```

**LangGraph — node in a brand-monitoring graph:**

```python
from langgraph.graph import StateGraph
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

def news_node(state: dict) -> dict:
    run = client.actor("harvestlab/news-monitor").call(run_input={
        "searchQueries": state["brand_keywords"],
        "timeRange": "1d",
        "enableAiAnalysis": True,
        "briefingStyle": "executive",
    })
    items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
    return {**state, "articles": items[0]["articles"], "briefing": items[0].get("ai_briefing")}

graph = StateGraph(dict)
graph.add_node("news", news_node)
## wire into downstream sentiment-router / PR-draft / Slack-alert nodes
```

See Apify's [`actor-templates/js-langchain`](https://github.com/apify/actor-templates/tree/master/templates/js-langchain) and [`js-langgraph-agent`](https://github.com/apify/actor-templates/tree/master/templates/js-langgraph-agent) for full reference setups.

### Troubleshooting

**No articles returned for my search query**
Google News search is keyword-sensitive. Try broader terms or check spelling. Very niche queries may return 0 results — use multiple keywords and combine with the `language` and `country` fields to target regional editions.

**Article content is truncated or missing**
Google News snippets are typically 1-3 sentences. Full article text is behind publisher paywalls. The actor scrapes what Google exposes publicly (title, snippet, source, date, URL) plus JSON-LD structured data. For full text, follow the `url` to the publisher site.

**AI briefing fails with "API key missing"**
Set your chosen provider's key in actor input (e.g. `openrouterApiKey`) OR as an environment variable (`OPENROUTER_API_KEY`). AI analysis is optional — set `enableAiAnalysis: false` to collect articles without the briefing. Get an OpenRouter key at openrouter.ai/keys (free tier available).

**Results look stale or cached**
Google News freshness depends on query specificity. Add a time filter (e.g. "climate change after:2026-01-01") or use `timeRange: "1h"` combined with `watchIntervalMinutes` for continuous monitoring with delta-only output.

**Approximately 5-10% of article URLs remain as Google News redirects**
The actor pre-sets Google's CONSENT cookie to bypass EU GDPR consent interstitials, but a small fraction of requests route through a mobile consent variant that strips the cookie. The `source` field is still populated so you can identify the publisher. Set `fetchArticleSnippets: false` to skip URL resolution entirely and always return raw Google News URLs.

**`sentiment_stub` always returns "neutral" for non-English articles**
The `sentiment_stub` field uses English keyword matching and is not multilingual. For accurate multilingual sentiment analysis, enable the AI briefing (`enableAiAnalysis: true`) — the LLM is fully language-aware and produces the real sentiment breakdown in `ai_briefing.sentiment`.

**Slow runs or timeouts**
The actor caps per-query enrichment at 180 seconds. If you hit timeouts frequently, reduce `maxArticles` (try 20-30) or set `fetchArticleSnippets: false`. Very high-frequency watch mode runs (every few minutes) may encounter Google News rate limits — hourly or daily intervals are recommended.

**`image_url` is null for some articles**
`image_url` is populated from the publisher's `og:image` or `twitter:image` meta tag. Niche or regional publishers may not set these. The field is also null when URL resolution fails, when `fetchArticleSnippets` is disabled, or when the publisher page blocks datacenter proxies with a 403.

**`author` / `date_published` / `date_modified` / `article_section` are null**
These fields come from the two-layer extractor (OpenGraph meta tags → JSON-LD fallback). Smaller regional sites, aggregators, press-release wires, and blog posts may ship neither, in which case the field is `null`. Paywalled articles serving a login-wall also return `null` here.

#### Known limitations

- **Google News RSS availability** — The actor relies on Google News RSS feeds, which may not include every article from every source. Paywalled articles appear in results but their full content is not extractable.
- **Requires an LLM API key for briefings** — AI briefings require an API key from OpenRouter, Anthropic, Google AI, or OpenAI (or a self-hosted Ollama instance). LLM usage is billed separately by your chosen provider.
- **Article snippet length** — Extracted content snippets are typically 200-500 characters due to copyright and paywall considerations.
- **Rate limiting** — Very high-frequency runs (every few minutes) may encounter Google News rate limits. Hourly or daily runs are recommended for most monitoring use cases.
- **Regional coverage gaps** — Some countries and languages have less coverage in Google News. Results quality depends on Google News indexing for your target region and topic.

### Legal and Compliance

This actor scrapes publicly available data from Google News RSS feeds. By using this actor, you agree to the following:

- **Your responsibility**: You are solely responsible for ensuring your use complies with all applicable laws, regulations, and the target website's terms of service. This includes but is not limited to GDPR (EU), CCPA (California), and other data protection laws in your jurisdiction.
- **No legal advice**: This actor does not constitute legal advice. Consult a qualified attorney if you have questions about the legality of your specific use case.
- **Intended use**: This actor is designed for legitimate business purposes such as market research, competitive analysis, and academic research using publicly accessible data.
- **Data handling**: You are responsible for how you store, process, and share any data collected. Ensure you have a lawful basis for processing any personal data under applicable privacy laws.
- **Rate limiting**: This actor implements polite crawling practices including request delays and retry backoff to minimize impact on target servers.
- **No warranty**: This actor is provided "as is" without warranty. Data accuracy depends on the target website's content and structure.
- **Copyright**: News articles are protected by copyright. This actor extracts metadata and summaries, not full article text. Do not republish full article content without permission from the copyright holder.
- **Google News Terms of Service**: Automated access to Google News may be subject to Google's Terms of Service. Users are responsible for reviewing and complying with Google's terms for their specific use case.

#### Related Actors

- **[Google Search Scraper](https://apify.com/harvestlab/google-search-scraper)** -- Correlate news coverage with search-trend signals. When news-monitor surfaces a story, run Google Search Scraper on the same query to see if SERP intent is matching (people are looking it up) or decoupled (media noise without audience interest).
- **[Reddit Scraper](https://apify.com/harvestlab/reddit-scraper)** -- Capture public reaction to news on the same topic. Cross-reference media coverage with grassroots Reddit sentiment for a multi-channel view of how stories actually land with audiences.
- **[YouTube Scraper](https://apify.com/harvestlab/youtube-scraper)** -- Track YouTube video coverage and creator commentary on breaking news. Combine news articles with video-channel analysis for comprehensive media monitoring across written and video formats.

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords, company names, or topics to monitor on Google News. Each query runs a separate search (e.g. \['OpenAI', 'artificial intelligence']).

## `searchQuery` (type: `string`):

Single search query — alias for Search Queries. Use this for a single topic instead of a list.

## `query` (type: `string`):

CLI alias for searchQuery. Hidden from Console form.

## `topic` (type: `string`):

CLI alias for searchQuery. Hidden from Console form.

## `maxArticles` (type: `integer`):

Maximum number of articles to collect per search query. Higher values find more coverage but take longer (each article requires URL resolution and snippet fetch). Start with 10-30 for testing; Google News typically returns 50-100 unique results per query before repetition.

## `maxItems` (type: `integer`):

CLI alias for maxArticles. Hidden from Console form.

## `maxArticlesPerQuery` (type: `integer`):

Legacy alias for maxArticles. Hidden from Console form.

## `timeRange` (type: `string`):

Freshness window for Google News results. 'Past hour' for breaking-news monitoring; 'Past 24 hours' (default) for daily briefings; 'Past week' for weekly roundups or trending topics; 'Past month' for broader coverage. Shorter windows return fresher but fewer articles.

## `country` (type: `string`):

Google News edition (gl parameter). Controls which regional publishers and local stories surface first. Pair with a matching Language below for best results — e.g. 'Germany' + 'German', or 'Netherlands' + 'Dutch'. 'United States' + 'English' (default) covers global English-language coverage.

## `language` (type: `string`):

Language for Google News results and AI briefing output.

## `fetchArticleSnippets` (type: `boolean`):

Resolves each article's Google News redirect URL to the actual publisher URL and fetches a short content snippet. STRONGLY RECOMMENDED — without this, the `url` field is a Google News redirect (not directly usable). Adds ~5-15 seconds to the run. Disable only if you want raw/unresolved output for speed.

## `enableAiAnalysis` (type: `boolean`):

Generate an AI-powered executive briefing from the collected articles. Requires an API key for your chosen LLM provider. (Legacy alias: enableAiBriefing still accepted.)

## `enableAiBriefing` (type: `boolean`):

Legacy alias for enableAiAnalysis. Hidden from Console form.

## `briefingStyle` (type: `string`):

Style of the AI-generated briefing.

## `llmProvider` (type: `string`):

Which AI provider to use for generating briefings.

## `llmModel` (type: `string`):

Specific model to use. Leave empty for the provider default (google/gemini-2.0-flash-001 for OpenRouter, claude-sonnet-4-20250514 for Anthropic, gemini-2.0-flash for Google AI, gpt-4o-mini for OpenAI, llama3.1 for Ollama).

## `openrouterApiKey` (type: `string`):

OpenRouter API key — alternative: set OPENROUTER\_API\_KEY env var. Get one at openrouter.ai/keys

## `anthropicApiKey` (type: `string`):

Anthropic API key — alternative: set ANTHROPIC\_API\_KEY env var. Get one at console.anthropic.com/settings/keys

## `googleApiKey` (type: `string`):

Google AI (Gemini) API key — alternative: set GOOGLE\_API\_KEY env var. Get one at aistudio.google.com/app/apikey

## `openaiApiKey` (type: `string`):

OpenAI API key — alternative: set OPENAI\_API\_KEY env var. Get one at platform.openai.com/api-keys

## `ollamaBaseUrl` (type: `string`):

Base URL for Ollama API. Default: http://localhost:11434

## `watchIntervalMinutes` (type: `integer`):

LIVE WATCH MODE: minutes to wait between scans. Leave at 0 (default) for a one-shot run. Set to 15-60 for real-time news monitoring — the Actor stays alive, re-queries Google News every N minutes, and pushes only newly-seen articles (deduped by Google News GUID). Recommended pairing: timeRange='1h' + watchIntervalMinutes=15 for crisis / PR-war-room monitoring. Minimum 1, maximum 1440 (24h).

## `watchDurationMinutes` (type: `integer`):

LIVE WATCH MODE: how long to keep watching before exiting. Leave at 0 (default) for a one-shot run. Common values: 60 (1h), 480 (8h shift), 1440 (24h), 4320 (3 days, the maximum). Set both this AND watchIntervalMinutes to enable watch mode. The Actor exits cleanly when duration elapses.

## `briefingRegenThreshold` (type: `integer`):

WATCH MODE ONLY: minimum number of NEW articles in an iteration before the AI briefing is regenerated. Separates always-on scrape cost ($0.002/article) from briefing cost ($0.05/briefing) — only pay for a new briefing when the story actually moves. Default 3. Set to 1 to regenerate every iteration. Ignored in one-shot mode; first iteration always runs the briefing if enableAiAnalysis is true.

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

Proxy settings. Google News RSS works fine with default datacenter proxy; switch to RESIDENTIAL only if you hit blocks.

## Actor input object example

```json
{
  "searchQueries": [
    "OpenAI",
    "artificial intelligence"
  ],
  "maxArticles": 30,
  "timeRange": "1d",
  "country": "us",
  "language": "en",
  "fetchArticleSnippets": true,
  "enableAiAnalysis": false,
  "briefingStyle": "executive",
  "llmProvider": "openrouter",
  "ollamaBaseUrl": "http://localhost:11434",
  "watchIntervalMinutes": 0,
  "watchDurationMinutes": 0,
  "briefingRegenThreshold": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `datasetOutput` (type: `string`):

Dataset containing scraped news articles, executive briefings with sentiment analysis, and watch-mode delta records.

# 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 = {
    "searchQueries": [
        "OpenAI",
        "artificial intelligence"
    ],
    "ollamaBaseUrl": "http://localhost:11434",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("harvestlab/news-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 = {
    "searchQueries": [
        "OpenAI",
        "artificial intelligence",
    ],
    "ollamaBaseUrl": "http://localhost:11434",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("harvestlab/news-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 '{
  "searchQueries": [
    "OpenAI",
    "artificial intelligence"
  ],
  "ollamaBaseUrl": "http://localhost:11434",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call harvestlab/news-monitor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "News MCP Monitor — Meltwater Alt + AI Briefings",
        "description": "Skyfire/x402 payment-ready. Monitor news across Google News + 50+ sources at $0.002/article — 99%+ run success, RAG-ready feed for AI agents via MCP. AI executive briefings + sentiment + brand alerts. Replaces Meltwater ($5k-$24k/yr), Cision, Mention, Notified, Onclusive, MuckRack.",
        "version": "1.10",
        "x-build-id": "fXsE4GOrmalV5Yb5s"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/harvestlab~news-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-harvestlab-news-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/harvestlab~news-monitor/runs": {
            "post": {
                "operationId": "runs-sync-harvestlab-news-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/harvestlab~news-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-harvestlab-news-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": {
                    "searchQueries": {
                        "title": "Search Queries",
                        "type": "array",
                        "description": "Keywords, company names, or topics to monitor on Google News. Each query runs a separate search (e.g. ['OpenAI', 'artificial intelligence']).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "searchQuery": {
                        "title": "Search Query (single, alias for Search Queries)",
                        "type": "string",
                        "description": "Single search query — alias for Search Queries. Use this for a single topic instead of a list."
                    },
                    "query": {
                        "title": "Query (CLI alias)",
                        "type": "string",
                        "description": "CLI alias for searchQuery. Hidden from Console form."
                    },
                    "topic": {
                        "title": "Topic (CLI alias)",
                        "type": "string",
                        "description": "CLI alias for searchQuery. Hidden from Console form."
                    },
                    "maxArticles": {
                        "title": "Max Articles per Query",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum number of articles to collect per search query. Higher values find more coverage but take longer (each article requires URL resolution and snippet fetch). Start with 10-30 for testing; Google News typically returns 50-100 unique results per query before repetition.",
                        "default": 30
                    },
                    "maxItems": {
                        "title": "Max Items (CLI alias)",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "CLI alias for maxArticles. Hidden from Console form."
                    },
                    "maxArticlesPerQuery": {
                        "title": "Max Articles Per Query (legacy alias)",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Legacy alias for maxArticles. Hidden from Console form."
                    },
                    "timeRange": {
                        "title": "Time Range",
                        "enum": [
                            "1h",
                            "1d",
                            "7d",
                            "30d"
                        ],
                        "type": "string",
                        "description": "Freshness window for Google News results. 'Past hour' for breaking-news monitoring; 'Past 24 hours' (default) for daily briefings; 'Past week' for weekly roundups or trending topics; 'Past month' for broader coverage. Shorter windows return fresher but fewer articles.",
                        "default": "1d"
                    },
                    "country": {
                        "title": "Country",
                        "enum": [
                            "us",
                            "gb",
                            "nl",
                            "de",
                            "fr",
                            "es",
                            "it"
                        ],
                        "type": "string",
                        "description": "Google News edition (gl parameter). Controls which regional publishers and local stories surface first. Pair with a matching Language below for best results — e.g. 'Germany' + 'German', or 'Netherlands' + 'Dutch'. 'United States' + 'English' (default) covers global English-language coverage.",
                        "default": "us"
                    },
                    "language": {
                        "title": "Language",
                        "enum": [
                            "en",
                            "nl",
                            "de",
                            "fr",
                            "es",
                            "it"
                        ],
                        "type": "string",
                        "description": "Language for Google News results and AI briefing output.",
                        "default": "en"
                    },
                    "fetchArticleSnippets": {
                        "title": "Resolve Article URLs & Fetch Snippets",
                        "type": "boolean",
                        "description": "Resolves each article's Google News redirect URL to the actual publisher URL and fetches a short content snippet. STRONGLY RECOMMENDED — without this, the `url` field is a Google News redirect (not directly usable). Adds ~5-15 seconds to the run. Disable only if you want raw/unresolved output for speed.",
                        "default": true
                    },
                    "enableAiAnalysis": {
                        "title": "Enable AI Briefing",
                        "type": "boolean",
                        "description": "Generate an AI-powered executive briefing from the collected articles. Requires an API key for your chosen LLM provider. (Legacy alias: enableAiBriefing still accepted.)",
                        "default": false
                    },
                    "enableAiBriefing": {
                        "title": "Enable AI Briefing (legacy alias)",
                        "type": "boolean",
                        "description": "Legacy alias for enableAiAnalysis. Hidden from Console form."
                    },
                    "briefingStyle": {
                        "title": "Briefing Style",
                        "enum": [
                            "executive",
                            "detailed",
                            "bullet-points"
                        ],
                        "type": "string",
                        "description": "Style of the AI-generated briefing.",
                        "default": "executive"
                    },
                    "llmProvider": {
                        "title": "LLM Provider",
                        "enum": [
                            "openrouter",
                            "anthropic",
                            "google",
                            "openai",
                            "ollama"
                        ],
                        "type": "string",
                        "description": "Which AI provider to use for generating briefings.",
                        "default": "openrouter"
                    },
                    "llmModel": {
                        "title": "LLM Model",
                        "type": "string",
                        "description": "Specific model to use. Leave empty for the provider default (google/gemini-2.0-flash-001 for OpenRouter, claude-sonnet-4-20250514 for Anthropic, gemini-2.0-flash for Google AI, gpt-4o-mini for OpenAI, llama3.1 for Ollama)."
                    },
                    "openrouterApiKey": {
                        "title": "OpenRouter API Key",
                        "type": "string",
                        "description": "OpenRouter API key — alternative: set OPENROUTER_API_KEY env var. Get one at openrouter.ai/keys"
                    },
                    "anthropicApiKey": {
                        "title": "Anthropic API Key",
                        "type": "string",
                        "description": "Anthropic API key — alternative: set ANTHROPIC_API_KEY env var. Get one at console.anthropic.com/settings/keys"
                    },
                    "googleApiKey": {
                        "title": "Google AI API Key",
                        "type": "string",
                        "description": "Google AI (Gemini) API key — alternative: set GOOGLE_API_KEY env var. Get one at aistudio.google.com/app/apikey"
                    },
                    "openaiApiKey": {
                        "title": "OpenAI API Key",
                        "type": "string",
                        "description": "OpenAI API key — alternative: set OPENAI_API_KEY env var. Get one at platform.openai.com/api-keys"
                    },
                    "ollamaBaseUrl": {
                        "title": "Ollama Base URL",
                        "type": "string",
                        "description": "Base URL for Ollama API. Default: http://localhost:11434"
                    },
                    "watchIntervalMinutes": {
                        "title": "Watch Interval (minutes)",
                        "minimum": 0,
                        "maximum": 1440,
                        "type": "integer",
                        "description": "LIVE WATCH MODE: minutes to wait between scans. Leave at 0 (default) for a one-shot run. Set to 15-60 for real-time news monitoring — the Actor stays alive, re-queries Google News every N minutes, and pushes only newly-seen articles (deduped by Google News GUID). Recommended pairing: timeRange='1h' + watchIntervalMinutes=15 for crisis / PR-war-room monitoring. Minimum 1, maximum 1440 (24h).",
                        "default": 0
                    },
                    "watchDurationMinutes": {
                        "title": "Watch Duration (minutes)",
                        "minimum": 0,
                        "maximum": 4320,
                        "type": "integer",
                        "description": "LIVE WATCH MODE: how long to keep watching before exiting. Leave at 0 (default) for a one-shot run. Common values: 60 (1h), 480 (8h shift), 1440 (24h), 4320 (3 days, the maximum). Set both this AND watchIntervalMinutes to enable watch mode. The Actor exits cleanly when duration elapses.",
                        "default": 0
                    },
                    "briefingRegenThreshold": {
                        "title": "AI Briefing Regen Threshold",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "WATCH MODE ONLY: minimum number of NEW articles in an iteration before the AI briefing is regenerated. Separates always-on scrape cost ($0.002/article) from briefing cost ($0.05/briefing) — only pay for a new briefing when the story actually moves. Default 3. Set to 1 to regenerate every iteration. Ignored in one-shot mode; first iteration always runs the briefing if enableAiAnalysis is true.",
                        "default": 3
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings. Google News RSS works fine with default datacenter proxy; switch to RESIDENTIAL only if you hit blocks."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
