Co-mention, with evidence

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.

FieldWhat it tells you
co_mentionsArticles naming both entities in the window.
shareThose co-mentions over the articles naming the entity you started from, from 0 to 1.
evidenceThe newest articles naming both: id, title, link, outlet, publication time, language and story. Up to 10 per edge.
sourcesDistinct outlets among the co-mentions. Broader reporting, not necessarily independent reporting: one wire report reaches many outlets.
storiesDistinct stories among them. Forty articles in one story are one event reported widely; forty across twenty stories are a recurring pairing.
first_seen / last_seenThe earliest and newest article naming both, so a tie that faded months ago does not read as current.
approximateTrue 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:

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.