Data / OSINT

gdelt

GDELT monitors world news in 65 languages and republishes it as structured records every 15 minutes. This is a study of what it actually ships today — which is materially less than it advertises — and a set of tools built on the parts that are alive.

  • Public repo
  • 45 tests
  • No install
  • Live map

What the research found

Everything below was measured against the live service on 2 August 2026, not transcribed from documentation — which matters, because the documentation is substantially wrong about what is currently running.

GDELT ships less than it advertises, and nothing errors

Four advertised datasets are dead or frozen while their manifests keep advancing. The GEO 2.0 API returns a bare 404 with no retirement notice, and is still listed as live. The TV 2.0 API responds normally but its data stops around 10 October 2024. The Global Frontpage Graph still reports itself as updating hourly while emitting 45-byte empty archives — it was 281 MB an hour in 2019. VGKG stalled in 2022, TV-GKG in 2023, and GEG stopped on 18 June 2026.

Silent-empty is the dominant failure mode. A client that reads "empty" as "no results" will report with complete confidence that nothing is happening anywhere in the world. The correct response is to probe at runtime and degrade visibly.

The DOC API answers errors in plain English

The DOC API answers errors with plain English, often under HTTP 200 — stopword rejections, over-limit record requests and invalid dates all return 200 with prose where JSON was requested. Rate limits return 429. Either way, a client calling .json() reports a decode failure at line 1 rather than the real reason.

No existing client covers more than one access path

The query APIs cannot give completeness — a 250-record cap and no pagination. The bulk files cannot give interactive latency. BigQuery cannot give real time. A full-capability interface needs all three behind one query model, and nothing published does that.

The tools

Three programs, all standard library only, no API key, no dependencies to install.

gdeltnow — what is happening in a place, right now

python3 -m gdeltnow Kyiv                 # last 2 hours
python3 -m gdeltnow Dublin --radius 150  # within 150km — reaches Belfast
python3 -m gdeltnow Gaza --translingual  # include machine-translated languages

Location matching is the real capability gap: the DOC API has no location operator and the API that had one returns 404. This reads GKG's geocoded location field directly, which is the only remaining way to ask what is happening in a given place. Note that is the place an article is about, not where it was published.

gdeltnow.monitor — money flows

Tracks remittances, stablecoins, illicit flows and FX across seven subjects, keeping only the ~7% of the feed that matches so the store stays small enough to hold weeks of history. Where GDELT's taxonomy has holes it falls back to keywords and counts what the themes missed, which makes the blind spot measurable rather than invisible.

SUBJECT                     articles   themes missed
Remittances                      78      —
Crypto & stablecoins             89     12  (13%)
Laundering & illicit flows       43      3  (7%)
Currency & FX                   747      3  (0%)

Sentiment uses the Loughran–McDonald finance dictionary rather than GDELT's general-purpose tone, which misreads "liability", "restructuring" and "volatility" as distress. Articles under 250 words are left unscored: polarity from two matched words is arithmetic, not signal.

build_map.py — the live world map

Writes one self-contained page: an Equal Earth projection with a mark per metro area, sized by article count and coloured by tone. Equal Earth because it is equal-area — dot density means the same thing everywhere, where Mercator would inflate northern coverage. Roughly 15% of place mentions are not in any city, so those are binned into equal-area grid cells rather than dropped; in one build that layer surfaced a helicopter crash in the Greek wildfires that the metro layer could not show.

Under the hood

Language
Python 3 — the three tools use the standard library only, no dependencies to install
Size
~3,175 lines across the package and tools
Tests
45, all offline — no network required to run them
Access paths
Bulk 15-minute files, DOC 2.0 API, BigQuery
Map projection
Equal Earth (equal-area)
Gazetteer
GeoNames, population ≥ 50k plus every capital
Source
Public repository, all rights reserved

Where it falls short

Place-name matching is string-based with no gazetteer disambiguation, so ambiguous names — Springfield, Cambridge — match all of them at once; the radius option is the workaround. A minority of publishers put their site name in the page title instead of the headline, and those come through as the site name. gdeltnow queries only the last few hours and keeps no local store.

The live map is regenerated every 15 minutes from a machine that is not always awake. When the generator stops, the page says so at the top rather than continuing to present old coverage as current.