State the decision regime: the appetite, the sample, and whether the model is…
States the decision regime the caller organisation's model decides under: how much of its own stream may be sent for examination, how much of the rest is…
PUT /v1/risk/policy
| Address | https://api.hanzo.ai/v1/risk/policy |
| Method | PUT |
| Operation | riskSetPolicy |
| Auth | Authorization: Bearer $HANZO_API_KEY |
States the decision regime the caller organisation's model decides under: how much of its own stream may be sent for examination, how much of the rest is sampled to measure what was missed, and whether the model may change an outcome at all.
The appetite is the decision a model is not permitted to make for itself: its output is a probability, so how likely it is to MISS something is a matter of policy that has to be stated, measured and reviewed rather than absorbed into a constant. The alert threshold is derived from it as a quantile of the scores actually observed, which is what keeps its meaning as the distribution drifts.
It is DURABLE BEFORE IT IS IN FORCE. The regime is recorded as a new version on the organisation's own shelf before anything in memory moves, so a policy that cannot be written down is refused rather than answered from state the next rollout would silently undo.
ARMING IS AN ADMIN ACT AND TUNING IS NOT. Setting live requires an admin of
this organisation; stating the appetite and the sample is self-service for any
member. Taking the model live decides whether it may change an OUTCOME at all —
a payment frozen, a grant refused — for every customer this organisation has,
and that is a decision an organisation takes rather than one of its members.
A RESTATEMENT OF THE REGIME IN FORCE MINTS NOTHING and answers the version already in force. Compare the version you receive with the version you had: unchanged means the numbers were the same, which is why there is no flag for it.
Learned state survives the change. The model's identity covers its SHAPE — the inventory and the geometry — and not its appetite, so restating policy unlearns nothing. It also does not REPORT the learned state: what the model is is read from the model.
Request
3 fields, body application/json (required).
| Field | In | Type | Required | Description |
|---|---|---|---|---|
live | body | boolean | — | Live turns the model out of shadow. It defaults to FALSE on every call, so going live is always an explicit act and never a side effect of changing a number. |
review | body | number | — | Review is the share of the stream that may be sent for examination, in (0, 0.5]. |
sample | body | number | — | Sample is the share of below-the-line events retained for review, in [0, 1]. |
Response
| Status | Body | Meaning |
|---|---|---|
200 | riskPolicyOut | ok |
200 body — 12 fields.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
changes | body | integer | — | Changes is how many DISTINCT regimes may be adopted per Window. |
disposed | body | integer | — | Disposed is how many versions retention has taken. |
history | body | riskPolicyVersion[] | — | History is the retained versions, newest first. |
history[].at | body | string | — | At is when it entered force, RFC 3339, from the server clock. |
history[].by | body | string | — | By is the identity that stated it, stamped server-side from the validated principal at the moment it entered force. |
history[].live | body | boolean | — | Live is whether the model was permitted to change an outcome under it. |
history[].review | body | number | — | Review is the share of the stream the regime states may be examined. |
history[].sample | body | number | — | Sample is the share of below-the-line events the regime retains for review. |
history[].version | body | integer | — | Version names this regime in this organisation's history. |
retained | body | integer | — | Retained is how many versions this organisation's history holds at most, derived from the byte budget its rows are a multiple of. |
version | body | integer | — | Version is the version in force — the one every score currently cites. |
window | body | string | — | Window is the period Changes is measured over. |
Failure carries the platform error shape — see Errors.
Examples
hanzo risk policy replaceimport { Configuration, RiskApi } from 'hanzoai';
const api = new RiskApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.riskSetPolicy({ live: false, review: 0 });from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import RiskApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = RiskApi(client).risk_set_policy(live=False, review=0)cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.RiskAPI.RiskSetPolicy(context.Background()).Execute()
if err != nil {
return err
}use hanzo_cloud::apis::{configuration::Configuration, risk_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = risk_api::risk_set_policy(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.RiskApi;
ApiClient client = new ApiClient();
client.setRequestInterceptor(b -> b.header("Authorization", "Bearer " + System.getenv("HANZO_API_KEY")));
var result = new RiskApi(client).riskSetPolicy();curl -X PUT https://api.hanzo.ai/v1/risk/policy \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"live": false,
"review": 0
}'The door reaches risk through the risk tool, which names its 10 operations with its own verbs — this one among them, under a name only the door declares. describe explains any of them:
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "describe",
"arguments": {
"op": "get_risk_health"
}
}
}'How is this guide?