Obscura

GDELT Events

Geopolitical and economic events extracted from worldwide news by the GDELT project, coded by actor, action and location.

gdelt_events — the dataset name to pass to the Obscura API.

Category Web attention Columns 36 Refresh Weekly Point-in-time available_date

What one row means

One CAMEO-coded actor-action-actor event that GDELT 2.0's NLP pipeline extracted from world news coverage and published in a single 15-minute Event-table export slot, keyed on GDELT's own globally unique GlobalEventID (one physical event can still spawn several GlobalEventIDs across different articles/slots — this table does not dedupe across those).

One row per global_event_id — GDELT's own globally unique event identifier (F1), unique across the entire v2 history and across every 15-minute export slot..

Point-in-time availability

Every Obscura dataset carries available_date: the calendar day the publisher made the row available, day-of, with no session rounding. It is the one column a backtest filters on, and it means the same thing on every dataset in the catalog.

For gdelt_events: available_date = date_added (F60), the 15-minute export-slot stamp under which this row's export.CSV.zip was published to data.gdeltproject.org — the collector builds the download URL directly from this same stamp, so it is provably the moment the row became publicly fetchable.

Refresh cadence

Obscura refreshes gdelt_events weekly — the most frequent scheduled job that re-collects or re-exports it. This is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when a row became public is recorded per row in available_date.

Schema — 36 columns

The full public column list for gdelt_events, with the meaning of every field. The same schema is served unauthenticated at https://api.obscura.trade/v1/catalog/gdelt_events.

ColumnTypeDescription
global_event_idbigint · not nullGDELT GlobalEventID (F1) — a globally unique, monotonically-assigned ID stamped by GDELT itself at extraction time; the primary key and the ON CONFLICT target for the upsert in gdelt.rs::conflict().
occurred_ondate · not nullParsed from SQLDATE (F2, YYYYMMDD) — GDELT's NLP-inferred date of the real-world event itself; a period/event date, distinct from available_date (when the row became public).
actor1_codetextActor1 CAMEO code (F6) — a compact code (country/ethnic/religious/type qualifiers concatenated) identifying the first, typically initiating, actor in the event; e.g. 'USA', 'CHN', 'COP' (police). Empty source cells become NULL via nonempty().
actor1_nametextHuman-readable name for Actor1 (F7), e.g. 'UNITED STATES', 'CHINA'; the display counterpart to actor1_code, extracted from the same CAMEO actor block.
actor1_country_codetextActor1CountryCode (F8) — 3-char CAMEO country code of Actor1's NATIONALITY (e.g. 'USA', 'CHN'), distinct from where the action occurred (action_geo_country); empty source cells become NULL.
actor1_type1_codetextActor1Type1Code (F13) — Actor1's primary CAMEO role/type category (GOV, MIL, BUS, COP, MED, REB, …); the categorical actor-kind filter.
actor2_codetextActor2 CAMEO code (F16) — the second/target actor in the coded interaction, same coding scheme as actor1_code; NULL when the event has only one actor (e.g. a natural disaster with no counterpart).
actor2_nametextHuman-readable name for Actor2 (F17), the display counterpart to actor2_code.
actor2_country_codetextActor2CountryCode (F18) — 3-char CAMEO country code of Actor2's NATIONALITY, distinct from the action geography; NULL when the event has only one actor or the source cell is empty.
actor2_type1_codetextActor2Type1Code (F23) — Actor2's primary CAMEO role/type category (GOV, MIL, BUS, COP, MED, REB, …); the categorical actor-kind filter.
is_root_eventbooleanGDELT IsRootEvent (F26), parsed from the source's '0'/'1' via parse_bool01 — true if this event was the lead/primary event of the article it was extracted from (vs. a secondary event mentioned in passing), a common relevance/dedup filter.
event_codetextCAMEO event code (F27), e.g. '043' (host visit) — the specific leaf-level action code in the CAMEO taxonomy describing what Actor1 did to/with Actor2.
event_base_codetextEventBaseCode (F28) — the intermediate 3-digit CAMEO code sitting between the leaf event_code (F27) and the 2-digit event_root_code (F29); a distinct level of the CAMEO taxonomy.
event_root_codetextCAMEO root event code (F29), e.g. '04' (consult) — the top-level (2-digit) category event_code rolls up into; the coarse-grained CAMEO bucket used for aggregate event-type analysis.
quad_classintegerQuadClass (F30): 1 = verbal cooperation, 2 = material cooperation, 3 = verbal conflict, 4 = material conflict — GDELT's coarsest tone/conflict bucketing of event_root_code, tolerant-parsed via parse_i32 (falls through f64 if the source cell has a decimal).
goldstein_scaledouble precisionGoldsteinScale (F31) — a fixed, CAMEO-code-driven theoretical score from -10 (most destabilizing) to +10 (most cooperative) of this event type's impact on country stability; a per-event-code constant, not a computed sentiment.
num_mentionsintegerNumMentions (F32) — total number of source documents (across all monitored languages/outlets) that mentioned this event, including duplicate mentions of the same underlying event within the 15-minute update window; a coverage-volume signal, not article count.
num_sourcesintegerNumSources (F33) — count of distinct source OUTLETS that mentioned the event; a third coverage-volume metric sitting between num_mentions (total mentions) and num_articles (distinct articles).
num_articlesintegerNumArticles (F34) — number of distinct source articles this event was extracted from within the current 15-minute update; lower and more conservative than num_mentions.
avg_tonedouble precisionAvgTone (F35) — average tone (roughly -100..+100, though empirically almost always within -10..+10) of all documents covering this event, per GDELT's tone dictionary; positive = more positive coverage, negative = more negative.
action_geo_country_codetextActionGeo_FullName (F53) — the geocoder's human-readable place name of the event's action location (e.g. 'Arundel, West Sussex, United Kingdom'). NOTE: despite the column name, this holds F53 (the full place name), NOT the FIPS country code — the real FIPS10-4 code is in action_geo_country (F54). Kept for backward compatibility.
action_geo_typeintegerActionGeo_Type (F52) — geocode RESOLUTION level of the kept action lat/long: 1=country, 2=US state, 3=US city, 4=world city, 5=world state; qualifies how precise action_geo_lat/long actually are.
action_geo_countrytextActionGeo_CountryCode (F54) — the actual FIPS10-4 COUNTRY code of the event's action location (e.g. 'UK', 'HA'), as distinct from actor nationality; the honest country code the mis-named action_geo_country_code above should have held.
action_geo_adm1_codetextActionGeo_ADM1Code (F55) — admin-1 (state/province) code of the action location (e.g. 'UKP6'); the geocoded region within the country.
action_geo_latdouble precisionLatitude (F57) of the geocoded ActionGeo point — the resolved location of the event's action, at whatever granularity GDELT's geocoder could resolve (point/city/ADM1/country centroid).
action_geo_longdouble precisionLongitude (F58) of the geocoded ActionGeo point, paired with action_geo_lat.
actor1_geo_country_codetextActor1Geo_CountryCode (F38) — FIPS10-4 country code of the geocoded location associated with ACTOR1 (as opposed to the action location); a secondary geo point.
actor1_geo_latdouble precisionActor1Geo_Lat (F41) — latitude of Actor1's geocoded location.
actor1_geo_longdouble precisionActor1Geo_Long (F42) — longitude of Actor1's geocoded location, paired with actor1_geo_lat.
actor2_geo_full_nametextActor2Geo_FullName (F45) — human-readable place name of the geocoded location associated with ACTOR2.
actor2_geo_country_codetextActor2Geo_CountryCode (F46) — FIPS10-4 country code of the geocoded location associated with ACTOR2; a secondary geo point.
actor2_geo_latdouble precisionActor2Geo_Lat (F49) — latitude of Actor2's geocoded location.
actor2_geo_longdouble precisionActor2Geo_Long (F50) — longitude of Actor2's geocoded location, paired with actor2_geo_lat.
date_addedtextDATEADDED (F60, YYYYMMDDHHMMSS) — the exact 15-minute export-slot stamp this row was published under; process_slot builds the row's own download URL from this same stamp, making it the provable moment the row became publicly fetchable. Kept as an untyped String (not yet parsed into a real timestamp); its date-part is materialized into available_date below.
source_urltextSOURCEURL (F61) — URL of the single news article this GlobalEventID's coding was extracted from; the citation/audit trail back to the original coverage, and the only free-text field carrying the actual story context.
available_datedatePUBLIC-availability date = date-part of date_added (the 15-minute export-slot publish stamp). DB-generated (STORED), read-only; the point-in-time column to filter/join on — NEVER occurred_on's NLP-inferred event date.

Access gdelt_events

Two delivery paths, one identifier. Both require an Obscura account and an active subscription; the catalog entry and the schema above are public.

import obscura

client = obscura.Client("obs_live_…")

df = client.query(
    dataset="gdelt_events",
    start="2024-01-01",
)

Create a free account Browse all 95 datasets

Frequently asked questions

What is in the gdelt_events dataset?

Geopolitical and economic events extracted from worldwide news by the GDELT project, coded by actor, action and location. One CAMEO-coded actor-action-actor event that GDELT 2.0's NLP pipeline extracted from world news coverage and published in a single 15-minute Event-table export slot, keyed on GDELT's own globally unique GlobalEventID (one physical event can still spawn several GlobalEventIDs across different articles/slots — this table does not dedupe across those).

How do I avoid look-ahead bias with gdelt_events?

Filter on gdelt_events.available_date, the day the publisher made the row public. For this dataset that date is derived as follows — available_date = date_added (F60), the 15-minute export-slot stamp under which this row's export.CSV.zip was published to data.gdeltproject.org — the collector builds the download URL directly from this same stamp, so it is provably the moment the row became publicly fetchable. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.

In what formats can I get gdelt_events?

As a Parquet bulk export (POST https://api.obscura.trade/v1/download) or as JSON from the typed query API (POST https://api.obscura.trade/v1/query), both with dataset="gdelt_events". The column schema is public at https://api.obscura.trade/v1/catalog/gdelt_events.

How often is gdelt_events updated?

Obscura refreshes gdelt_events on a weekly schedule — that is the most frequent scheduled job that re-collects or re-exports the table. It is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when the publisher makes a row available is described by the availability rule above, and is recorded per row in available_date.

Related datasets

GitHub ReposActivity on tracked GitHub repositories: stars, forks and commit frequency. Google TrendsGoogle search interest over time for the full US equity universe by ticker, back two decades. Scores are 0-100 rescaled … Hacker News StoriesFront-page stories from Hacker News. Open Data CatalogDataset listings harvested from government open-data portals running CKAN. Web PopularityDaily website popularity rank of each public company's domain, from four independent top-sites lists (Majestic Million, … Wikipedia PageviewsDaily Wikipedia pageviews for a universe of public companies, by ticker. Wikipedia RevisionsEdit activity on tracked Wikipedia articles. Wikipedia TopWikipedia's most-viewed articles for each day.