# News Articles by Keyword, Country and Language (GDELT) (`usta/gdelt-news-articles`) Actor

News scraper for google news and news monitoring. Articles by keyword, country and language from the open GDELT DOC index, deduplicated by URL. Every result row is one charge. Failed inputs are not result rows.

- **URL**: https://apify.com/usta/gdelt-news-articles.md
- **Developed by:** [US Tech Automations](https://apify.com/usta) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 result rows

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

## News Articles by Keyword, Country and Language (GDELT)

This news scraper turns a google news style search into a news monitoring table: articles by keyword, country and language from the open GDELT index, one row per article URL.

Each phrase is sent on its own to the GDELT DOC 2.0 article list. The same URL found under more than one phrase is kept once, with every matched phrase listed. Article pages are not opened.

### Input

| Field | What it does |
|---|---|
| **Keywords** | One or more phrases, up to 20. Duplicates are ignored. |
| **Source country** | Optional. A country name or a 2-letter code, passed through as GDELT `sourcecountry`. Blank means every country. |
| **Source language** | Optional. A language name (`english`), a 3-letter code (`eng`), or a common 2-letter code (`en`). Blank means every language. |
| **How far back** | `15min`, `24h`, `7d`, `2w`, or `3m`. Default `7d`. Longer than 3 months is refused. |
| **Maximum article rows** | Hard ceiling on article rows, and so on the cost of the run. Default 250, maximum 5000. |
| **Proxy configuration** | Optional Apify proxy. Off by default, including on a local run. |

### Pricing

**Pay per result. $0.002 per article row. No start fee.**

Every row in the results is one charged result. Failed inputs are not rows; they are listed in the run log and the RUN\_SUMMARY record, and cost nothing.

**Maximum article rows** is the ceiling on how many result rows a run can return.

### Output (one row per article URL)

One example row from a real local pull on 2026-09-22. The input was the keyword `climate` over the last `1d`. The index returned 5 articles. This is the first:

```json
{
  "keyword": "climate",
  "keywords": ["climate"],
  "url": "https://krna.com/cedar-rapids-paint-plow-program/",
  "title": "Paint A Plow : Local Kids Can Turn City Equipment into Winter Art",
  "domain": "krna.com",
  "language": "English",
  "source_country": "United States",
  "seen_date": "2026-09-22T18:45:00Z",
  "social_image": "https://townsquare.media/site/676/files/2026/09/attachment-paint-a-plow-program.jpg?&q=75&format=natural"
}
```

A later run of that same input from this machine was refused by the index (its "one request every 5 seconds" reply, twice). That run produced no result row. The refusal is listed in the run log and the RUN\_SUMMARY record. The row above is from the pull that succeeded, not from the refused rerun.

| Field | What it holds |
|---|---|
| `keyword` | The first phrase that matched this URL |
| `keywords` | Every phrase in this run that matched this URL |
| `url` | Article URL as the index published it. The page is not fetched. |
| `title` | Title as the index published it |
| `domain` | Domain as the index published it |
| `language` | Language name as the index published it |
| `source_country` | Country name as the index published it |
| `seen_date` | When the index says it saw the article, in UTC |
| `social_image` | Image URL when the index sent one, otherwise `null` |

### What this does not do

- It does not search the Google News website. It searches the GDELT index.
- It does not open, save, or quote the article page. You get the index fields only.
- It does not look back more than 3 months.
- It does not return more than 250 matches per keyword. The index caps a single call there. `maxItems` then trims the combined table.
- It does not invent a missing field. If the index left it blank, the value is `null`.
- It does not log in, send cookies, or solve a challenge page.
- It does not retry forever. A rate-limit reply is waited out once (30 seconds). If it is still refused, that phrase is written to the run log and the RUN\_SUMMARY record. It is not a result row.

### Limits

- At most one index request every 6 seconds. The index's own reply asks for one every 5 seconds. On that reply, this tool waits 30 seconds and tries that phrase once more.
- 1 to 20 keywords. 1 to 5000 article rows (default 250).
- A blocked phrase does not stop the other phrases in the same run.
- Email addresses and phone-number-shaped strings in a title are replaced with `[redacted]`.

### Refunds and support

Refunds: if a run returns zero articles for a valid input, email operations@ustechautomations.com within 7 days and we refund that run. Support: same address, replies within 2 business days.

# Actor input Schema

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

One or more phrases. Each phrase is searched on its own, then rows are combined and duplicate URLs are kept once with every phrase that matched. Up to 20 phrases.

## `sourceCountry` (type: `string`):

Optional. A country name (United States) or a 2-letter code (US). Passed to GDELT as sourcecountry. Leave blank for every country.

## `sourceLanguage` (type: `string`):

Optional. A language name (english), a 3-letter code (eng), or a common 2-letter code (en). Passed to GDELT as sourcelang. Leave blank for every language.

## `timespan` (type: `string`):

How far back to search, counting from now. Examples: 15min, 24h, 7d, 2w, 3m. Maximum is 3 months. Default 7d.

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

Hard ceiling on article rows returned, and therefore on the cost of the run. Default 250, maximum 5000. The index itself returns at most 250 matches per keyword. A rate-limit or block is not a result row.

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

Optional Apify proxy. Leave off for a local run. The only request is an ordinary HTTPS GET to the GDELT DOC API.

## Actor input object example

```json
{
  "keywords": [
    "climate"
  ],
  "sourceCountry": "",
  "sourceLanguage": "",
  "timespan": "7d",
  "maxItems": 250,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `articles` (type: `string`):

No description

## `csv` (type: `string`):

No description

## `report` (type: `string`):

No description

## `summary` (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": [
        "climate"
    ],
    "timespan": "7d",
    "maxItems": 250
};

// Run the Actor and wait for it to finish
const run = await client.actor("usta/gdelt-news-articles").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"],
    "timespan": "7d",
    "maxItems": 250,
}

# Run the Actor and wait for it to finish
run = client.actor("usta/gdelt-news-articles").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"
  ],
  "timespan": "7d",
  "maxItems": 250
}' |
apify call usta/gdelt-news-articles --silent --output-dataset

```

## MCP server setup

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

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/rVcUIJbcq5Up0EooE/builds/MvcQu955mZL0peTC0/openapi.json
