DATA & SOURCES / API CATALOG

Find your data.
Choose your endpoint.

Start with a data family, then inspect the records and filters. Open a working tool in API Arena when you’re ready to try a request.

22 endpoints · Events & news

Events & news

Discover developments, grouped reporting and the evidence behind them.

GDELT article stream · GDELT Cloud classification
GETRead publication activity/api/v2/activity

Paginated observed evidence of successful serving/reference publication. Unchanged reloads and baseline inventories are excluded. Linked entities are mentions or participants according to the record; they are not newly created identities. Source dates retain their stated precision. Source capability and collection start are explicit; missing history is not zero. Reads are ordered by the selected time_basis, newest first. Only committed batches are visible; cursors pin committed source sequences across pages. recorded_at retains journal availability time independently from published_at and source_date. Exhausting next_cursor completes the observed journal at its publication cutoff, not all upstream source intake. Query Monitors may watch observed publication entries while retaining source/history qualifications; partial history cannot establish exhaustive all-source counts or quiet days. Failed, unavailable or capped journal reads cannot complete a Monitor checkpoint.

Response: PublicationActivityCard · MCP tool: get_activity

Parameters and accepted values (12)
time_basis
Clock for date/hour filters and ordering: published preserves the serving/reference publication time; recorded uses the durable journal commit time and includes late publications when they become available. Omission retains published compatibility. Choose recorded explicitly for ongoing activity Monitors; source dates remain unchanged.

Accepted values: published, recorded

date_start
First UTC date in the selected time_basis. Defaults to today; future dates are rejected. Neither clock is Event occurrence time.
date_end
Last UTC date in the selected time_basis, inclusive. Defaults to date_start and cannot be later than the current UTC day.
hour
Optional UTC hour, 0–23. Requires a single date and rejects hours that have not started. The current hour is allowed and describes publications so far; omit for the whole selected day.
country
Known country attribution. Evidence distinguishes location, actor origin, reporting and source association.
recorded_start
Inclusive start of API publication time, as an ISO UTC timestamp. Supply both bounds. Includes late arrivals without changing when the event happened. Cannot combine with reporting-date filters.
recorded_end
Exclusive end of API publication time, as an ISO UTC timestamp. Supply both bounds. Includes late arrivals without changing when the event happened. Cannot combine with reporting-date filters.
kind
Published record type to include in activity evidence.

Accepted values: event, story, entity, facility, list_entry, office_holder

change
Publication transition. Defaults to all substantive transitions.

Accepted values: added, updated, removed

entity
Selected entity ID from /api/v2/search; returns records linked to that identity.
limit
Number of publication records per page, from 1 to 100.
cursor
Opaque next_cursor from the previous response. Keep the other filters unchanged.
GETSearch Events/api/v2/events

Continuous events coverage begins 2026-03-01. Use consecutive windows of at most 30 inclusive days; a calendar month can be too long. Finish pagination.next_cursor within each fixed window before starting the next chunk without a cursor. Without an explicit window, entity filters default to 30 days and other queries to the last 24 hours. meta.query_window reports the effective predicates; meta.coverage describes the available corpus. Discrete events we code in-house from news coverage into a CAMEO+ / ACLED-aligned taxonomy. Each carries: the ACTORS on both sides (actors, with their countries and roles), geography down to admin-1 with a stated precision, the linked story and its source articles, a written rationale, and a set of METRICS — significance (the default sort, and the only one meant to compare events across domains), plus magnitude, systemic_importance, propagation_potential and market_sensitivity, each filterable with <metric>_min / <metric>_max. Goldstein and quad class are published where the taxonomy defines them. Metric values also carry metrics.metric_inputs: the sub-factor scores the coder read off the article, each with the reason it gave — so a score can be audited rather than trusted. Definitions: https://docs.gdeltcloud.com/reference/metrics

Response: EventCard · MCP tool: search_events

Parameters and accepted values (50)
recorded_start
Inclusive start of API publication time, as an ISO UTC timestamp. Supply both bounds. Includes late arrivals without changing when the event happened. Cannot combine with reporting-date filters. Event and Story lists return records first made available in this interval, not later updates to existing records. Use /api/v2/activity for changes.
recorded_end
Exclusive end of API publication time, as an ISO UTC timestamp. Supply both bounds. Includes late arrivals without changing when the event happened. Cannot combine with reporting-date filters. Event and Story lists return records first made available in this interval, not later updates to existing records. Use /api/v2/activity for changes.
date_start
EVENT TIME — inclusive start of the window by when it HAPPENED (YYYY-MM-DD). Windows are capped at 30 inclusive days. Use consecutive date chunks; calendar months can exceed the cap. Follow the endpoint's pagination guidance within each chunk.
date_end
EVENT TIME — inclusive end of the window by when it HAPPENED (YYYY-MM-DD).
days
Calendar-date window ending today, in days (max 30). `window=7d` and `days=7` are equivalent. When omitted, a request without entity filters uses the last 24 hours; entity filters use 30 days. Read meta.query_window for the actual bounds. There is no equivalent numeric default: sending days explicitly selects calendar dates and removes the implicit observed-time bound. Pass `days` explicitly, or `date_start`/`date_end`, whenever the window matters.
limit
Rows per page. Default 25, max 100.
cursor
Opaque pagination cursor taken from the previous response's `pagination.next_cursor`. The cursor binds the resolved date window, filters, workspace, ordering and retained serving generations for 24 hours. Keep the other filters unchanged; authentication and current access are checked on every page.
country
Country filter. Accepts ISO-3, ISO-2, FIPS or an English name; comma-separate for OR. Matches the event's own location OR either actor's origin country by default, so a result can include events that happened elsewhere — set `country_match` to narrow it to location only. The definition in force is echoed as `applied_filters.country_match`.
region
One ACLED-style region. Expanded to its member countries.

Accepted values: Africa, Asia, Middle East, Northern Africa, Western Africa, Eastern Africa, Middle Africa, Southern Africa, Europe, Eastern Europe, South Asia, Southeast Asia, East Asia, Central Asia, North America, Central America, Caribbean, South America, Oceania

continent
One continent. Expanded to its member countries.

Accepted values: Africa, Asia, Europe, North America, South America, Oceania

country_match
Which definition of "in this country" the `country` / `region` / `continent` filters use. Defaults to the wider one, which is why omitting it changes nothing. Applies to `region` and `continent` too, since both expand into the same country set. Note that `group_by=country` buckets on the event's own location, while the default match also admits actor origin — so a filtered total and the bucket for that same country can differ. Pass `country_match=location` when you need the two to agree.

Accepted values: location_or_actor_origin, location

admin1
State or province (admin1), not a city. Discover valid values with `GET /api/v2/geo/admin1?country=`.
bbox
Bounding box `lat_min,lon_min,lat_max,lon_max`.
near
Point proximity `lat,lon`, combined with `radius_km`. The box is used for index pruning and rows are refined by true great-circle distance.
radius_km
Radius in km for point proximity. Default 100, capped 2000.
source_actor_country
Origin country of the ACTING side. Combine with `target_actor_country` to express a direction — `source_actor_country=CHN&target_actor_country=USA,GBR` is "China acting on those countries", which `country=` cannot say. Accepts ISO-3, ISO-2, FIPS or an English country name; comma-separate for OR. Unlike `country`, `region` and `continent` do not expand onto the actor side. On CAMEO+ events the source actor IS the performer of the action; on conflict (ACLED) events the first actor is the PRIMARY actor and not necessarily the initiator, so this asserts involvement in that role rather than who started it.
target_actor_country
Origin country of the RECEIVING side — the actor the action was directed at. Accepts ISO-3, ISO-2, FIPS or an English country name; comma-separate for OR. Unlike `country`, `region` and `continent` do not expand onto the actor side. On CAMEO+ events the source actor IS the performer of the action; on conflict (ACLED) events the first actor is the PRIMARY actor and not necessarily the initiator, so this asserts involvement in that role rather than who started it.
actor_country
Origin country of EITHER side, without regard to direction. This is the actor-origin half of what `country=` matches, on its own — use it to exclude events that merely happened in a country without any actor from it. Accepts ISO-3, ISO-2, FIPS or an English country name; comma-separate for OR. Unlike `country`, `region` and `continent` do not expand onto the actor side.
entity
Restrict to an entity's resolved coverage. Accepts a spine id (`e_…`), a news id (`wiki:…`) or a name, resolved through the shared arbiter so the same handle means the same entity on every endpoint. Accepts up to 25 comma-separated handles, which are UNIONED: a row is returned if ANY handle matches, never only the rows matching all of them. Every handle resolves through that same arbiter, so a handle means the same entity alone or in a list. A handle that resolves to nothing contributes nothing — it never widens the result — and is named in `applied_filters.entity_handles_unresolved`. More than 25 handles is refused with 400 MULTIPLE_ENTITY_HANDLES rather than truncated.
entity_match
Coverage matching: Stories mentioning or linking the entity and the Events those Stories carry. The default and only supported policy; it does not establish actor participation or material involvement.

Accepted values: coverage

entity_family
Which canonical ids the handle stands for. `expand` (default) also matches the sibling ids the entity arbiter has already merged into the same real-world entity — a Wikipedia identity minted twice under different URL spellings, for instance — and echoes the union back as `applied_filters.entity_ids_expanded`. `exact` restricts to the one canonical id the handle resolves to, reproducing the pre-2026-08-25 counts.

Accepted values: expand, exact

office
Restrict to the OFFICE-HOLDERS of a political office: the Wikidata QID of the office (`Q…`) or the `p_…` id `/api/v2/offices` serves. Resolves to every holder whose published term overlaps the window (or `office_as_of`, when sent), then scopes exactly as `entity=<those holders>` would — a row is returned if ANY holder matches, and it is UNIONED with `entity=` when both are sent. A name is refused with 400; resolve it with `GET /api/v2/offices?q=` first. A roster of more than 1,000 holders inside the window is refused with 400 OFFICE_SCOPE_TOO_LARGE, never truncated. Holders reach the news layer only through a Wikipedia identity, so `applied_filters.office_holders` discloses how many of the roster are `bridged_to_news` versus `unbridged` — an unbridged holder carries no key coverage matching can match on and contributes no rows, so the counts are a FLOOR on the office's real coverage rather than a measurement of it. Each matched row carries `entity_link.via: "office"` with `entity_link.entity` naming the HOLDER (a spine id), not the office.
office_as_of
VALID TIME for `office=` — scope to whoever held the office ON this date (YYYY-MM-DD) rather than to everyone whose term overlaps the window. This is the publisher's start/end clock, not what we knew then: it is NOT the knowledge-time `as_of` and is not gated by it. Office-holders with no published start date cannot be placed on a date and are excluded (counted in `applied_filters.office_holders.undated_excluded`), never fabricated. Ignored without `office`.
category
Event category — an ACLED event type or a CAMEO+ domain. Comma-separate for OR. Validated together with `subcategory`: an impossible pair returns 400, never an empty 200.

Accepted values: Battles, Protests, Riots, Explosions/Remote violence, Violence against civilians, Strategic developments, POLITICAL, CRIME, ECONOMIC, CORPORATE, TECHNOLOGY, INFRASTRUCTURE, ENVIRONMENT, HEALTH, DEMOGRAPHIC, INFORMATION

subcategory
Sub-event type (Conflict) or CAMEO+ leaf code. Comma-separate multiple values for OR. Scoped by `category` — sending it alone is 400 SUBCATEGORY_REQUIRES_CATEGORY and a pair that cannot exist is 400 INVALID_SUBCATEGORY_FOR_CATEGORY with the accepted values, so a bad value is never an empty 200 (both verified 2026-08-13). The taxonomy is closed and published in full, but PUBLICATION IS NOT COVERAGE — a defined code can carry zero events in any given window, and a few carry zero in most windows (`Sexual violence` is the measured example: its definition boundary sends nearly all such reporting to `Attack`). Before building a monitor on one code, measure it: `GET /api/v2/events/summary?group_by=subcategory` returns the codes that actually carry events in your window, with counts. An empty 200 here means no coverage for that combination, never zero real-world activity.
significance_min
Significance lower bound (0–1).
significance_max
Significance upper bound (0–1).
confidence_min
Confidence lower bound (0–1).
confidence_max
Confidence upper bound (0–1).
goldstein_scale_min
Goldstein scale lower bound (-10–10).
goldstein_scale_max
Goldstein scale upper bound (-10–10).
magnitude_min
Magnitude lower bound (0–10). Published only for the cameoplus family — filtering on it excludes every event outside that family.
magnitude_max
Magnitude upper bound (0–10). Published only for the cameoplus family — filtering on it excludes every event outside that family.
systemic_importance_min
Systemic importance lower bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
systemic_importance_max
Systemic importance upper bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
propagation_potential_min
Propagation potential lower bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
propagation_potential_max
Propagation potential upper bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
market_sensitivity_min
Market sensitivity lower bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
market_sensitivity_max
Market sensitivity upper bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
geo_precision_min
Geo precision lower bound (1–3).
geo_precision_max
Geo precision upper bound (1–3).
search_mode
Search interpretation. semantic (default) is a bounded hybrid search: complete-phrase name/title matches rank ahead of vector-ranked conceptual neighbours. lexical filters the complete serving set for a case-insensitive literal phrase in Events title/summary or Stories title before pagination; no stemming or boolean parsing. Lexical mode requires a supported serving snapshot and never falls back to the warehouse.

Accepted values: semantic, lexical

search
Search text. With search_mode=lexical this is a literal phrase in served Events title/summary or Stories title. By default the complete phrase is checked against name/title evidence and is also embedded for vector ranking; literal matches rank first and remaining results are conceptual neighbours. There is no boolean parser: a query shaped `a OR b` is reduced to its first term and the response says so. Costs an embedding call and can return 503 SEMANTIC_SEARCH_UNAVAILABLE.
sort
Ranking. A bare `search` with no explicit sort ranks by relevance instead.

Accepted values: significance, recent

include_total
Add `pagination.estimated_total` — how many events match the filters, ignoring the page. Off by default because it costs a second scan of the same window. Counted from the SAME filters and the same row source as the page, so it always describes the result set you are walking. It is `null` (not a number) on a `search=` request: semantic retrieval is bounded by a candidate cap, so any total there would describe the candidate pool rather than the matching events. Without it, `pagination.next_cursor` still tells you whether more rows exist — non-null means yes, null means the walk is finished.
has_fatalities
Restrict to events with a non-zero fatality count. CONFLICT FAMILY ONLY. `fatalities` is an ACLED-family observable; the CAMEO+ family has no fatality field, so its events carry `fatalities: null` (never a fabricated 0) and can never satisfy `true`. Over 2026-08-06..13 that was 92.5% of all events, including every ENVIRONMENT, INFRASTRUCTURE and HEALTH event — so a disaster or industrial death toll is NOT in this filter, and the total it sums is the armed-conflict toll, not a global one. `false` is not the complement: it returns both a conflict event coded with a real 0 and every event that has no fatality observable at all, so it means "not known to be lethal", never "known to be non-lethal". For a lethality screen across all families use `significance_min` (cross-domain by construction) or `goldstein_scale_max` — Goldstein is signed, so an upper bound like `goldstein_scale_max=-5` selects the strongly conflictual end — and read `fatalities` off the card to tell a measured 0 from an absent observable.
civilian_targeting
Restrict to events coded as targeting civilians.
languages
Source-language filter (ISO 639-1/2) on the linked Story's coverage.
include_images
Attach article images to each card. Off by default. When enabled, entity thumbnails are also included unless `include_entity_images=false`.
include_entity_images
Include entity thumbnails when `include_images=true`. Defaults to true, but has no effect while `include_images` is false or omitted. Pass false to skip the additional Wikipedia lookups while retaining article images.
GETSearch Stories/api/v2/stories

Continuous stories coverage begins 2026-03-08. Use consecutive windows of at most 30 inclusive days; a calendar month can be too long. Finish pagination.next_cursor within each fixed window before starting the next chunk without a cursor. Without an explicit window, entity filters default to 30 days and other queries to the last 24 hours. meta.query_window reports the effective predicates; meta.coverage describes the available corpus. Deduplicated news Stories — clusters of articles about the same real-world development, built by us from the articles themselves. Each carries the source articles behind it, article and outlet counts, the coverage languages it appeared in, the entities it mentions, and the Events coded from it. One story can yield several events. related=true attaches adjacent clusters; Stories independently adjudicated as the same incident always share one canonical public representative. matched_categories reports which of your taxonomy filters each story actually matched, which is the fastest way to see why a result came back. Stories do not accept Event metric filters such as significance_min; query /api/v2/events with the metric filter and follow each Event's story_refs instead.

Response: StoryCard · MCP tool: search_stories

Parameters and accepted values (33)
recorded_start
Inclusive start of API publication time, as an ISO UTC timestamp. Supply both bounds. Includes late arrivals without changing when the event happened. Cannot combine with reporting-date filters. Event and Story lists return records first made available in this interval, not later updates to existing records. Use /api/v2/activity for changes.
recorded_end
Exclusive end of API publication time, as an ISO UTC timestamp. Supply both bounds. Includes late arrivals without changing when the event happened. Cannot combine with reporting-date filters. Event and Story lists return records first made available in this interval, not later updates to existing records. Use /api/v2/activity for changes.
date_start
EVENT TIME — inclusive start of the window by when it HAPPENED (YYYY-MM-DD). Windows are capped at 30 inclusive days. Use consecutive date chunks; calendar months can exceed the cap. Follow the endpoint's pagination guidance within each chunk.
date_end
EVENT TIME — inclusive end of the window by when it HAPPENED (YYYY-MM-DD).
days
Calendar-date window ending today, in days (max 30). `window=7d` and `days=7` are equivalent. When omitted, a request without entity filters uses the last 24 hours; entity filters use 30 days. Read meta.query_window for the actual bounds. There is no equivalent numeric default: sending days explicitly selects calendar dates and removes the implicit observed-time bound. Pass `days` explicitly, or `date_start`/`date_end`, whenever the window matters.
limit
Rows per page. Default 25, max 100.
cursor
Opaque pagination cursor taken from the previous response's `pagination.next_cursor`. The cursor binds the resolved date window, filters, workspace, ordering and retained serving generations for 24 hours. Keep the other filters unchanged; authentication and current access are checked on every page.
country
Country filter. Accepts ISO-3, ISO-2, FIPS or an English name; comma-separate for OR. Matches the event's own location OR either actor's origin country by default, so a result can include events that happened elsewhere — set `country_match` to narrow it to location only. The definition in force is echoed as `applied_filters.country_match`. A Story also matches on its OWN attributed country, so Stories with no coded Event are reachable — over 2026-08-14..16 that took the reachable set from 5,386 to 24,207 of 25,463 Stories. Combining `country` with an Event-scoped filter (`event_category`, `subcategory`, `admin1`, `bbox`, `domain`, `civilian_targeting`) keeps the Event-only definition, because those ask about the Story's Events. Attribution begins 2026-07; earlier windows are Event-derived only.
region
One ACLED-style region. Expanded to its member countries.

Accepted values: Africa, Asia, Middle East, Northern Africa, Western Africa, Eastern Africa, Middle Africa, Southern Africa, Europe, Eastern Europe, South Asia, Southeast Asia, East Asia, Central Asia, North America, Central America, Caribbean, South America, Oceania

continent
One continent. Expanded to its member countries.

Accepted values: Africa, Asia, Europe, North America, South America, Oceania

country_match
Which definition of "in this country" the `country` / `region` / `continent` filters use. Defaults to the wider one, which is why omitting it changes nothing. Applies to `region` and `continent` too, since both expand into the same country set. Note that `group_by=country` buckets on the event's own location, while the default match also admits actor origin — so a filtered total and the bucket for that same country can differ. Pass `country_match=location` when you need the two to agree.

Accepted values: location_or_actor_origin, location

admin1
State or province (admin1), not a city. Discover valid values with `GET /api/v2/geo/admin1?country=`.
bbox
Bounding box `lat_min,lon_min,lat_max,lon_max`.
entity
Restrict to an entity's resolved coverage. Accepts a spine id (`e_…`), a news id (`wiki:…`) or a name, resolved through the shared arbiter so the same handle means the same entity on every endpoint. Accepts up to 25 comma-separated handles, which are UNIONED: a row is returned if ANY handle matches, never only the rows matching all of them. Every handle resolves through that same arbiter, so a handle means the same entity alone or in a list. A handle that resolves to nothing contributes nothing — it never widens the result — and is named in `applied_filters.entity_handles_unresolved`. More than 25 handles is refused with 400 MULTIPLE_ENTITY_HANDLES rather than truncated.
entity_match
Coverage matching: Stories mentioning or linking the entity and the Events those Stories carry. The default and only supported policy; it does not establish actor participation or material involvement.

Accepted values: coverage

entity_family
Which canonical ids the handle stands for. `expand` (default) also matches the sibling ids the entity arbiter has already merged into the same real-world entity — a Wikipedia identity minted twice under different URL spellings, for instance — and echoes the union back as `applied_filters.entity_ids_expanded`. `exact` restricts to the one canonical id the handle resolves to, reproducing the pre-2026-08-25 counts.

Accepted values: expand, exact

office
Restrict to the OFFICE-HOLDERS of a political office: the Wikidata QID of the office (`Q…`) or the `p_…` id `/api/v2/offices` serves. Resolves to every holder whose published term overlaps the window (or `office_as_of`, when sent), then scopes exactly as `entity=<those holders>` would — a row is returned if ANY holder matches, and it is UNIONED with `entity=` when both are sent. A name is refused with 400; resolve it with `GET /api/v2/offices?q=` first. A roster of more than 1,000 holders inside the window is refused with 400 OFFICE_SCOPE_TOO_LARGE, never truncated. Holders reach the news layer only through a Wikipedia identity, so `applied_filters.office_holders` discloses how many of the roster are `bridged_to_news` versus `unbridged` — an unbridged holder carries no key coverage matching can match on and contributes no rows, so the counts are a FLOOR on the office's real coverage rather than a measurement of it. Each matched row carries `entity_link.via: "office"` with `entity_link.entity` naming the HOLDER (a spine id), not the office.
office_as_of
VALID TIME for `office=` — scope to whoever held the office ON this date (YYYY-MM-DD) rather than to everyone whose term overlaps the window. This is the publisher's start/end clock, not what we knew then: it is NOT the knowledge-time `as_of` and is not gated by it. Office-holders with no published start date cannot be placed on a date and are excluded (counted in `applied_filters.office_holders.undated_excluded`), never fabricated. Ignored without `office`.
category
Event category — an ACLED event type or a CAMEO+ domain. Comma-separate for OR. Validated together with `subcategory`: an impossible pair returns 400, never an empty 200. On Stories this filters the LINKED EVENTS. Passing a Story cluster label here (for example `cameoplus_political`) is a legacy alias for `story_category` and is applied as one — a materially different filter, so prefer `story_category` for a Story label and keep `category` for linked-event taxonomy. `applied_filters` reports which one received it.

Accepted values: Battles, Protests, Riots, Explosions/Remote violence, Violence against civilians, Strategic developments, POLITICAL, CRIME, ECONOMIC, CORPORATE, TECHNOLOGY, INFRASTRUCTURE, ENVIRONMENT, HEALTH, DEMOGRAPHIC, INFORMATION

subcategory
Sub-event type (Conflict) or CAMEO+ leaf code. Comma-separate multiple values for OR. Scoped by `category` — sending it alone is 400 SUBCATEGORY_REQUIRES_CATEGORY and a pair that cannot exist is 400 INVALID_SUBCATEGORY_FOR_CATEGORY with the accepted values, so a bad value is never an empty 200 (both verified 2026-08-13). The taxonomy is closed and published in full, but PUBLICATION IS NOT COVERAGE — a defined code can carry zero events in any given window, and a few carry zero in most windows (`Sexual violence` is the measured example: its definition boundary sends nearly all such reporting to `Attack`). Before building a monitor on one code, measure it: `GET /api/v2/events/summary?group_by=subcategory` returns the codes that actually carry events in your window, with counts. An empty 200 here means no coverage for that combination, never zero real-world activity.
search_mode
Search interpretation. semantic (default) is a bounded hybrid search: complete-phrase name/title matches rank ahead of vector-ranked conceptual neighbours. lexical filters the complete serving set for a case-insensitive literal phrase in Events title/summary or Stories title before pagination; no stemming or boolean parsing. Lexical mode requires a supported serving snapshot and never falls back to the warehouse.

Accepted values: semantic, lexical

search
Search text. With search_mode=lexical this is a literal phrase in served Events title/summary or Stories title. By default the complete phrase is checked against name/title evidence and is also embedded for vector ranking; literal matches rank first and remaining results are conceptual neighbours. There is no boolean parser: a query shaped `a OR b` is reduced to its first term and the response says so. Costs an embedding call and can return 503 SEMANTIC_SEARCH_UNAVAILABLE.
story_category
Story-level category. Comma-separate for OR.

Accepted values: conflict_security, cameoplus_political, cameoplus_crime, cameoplus_economic, cameoplus_corporate, cameoplus_technology, cameoplus_infrastructure, cameoplus_environment, cameoplus_health, cameoplus_demographic, cameoplus_information, CONFLICT, CORPORATE, CRIME, DEMOGRAPHIC, ECONOMIC, ENVIRONMENT, HEALTH, INFORMATION, INFRASTRUCTURE, POLITICAL, TECHNOLOGY

has_events
Restrict to Stories that have (or have not) linked Events.
has_fatalities
Restrict to Stories whose linked Events carry fatalities. CONFLICT FAMILY ONLY. `fatalities` is an ACLED-family observable; the CAMEO+ family has no fatality field, so its events carry `fatalities: null` (never a fabricated 0) and can never satisfy `true`. Over 2026-08-06..13 that was 92.5% of all events, including every ENVIRONMENT, INFRASTRUCTURE and HEALTH event — so a disaster or industrial death toll is NOT in this filter, and the total it sums is the armed-conflict toll, not a global one. `false` is not the complement: it returns both a conflict event coded with a real 0 and every event that has no fatality observable at all, so it means "not known to be lethal", never "known to be non-lethal". Stories publish no metric filters, so for a cross-family severity screen query `/api/v2/events` — which does — and follow `story_refs` back. Read `fatalities` off each linked event to tell a measured 0 from an absent observable.
civilian_targeting
Restrict to Stories whose linked Events target civilians.
article_count_min
Minimum article count.
article_count_max
Maximum article count.
languages
Coverage-language filter (ISO 639-1/2).
include_images
Attach article images to each card. Off by default. When enabled, entity thumbnails are also included unless `include_entity_images=false`.
include_entity_images
Include entity thumbnails when `include_images=true`. Defaults to true, but has no effect while `include_images` is false or omitted. Pass false to skip the additional Wikipedia lookups while retaining article images.
sort
Ranking.

Accepted values: significance, recent

related
Attach related Stories (schema 130).
GETSummarize Events/api/v2/events/summary

Continuous events coverage begins 2026-03-01. Use consecutive windows of at most 30 inclusive days; a calendar month can be too long. This summary endpoint does not support cursor pagination; request each date chunk separately. Without an explicit window, entity filters default to 30 days and other queries to the last 24 hours. meta.query_window reports the effective predicates; meta.coverage describes the available corpus. Aggregate counts and metric statistics over the same Events /api/v2/events returns, grouped by date, country, region, continent, category or subcategory. Accepts every filter the list accepts, so a summary and a list of the same window are directly reconcilable. Metric averages are means over the rows where that metric is present, not over event_count — family-scoped metrics are genuinely absent on the other family.

Response: EventSummaryBucket · MCP tool: summarize_events

Parameters and accepted values (42)
date_start
EVENT TIME — inclusive start of the window by when it HAPPENED (YYYY-MM-DD). Windows are capped at 30 inclusive days. Use consecutive date chunks; calendar months can exceed the cap. Follow the endpoint's pagination guidance within each chunk.
date_end
EVENT TIME — inclusive end of the window by when it HAPPENED (YYYY-MM-DD).
days
Calendar-date window ending today, in days (max 30). `window=7d` and `days=7` are equivalent. When omitted, a request without entity filters uses the last 24 hours; entity filters use 30 days. Read meta.query_window for the actual bounds. There is no equivalent numeric default: sending days explicitly selects calendar dates and removes the implicit observed-time bound. Pass `days` explicitly, or `date_start`/`date_end`, whenever the window matters.
limit
Maximum number of BUCKETS returned (not rows). Default 50, max 500. There is no cursor on this endpoint, so a result at the limit may be truncated — widen the limit or narrow the window.
group_by
The dimension to aggregate over. Every dimension reconciles to the same total.

Accepted values: date, country, region, continent, category, subcategory, source_actor_country, target_actor_country

country
Country filter. Accepts ISO-3, ISO-2, FIPS or an English name; comma-separate for OR. Matches the event's own location OR either actor's origin country by default, so a result can include events that happened elsewhere — set `country_match` to narrow it to location only. The definition in force is echoed as `applied_filters.country_match`.
region
One ACLED-style region. Expanded to its member countries.

Accepted values: Africa, Asia, Middle East, Northern Africa, Western Africa, Eastern Africa, Middle Africa, Southern Africa, Europe, Eastern Europe, South Asia, Southeast Asia, East Asia, Central Asia, North America, Central America, Caribbean, South America, Oceania

continent
One continent. Expanded to its member countries.

Accepted values: Africa, Asia, Europe, North America, South America, Oceania

country_match
Which definition of "in this country" the `country` / `region` / `continent` filters use. Defaults to the wider one, which is why omitting it changes nothing. Applies to `region` and `continent` too, since both expand into the same country set. Note that `group_by=country` buckets on the event's own location, while the default match also admits actor origin — so a filtered total and the bucket for that same country can differ. Pass `country_match=location` when you need the two to agree.

Accepted values: location_or_actor_origin, location

admin1
State or province (admin1), not a city. Discover valid values with `GET /api/v2/geo/admin1?country=`.
bbox
Bounding box `lat_min,lon_min,lat_max,lon_max`.
near
Point proximity `lat,lon`, combined with `radius_km`. The box is used for index pruning and rows are refined by true great-circle distance.
radius_km
Radius in km for point proximity. Default 100, capped 2000.
source_actor_country
Origin country of the ACTING side. Combine with `target_actor_country` to express a direction — `source_actor_country=CHN&target_actor_country=USA,GBR` is "China acting on those countries", which `country=` cannot say. Accepts ISO-3, ISO-2, FIPS or an English country name; comma-separate for OR. Unlike `country`, `region` and `continent` do not expand onto the actor side. On CAMEO+ events the source actor IS the performer of the action; on conflict (ACLED) events the first actor is the PRIMARY actor and not necessarily the initiator, so this asserts involvement in that role rather than who started it.
target_actor_country
Origin country of the RECEIVING side — the actor the action was directed at. Accepts ISO-3, ISO-2, FIPS or an English country name; comma-separate for OR. Unlike `country`, `region` and `continent` do not expand onto the actor side. On CAMEO+ events the source actor IS the performer of the action; on conflict (ACLED) events the first actor is the PRIMARY actor and not necessarily the initiator, so this asserts involvement in that role rather than who started it.
actor_country
Origin country of EITHER side, without regard to direction. This is the actor-origin half of what `country=` matches, on its own — use it to exclude events that merely happened in a country without any actor from it. Accepts ISO-3, ISO-2, FIPS or an English country name; comma-separate for OR. Unlike `country`, `region` and `continent` do not expand onto the actor side.
entity
Restrict to an entity's resolved coverage. Accepts a spine id (`e_…`), a news id (`wiki:…`) or a name, resolved through the shared arbiter so the same handle means the same entity on every endpoint. Accepts up to 25 comma-separated handles, which are UNIONED: a row is returned if ANY handle matches, never only the rows matching all of them. Every handle resolves through that same arbiter, so a handle means the same entity alone or in a list. A handle that resolves to nothing contributes nothing — it never widens the result — and is named in `applied_filters.entity_handles_unresolved`. More than 25 handles is refused with 400 MULTIPLE_ENTITY_HANDLES rather than truncated.
entity_match
Coverage matching: Stories mentioning or linking the entity and the Events those Stories carry. The default and only supported policy; it does not establish actor participation or material involvement.

Accepted values: coverage

entity_family
Which canonical ids the handle stands for. `expand` (default) also matches the sibling ids the entity arbiter has already merged into the same real-world entity — a Wikipedia identity minted twice under different URL spellings, for instance — and echoes the union back as `applied_filters.entity_ids_expanded`. `exact` restricts to the one canonical id the handle resolves to, reproducing the pre-2026-08-25 counts.

Accepted values: expand, exact

office
Restrict to the OFFICE-HOLDERS of a political office: the Wikidata QID of the office (`Q…`) or the `p_…` id `/api/v2/offices` serves. Resolves to every holder whose published term overlaps the window (or `office_as_of`, when sent), then scopes exactly as `entity=<those holders>` would — a row is returned if ANY holder matches, and it is UNIONED with `entity=` when both are sent. A name is refused with 400; resolve it with `GET /api/v2/offices?q=` first. A roster of more than 1,000 holders inside the window is refused with 400 OFFICE_SCOPE_TOO_LARGE, never truncated. Holders reach the news layer only through a Wikipedia identity, so `applied_filters.office_holders` discloses how many of the roster are `bridged_to_news` versus `unbridged` — an unbridged holder carries no key coverage matching can match on and contributes no rows, so the counts are a FLOOR on the office's real coverage rather than a measurement of it. Each matched row carries `entity_link.via: "office"` with `entity_link.entity` naming the HOLDER (a spine id), not the office.
office_as_of
VALID TIME for `office=` — scope to whoever held the office ON this date (YYYY-MM-DD) rather than to everyone whose term overlaps the window. This is the publisher's start/end clock, not what we knew then: it is NOT the knowledge-time `as_of` and is not gated by it. Office-holders with no published start date cannot be placed on a date and are excluded (counted in `applied_filters.office_holders.undated_excluded`), never fabricated. Ignored without `office`.
category
Event category — an ACLED event type or a CAMEO+ domain. Comma-separate for OR. Validated together with `subcategory`: an impossible pair returns 400, never an empty 200.

Accepted values: Battles, Protests, Riots, Explosions/Remote violence, Violence against civilians, Strategic developments, POLITICAL, CRIME, ECONOMIC, CORPORATE, TECHNOLOGY, INFRASTRUCTURE, ENVIRONMENT, HEALTH, DEMOGRAPHIC, INFORMATION

subcategory
Sub-event type (Conflict) or CAMEO+ leaf code. Comma-separate multiple values for OR. Scoped by `category` — sending it alone is 400 SUBCATEGORY_REQUIRES_CATEGORY and a pair that cannot exist is 400 INVALID_SUBCATEGORY_FOR_CATEGORY with the accepted values, so a bad value is never an empty 200 (both verified 2026-08-13). The taxonomy is closed and published in full, but PUBLICATION IS NOT COVERAGE — a defined code can carry zero events in any given window, and a few carry zero in most windows (`Sexual violence` is the measured example: its definition boundary sends nearly all such reporting to `Attack`). Before building a monitor on one code, measure it: `GET /api/v2/events/summary?group_by=subcategory` returns the codes that actually carry events in your window, with counts. An empty 200 here means no coverage for that combination, never zero real-world activity.
significance_min
Significance lower bound (0–1).
significance_max
Significance upper bound (0–1).
confidence_min
Confidence lower bound (0–1).
confidence_max
Confidence upper bound (0–1).
goldstein_scale_min
Goldstein scale lower bound (-10–10).
goldstein_scale_max
Goldstein scale upper bound (-10–10).
magnitude_min
Magnitude lower bound (0–10). Published only for the cameoplus family — filtering on it excludes every event outside that family.
magnitude_max
Magnitude upper bound (0–10). Published only for the cameoplus family — filtering on it excludes every event outside that family.
systemic_importance_min
Systemic importance lower bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
systemic_importance_max
Systemic importance upper bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
propagation_potential_min
Propagation potential lower bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
propagation_potential_max
Propagation potential upper bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
market_sensitivity_min
Market sensitivity lower bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
market_sensitivity_max
Market sensitivity upper bound (0–1). Published only for the cameoplus family — filtering on it excludes every event outside that family.
geo_precision_min
Geo precision lower bound (1–3).
geo_precision_max
Geo precision upper bound (1–3).
has_fatalities
Restrict to events with a non-zero fatality count. CONFLICT FAMILY ONLY. `fatalities` is an ACLED-family observable; the CAMEO+ family has no fatality field, so its events carry `fatalities: null` (never a fabricated 0) and can never satisfy `true`. Over 2026-08-06..13 that was 92.5% of all events, including every ENVIRONMENT, INFRASTRUCTURE and HEALTH event — so a disaster or industrial death toll is NOT in this filter, and the total it sums is the armed-conflict toll, not a global one. `false` is not the complement: it returns both a conflict event coded with a real 0 and every event that has no fatality observable at all, so it means "not known to be lethal", never "known to be non-lethal". For a lethality screen across all families use `significance_min` (cross-domain by construction) or `goldstein_scale_max` — Goldstein is signed, so an upper bound like `goldstein_scale_max=-5` selects the strongly conflictual end — and read `fatalities` off the card to tell a measured 0 from an absent observable.
civilian_targeting
Restrict to events coded as targeting civilians.
languages
Coverage-language filter (ISO 639-1/2) on the underlying articles.
GETSummarize Stories/api/v2/stories/summary

Continuous stories coverage begins 2026-03-08. Use consecutive windows of at most 30 inclusive days; a calendar month can be too long. This summary endpoint does not support cursor pagination; request each date chunk separately. Without an explicit window, entity filters default to 30 days and other queries to the last 24 hours. meta.query_window reports the effective predicates; meta.coverage describes the available corpus. Aggregate counts and statistics over the same Stories /api/v2/stories returns, grouped by date, country, region, continent, category or subcategory. Event-scoped filters are applied inside the linked-event rollup, so a story's counts reflect the events that matched your filters rather than its total. With group_by=country, country_attribution=all counts each distinct Story under every country matching the ordinary Stories country filter. Country buckets may overlap; use group_by=date for distinct global totals.

Response: StorySummaryBucket · MCP tool: summarize_stories

Parameters and accepted values (26)
date_start
EVENT TIME — inclusive start of the window by when it HAPPENED (YYYY-MM-DD). Windows are capped at 30 inclusive days. Use consecutive date chunks; calendar months can exceed the cap. Follow the endpoint's pagination guidance within each chunk.
date_end
EVENT TIME — inclusive end of the window by when it HAPPENED (YYYY-MM-DD).
days
Calendar-date window ending today, in days (max 30). `window=7d` and `days=7` are equivalent. When omitted, a request without entity filters uses the last 24 hours; entity filters use 30 days. Read meta.query_window for the actual bounds. There is no equivalent numeric default: sending days explicitly selects calendar dates and removes the implicit observed-time bound. Pass `days` explicitly, or `date_start`/`date_end`, whenever the window matters.
limit
Maximum number of BUCKETS returned (not rows). Default 50, max 500. There is no cursor on this endpoint, so a result at the limit may be truncated — widen the limit or narrow the window.
group_by
The dimension to aggregate over. Country buckets overlap when country_attribution=all; use group_by=date for distinct totals.

Accepted values: date, country, region, continent, category, subcategory

country_attribution
For group_by=country: primary preserves one primary country per Story; all counts each Story under every authoritative country attribution or linked Event location/actor origin, using the same country_match and other filters as the Stories list. Explicit geographic filters also restrict the emitted country buckets. Buckets overlap and must not be summed as a global total. Other groupings ignore this option.

Accepted values: primary, all

country
Country filter. Accepts ISO-3, ISO-2, FIPS or an English name; comma-separate for OR. Matches the event's own location OR either actor's origin country by default, so a result can include events that happened elsewhere — set `country_match` to narrow it to location only. The definition in force is echoed as `applied_filters.country_match`. A Story also matches on its OWN attributed country, so Stories with no coded Event are reachable — over 2026-08-14..16 that took the reachable set from 5,386 to 24,207 of 25,463 Stories. Combining `country` with an Event-scoped filter (`event_category`, `subcategory`, `admin1`, `bbox`, `domain`, `civilian_targeting`) keeps the Event-only definition, because those ask about the Story's Events. Attribution begins 2026-07; earlier windows are Event-derived only.
region
One ACLED-style region. Expanded to its member countries.

Accepted values: Africa, Asia, Middle East, Northern Africa, Western Africa, Eastern Africa, Middle Africa, Southern Africa, Europe, Eastern Europe, South Asia, Southeast Asia, East Asia, Central Asia, North America, Central America, Caribbean, South America, Oceania

continent
One continent. Expanded to its member countries.

Accepted values: Africa, Asia, Europe, North America, South America, Oceania

country_match
Which definition of "in this country" the `country` / `region` / `continent` filters use. Defaults to the wider one, which is why omitting it changes nothing. Applies to `region` and `continent` too, since both expand into the same country set. Note that `group_by=country` buckets on the event's own location, while the default match also admits actor origin — so a filtered total and the bucket for that same country can differ. Pass `country_match=location` when you need the two to agree.

Accepted values: location_or_actor_origin, location

admin1
State or province (admin1), not a city. Discover valid values with `GET /api/v2/geo/admin1?country=`.
bbox
Bounding box `lat_min,lon_min,lat_max,lon_max`.
entity
Restrict to an entity's resolved coverage. Accepts a spine id (`e_…`), a news id (`wiki:…`) or a name, resolved through the shared arbiter so the same handle means the same entity on every endpoint. Accepts up to 25 comma-separated handles, which are UNIONED: a row is returned if ANY handle matches, never only the rows matching all of them. Every handle resolves through that same arbiter, so a handle means the same entity alone or in a list. A handle that resolves to nothing contributes nothing — it never widens the result — and is named in `applied_filters.entity_handles_unresolved`. More than 25 handles is refused with 400 MULTIPLE_ENTITY_HANDLES rather than truncated.
entity_match
Coverage matching: Stories mentioning or linking the entity and the Events those Stories carry. The default and only supported policy; it does not establish actor participation or material involvement.

Accepted values: coverage

entity_family
Which canonical ids the handle stands for. `expand` (default) also matches the sibling ids the entity arbiter has already merged into the same real-world entity — a Wikipedia identity minted twice under different URL spellings, for instance — and echoes the union back as `applied_filters.entity_ids_expanded`. `exact` restricts to the one canonical id the handle resolves to, reproducing the pre-2026-08-25 counts.

Accepted values: expand, exact

office
Restrict to the OFFICE-HOLDERS of a political office: the Wikidata QID of the office (`Q…`) or the `p_…` id `/api/v2/offices` serves. Resolves to every holder whose published term overlaps the window (or `office_as_of`, when sent), then scopes exactly as `entity=<those holders>` would — a row is returned if ANY holder matches, and it is UNIONED with `entity=` when both are sent. A name is refused with 400; resolve it with `GET /api/v2/offices?q=` first. A roster of more than 1,000 holders inside the window is refused with 400 OFFICE_SCOPE_TOO_LARGE, never truncated. Holders reach the news layer only through a Wikipedia identity, so `applied_filters.office_holders` discloses how many of the roster are `bridged_to_news` versus `unbridged` — an unbridged holder carries no key coverage matching can match on and contributes no rows, so the counts are a FLOOR on the office's real coverage rather than a measurement of it. Each matched row carries `entity_link.via: "office"` with `entity_link.entity` naming the HOLDER (a spine id), not the office.
office_as_of
VALID TIME for `office=` — scope to whoever held the office ON this date (YYYY-MM-DD) rather than to everyone whose term overlaps the window. This is the publisher's start/end clock, not what we knew then: it is NOT the knowledge-time `as_of` and is not gated by it. Office-holders with no published start date cannot be placed on a date and are excluded (counted in `applied_filters.office_holders.undated_excluded`), never fabricated. Ignored without `office`.
category
Event category — an ACLED event type or a CAMEO+ domain. Comma-separate for OR. Validated together with `subcategory`: an impossible pair returns 400, never an empty 200. On Stories this filters the LINKED EVENTS. Passing a Story cluster label here (for example `cameoplus_political`) is a legacy alias for `story_category` and is applied as one — a materially different filter, so prefer `story_category` for a Story label and keep `category` for linked-event taxonomy. `applied_filters` reports which one received it.

Accepted values: Battles, Protests, Riots, Explosions/Remote violence, Violence against civilians, Strategic developments, POLITICAL, CRIME, ECONOMIC, CORPORATE, TECHNOLOGY, INFRASTRUCTURE, ENVIRONMENT, HEALTH, DEMOGRAPHIC, INFORMATION

subcategory
Sub-event type (Conflict) or CAMEO+ leaf code. Comma-separate multiple values for OR. Scoped by `category` — sending it alone is 400 SUBCATEGORY_REQUIRES_CATEGORY and a pair that cannot exist is 400 INVALID_SUBCATEGORY_FOR_CATEGORY with the accepted values, so a bad value is never an empty 200 (both verified 2026-08-13). The taxonomy is closed and published in full, but PUBLICATION IS NOT COVERAGE — a defined code can carry zero events in any given window, and a few carry zero in most windows (`Sexual violence` is the measured example: its definition boundary sends nearly all such reporting to `Attack`). Before building a monitor on one code, measure it: `GET /api/v2/events/summary?group_by=subcategory` returns the codes that actually carry events in your window, with counts. An empty 200 here means no coverage for that combination, never zero real-world activity.
story_category
Story-level topic, comma-separated for OR. Distinct from the EVENT taxonomy that `category` filters.

Accepted values: conflict_security, cameoplus_political, cameoplus_crime, cameoplus_economic, cameoplus_corporate, cameoplus_technology, cameoplus_infrastructure, cameoplus_environment, cameoplus_health, cameoplus_demographic, cameoplus_information, CONFLICT, CORPORATE, CRIME, DEMOGRAPHIC, ECONOMIC, ENVIRONMENT, HEALTH, INFORMATION, INFRASTRUCTURE, POLITICAL, TECHNOLOGY

has_events
Restrict to Stories with at least one linked Event.
has_fatalities
Restrict to Stories whose linked events carry fatalities. CONFLICT FAMILY ONLY. `fatalities` is an ACLED-family observable; the CAMEO+ family has no fatality field, so its events carry `fatalities: null` (never a fabricated 0) and can never satisfy `true`. Over 2026-08-06..13 that was 92.5% of all events, including every ENVIRONMENT, INFRASTRUCTURE and HEALTH event — so a disaster or industrial death toll is NOT in this filter, and the total it sums is the armed-conflict toll, not a global one. `false` is not the complement: it returns both a conflict event coded with a real 0 and every event that has no fatality observable at all, so it means "not known to be lethal", never "known to be non-lethal". Stories publish no metric filters, so for a cross-family severity screen query `/api/v2/events` — which does — and follow `story_refs` back. Read `fatalities` off each linked event to tell a measured 0 from an absent observable.
civilian_targeting
Restrict to Stories with civilian-targeting events.
article_count_min
Lower bound on the number of source articles behind a Story.
article_count_max
Upper bound on the number of source articles behind a Story.
languages
Coverage-language filter (ISO 639-1/2) on the underlying articles.
GETShare of Voice/api/v2/share-of-voice

Compare an entity’s share of canonical settled Story records within one explicit news denominator. Story membership and entity references come from the Core serving tables; unsupported article-level and upstream-salience weighting are not published.

Response: ShareOfVoiceResponse · MCP tool: share_of_voice

Parameters and accepted values (19)
query
Semantic denominator query.
topic
Lexical denominator topic.
category
Story or event category denominator.
country
Country denominator. Accepts an English name, ISO-2, or ISO-3. A Story matches when its own attributed countries include the value, or a linked Event is located there, or either linked Event actor originates there.
region
Region denominator.
continent
Continent denominator.
languages
Language-code denominator.
source_set
Source denominator. `all` selects the complete served Story corpus in the requested window; otherwise pass one or more article domains such as `reuters.com`.
entities
Entity identifiers. `entity_id` and `entity` are singular compatibility aliases.
entity_query
Entity-name resolver input. `entity_search`, `entity_terms`, and `numerator` are aliases.
run_id
Previously materialized analytics run.
denominator_hash
Previously computed denominator identity.
start_date
First occurrence date. `date_start` is an alias.
end_date
Last occurrence date. `date_end` is an alias.
date
Single occurrence date.
days
Trailing window. `window` is an alias.
limit
Maximum entity rows.
cursor
Pagination cursor.
offset
Legacy numeric offset.
GETGet Story Articles/api/v2/stories/{story_id}/articles

Canonical-URL-deduplicated article evidence with source language and provenance-backed publisher country.

Response: Structured JSON response · MCP tool: get_story_articles

Parameters and accepted values (10)
start_date
First Story partition date. `date_start` is an alias.
end_date
Last Story partition date. `date_end` is an alias.
date
Single Story partition date.
days
Trailing date window. `window` is an alias.
limit
Maximum articles returned.
cursor
Pagination cursor.
offset
Legacy numeric offset.
include_images
Attach resolved article images.
language
Origin language filter. `languages` is an alias.
publisher_country_iso3
Known publisher-country filter. `publisher_country` is an alias; unknown publishers are never guessed.
GETList Situations/api/v2/situations

Discover stored Situations by title, current servable span overlap and volume counts, or member-linked coded Event location/category. Event facets require a reporting window of at most 30 days and match the same Event; they do not establish a primary country or category. Directory filtering, ordering and totals use current full serving membership. scope and selected_scope distinguish whole-Situation counts from requested reporting dates and carry content versions. narrative is a dated, independently verified summary when one has been published; null means unavailable. Entity counts cover all current servable members and are null if measurement fails.

Response: SituationSummaryCard · MCP tool: search_situations

Parameters and accepted values (15)
entity
Canonical entity handle or name, using the same identity resolution as Stories. Requires both reporting date bounds, at most 30 days.
story_id
Only Situations containing this currently served Story.
event_uid
Only Situations containing a served Story linked to this coded Event.
include_map
Include country aggregates over every matching Situation, independently of page size. Requires a reporting window of at most 30 days.
date_start
Return Situations still running on or after this date (YYYY-MM-DD) — matched against `span_end`, so an occurrence that began earlier and is ongoing IS returned. Optional and independent of `date_end`. There is no maximum span: the Situations table is one row per adjudicated occurrence and is small by construction, so this is a filter on a stored column rather than a bound on how much is scanned.
date_end
Return Situations that had already begun by this date (YYYY-MM-DD) — matched against `span_start`. Sent together with `date_start` the pair selects every occurrence whose span OVERLAPS the window; sent alone it leaves the other side open. An inverted pair is refused with `INVALID_DATE_RANGE` rather than answered empty.
search
Free text matched against the stored `title` OR the headline of any member Story reported inside the window (the last 30 days when no dates are sent) — a case-insensitive match requiring EVERY whitespace-separated term to appear in one of the two, so `nepal flood` matches "Flash floods hit northern Nepal-Tibet border" and `AI slowdown` finds a Situation titled "Trump says US will not slow AI race" through a member headline that says slowdown. The phrase also runs through the hybrid `GET /api/v2/stories?search=` in the same window, and a Situation holding one of the top-ranked Stories matches too, so `AI pause` can reach the same Situation through meaning; `meta.search.semantic_story_candidates` reports how many Story hits that arm contributed and `meta.search.note` says when it was unavailable. What it CANNOT do: read article text or entities directly; and `title` is the PEAK member's headline, re-stamped every time the Situation is recomputed. At most 8 terms; more is refused with `INVALID_SEARCH` rather than silently truncated. To search what a Situation is actually ABOUT, run `GET /api/v2/stories?search=` and take any returned Story id to `/api/v2/situations/{story_id}`.
min_stories
Minimum member Stories across the whole current servable membership, not the selected reporting window. The public discovery page sends min_stories=2&min_events=2; the API applies no minimum when omitted. Use min_stories=1&min_events=0 to include emerging seeds. This filter does not change creation, growth or direct UID lookup.
min_articles
Minimum articles across the member Stories — the best single proxy for how big an occurrence got, and the default sort key. Compared against the stored `article_count`.
min_events
Minimum coded Events at canonical-incident grain across the whole current servable membership. The public discovery page sends min_stories=2&min_events=2; the API applies no minimum when omitted. Use min_stories=1&min_events=0 to include emerging seeds, including reporting with no coded Events. Explicit zero is permitted.
sort
Ranking. `recent` (default) uses latest reporting date, then first-observed membership time; `created` orders by immutable creation time, newest first; `updated` orders by the latest serving-membership refresh; article_count, story_count and event_count are volume alternatives; `span_days` puts the longest-running occurrence first — the inclusive day count between `span.start` and `span.end`, with an unmeasured span last. Recent never uses refresh time or volume. Every order breaks ties on `situation_uid`, so paging with `offset` is stable.

Accepted values: article_count, story_count, event_count, recent, created, updated, span_days

limit
Situations per page. Default 25, max 200. `pagination.total` is the true number matching your filters, counted separately from the page, so `has_more` is measured rather than inferred from a full page.
offset
Situations to skip. This endpoint pages by offset and has no cursor — every sort is a total order (ties break on `situation_uid`), so an offset walk cannot repeat or skip a row.
country
Any member-linked coded Event located in this ISO-3 country. Actor nationality is not used. Requires date_start and date_end, at most 30 inclusive days. Both country and category match the SAME Event.
category
Any member-linked coded Event in this Event taxonomy category, not Story category or a primary Situation label. Requires both reporting date bounds, at most 30 days. Country and category match the same Event.

Accepted values: Battles, Protests, Riots, Explosions/Remote violence, Violence against civilians, Strategic developments, POLITICAL, CRIME, ECONOMIC, CORPORATE, TECHNOLOGY, INFRASTRUCTURE, ENVIRONMENT, HEALTH, DEMOGRAPHIC, INFORMATION

GETGet a Situation/api/v2/situations/{story_id}

Every Story and Event belonging to one real-world occurrence. The path accepts EITHER a situation_uid (sit_…) or any member Story id, and both return the same occurrence — a Story resolves to its primary Situation. A situation_uid is minted and content-independent, so it never changes; a Situation that merges into another resolves FORWARD to the survivor rather than 404ing. meta.situation_source says which you got: curated is the stored, adjudicated membership set, and walked is the adjudicated neighbourhood around a Story that no Situation covers yet — the same shape, a weaker claim. Stored members carry route; antecedent and consequence are chronological, not proof of causality. membership reports the basis and any recorded decision reason; missing evidence stays null. origin is the earliest member carrying material coverage and peak the largest; both are derived and recomputed, and neither is the identity. Membership is not exclusive — a Story may belong to more than one Situation. Returns the member Stories (paged, with the relation and the evidence arm that produced each link), a per-day rollup of how the occurrence built up, and its Events collapsed to one row per canonical incident. How Stories adjudicated as the SAME incident are reported DIFFERS BY PATH, so read meta.situation_source first. On a walked situation they are folded out of the member list and listed under duplicates; on a curated one they are admitted as MEMBERS carrying route same_incident, duplicates is empty by construction, and how many there are is totals.story_count minus totals.distinct_incident_count. Either way, if the Story you asked for was the folded side, the situation is served from its survivor and requested_story_id names what you sent. Members and Events resolve through the same settled tables /api/v2/stories and /api/v2/events read, so a situation can never name a record those endpoints will not return. incident_relations publishes only independently adjudicated, directional umbrella/component links; it never changes Event identity or event_count, and null confirmed counts mean relation publication is unavailable or incomplete for the returned Event dates rather than zero. The Situation graph hides confirmed umbrella summaries by default and lets the reader reveal both summaries and containment edges. Curated responses include scopes.whole and scopes.selected, each with a content version and full totals independent of graph limits. narrative, when present, is independently verified and dated; current=false retains a previous publication while a refresh is pending. The incident_adjudication split describes returned incident rows, not unseen Events. Fatalities are reported as both a maximum and a raw sum, and the incident count ships with its adjudication split, because most Events have never been compared to anything. Three arrays are bounded — member Stories, incidents and the entity cast — and caps reports each ceiling and whether it bit, so nothing here is capped in silence.

Response: SituationCard · MCP tool: get_situation

Parameters and accepted values (9)
edition_id
Pin a retained edition. Mutually exclusive with as_of.
as_of
Latest edition published at or before this UTC ISO timestamp. No reconstruction before retention began.
date_start
Earliest member date to include. Defaults to seven days before the anchor Story's own date — not to today, because a situation is anchored on a Story, not on the request clock. On a curated Situation it filters the stored membership and `coverage` is re-derived from the members that survived, so the window reported is never wider than the payload.
date_end
Latest member date to include. Defaults to seven days after the anchor Story's own date. The span may not exceed 30 days when both bounds are sent — the same ceiling the service compares against, not a number typed into a sentence. On a curated Situation, sending neither bound returns the whole stored span; sending one leaves the other side open.
limit
How many member Stories to return. The per-day rollup, the incidents and every total always describe the WHOLE situation, so a small page never shrinks the numbers.
depth
How many adjudicated hops out from the anchor to walk. `depth=1` returns only Stories a judge compared with the anchor DIRECTLY. Higher values reach further across time — no link in the source spans more than two days, so a week is depth, not distance — but a Story at hop 2 or 3 was never compared with the anchor itself: it was reached along a path of individually adjudicated edges, which `edges` and each Story's `hop` and `via_story_id` make explicit. Treat depth > 1 as reachability, not membership. NOT APPLICABLE on a curated Situation, whose membership was adjudicated rather than traversed: there is no frontier, so the value appears under `applied_filters.ignored` beside `meta.situation_source: "curated"` rather than being echoed back as honoured.
max_nodes
Ceiling on member Stories. On a walked situation it bounds the frontier, ordered largest-first so a cut is reproducible rather than dependent on row order. On a curated one it bounds the membership read, taking them in the order `stories` is served in — earliest date first, largest within a date — so the cut is the head of the list you would have paged through rather than an arbitrary slice. `truncated` and `caps.members` say whether it bit, both measured. It is a FILTER, not a page size: the totals describe the members it admitted, while `limit` pages those members without changing any number.
include
Optional blocks. `edges` returns one undirected row per adjudicated pair across the bounded graph membership, independently of Story pagination (`limit` and `offset`). An edge can reference a Story outside the returned page; fetch the member pages to hydrate those IDs and inspect `caps` and `scopes` for coverage. `/connections` pages membership provenance, not pairwise edges. Edges are omitted by default; `totals.edge_count` reports all pairs in the selected scope even when the returned graph is capped.

Accepted values: edges

offset
Member Stories to skip. The member list is ordered by date then article count.
GETList all linked entities in a stored Situation/api/v2/situations/{story_id}/entities

Paginated canonical entities across full servable stored membership, independently of the detail endpoint’s 40-entity or 200/250-member view. Identity merging precedes type filtering and pagination. summary.entity_count and by_type cover the whole requested scope; pagination.total covers the type filter. Bounded query failure returns an error, never a partial exact total. Shared auth and query quotas apply.

Response: SituationEntityCard · MCP tool: get_situation_entities

Parameters and accepted values (8)
edition_id
Pin a retained edition. Mutually exclusive with as_of.
as_of
Latest edition published at or before this UTC ISO timestamp. No reconstruction before retention began.
scope_version
Optional version from the preceding page scope. A changed scope returns 409 instead of silently mixing pages.
date_start
Optional earliest member reporting date. Omit both dates for the full servable membership.
date_end
Optional latest member reporting date. No implicit first200-member truncation.
entity_type
Case-insensitive type from summary.by_type (person, organization, company, ministry, agency, regulator, party, ngo, union, campaign, armed_group, brand, place, location, other); `unknown` selects untyped entities. A value outside that set is refused with 400 INVALID_ENUM rather than answered as an empty page. Applied after identity folding and echoed in applied_filters.
limit
Maximum linked entities returned per page.
offset
Entities to skip after canonical folding and type filtering. Stable order: distinct Story breadth, mentions, entity ID.
GETList a Situation's stories/api/v2/situations/{story_id}/stories

Independently paginated stories over current servable membership. Summary and pagination totals cover all matching members, never a graph sample. Article counts sum member Story counts, not unique URLs. Date filters select member reporting dates; Event occurrence dates remain separate.

Response: SituationMemberStoryCard · MCP tool: get_situation_stories

Parameters and accepted values (8)
edition_id
Pin a retained edition. Mutually exclusive with as_of.
as_of
Latest edition published at or before this UTC ISO timestamp. No reconstruction before retention began.
scope_version
Optional version from the preceding page scope. A changed scope returns 409 instead of silently mixing pages.
date_start
Optional earliest member reporting date. Omit both dates for the full servable membership.
date_end
Optional latest member reporting date. No implicit first200-member truncation.
limit
Records per page; independent of graph limits.
offset
Records to skip in this list. Stories order by reporting date, article count, ID; Events by significance then ID.
record_ids
Up to eight comma-separated retained Story IDs. Requires edition_id or as_of, cannot be combined with date_start or date_end, and returns complete frozen records in edition order. Offset and limit paginate that selected set.
GETList a Situation's events/api/v2/situations/{story_id}/events

Independently paginated events over current servable membership. Summary and pagination totals cover all matching members, never a graph sample. Article counts sum member Story counts, not unique URLs. Date filters select member reporting dates; Event occurrence dates remain separate. Event facts are hydrated from serving_events, while serving_event_story_links supplies membership only. incident_relations contains accepted directional umbrella/component links whose two endpoints are on this returned page; nullable summary counts distinguish unavailable or incomplete publication from a measured zero.

Response: SituationMemberEventCard · MCP tool: get_situation_events

Parameters and accepted values (8)
edition_id
Pin a retained edition. Mutually exclusive with as_of.
as_of
Latest edition published at or before this UTC ISO timestamp. No reconstruction before retention began.
scope_version
Optional version from the preceding page scope. A changed scope returns 409 instead of silently mixing pages.
date_start
Optional earliest member reporting date. Omit both dates for the full servable membership.
date_end
Optional latest member reporting date. No implicit first200-member truncation.
limit
Records per page; independent of graph limits.
offset
Records to skip in this list. Stories order by reporting date, article count, ID; Events by significance then ID.
record_ids
Up to eight comma-separated retained Event UIDs. Requires edition_id or as_of, cannot be combined with date_start or date_end, and returns complete frozen records in edition order. Offset and limit paginate that selected set.
GETList Situation membership connections chronologically/api/v2/situations/{story_id}/connections

Every servable membership connection, independently paginated and grouped by reporting day. Includes the stored membership relationship, first-observed timestamp, linking Story and recorded adjudication evidence. This is membership provenance, not a causal assertion or a sampled pair graph.

Response: SituationConnectionCard · MCP tool: get_situation_connections

Parameters and accepted values (7)
edition_id
Pin a retained edition. Mutually exclusive with as_of.
as_of
Latest edition published at or before this UTC ISO timestamp. No reconstruction before retention began.
scope_version
Optional version from the preceding page scope. A changed scope returns 409 instead of silently mixing pages.
date_start
Optional earliest member reporting date. Omit both dates for the full servable membership.
date_end
Optional latest member reporting date. No implicit first200-member truncation.
limit
Records per page; independent of graph limits.
offset
Records to skip in this list. Stories order by reporting date, article count, ID; Events by significance then ID.
GETRead a retained Situation brief/api/v2/situations/{story_id}/brief

Edition-bound as-of explanation, salient Events and actors, supported relationships, time-step traversal, full-scope statistics, frozen citations, previews and detail links. New editions do not forecast. Structure adds typed graph nodes and edges; context adds source-gated existing context. No model calls occur during reads. Unavailable analysis remains explicit.

Response: SituationBrief · MCP tool: get_situation_brief

Parameters and accepted values (3)
edition_id
Pin a retained edition. Mutually exclusive with as_of.
as_of
Latest edition published at or before this UTC ISO timestamp. No reconstruction before retention began.
level
Progressive detail level: brief (default), structure, context.
GETList retained Situation editions/api/v2/situations/{story_id}/editions

Immutable manifests newest first, including stable daily references. Capture time, reporting cutoff and publication time are distinct. Retention begins at rollout; older clipped snapshots are not reconstructed.

Response: SituationEdition · MCP tool: get_situation_editions

Parameters and accepted values (2)
limit
Maximum linked entities returned per page.
offset
Entities to skip after canonical folding and type filtering. Stable order: distinct Story breadth, mentions, entity ID.
GETEntity tone (by entity)/api/v2/entities/{entity_id}/tone

Media tone toward a specific entity over a date window, with optional cited evidence. Requires a plan with Entity media tone access (can_use_tone) — see Pricing for the plans that include it. **bucket is not a parameter of this endpoint.** Entity tone is always DAILY. The series is scored per entity per story per day and the response carries bucket_granularity: "day" on every row; there is no weekly or monthly aggregation to request. The spec previously advertised bucket=day|week|month, which the service never parsed — bucket=month returned daily rows with a 200. Aggregate on your side, or narrow the window with date_start/date_end. **quality is not a parameter of this endpoint.** Not applied. Entity tone rows are served as scored; there is no quality tier to select. Filter on the score_status and confidence fields carried on each row instead.

Response: status, start_date, end_date, entities, resolved_entities, unresolved_terms, entity_coverage, rows, methodology, evidence_samples, language_breakdown

Parameters and accepted values (9)
entity_id
Canonical entity id or wikipedia_url.
date_start
Window start YYYY-MM-DD. The inclusive date span may not exceed 30 days.
date_end
Window end YYYY-MM-DD. The inclusive date span may not exceed 30 days.
days
Trailing N-day window (1–30).
languages
Comma-separated language filter (e.g. en,zh). Accepted codes: Taxonomy & Codes — Languages. Observed vocabulary, measured 2026-08-10 (77 distinct values). Values outside it are accepted, not rejected. Discover current values: GET /api/v2/stories?limit=1 — read coverage.languages. The languages the corpus actually carries, canonicalized toward ISO 639-1 (639-2 codes are folded to their 2-letter form, and a long tail of 639-3 codes survives for outlets that have no 639-1 code). The filter validates SHAPE, not membership: it rejects only a token that cannot be an ISO code — a normalized value longer than 3 characters, so languages=english is a 400 while languages=zz is an accepted, empty 200. A code absent from this list may still be valid; it just had no coverage in the measured window. Values seen in the corpus: https://docs.gdeltcloud.com/reference/enums#coverage_language
category
Story category filter (CSV). Same vocabulary as /api/v2/share-of-voice?category= and /api/v2/stories?story_category= — see Taxonomy & Codes. An unrecognised value returns 400 INVALID_ENUM with accepted_values. Omitted means all categories. Answered from the per-cluster tone rollup, so it narrows the time series AND the evidence samples together.
include_evidence
Return cited evidence snippets.
limit
Max rows.
min_confidence
Minimum per-bucket tone confidence to include (0–1).
GETEntity tone/api/v2/entity-tone

Entity-conditioned media tone, risk, and confidence over a window, with cited evidence. Resolve the entity first with /api/v2/search. Requires a plan with Entity media tone access (can_use_tone) — see Pricing for the plans that include it.

Response: status, start_date, end_date, entities, resolved_entities, unresolved_terms, entity_coverage, rows, methodology, evidence_samples, language_breakdown

Parameters and accepted values (11)
entity_id
Canonical entity id / wikipedia_url.
entity_search
Resolve by name instead of id.
q
Alias for entity_search.
date_start
Window start YYYY-MM-DD. The inclusive date span may not exceed 30 days.
date_end
Window end YYYY-MM-DD. The inclusive date span may not exceed 30 days.
days
Trailing N-day window (1–30).
languages
Language filter (e.g. en,zh,ar). Accepted codes: Taxonomy & Codes — Languages.
category
Story category filter (CSV). Same vocabulary as /api/v2/share-of-voice?category= and /api/v2/stories?story_category= — see Taxonomy & Codes. An unrecognised value returns 400 INVALID_ENUM with accepted_values. Omitted means all categories. Answered from the per-cluster tone rollup, so it narrows the time series AND the evidence samples together.
include_evidence
Include evidence snippets.
evidence_limit
Max evidence samples returned for the window — one card per story (default 25, max 250). Applied as a single global limit over the window, not a per-bucket cap.
limit
Max rows.
GETTone run status/api/v2/entity-tone/runs/{run_id}

Status + result of a queued entity-tone run. Requires a plan with Entity media tone access (can_use_tone) — see Pricing for the plans that include it.

Response: success, data

Parameters and accepted values (1)
run_id
Run id from the create call.
GETList tone runs/api/v2/entity-tone/runs

List entity-tone scoring runs. Requires a plan with Entity media tone access (can_use_tone) — see Pricing for the plans that include it.

Response: success, data, pagination

Parameters and accepted values (2)
limit
Rows per page.
cursor
Pagination cursor (opaque offset).
GETGet Event/api/v2/events/{event_id}

Fetch one known structured Event by ID.

Response: success, data

Parameters and accepted values (1)
event_id
Event ID returned by Search Events, for example conflict_... or cameoplus_....
GETGet Event Stories/api/v2/events/{event_id}/stories

Stored, addressable Stories connected to this Event through primary or rehomed links. Incident-member IDs resolve to the canonical Event. Published serving edges select membership; Story titles, dates and article counts come from the published Story snapshot. The serving edge does not yet project relationship roles, so bounded live provenance supplies primary/rehomed roles only within published membership. Metadata declares mixed relationship provenance and partial coverage; this context is not a whole-Event Story total. Default bounds anchor to the Event date; supplied/default bounds include two additional days on either side. Returns up to 50 Stories ordered by article count descending. meta.pagination reports limit, returned, has_more and total:null; has_more indicates additional matching context beyond the returned cap. A Story excluded only by general-list dedup remains addressable here. relation is reconnected for rehomed-only links, otherwise primary (primary takes precedence). An unavailable Story or serving-edge snapshot returns retryable 503; missing stored membership or Stories are not reconstructed from the warehouse.

Response: success, data, meta

Parameters and accepted values (3)
event_id
Event ID returned by Search Events, for example conflict_... or cameoplus_....
start_date
Optional ISO date (YYYY-MM-DD) lower bound. Defaults to the Event's own date window. The effective window extends two days beyond each supplied/default bound; response meta.window reports those bounds.
end_date
Optional ISO date (YYYY-MM-DD) upper bound. Defaults to the Event's own date window. The effective window extends two days beyond each supplied/default bound; response meta.window reports those bounds.
GETGet Story/api/v2/stories/{story_id}

Fetch one known Story by ID with linked Events, linked Entities, metrics, public URL, normalized geo, and top 3 inline articles.

Response: success, data

Parameters and accepted values (3)
story_id
Story ID returned by Search Stories or linked from an Event.
include_images
Attach resolved article images to the Story card. Off by default because it requires an extra lookup.
include_entity_tone
Attach entity-conditioned tone rows for the entities in this Story. Requires Entity media tone access (can_use_tone); unavailable evidence is omitted rather than reported as neutral.

UNDERSTAND THE SOURCE

Where the data comes from.

SEC EDGAR ↗

Retrieve SEC filer identity, filing records and evidence-backed company relationships through GDELT Cloud. Connect US registrants to reporting with resolved entity identifiers.

Read the source guide
FRED ↗

Use FRED and ALFRED economic series through GDELT Cloud’s macro API. Inspect metadata, dated observations, source attribution and redistribution limits.

Read the source guide
Global Energy Monitor ↗

Explore Global Energy Monitor facilities through a structured API. Filter by country or proximity, inspect capacity and registry dates, and connect reporting to infrastructure carefully.

Read the source guide
Sanctions & public records ↗

Inspect original-publisher sanctions and public-record sources through GDELT Cloud. Understand list coverage, entity connections and how MIT-licensed OpenSanctions crawler code is used.

Read the source guide