Skip to main content
One task, end to end: watch what is happening to a company — in the news, in federal contracting, and in the physical world. It takes four calls, and the shape of it generalises to almost everything else you will build here. The responses below are examples recorded in August 2026. Run the calls for current data and inspect meta.query_window, meta.coverage and applied_filters before using the results. The design starts by resolving the name once. Then check which identifier each destination accepts: an e_… identity works on many surfaces, while a wiki:… or llm:… candidate and source-specific records may need a different, documented key. Never infer a cross-dataset join from a name alone.
1

Resolve the name

Never filter by a company name string. Names are ambiguous, they change, and every surface spells them differently. Ask the resolver instead:
Illustrative candidate response; counts and source availability depend on the request and account:
Three fields decide what you do next:
  • entity_id is the selected identity. Keep its exact value and reuse it only on endpoints that accept its identifier space; e_…, wiki:… and llm:… are not interchangeable. A facility has a separate facility_id.
  • sources describes measured source availability. It does not establish the result count of another endpoint or prove that an entity owns no facilities. Withheld source keys are omitted; missing or failed coverage remains unknown. Inspect the actual selected-ID response.
  • identifiers helps reach source-specific surfaces. SEC filing detail takes a CIK; some asset and ownership endpoints use GEM owner IDs or LEIs. Check the identifier parameters for each call.
An empty result means this search found no candidate; it does not establish that the entity does not exist or has no activity. Refine the name, type or country evidence before concluding anything. When several candidates come back, show them — do not auto-pick the top one.
2

What is happening to it

Three coded events, ranked by how much they matter rather than by when they landed:sort=significance is the default and the one you want for monitoring. Sorting by recency gives you a feed dominated by whatever a wire service published in the last hour.Start wide. The most common mistake on this API is stacking four filters on the first call and concluding the data is missing when the empty result is really your AND.
3

Read the evidence

An event is a claim; the articles are why we made it. Every event links to the story it was coded from — take the top row of that table:
Then follow the story id to the source URLs:
Twenty-two articles back that one story, and the first three are Turkish, Indian and Afghan outlets — independent coverage rather than one wire story republished, which is how you tell a well-supported event from a thin one. Build citation into your feed from the start; an alert nobody can verify gets ignored the second time it fires.
4

Fan out using supported identifiers

This selected e_… ID is accepted by the examples below. Other candidates may have a wiki:… or llm:… ID that a destination cannot use. Check the destination contract and the actual response; the sources map alone cannot promise rows or establish absence.Press tone over time — scored by us across news coverage, per entity per story per day.
Rows come back under rows, one per bucket date, and 22 of the 27 buckets in that real response carried avg_news_tone_score: null — days with coverage but no news-tone reading. That is not a zero. Charting it as one invents a trend.Share of voice — the same tone in context: a drop reads differently when coverage volume tripled the same week.
This endpoint refuses to compute without a denominator — a share with no stated denominator is not a number. Omit one and you get 400 DENOMINATOR_REQUIRED, whose details.allowed_filters names every filter that defines one. The denominator comes back with a hash, so the same share is reproducible months later.Federal awards — the same id against USAspending.
Twenty-two SAM.gov recipient records roll up under one entity id. That collapse is the product: filtering by the name string would have matched some of the twenty-two and silently dropped the rest.Physical assets — same call shape for this e_… identifier. The example resolver response reported "gem": false for Lockheed Martin, but that flag alone does not prove the company owns no facilities. Here we use another selected identity, Chevron Corp, e_7efd743ec55a5285.
If you had filtered by name instead of by id, each of these four would have matched a different subset and you would have silently dropped half the data — without any endpoint returning an error.
Every request and response above was run on 2026-08-26 and is reproduced as returned, trimmed to the fields each step uses. Live rows carry more, and the values move with the news.

Doing the same thing through MCP

Same four steps, no HTTP. Point an agent at the MCP server and it discovers the tools itself:
Use REST when you are writing a service; use MCP when a model is deciding what to call next. The data and the gating are identical — the MCP routes to the same serve functions.

Four things worth knowing before you build

Without an entity filter, Event and Story lists default to a rolling 24 hours; an entity-filtered list defaults to 30 calendar days. Other families have their own defaults. Read meta.query_window and pass days or explicit date_start/date_end whenever the window matters. Windows are bounded — an unbounded scan across the whole corpus is refused rather than served slowly.
It echoes what the server actually applied, using canonical names whatever spelling you sent. If a strict endpoint does not recognize a parameter, the request fails with 400 UNKNOWN_PARAM and names the parameters it does accept. On an endpoint still using the compatibility contract, the request may succeed but list that parameter under applied_filters.ignored — a 200 that quietly answered a different question. In either case, correct the request before using the returned data.
A null metric means the observable was not found. A 0 means it was found and measured as zero. The tone response above is the live case: most buckets have no news-tone reading, and charting them as 0 invents a trend that is not there.
For Event and Story lists, copy pagination.next_cursor into the next request’s cursor until it is null; page at the documented maximum when collecting all rows. QU is charged per call, so a shorter page does not save QU. Do not infer completeness from a short page. Check meta.coverage.window_complete before treating a date range as complete.

Next

Run it on a schedule

Hand this same question to a hosted Monitor and have it deliver new matches to you.

Recipes

Short copy-paste queries for the common shapes.