This page is about what the nouns MEAN. Response shapes are in the
OpenAPI schemas; the values each filter accepts are in
Reference.
The six nouns
Article → Story → Event is the spine
An article is evidence. A story is the deduplicated development several articles describe. An event is the structured claim we are willing to stand behind, coded into a taxonomy with a date, a place, actors and metrics. The distinction matters for counting. Three publishers covering one strike is one story and one event, not three — which is the whole reason the pipeline exists, and it is why an article-count and an event-count answer different questions. It runs the other way too: one story can produce several events. A single cluster covering a border incident may yield an armed clash, a diplomatic protest and an airspace closure — three distinct coded claims, each with its own actors, date and metrics, all citing the same coverage. So stories and events are not two views of the same list, and neither count is a proxy for the other. Ask for events when you want incidents; ask for stories when you want narratives.Events come in two families
The family is decided by a single test: did it happen, or was it said?- Conflict (ACLED) — a discrete act of political violence, armed conflict, protest, riot or explosion that occurred.
- CAMEO+ — every speech act (a threat, demand, agreement, sanction) and every non-violent event across nine further domains.
Conventions every endpoint shares
One identity, everywhere
Resolve candidates once, select the intended identity, and reuse its returned ID in each destination endpoint’s documentedentity parameter. Accepted identifier spaces differ by
endpoint: reporting supports spine and news identities, while some source-specific legs require
particular identifiers. Check the identifier parameter contracts
before chaining calls; an unsupported or unlinked identity must not become a claim of zero records.
Finding an entity by name
Start at the unified search endpoint, then reuse the id it hands back:sources availability map and its cross-source identifiers. Use type
to narrow an ambiguous name to a person, organization, place or facility; clients should present weak or
ambiguous candidates rather than selecting one automatically.
Select an entity candidate, then reuse its returned ID in the destination endpoint’s documented
entity= parameter. Facilities return facility_id, separate from an owner entity or nearby
Events. Unlinked source records retain their source key and a null entity ID.
Country selection uses strict known source association in recommended requests. Inspect
country_evidence: office country, legal registration, citizenship and reporting geography are
different relationships. country_match=include_unknown explicitly broadens to unknown associations;
omitting the parameter preserves compatibility behavior. Politicians remain people selected through
holds_office=true and published office evidence.
The reporting directory /api/v2/entities answers which entities appear in a selected reporting
window. Initial identity lookup uses /api/v2/search. Source and facility access remains subject
to the existing account entitlements; withheld source keys are omitted and failed coverage is unknown.
Entity Monitors take a resolved entity id rather than a bare name, and accept every id-space
/api/v2/search returns — a spine id (e_…), a news id (wiki:…) or an extracted-identity id
(llm:…). Pass whichever the resolver gave you; the monitorable boolean on each search
result says outright whether that exact id is accepted as a Monitor subject. Holding out for an
e_… id is the one thing to avoid: six of the twenty most-covered organizations — TikTok, the
Pentagon, the Senate, the Supreme Court, ICE and North Korea — have no e_ id at all, and an
e_-only rule made them unwatchable. A
scheduled question must not silently change subjects when name rankings change. Their public v1
match mode is coverage: mention and linked-Story evidence, not a claim of material involvement or
actor attribution.
Some endpoints take a name directly and resolve it for you; those that require an id return
400 INVALID_ENTITY_ID for a bare name. Either way this endpoint is how you get the id. Older
material referring to /api/v2/entities/resolve is wrong — no such endpoint exists.applied_filters tells you what actually happened
Every successful response echoes the filters the server applied. Descriptor-backed endpoints reject
an undeclared parameter with 400 UNKNOWN_PARAM and include details.did_you_mean plus the accepted
parameter names. Endpoints still being migrated may instead return it under
applied_filters.ignored; a non-empty ignored object means those parameters did not affect the rows.
Whichever spelling you sent, applied_filters reports the canonical name. The alias table is in
Parameter reference.
NULL means unknown; it is never a fabricated 0
A missing observable is UNKNOWN. A 0 asserts a measurement somebody made. This applies to metrics,
to coverage counts, and to every derived number the API serves — and it is the reason some fields
come back null rather than helpfully zeroed.
Date windows are bounded
Windows are capped (30 days on most endpoints) anddays / window / date_start + date_end are
resolved together. Bounds and defaults per endpoint are in
Parameter reference.
Search is not one thing
Some endpoints run semantic search — the string is embedded and ranked by cosine similarity, so results are conceptual neighbours. Others run a lexical substring match over named columns and keep their own default ordering, which means a query matching more rows thanlimit returns an
arbitrary slice. The per-parameter description says which, and it is worth reading before assuming
relevance ordering.
Coverage
Consistently coded history begins in March 2026 and runs to now, refreshed through the day. Earlier dates return a near-empty result that reads like a bug and is not — there is a thin tail of back-dated article noise before that, not usable history, and the window is being extended backwards over time. Coverage is not uniform, and the honest way to find out where it is thin is to ask rather than to trust a number written here:GET /api/v2/intelligence/coverage reports what can and cannot be
read, per place and period. Per-dataset windows, cadences and known gaps are in the
data catalog, which is generated from the same records the public data page uses.
The general shape: world and continent readings are well supported, country readings much less so,
and any single day in a low-coverage place should be treated as a sample rather than a census.
How fresh is it
The pipeline runs continuously; nothing here is a nightly batch. Concretely:
Two consequences worth designing for:
- Today is still moving. A query for today returns fewer events than the same query tomorrow, because coding is still in progress. That is not a gap; it is the current state. For stable day-over-day comparisons, end your window yesterday.
meta.settled_attells you when. Every/api/v2/eventsresponse carries ametablock:row_sourcesays whether the rows came from a snapshot or were computed live, andsettled_atis the oldest partition build time across the requested window. It is a conservative freshness floor, not the build time of every returned row; a wide historical window can therefore show an oldsettled_ateven when its newest partitions are fresh.
Where the values live
When you need a value list — a category, a code, a country format, an id space — do not guess and do not hardcode from an example. Every vocabulary the API validates against is published, and each is labelled with whether the list is exhaustive:
The distinction that matters most is on How to read the reference: a vocabulary
is closed (a fixed list — safe to switch on), observed (what the corpus currently holds —
never treat as exhaustive), or an identifier (discovered through a call, never enumerated).
Treating an observed list as closed is the single most common way to build a filter that silently
misses data.
Monitors are standing API questions
A Monitor stores one Event/Story question, evaluates it on an hourly or daily half-open window, and retains triggered runs for seven days. It uses the same serving functions as the Core API. Scheduled evaluation costs 0 QU; an accepted on-demand Preview costs 1 QU and returns representative rows for inspection without saving or delivering anything. Run counts and inline samples are different.result_count is the execution’s reported count,
retained_row_count is how many execution rows were stored, and the canonical matches array holds
at most ten cards. When semantic retrieval reaches its candidate ceiling,
total_matches_is_lower_bound is true and candidate_limit names that ceiling. See
Monitors for the complete workflow and exact replay rules.
Next
Quickstart
Make your first call.
Endpoint index
See the whole surface at once.
Event metrics
What the numbers mean.
How events are coded
The pipeline behind an event.
Conflicting candidate types
Candidate search preserves unresolved disagreement between linked source records. Such a candidate returnsentity_type: "entity" with type_evidence.status: "conflicting", the possible types, and each supporting record’s ID, source, and raw type. A type filter may include the candidate when that type is a published possibility; it does not resolve the disagreement. Select the stable identity explicitly and inspect the evidence before treating it as a person or organization. Politician filtering also requires published office evidence.
A registry country association can describe the source relationship. For example, an SEC-seeded USA association means SEC filing association; it does not establish the issuer’s headquarters, domicile or citizenship. Candidate country_evidence states this basis when available. Unknown association remains unknown, and strict country matching never guesses a country from an entity’s name.
