# GDELT News Monitor: Keyword Alerts, Tone, Themes, Entities (`datagleaner/gdelt-news-monitor`) Actor

Monitor news in 65+ languages from the GDELT Project's 15-minute feed. Filter by keyword, source domain, country and language; get the article URL, title, tone, themes, locations, people and organizations. Watch mode returns only new articles since the last run. $0.002 per article.

- **URL**: https://apify.com/datagleaner/gdelt-news-monitor.md
- **Developed by:** [Data Gleaner](https://apify.com/datagleaner) (community)
- **Categories:** News, Automation, AI
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 news articles

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## GDELT News Monitor: keyword alerts, tone, themes, people and organizations

Monitor news from around the world by keyword, source domain, country and language, straight from the **GDELT Project's 15-minute article feed**. Every row is one news article with its URL, title, source domain, tone score, GDELT themes, mentioned locations and organizations (people only if you switch them on). **Watch mode** returns only the articles that appeared since your last run, so a scheduled run becomes an alert feed.

The feed covers online news in 65+ languages. This Actor reads GDELT's published files directly (no scraping of news sites, no proxies, no search-engine results), so it is stable and cheap to run. Speed depends on how much of the feed you read: a watch-mode run (a window of 15 to 60 minutes) finishes in seconds, a 6-hour run in under a minute, and a full 24-hour run across all languages reads about 760 MB of files and can take around 10 minutes. Set `includeTranslated` to false, or filter by `languages`, to read English-language sources only, which is about a third of the data.

### What you get

- **Filters:** keywords (whole-word, any of, plus an exclude list), source domains, countries mentioned, source languages, tone range, a time window up to 7 days back.
- **Per article:** `url`, `title`, `sourceDomain`, `language`, `seenAt`, `publishedAt` (when the page declares it), `tone`, `positiveScore`, `negativeScore`, `polarity`, `wordCount`, `themes`, `locations` (name, country code, latitude, longitude), `organizations`, `imageUrl`, `matchedKeywords`, and `persons` only when you switch on `includePersons`.
- **Watch mode:** the position is saved in a named key-value store on your account (`gdelt-news-monitor-state`). The next run continues exactly where the last one ended, and articles are never returned twice.

### Input example

```json
{
  "keywords": ["Nvidia", "semiconductor"],
  "excludeKeywords": ["horoscope"],
  "languages": ["en"],
  "hoursBack": 24,
  "watchMode": true,
  "maxItems": 500
}
```

Leave every filter empty to run a free-form 5-article example (keyword `election`, last two hours).

### Output example

```json
{
  "url": "https://www.example-news.com/nvidia-earnings-preview",
  "title": "Nvidia earnings preview: what analysts expect",
  "sourceDomain": "example-news.com",
  "language": "eng",
  "translated": false,
  "publishedAt": "2026-11-01T13:02:11Z",
  "seenAt": "2026-11-01T13:45:00Z",
  "tone": -1.42,
  "positiveScore": 2.1,
  "negativeScore": 3.5,
  "polarity": 5.6,
  "wordCount": 612,
  "themes": ["ECON_STOCKMARKET", "TAX_FNCACT_ANALYST", "WB_1920_FINANCIAL_SECTOR_DEVELOPMENT"],
  "locations": [{"name": "Santa Clara, California, United States", "countryCode": "US", "lat": 37.35, "lon": -121.95}],
  "persons": [],
  "organizations": ["nvidia", "securities and exchange commission"],
  "matchedKeywords": ["nvidia"],
  "source": "GDELT Project",
  "sourceUrl": "https://www.gdeltproject.org/",
  "citation": "Data: The GDELT Project (https://www.gdeltproject.org/). Any use or redistribution of GDELT data must include a citation to the GDELT Project and a link to https://www.gdeltproject.org/.",
  "scrapedAt": "2026-11-01T14:00:00Z"
}
```

### Pricing

**$0.002 per article returned**, with no start fee. Reading files and filtering is free: a run that finds nothing costs nothing.

- 100 articles: $0.20
- 1,000 articles: $2.00
- A watcher on a narrow keyword (about 20 new articles an hour): roughly $1 a day

Set `maxItems` (or the run's maximum cost) to cap a run.

### Citation and licence

All article data comes from **The GDELT Project** (https://www.gdeltproject.org/), which makes it available for unrestricted academic, commercial and governmental use. GDELT's terms require that **any use or redistribution of the data includes a citation to the GDELT Project and a link to https://www.gdeltproject.org/**. Every row carries that citation in the `citation` field; keep it when you republish or share the data. This Actor is not affiliated with or endorsed by GDELT.

### How it differs from a news-search scraper

- **The source is GDELT's open event feed, not a search engine.** Results are not ranked by relevance or popularity: you get every matching article GDELT saw in the window, in time order.
- **Rich entities and tone** for every article: themes, places with coordinates, people, organizations and a tone score, which plain headline scrapers do not return.
- **Open licence.** The data may be stored and redistributed with the citation above.

### Limits and good to know

- **Titles and matching.** Keywords are matched against the title, URL and organizations of each article (and the people, when `includePersons` is on), not the full text. About 98% of articles carry a title.
- **Non-English articles** come from GDELT's machine-translated stream: the title stays in the original language, so match those with keywords in that language or filter by `countries`. Themes and organizations are normalized to English.
- **Countries** filters by the places an article mentions. GDELT does not record where the publisher is based.
- **Latency:** GDELT publishes a new file every 15 minutes, a few minutes after each quarter hour, so alerts lag the original story by roughly 15 to 30 minutes.
- **Window:** up to 168 hours (7 days) per run. Files GDELT did not publish are skipped and reported in the status message.
- Not every news site is monitored by GDELT. Coverage is broad, not complete.

### FAQ

**How do I get alerts?** Turn on `watchMode`, then schedule the Actor (Apify Schedules) every 15 to 60 minutes and connect the dataset to a webhook, Zapier, Make or n8n.

**Can two watchers use the same keywords?** Yes, give each a different `watchName`.

**Why is `publishedAt` often empty?** It is filled only when the page itself declares a publication time. `seenAt` is always present: it is when GDELT processed the article.

**Does it return the article text?** No. It returns the URL, title and GDELT's analysis. Fetch the text separately from the publisher where its terms allow.

### Purpose limit

This Actor is for monitoring topics, companies, organizations and public figures in the news. Do not use it to track, profile or contact private individuals by name. News articles also name victims, suspects, minors and bystanders, so `includePersons` is off by default; turn it on only for a public-figure watchlist, and do not use the output for credit, employment, insurance, housing or similar decisions about a person.

### Removal requests

If your name appears in a `persons` list and you want it dropped, email datagleaner@gmail.com with the name as it appears. We answer within 30 days, record each request with its date and answer, and add the name to the Actor's exclusion list in the next release. The Actor keeps no copy of the data: the articles stay with their publishers and the GDELT Project.

### Responsible use

The data is GDELT's public analysis of published news. Person and organization names are those that appear in public articles. Use the data lawfully, keep the GDELT citation, and respect the terms of the original publishers when you open their pages.

# Actor input Schema

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

Return articles whose title, URL, people or organizations contain any of these words or phrases (whole-word, case-insensitive, OR). Example: `electric vehicles`, `Nvidia`. Leave all filters empty to run a 5-article example.

## `excludeKeywords` (type: `array`):

Drop articles that contain any of these words or phrases in the title, URL, people or organizations.

## `domains` (type: `array`):

Only articles published on these domains (subdomains included), e.g. `reuters.com`, `bbc.co.uk`. Without `www.`.

## `countries` (type: `array`):

Only articles that mention a place in one of these countries. Use the country name (`Germany`) or its two-letter FIPS code (`GM`). GDELT does not record the publisher's country, so this filters by where the story takes place.

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

Only articles written in these languages: `en`, `es`, `fr`, `de`, `zh`, `ja`, `ar` ... (two-letter or three-letter codes). Empty means all languages. Non-English articles are GDELT's machine-translated stream: the title stays in the original language, and the themes, people and organizations are normalized to English.

## `hoursBack` (type: `integer`):

How far back to read, 1 to 168 hours (default 24). In watch mode this applies to the first run only; later runs continue where the last one stopped.

## `startTime` (type: `string`):

Optional ISO 8601 start, e.g. `2026-11-01T00:00:00Z`. Overrides `hoursBack` and the watch-mode state.

## `endTime` (type: `string`):

Optional ISO 8601 end. Defaults to now.

## `includePersons` (type: `boolean`):

Off by default. When on, rows carry GDELT's `persons` list and keywords also match people named in an article. News names victims, suspects and bystanders, so use this only for monitoring public figures, companies and topics: never to track a private individual by name. Names on our removal list are always dropped.

## `watchMode` (type: `boolean`):

Return only articles that appeared since the last run with the same filters. The position is saved in a named key-value store on your account. Schedule the Actor every 15 to 60 minutes to get an alert feed.

## `watchName` (type: `string`):

Optional label that keeps separate watchers with identical filters apart. Letters, digits, `-` and `_`.

## `includeTranslated` (type: `boolean`):

Also read GDELT's machine-translated stream (about 65 languages). Turn off to read English-language sources only.

## `minTone` (type: `number`):

Only articles with an average tone at or above this value. Tone runs roughly from -10 (very negative) to +10 (very positive).

## `maxTone` (type: `number`):

Only articles with an average tone at or below this value, e.g. `-3` for strongly negative coverage.

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

Stop after this many articles (each one is billed).

## Actor input object example

```json
{
  "keywords": [
    "Nvidia",
    "electric vehicles"
  ],
  "excludeKeywords": [
    "horoscope"
  ],
  "domains": [
    "reuters.com",
    "bbc.co.uk"
  ],
  "countries": [
    "Germany",
    "Japan"
  ],
  "languages": [
    "en",
    "de"
  ],
  "hoursBack": 6,
  "startTime": "2026-11-01T00:00:00Z",
  "endTime": "2026-11-01T12:00:00Z",
  "includePersons": false,
  "watchMode": false,
  "watchName": "default",
  "includeTranslated": true,
  "maxItems": 10
}
```

# Actor output Schema

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

No description

# 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": [
        "Nvidia",
        "semiconductor"
    ],
    "hoursBack": 6,
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("datagleaner/gdelt-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 = {
    "keywords": [
        "Nvidia",
        "semiconductor",
    ],
    "hoursBack": 6,
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("datagleaner/gdelt-news-monitor").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": [
    "Nvidia",
    "semiconductor"
  ],
  "hoursBack": 6,
  "maxItems": 10
}' |
apify call datagleaner/gdelt-news-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datagleaner/gdelt-news-monitor"
        }
    }
}
```

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/TuXVHJE60nVTYLWPW/builds/TzDXgFyKme6ikqozd/openapi.json
