# News & Media Monitor (Event Clustering + Sentiment) (`akozaruk/newsapi-ai-scraper`) Actor

Monitor news worldwide by keyword: groups coverage of the same story across sources with sentiment, and supports incremental scheduled runs. Powered by the NewsAPI.ai (Event Registry) API.

- **URL**: https://apify.com/akozaruk/newsapi-ai-scraper.md
- **Developed by:** [Anastasiia Kozaruk](https://apify.com/akozaruk) (community)
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

### What does News & Media Monitor do?

Give it one or more keywords and it searches news articles from thousands of sources worldwide — but instead of handing back a flat list of articles, it **groups coverage of the same real-world story together**, showing you how many outlets picked it up and their average sentiment. It also supports **incremental scheduled runs**, so you can point it at Apify's Scheduler and only ever fetch new coverage since the last run. No API key or third-party account needed — access is built in.

### Why use News & Media Monitor?

- **No account or API key needed** — just add keywords and run; access to the underlying news API is included
- **See the story, not just the article list** — 7 outlets covering the same event show up as one grouped item with a source count and average sentiment, not 7 disconnected rows you have to de-duplicate yourself
- **Brand and topic monitoring** — track what's being written about a company, product, or event as it happens, and how sentiment shifts across outlets
- **Competitor and market research** — see how widely a story spread and which outlets picked it up
- **Built for scheduling** — turn on incremental mode, schedule the Actor to run daily via Apify's Scheduler, and it will only fetch articles published since its last run

### How to use News & Media Monitor

1. Open the Actor's **Input** tab and add one or more **Keywords** to search for (e.g. `electric vehicles`).
2. Optionally narrow results with **Languages**, a **Date from/to** range, or a different **Sort by** order.
3. Click **Start** and download the results from the **Dataset** tab once the run finishes.
4. To monitor a topic over time: turn on **Incremental monitoring mode** and add a [Schedule](https://console.apify.com/schedules) to run the Actor daily (or hourly) — each run will only fetch articles published since the previous one.

### Input

See the **Input** tab for the full list of options. Only **Keywords** is required. Two options shape the output the most:

- **Group into stories (event clustering)** — on by default. Groups articles about the same event into one dataset item instead of a flat article list.
- **Incremental monitoring mode** — off by default. When on, each scheduled run only fetches articles newer than the previous run for the same keywords/languages.

### Output

With event clustering (the default), each dataset item is one **story**, with every source that covered it:

```json
[
  {
    "eventUri": "eng-11971843",
    "title": "Two senior officials step down after undercover report",
    "firstSeenDateTime": "2026-09-04T07:30:23Z",
    "sourceCount": 7,
    "articleCount": 7,
    "averageSentiment": 0.13,
    "sources": [
      { "title": "BBC", "url": "https://www.bbc.com/news/articles/...", "date": "2026-09-04T07:30:23Z", "sentiment": 0.19 },
      { "title": "The Telegraph", "url": "https://www.telegraph.co.uk/...", "date": "2026-09-04T07:54:23Z", "sentiment": 0.22 }
    ]
  }
]
```

With event clustering turned off, each dataset item is one raw article as returned by the underlying API (title, body, url, source, date, sentiment, and more).

**What does `sentiment` mean?** It's a score from about **-1** (very negative tone) to **+1** (very positive tone), with values near 0 being neutral. `averageSentiment` is the mean of that score across every source covering a story.

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel from the Apify Console.

### Tips

- Keep **Max articles** low (e.g. 50–100) — this Actor's news-API access is shared across all users on a monthly quota.
- Use a narrow **Date from/to** range and specific **Keywords** to get more relevant results per search.
- For ongoing monitoring, combine **Incremental monitoring mode** with a daily [Schedule](https://console.apify.com/schedules) rather than running large one-off pulls — it fetches only new articles each time, which is both faster and easier on the shared quota.

### Real-time API access (Standby mode)

Besides normal Console/scheduled runs, this Actor also runs in **[Standby mode](https://docs.apify.com/platform/actors/running/standby)** — a stable HTTP endpoint you can call directly for a single, real-time lookup instead of starting a full Actor run.

**Base URL:** your Actor's Standby URL, shown on the **Standby** tab in Apify Console (format `https://<username>--<actor-name>.apify.actor`).

**Authentication:** `Authorization: Bearer <your Apify API token>` header (or `?token=<token>` query param).

**Endpoints:**

- `GET /search` — pass parameters as query string, e.g.:
  `GET /search?keywords=electric+vehicles&languages=eng&maxArticles=20`
  (comma-separate multiple keywords/languages)
- `POST /search` — pass a JSON body with the same fields as the Actor's input schema, e.g.:
  ```json
  { "keywords": ["electric vehicles"], "languages": ["eng"], "maxArticles": 20 }
  ```

Both return:

```json
{ "articleCount": 20, "results": [ /* stories or articles, same shape as the Dataset output */ ] }
```

A `429` response means the shared monthly quota is exhausted; a `400` response means the input was invalid (e.g. missing `keywords`). Full interactive API docs (Swagger UI) are on the **API** tab in Console. Note: incremental monitoring mode is a batch-run-only feature and isn't available via Standby.

### FAQ & support

**Why did my run fail with a "shared monthly quota" error?** This Actor's news-API access is shared across all its users with a monthly cap. Once that's reached, runs fail immediately (without using Apify compute) until it resets on the 1st of the next month.

**Can I search in a specific language only?** Yes — add one or more languages to the **Languages** input, either as ISO 639 3-letter codes (`eng`, `deu`, `spa`) or common English names (`English`, `German`, `Spanish`) — both are accepted.

**How does incremental mode know what's new?** It keeps a small checkpoint (the newest article timestamp seen) per unique combination of keywords/languages, stored privately in your own Apify account. Each run reads that checkpoint and only asks for articles published since then. The checkpoint has day-level precision, so the boundary day may occasionally include an article you've already seen.

Our Actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what is publicly available through the source API. However, you should be aware that your results could contain personal data (e.g. names mentioned in articles). Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

If you run into an issue or have a feature request, use the Actor's **Issues** tab on Apify Store.

# Actor input Schema

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

One or more keywords or phrases to search for, one per line (e.g. "electric vehicles"). Articles matching ANY of the keywords are returned.

## `keywordsLocation` (type: `string`):

Which part of the article to match the keywords against.

## `languages` (type: `array`):

Restrict results to these article languages. Pick from the list or type a custom ISO 639 3-letter code. Leave empty for all languages.

## `dateStart` (type: `string`):

Only return articles published on or after this date. Leave empty for no lower limit.

## `dateEnd` (type: `string`):

Only return articles published on or before this date. Leave empty for no upper limit.

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

Order in which matching articles are returned.

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

Maximum number of articles to fetch in total. Each page of results counts against this Actor's shared monthly search quota, so please keep this conservative.

## `groupIntoEvents` (type: `boolean`):

Group articles covering the same real-world event into one dataset item, showing how many sources reported it and their average sentiment. Turn off to get one flat dataset item per article instead.

## `incrementalMode` (type: `boolean`):

Only fetch articles published since the last run with the same keywords/languages. Designed for scheduling this Actor to run repeatedly (e.g. daily) as a monitor, without re-fetching or re-paying for articles you've already seen. The very first run still uses "Date from"/"Date to" if set.

## Actor input object example

```json
{
  "keywords": [
    "climate change"
  ],
  "keywordsLocation": "body",
  "languages": [],
  "sortBy": "date",
  "maxArticles": 50,
  "groupIntoEvents": true,
  "incrementalMode": false
}
```

# Actor output Schema

## `results` (type: `string`):

One row per story (event clustering on) or per raw article (event clustering off).

# 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": [
        "climate change"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("akozaruk/newsapi-ai-scraper").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": ["climate change"] }

# Run the Actor and wait for it to finish
run = client.actor("akozaruk/newsapi-ai-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).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": [
    "climate change"
  ]
}' |
apify call akozaruk/newsapi-ai-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,akozaruk/newsapi-ai-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/LgXE6a1ip1NIcbDWZ/builds/6I0ZJXE0cyNj4Sr3t/openapi.json
