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_idis the join key. That one string is what every call below takes.sourcesdescribes 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.identifiersis how you reach the surfaces that are keyed on someone else’s id — the SEC filings endpoints take a CIK, and the resolver already handed you one.
2
What is happening to it
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 with the same id
This is the payoff. The Rows come back under This endpoint refuses to compute without a denominator — a share with no stated denominator is
not a number. Omit one and you get 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. Step 1 reported 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.
entity_id from step 1 works unchanged on the other surfaces, and the
sources map from step 1 already told you which of them will have rows.Press tone over time — scored by us across news coverage, per entity per story per day.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.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."gem": false for Lockheed Martin, and
/facilities is duly empty for it: zero rows, 200, no error. So this one runs against a resolved
id that does carry assets — Chevron Corp, e_7efd743ec55a5285.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:Four things worth knowing before you build
Event and story lists default to 7 days
Event and story lists default to 7 days
Not to all of history. Other families carry their own default, declared on each
days parameter in
the API reference. Pass days or an explicit date_start/date_end window
whenever the window matters to your answer. Windows are bounded — an unbounded scan across the whole
corpus is refused rather than served slowly.Read applied_filters on every response
Read applied_filters on every response
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.null is not zero
null is not zero
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.Paginate with the cursor, not an offset
Paginate with the cursor, not an offset
List endpoints return a
cursor. Offset pagination drifts as new rows land mid-walk; the cursor does
not.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.

