Assert ground truth about events
Records a batch of ground truth against the entities it judges.
POST /v1/label
| Address | https://api.hanzo.ai/v1/label |
| Method | POST |
| Operation | riskLabel |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Records a batch of ground truth against the entities it judges.
Each assertion carries TWO times — when the judged event happened, and when the assertion became knowable — and both are required. The second is what keeps a chargeback that landed in June out of a model that had to decide in February.
It is idempotent on the CONTENT of an assertion, so a webhook that redelivers is safe. It never overwrites: a source that corrects itself later files a NEW assertion, which wins from the moment it became knowable and leaves every earlier observation instant seeing exactly what it saw.
The asserter is stamped from the validated credential and is not a body field.
Request
9 fields, body application/json (required).
| Field | In | Type | Required | Description |
|---|---|---|---|---|
labels | body | riskLabelFact[] | — | Labels is the batch. Each member is judged on its own: one refusal does not discard the rest, because a webhook redelivering five disputes must not lose four… |
labels[].at | body | string | — | At is when the judged event happened, RFC 3339. |
labels[].confidence | body | number | — | Confidence in [0,1]. A processor chargeback is 1; an analyst's hunch is not. |
labels[].disposition | body | string | — | Disposition is productive, unproductive, or empty for an explicit unjudged — the AML engine's own vocabulary, verbatim. |
labels[].evidence | body | string | — | Evidence points at the record this conclusion came from: a dispute id, a case id, a decision id. |
labels[].kind | body | string | — | Kind is what the subject is: account, agent, merchant, payout, person, session or transaction. |
labels[].seen | body | string | — | Seen is when this assertion became KNOWABLE, RFC 3339. |
labels[].source | body | string | — | Source is who asserted: chargeoff, dispute, case, refund, review or sample. |
labels[].subject | body | string | — | Subject identifies the thing being judged, in the tenant's own namespace. |
Response
| Status | Body | Meaning |
|---|---|---|
200 | riskLabelOut | ok |
200 body — 9 fields.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
duplicate | body | integer | — | Duplicate is how many members this tenant already held, byte for byte. |
mirror | body | string | — | Mirror names why the columnar copy did not take this batch, when it did not. |
pending | body | integer | — | Pending is how many assertions the derived copy is still to take. |
recorded | body | integer | — | Recorded is how many members became a NEW row in the tenant's record. |
refused | body | integer | — | Refused is how many members failed admission and were NOT recorded. |
results | body | riskLabelResult[] | — | Results is per fact, in the order sent, so a caller can retry exactly the members that were refused and can log the content digest of the ones that landed. |
results[].id | body | string | — | ID is the content digest of the assertion — the id a redelivery of the same fact resolves to. |
results[].refusal | body | string | — | Refusal states what was wrong, for the refused. |
results[].status | body | string | — | Status is recorded, duplicate or refused. |
Failure carries the platform error shape — see Errors.
Examples
hanzo has no subcommand for this operation — the CLI serves only what cloud's live route table confirms. Use HTTP or an SDK.
import { Configuration, LabelApi } from 'hanzoai';
const api = new LabelApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.riskLabel({ labels: [{"at":"<at>","confidence":0,"disposition":"<disposition>","evidence":"<evidence>"}] });from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import LabelApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = LabelApi(client).risk_label(labels=[{"at":"<at>","confidence":0,"disposition":"<disposition>","evidence":"<evidence>"}])cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.LabelAPI.RiskLabel(context.Background()).Execute()
if err != nil {
return err
}use hanzo_cloud::apis::{configuration::Configuration, label_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = label_api::risk_label(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.LabelApi;
ApiClient client = new ApiClient();
client.setRequestInterceptor(b -> b.header("Authorization", "Bearer " + System.getenv("HANZO_API_KEY")));
var result = new LabelApi(client).riskLabel();curl -X POST https://api.hanzo.ai/v1/label \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"labels": [
{
"at": "<at>",
"confidence": 0,
"disposition": "<disposition>",
"evidence": "<evidence>"
}
]
}'Tool label, op riskLabel — 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": "label",
"arguments": {
"op": "riskLabel",
"input": {
"labels": [
{
"at": "<at>",
"confidence": 0,
"disposition": "<disposition>",
"evidence": "<evidence>"
}
]
}
}
}
}'How is this guide?