For agent builders · versioned commitment
Any market API can tell your agent what happened. This is a commitment about the harder case: what Fahali does when it cannot answer.
An autonomous system acting on financial data needs to distinguish “no risk detected” from “the measurement failed.” Those are opposite conclusions and most APIs render them identically — as a zero, an empty array, or a confident-looking default. Fahali will not do that, and this page is the guarantee you can build against.
Version 1.0Effective 20 Aug 2026Applies to REST + MCP
This contract does not describe intended behaviour. Each clause below is enforced in production code today and covered by tests that fail if it is removed.
Agent-consumed fields are never a bare null. A value that could not be produced carries the reason it could not be produced, in the same object.
// never this "historicalWinRate": null // always this "historicalWinRate": { "value": null, "reason": "insufficient_sample" }
Every measured claim carries a publishable flag. A figure that has not cleared its effective-sample and lift thresholds is withheld — it is not softened, hedged, or published with a caveat.
Read the flag, never the number. A percentage present in a payload is not a percentage we stand behind unless publishable is true.
Refusals use stable reason codes, not prose. Your agent branches on the code; the human-readable message is for your logs, and may change.
"highestRiskSymbol": null,
"highestRiskTiedCount": 12,
"highestRiskWithheld":
"tied_top_score_no_separated_leader"
That example is real: when many symbols share the top score, we publish the size of the tie rather than naming whichever one the database returned first.
When a derived surface cannot parse what it was given, it leaves the previous verified statement standing rather than emitting a partial one.
The rule is fail closed: a broken pipeline produces the last thing we could prove, or nothing — never a plausible-looking value assembled from what survived.
These are the commitments that cost us conversions, which is the only reason they are worth publishing.
Three rules that make your agent correct rather than merely working.
| Do | Instead of | Because |
|---|---|---|
Branch on reason | Branching on the message string | Reason codes are stable and versioned; messages are not |
Check publishable | Reading the percentage | A number can be present and still be one we withhold |
Treat a 403 as under-scoped | Treating it as an outage | Paid refusals return an upgrade object naming the plan, price and checkout URL |
Preserve as_of and horizon in citations | Quoting the value alone | A risk read without its horizon is not the same claim |
A contract you cannot rely on across deploys is not a contract.
{value, reason} will not later return a bare scalar.Questions, or a shape that would make this easier to build against: the developer portal · the public evidence ledger · machine-readable guide