Relationships
Which organizations, people, places and topics are reported alongside an entity, how two entities connect, what changed around one since last month, and what a watchlist shares. Every answer carries the articles behind it, and says what a co-mention does not prove.
What does a co-mention between two entities mean?
An edge between two entities counts the articles that name both of them in the window you asked about. It is computed when you ask, from the same index that search reads: the articles mentioning the entity you started from are tallied by the other entities they mention, and the strongest pairs are then searched for the articles that support them. An edge is as fresh as the index, and it moves when the reporting does.
The count records that journalists wrote about two things together. It does not record
why. A chipmaker and an equipment maker can share forty articles because one buys from
the other, because they are in a patent dispute, because an export rule names both, or
because both sit in a daily list of the market's biggest movers. The number is the same
in each case and only the articles tell them apart. Co-mention is evidence of
association in reporting, not of ownership, partnership, supply, causation or exposure.
Every response states that in a note field, so the distinction travels with
the data into whatever reads it next, including a model that would otherwise write
"partners".
The evidence every edge carries
No association comes back without the means to check it. Every edge carries its count and share; the strongest edges in an answer also carry the articles themselves and the breadth counts drawn from them. You choose how many edges get evidence, from none for counts only up to ten.
| Field | What it tells you |
|---|---|
co_mentions | Articles naming both entities in the window. |
share | Those co-mentions over the articles naming the entity you started from, from 0 to 1. |
evidence | The newest articles naming both: id, title, link, outlet, publication time, language and story. Up to 10 per edge. |
sources | Distinct outlets among the co-mentions. Broader reporting, not necessarily independent reporting: one wire report reaches many outlets. |
stories | Distinct stories among them. Forty articles in one story are one event reported widely; forty across twenty stories are a recurring pairing. |
first_seen / last_seen | The earliest and newest article naming both, so a tie that faded months ago does not read as current. |
approximate | True when a count came from a capped tally, from spellings one article can repeat, or was combined across parts of the index. |
Around the edges, each response reports indexed_through, the newest article
the answering index holds in the window; entity_resolution_version;
credits_charged; and partial with coverage, which
say whether all of the index answered. An empty evidence list means the edge ranked
below the evidence cut or the call spent its query budget, not that no article exists.
Entity ids and the resolution version
Relationship calls start from ids, not names. resolve_entity over MCP, or
GET /entities over REST, turns a name into ids such as
organization:asml: the entity type, a colon and a normalised key. Under
version er-v1 the key is lowercased and stripped of punctuation and of
trailing corporate suffixes, so ASML Holding N.V. and asml
land on one id, and the alias spellings the index holds are grouped under it. Each match
carries a confidence: 1.0 for an exact match after normalisation, 0.8 for a prefix on a
word boundary, 0.6 for an acronym.
The same spelling produces the same id every time under the same version. The id is not a registry identifier. Nothing ties it to a company register, a legal entity identifier or Wikidata, and two different organizations whose names normalise to the same key share one. Responses name the version that produced their ids, so a comparison spanning a change in normalisation can be recognised and recomputed instead of trusted. The same ids work as filters on search, stories, top headlines and aggregate, covered on the filters page.
The bounds
News coverage connects almost anything to anything within a few hops, because one busy article names dozens of entities. A long path is noise that looks like a finding, so every call has fixed ceilings:
- Paths stop at two hops: a direct connection, or one shared neighbour between the two entities.
- A related list returns at most 50 neighbours, and a network at most 20 per type.
- Evidence stops at 10 articles per edge.
- A call issues at most 16 index queries, a credit each, and reports what it spent as
credits_charged.
The corpus a call counts over narrows with language,
publisher_country, source_type and country, the
country an article is about, as well as from and to. Scoping
to one market's own press asks a different question from counting everything: who a
company is reported alongside at home, rather than abroad.
A worked example: who appears alongside one company
Resolve the name, then ask for its neighbours over a month, with evidence on the strongest two:
related_entities { "entity_id": "organization:asml", "from": "2026-08-01", "to": "2026-09-01", "evidence": 2 }
GET /graph/related?entity_id=organization:asml&from=2026-08-01&to=2026-09-01&evidence=2 An excerpt of the answer, with invented values for illustration rather than a measurement of coverage:
{
"seed": {
"entity_id": "organization:asml",
"type": "organization",
"aliases_used": ["asml", "asml holding nv", "asml holding"],
"articles": 1840
},
"related": [
{
"entity_id": "location:netherlands",
"type": "location",
"label": "netherlands",
"aliases": ["netherlands", "the netherlands"],
"co_mentions": 612,
"share": 0.333,
"stories": 204,
"sources": 311,
"first_seen": "20260801031500",
"last_seen": "20260831194200",
"evidence": [
{
"id": "20260831194200-7c1e",
"title": "Chip equipment makers report quarterly orders",
"url": "https://news.example.com/markets/chip-equipment-orders",
"source": "news.example.com",
"published_at": "20260831194200",
"language": "eng",
"story_id": "20260831061000-3a9f"
}
],
"approximate": false
},
{
"entity_id": "organization:tsmc",
"type": "organization",
"label": "tsmc",
"aliases": ["tsmc", "taiwan semiconductor manufacturing"],
"co_mentions": 287,
"share": 0.156,
"stories": 41,
"sources": 150,
"first_seen": "20260803082000",
"last_seen": "20260830101500",
"evidence": [ … ],
"approximate": false
},
{
"entity_id": "topic:econ_stockmarket",
"type": "topic",
"label": "econ_stockmarket",
"aliases": ["econ_stockmarket"],
"co_mentions": 158,
"share": 0.086,
"evidence": [],
"approximate": true
}
],
"indexed_through": "20260831235100",
"entity_resolution_version": "er-v1",
"credits_charged": 6,
"note": "Co-mention in reporting is evidence of association, not of ownership, partnership, causation or exposure. Read the evidence before stating a relationship.",
"partial": false,
"coverage": "complete"
}
The third neighbour ranked below the evidence cut, so it carries counts only, and its
approximate flag says the count came from a capped tally. Pass its
entity_id back into any call to follow it.
Why compare share rather than co-mention counts?
In the excerpt the Netherlands appears in 612 of the 1,840 articles naming the company,
a share of 0.333. The count alone says little, because a heavily covered company piles
up large counts with everything near it. share divides the co-mentions by
the articles naming the entity you started from, so it answers "how much of this
entity's coverage also names that one", and it stays comparable when two seeds differ a
hundredfold in coverage. Rank and compare on share; quote counts only alongside it.
Then read it with the breadth counts. A high share spread across many stories and
outlets is a recurring pairing in the reporting. A high share concentrated in one or two
stories is one event covered widely, and stories is there to stop it being
read as a standing tie. Share also depends on the window: one large story about both
entities can lift it for a month, and the same pair over a year may barely register.
How two entities connect
connection_path takes from_entity and to_entity
and returns the direct edge, the articles naming both, and up to five paths through one
shared neighbour, strongest first. A path's strength is its weaker hop's
co-mentions, so a path is only as well supported as its thinnest link, and
max_hops=1 asks for the direct connection alone. Two entities with no
direct co-mention and a strong shared neighbour were each reported with the same third
party and nothing more: two suppliers of one manufacturer connect this way without ever
having dealt with each other.
What changed: a network against a comparison window
entity_network returns one entity's neighbours grouped by type,
organizations, people, places and topics, strongest first. Add
compare_from and compare_to and the same call counts the
network over a second window and reports the difference:
entity_network {
"entity_id": "organization:asml",
"from": "2026-08-01", "to": "2026-09-01",
"compare_from": "2026-07-01", "compare_to": "2026-08-01"
} changes.new lists neighbours present now and absent then, and
gone the reverse. strengthened holds ties whose share grew by
half or more, with at least two co-mentions now, and weakened those whose
share fell by a third or more, each with its before and after count and share. A new
neighbour is where to start reading, not a conclusion: a regulator appearing in a
company's August network means the August coverage named the regulator, and the
evidence says whether that was an investigation or a conference panel.
A watchlist: what several entities share
shared_exposures takes up to five ids, a company and four of its suppliers
say, and describes the reporting that names all of them: how many articles, stories and
outlets, the facets you ask for over those articles, the mean and percentile intensity
of any signals you name, and the newest shared articles as evidence.
GET /graph/exposures
?entity_id=organization:asml,organization:tsmc,organization:intel
&facets=topic,country,source
&signal_stats=supply_disruption,trade
&from=2026-08-01
Across a watchlist this answers what a set of separate searches cannot: whether one
incident touches several names at once. A disruption story naming three of five
suppliers shows up as shared articles with a raised supply_disruption
intensity, where separate searches return it once per name with nothing marking the
overlap. It does not establish that any of them is exposed to anything. It establishes
that the reporting put them in the same articles, and the evidence is there to read
before anyone says more.
What this is not
It is not a knowledge graph of facts. Nothing here extracts claims such as "owns", "supplies" or "invested in" from the text; an edge is a count of articles, and the relationship it hints at is for a reader of the evidence to state. It is not a registry: ids group spellings by rule, so a common name can merge two organizations and a renamed one can split in two. It sees only what was reported, so an entity with little coverage has few edges whatever its real connections, and a quiet network is not a clean one. And it is not a screening product. Sanctions, ownership and adverse-media obligations need list coverage, registry resolution and audit guarantees a news index does not offer.
Reference
Every operation, parameter and field: the relationship reference. How a name becomes an id: the /entities reference.