Teach your organisation's own model from its own events
Learn records a batch of events into the caller organisation's own aggregates and lets its model learn from them. It answers how many it learned from.
POST /v1/risk/learn
| Address | https://api.hanzo.ai/v1/risk/learn |
| Method | POST |
| Operation | riskLearn |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Learn records a batch of events into the caller organisation's own aggregates and lets its model learn from them. It answers how many it learned from.
IT DOES NOT SCORE, AND THAT IS THE POINT. An observation is a value you record; learning is a transformation over observations; a verdict is a query against the result. This op is the first two. [ops.score] is the third, it is pure, and it is the ONE door to a verdict. They were one call, which meant you could not record without training and could not train without being answered — and the model ran twice over every event to produce a verdict the response carried and no caller read.
TO OBSERVE AND JUDGE, COMPOSE THE TWO, and mind the order. Score FIRST, then learn: the score is then the model's opinion of an event it has not yet learned from, which is the question worth asking. The other order answers for a model that has already absorbed the event it is judging.
This is the training path, and there is no job behind it: the model IS a set of mass counters over half-space trees, so learning is an increment and the model is current the instant the last event lands. Nothing from any other organisation is in it, and nothing from this organisation leaves it.
A RETRY IS INERT. The record deduplicates on the event id you send, and an event already in it moves nothing, costs nothing and is not counted — so a client that timed out can send the same batch again and its model holds what it holds. Without an id of your own there is nothing to converge on: two identical bodies are two events.
Request
8 fields, body application/json (required).
| Field | In | Type | Required | Description |
|---|---|---|---|---|
events | body | riskEvent[] | — | Events are the things that happened, oldest first. |
events[].at | body | string | — | At is when it happened, RFC 3339. Empty means now. |
events[].device | body | string | — | Device is the device fingerprint, if any. |
events[].id | body | string | — | ID is the caller's own stable identifier for the event. |
events[].kind | body | string | — | Kind is whose behaviour this is: person, session or account. |
events[].nano | body | integer | — | Nano is the value moved, in nano-USD. Omit it for an event that moves no money: the value features then read BLIND rather than being told the amount was zero,… |
events[].peer | body | string | — | Peer is the counterparty, if any. |
events[].subject | body | string | — | Subject is the identifier on that kind. |
Response
| Status | Body | Meaning |
|---|---|---|
200 | riskLearnOut | ok |
200 body — 1 field.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
learned | body | integer | — | Learned is how many of the events the model actually learned from, and is also what the call is metered at: one screen per event learned from. |
Failure carries the platform error shape — see Errors.
Examples
hanzo risk learnimport { Configuration, RiskApi } from 'hanzoai';
const api = new RiskApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.riskLearn({ events: [{"at":"<at>","device":"<device>","id":"<id>","kind":"<kind>"}] });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_learn(events=[{"at":"<at>","device":"<device>","id":"<id>","kind":"<kind>"}])cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.RiskAPI.RiskLearn(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_learn(&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).riskLearn();curl -X POST https://api.hanzo.ai/v1/risk/learn \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"at": "<at>",
"device": "<device>",
"id": "<id>",
"kind": "<kind>"
}
]
}'Tool risk, op riskLearn — 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": "riskLearn",
"input": {
"events": [
{
"at": "<at>",
"device": "<device>",
"id": "<id>",
"kind": "<kind>"
}
]
}
}
}
}'How is this guide?