Put one of your organisation's own published model values in force
Puts one of your organisation's OWN PUBLISHED VALUES in force, by name — which is what an instant rollback is, what promoting a challenger is, and what…
PUT /v1/risk/state/model
| Address | https://api.hanzo.ai/v1/risk/state/model |
| Method | PUT |
| Operation | riskAdoptModel |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Puts one of your organisation's OWN PUBLISHED VALUES in force, by name — which is what an instant rollback is, what promoting a challenger is, and what installing the shape a search found is.
IT TAKES AN ADDRESS AND NEVER STATE. The masses are read from your own store, so nothing about your model has to be held by whatever is making this call. That closes the sharpest edge the previous shape had: a body of counters is something a caller can COMPOSE, and a region filled until activity inside it reads as ordinary is a model that has been shaped rather than learned. The engine's mass invariant was the only thing standing between a composed body and the model; with an address there is no body to compose.
IT ADOPTS THE SHAPE, NOT ONLY THE MASSES. A value records the model space its masses were taken in, and a value whose space differs from the one in force REPLANTS your model into that space before restoring them. That is what makes POST /v1/risk/search actionable: a search answers with the shape that fits your own history best and publishes it fitted, and its address is what you name here. Before this, a winning shape was advice nobody could take — the adoption path refused every shape change, and a winner is a different shape by definition.
WHAT ADOPTING A SEARCHED SHAPE COSTS, SAID PLAINLY: the value a search fits has learned the window the search replayed and nothing older, so installing it trades history for fit. Your appetite is untouched — that is your policy record's, with its own versions — and so is the geometry, which stays your own.
An address your organisation has not published is NOT FOUND. That includes one another organisation published, and it is not a lookup that failed: the store is per organisation and the address is a name, never an authority.
Request
1 field, body application/json (required).
| Field | In | Type | Required | Description |
|---|---|---|---|---|
address | body | string | — | Address is one of YOUR organisation's own published values (GET /v1/risk/state reports them, and a search reports the one it fitted for you). |
Response
| Status | Body | Meaning |
|---|---|---|
200 | riskModelState | ok |
200 body — 36 fields.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
aggregates | body | riskAggregates | — | |
aggregates.bound | body | integer | — | Bound is the most they can hold. |
aggregates.forgotten | body | integer | — | Forgotten is how many of its own subjects have been dropped to stay inside that bound. |
aggregates.saturated | body | boolean | — | Saturated is whether the bound is binding right now. |
aggregates.subjects | body | integer | — | Subjects is how many of this organisation's subjects the aggregates hold. |
blind | body | object | — | Blind counts, per feature, how often it took its neutral value for want of data. |
blind.* | body | integer | — | |
cut | body | number | — | Cut is the threshold in force, derived from Stated as a quantile of the scores actually observed. |
descends | body | string | — | Descends is the published value the working model grew out of: the newest one whose mass count it has reached or passed. |
disposed | body | integer | — | Disposed is how many published values retention has taken. |
learned | body | integer | — | Learned is how many events the model has learned from. |
live | body | boolean | — | Live is false while the model is in shadow — scoring, learning and recording what it WOULD have alerted on, and changing no outcome. |
policy | body | integer | — | Policy is the version of the decision regime this model is deciding under, from your organisation's own policy history (GET /v1/risk/policy). |
realised | body | number | — | Realised is the share that actually was. |
refused | body | object | — | Refused counts events the model would not score, by reason. |
refused.* | body | integer | — | |
sample | body | number | — | Sample is the share of below-the-line events retained for review, which is how the miss rate is measured rather than assumed. |
saturated | body | boolean | — | Saturated means no threshold can honour the stated appetite because too much of the stream scores in the top bucket, so the model is alerting on nothing — the… |
shape | body | string | — | Shape is the model's identity, as <family>:<digest>: the KIND of model, and that family's own digest over the inventory in order and the detector's geometry… |
stated | body | number | — | Stated is the share of the stream this organisation said may be examined. |
surface | body | riskSurface | — | |
surface.folded | body | integer | — | Folded is how many buckets of the tenant's own feature surface were folded into the model when it became resident. |
surface.gap | body | string | — | Gap says why the fold did not happen or did not complete, when that is the case. |
surface.refused | body | integer | — | Refused is how many buckets of this organisation's own surface the fold could not fold, because a subject on them is longer than this plane's own field bound. |
surface.replayed | body | integer | — | Replayed is how many of this organisation's own recorded observations rebuilt its sliding aggregates when the model became resident. |
surface.rolled | body | integer | — | Rolled is how many windows of this organisation's own source planes — product events, captured failures, metered inference — were rolled up into its feature… |
surface.window | body | string | — | Window is the lookback the fold covered. |
tenant | body | string | — | Tenant is the qualified key the model is held under — the brand whose issuer vouched for the caller and the organisation it acts for. |
values | body | riskModelValue[] | — | Values is your organisation's own published model values, newest first — every state it deliberately named, each addressed by its own content and immutable. |
values[].address | body | string | — | Address names this value by its own content: the model's shape, the geometry seed, its position in the window, its threshold, its masses as IEEE-754 bits and… |
values[].at | body | string | — | At is when it was published, RFC 3339, on the server clock. |
values[].learned | body | integer | — | Learned is how many events are behind the masses. |
values[].sequence | body | integer | — | Sequence is this value's place in YOUR organisation's own history, from 1 and contiguous until retention disposes of the oldest. |
values[].shape | body | string | — | Shape NAMES the model space the masses are only meaningful against, as <family>:<digest> — the KIND of model, and that family's own digest over the feature… |
values[].warmed | body | string | — | Warmed is how far your own event surface had been folded in when this value was published, RFC 3339. |
warm | body | boolean | — | Warm is whether that is enough for the model to have an opinion at all. |
Failure carries the platform error shape — see Errors.
Examples
hanzo risk state model replaceimport { Configuration, RiskApi } from 'hanzoai';
const api = new RiskApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.riskAdoptModel({ address: "<address>" });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_adopt_model(address="<address>")cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.RiskAPI.RiskAdoptModel(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_adopt_model(&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).riskAdoptModel();curl -X PUT https://api.hanzo.ai/v1/risk/state/model \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"address": "<address>"
}'Tool risk, op riskAdoptModel — POST the JSON-RPC envelope to https://api.hanzo.ai/v1/mcp.
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "risk",
"arguments": {
"op": "riskAdoptModel",
"input": {
"address": "<address>"
}
}
}
}'How is this guide?