Policies
One read-back endpoint, session-only. There is no policy CRUD API.
GET /v1/console/policies lists every policy version an organisation has. Writing a policy is a console action, not an API call.
GET /v1/console/policies
Cookie: warrant_session=…No create, update or delete
There is no POST /v1/policies and no PATCH. Policies are written in the
console at console.gowarrant.xyz/policies. The endpoint below requires a
signed-in person with at least viewer; an API key gets 403
user_session_required.
What a policy contains
See concepts: policies for how bands are evaluated and why reason codes override the score. In brief:
| Field | Type | Notes |
|---|---|---|
bands | array | At least one, and one must have minScore: 0. |
bands[].minScore | number | 0 to 1 inclusive. |
bands[].outcome | string | release, partial_release, escalate, refund. |
bands[].releasedBps | int | Required on partial_release, strictly 0–10000. |
maxAmount | string | Optional. Smallest unit, ^[0-9]+$. |
alwaysEscalate | string[] | Reason codes that escalate whatever the score. |
alwaysRefund | string[] | Reason codes that refund whatever the score. |
minScore is a fraction here, 0 to 1, because it is compared against the
engine's score. releasedBps is basis points, 0 to 10000, because it is a
share of an amount. Two scales in one object, and the field names are the only
thing telling them apart.
Validation happens at write time
A policy that cannot be applied is rejected when it is saved, not when a warrant settles:
code | Cause |
|---|---|
policy_no_bands | The bands array is empty or missing. |
policy_no_floor_band | No band reaches down to minScore: 0. |
policy_band_out_of_range | A minScore outside 0–1. |
policy_band_bps_required | A partial_release band without valid releasedBps. |
policy_no_floor_band is the one worth understanding. Without a band at zero, a
low score matches nothing, and a policy that can decline to decide would leave
funds held indefinitely.
Read them back
Versions are returned newest-first within each name. A policy row is never
edited in place — new rules create a new version, and a warrant pins the
version it ran under.
GET /v1/console/policies HTTP/1.1
Host: api.gowarrant.xyz
Cookie: warrant_session=…200
{
"object": "list",
"data": [
{
"id": "pol_01J8Z3M4YQ7K2V9XABCDEFGHJK",
"agent_id": "agt_01J8Z3M4YQ7K2V9XABCDEFGHJK",
"name": "strict",
"version": 2,
"rules": {
"bands": [
{ "minScore": 1, "outcome": "release", "label": "clean pass" },
{ "minScore": 0.8, "outcome": "partial_release", "releasedBps": 5000 },
{ "minScore": 0, "outcome": "escalate", "label": "anything else" }
],
"maxAmount": "50000000",
"alwaysRefund": ["source_not_found"]
},
"rules_hash": "b1946ac92492d2347c6235b4d2611184",
"created_at": "2026-08-10T09:14:22.000Z"
}
]
}curl -sS https://api.gowarrant.xyz/v1/console/policies \
-b "warrant_session=$WARRANT_SESSION"agent_id is null on the organisation default. Resolution order when a warrant
opens is: the agent's own newest version, then the org default, then the
built-in default, which pays only on a clean pass.
rules_hash is a SHA-256 of the rules object and is recorded on the
trace, so a settlement from months ago can be re-read
against the exact rules that produced it.
Amounts
maxAmount follows the wire convention: an integer string of the asset's
smallest unit, matching ^[0-9]+$.
"50000000" 50.00 USDC
50000000 rejected — a JSON number
"50.00" rejected — not the smallest unit