Signals
Twenty-five scored dimensions per article across industry, business register and risk context. Filter on ranges, stack them, and stop trying to express "energy coverage that sounds worried" as a keyword query.
Why one sentiment number is not enough
Sentiment collapses an article to a single axis, which forces unrelated things to compete. A piece about a record harvest that also warns about export tariffs averages out to roughly neutral, and the average describes nothing that is in it.
Signals keep the dimensions separate. The same article can score high on agriculture, high on trade, and high on financial uncertainty simultaneously — which is a description you can filter on and act on.
Industry
How strongly an article reads as being about a sector, rather than merely mentioning one.
| Signal | Reads as |
|---|---|
signal_economy | General economic activity |
signal_finance | Banking, markets, capital |
signal_energy | Power, fuel, utilities |
signal_agriculture | Farming, food production, commodities |
signal_healthcare | Care delivery, providers, public health |
signal_labor | Employment, unions, workforce |
signal_transportation | Freight, aviation, shipping, rail |
signal_real_estate | Property, construction, housing |
signal_defense | Military, procurement, security industry |
signal_science_technology | Research, computing, engineering |
signal_trade | Imports, exports, tariffs |
signal_environment | Ecology, pollution, conservation |
signal_public_sector | Government administration and services |
Business language
The register a piece is written in — how markets and lawyers talk, rather than the subject.
| Signal | Reads as |
|---|---|
signal_financial_positive | Optimistic financial framing |
signal_financial_negative | Pessimistic financial framing |
signal_financial_uncertainty | Hedging, unresolved outcomes |
signal_financial_stability_stress | Systemic stress language |
signal_legal_litigation | Proceedings, claims, regulatory action |
Risk context
Operational and systemic risk language, for monitoring rather than sentiment.
| Signal | Reads as |
|---|---|
signal_supply_disruption | Interrupted production, logistics, shortage |
signal_cyber_incident | Breach, intrusion, outage |
signal_conflict | Armed conflict and hostilities |
signal_climate | Climate and extreme weather |
signal_health_security | Outbreaks and health emergencies |
signal_governance_risk | Corruption, institutional failure |
signal_anxiety | Public alarm and apprehension |
Filtering on them
Each signal is a number. Filter on a range, not a value, and stack constraints when you need more than one to hold at once.
# one signal, lower bound
GET /search?signal=signal_cyber_incident&signal_min=0.25
# several at once — every constraint must match
GET /search?signals=signal_energy:0.3,signal_financial_stability_stress:0.2
# combine with any other filter
GET /stories?country=GM&signal=signal_supply_disruption&signal_min=0.2 Every article response also carries its full signal map, so you can retrieve broadly and threshold client-side while you work out where the useful cut is.
Choosing a threshold
There is no universal cutoff. Scores are relative to how strongly the language appears, and the useful threshold depends on how noisy your query already is. Retrieve a week without a signal filter, look at the distribution for the signal you care about, and cut where the results stop being about what you meant.
Re-check it quarterly. Editorial vocabulary shifts, and a threshold tuned during a quiet period will admit far too much during an active one.
What they are not
Signals measure language, not events. A high risk score means an article is written in the register of that risk — it does not confirm the risk is real, material, or new. Treat them as a retrieval and triage tool, not as a finding.
They are also versioned. Responses carry the version that produced them, so a series computed across a version change is comparing two different things and should be recomputed rather than concatenated.