Skip to content
Warrantv0.1

Warrants

Open, read, verify and settle. The whole money surface.

Eight endpoints under /v1/warrants — everything that moves money in Warrant is one of them.

POST   /v1/warrants              open
GET    /v1/warrants              list
GET    /v1/warrants/:id          read
GET    /v1/warrants/:id/trace    the record
POST   /v1/warrants/:id/verify   run the check
POST   /v1/warrants/:id/release  pay in full
POST   /v1/warrants/:id/partial  pay a share
POST   /v1/warrants/:id/refund   return the hold

Amounts are integer strings

Before anything else, because it is the single thing most likely to break a first integration:

"8400000"    8.40 USDC
8400000      rejected — a JSON number
"8.40"       rejected — not the smallest unit

Validated against ^[0-9]+$ and required to be greater than zero.

Open a warrant

POST /v1/warrants — needs the operator role, or any API key. Requires an Idempotency-Key.

FieldTypeRequiredNotes
amountstringyesSmallest unit, ^[0-9]+$, > 0.
assetstringnoDefaults to USDC.
payeestringyes
deadlinestringyesISO 8601, must be in the future.
spec.clausesarrayyesAt least one. See verifiers.
agent_idstringnoWhich agent is spending.
verifier_idstringno
policy_idstringnoDefaults to the resolved policy.

Opening holds the funds. If available balance will not cover the amount you get 402 insufficient_funds and no warrant exists.

POST /v1/warrants HTTP/1.1
Host: api.gowarrant.xyz
Authorization: Bearer wr_test_8f0c1b4e2b1a4d599d0e3a2f7c1b9e44
Idempotency-Key: 0d8f1a1e-6f2c-4c1a-9a3f-2b6e5d4c3b2a
Content-Type: application/json

{
"amount": "8400000",
"asset": "USDC",
"payee": "api.exampledata.io",
"deadline": "2026-08-16T12:00:00.000Z",
"spec": {
  "clauses": [
    { "kind": "http.status", "equals": 200 },
    { "kind": "data.freshness", "maxAgeSeconds": 60 }
  ]
}
}

201

{
"id": "wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK",
"object": "warrant",
"state": "held",
"version": 1,
"amount": "8400000",
"asset": "USDC",
"released_bps": null,
"payee": "api.exampledata.io",
"spec_hash": "b1946ac92492d2347c6235b4d2611184",
"spec": { "clauses": [{ "kind": "http.status", "equals": 200 }, { "kind": "data.freshness", "maxAgeSeconds": 60 }] },
"agent_id": null,
"verifier_id": null,
"policy_id": null,
"policy_version": null,
"deadline": "2026-08-16T12:00:00.000Z",
"opened_at": "2026-08-15T12:00:00.000Z",
"settled_at": null,
"created_at": "2026-08-15T12:00:00.000Z"
}
curl -sS https://api.gowarrant.xyz/v1/warrants \
-H "Authorization: Bearer $WARRANT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
  "amount": "8400000",
  "asset": "USDC",
  "payee": "api.exampledata.io",
  "deadline": "2026-08-16T12:00:00.000Z",
  "spec": {
    "clauses": [
      { "kind": "http.status", "equals": 200 },
      { "kind": "data.freshness", "maxAgeSeconds": 60 }
    ]
  }
}'

Read one

GET /v1/warrants/:id — viewer and up, or any API key.

Another organisation's warrant returns 404, not 403. Answering "forbidden" would confirm the id exists.

GET /v1/warrants/wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK HTTP/1.1
Host: api.gowarrant.xyz
Authorization: Bearer wr_test_8f0c1b4e2b1a4d599d0e3a2f7c1b9e44

200

{
"id": "wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK",
"object": "warrant",
"state": "released",
"version": 3,
"amount": "8400000",
"asset": "USDC",
"released_bps": null,
"payee": "api.exampledata.io",
"spec_hash": "b1946ac92492d2347c6235b4d2611184",
"spec": { "clauses": [{ "kind": "http.status", "equals": 200 }] },
"agent_id": null,
"verifier_id": null,
"policy_id": null,
"policy_version": null,
"deadline": "2026-08-16T12:00:00.000Z",
"opened_at": "2026-08-15T12:00:00.000Z",
"settled_at": "2026-08-15T12:02:11.000Z",
"created_at": "2026-08-15T12:00:00.000Z"
}
curl -sS https://api.gowarrant.xyz/v1/warrants/wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK \
-H "Authorization: Bearer $WARRANT_API_KEY"

List

GET /v1/warrants — see pagination for sort, limit, offset, starting_after and ending_before.

Filters: state (any of the nine lifecycle states) and agent_id.

GET /v1/warrants?state=escalated&limit=2 HTTP/1.1
Host: api.gowarrant.xyz
Authorization: Bearer wr_test_8f0c1b4e2b1a4d599d0e3a2f7c1b9e44

200

{
"object": "list",
"data": [
  {
    "id": "wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK",
    "object": "warrant",
    "state": "escalated",
    "version": 2,
    "amount": "8400000",
    "asset": "USDC",
    "released_bps": null,
    "payee": "api.exampledata.io",
    "spec_hash": "b1946ac92492d2347c6235b4d2611184",
    "spec": { "clauses": [{ "kind": "http.status", "equals": 200 }] },
    "agent_id": null,
    "verifier_id": null,
    "policy_id": null,
    "policy_version": null,
    "deadline": "2026-08-16T12:00:00.000Z",
    "opened_at": "2026-08-15T12:00:00.000Z",
    "settled_at": null,
    "created_at": "2026-08-15T12:00:00.000Z"
  }
],
"has_more": false,
"sort": "deadline",
"next_offset": null,
"next_cursor": null
}
curl -sS "https://api.gowarrant.xyz/v1/warrants?state=escalated&limit=2" \
-H "Authorization: Bearer $WARRANT_API_KEY"

Verify

POST /v1/warrants/:id/verify — runs the spec against a source and lets the policy decide. Requires an Idempotency-Key.

The response is the warrant in whatever state the policy put it in: released, partially_released, escalated or refunded. Verifying is not a request to pay — it is a request to decide, and escalating is one of the answers.

POST /v1/warrants/wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK/verify HTTP/1.1
Host: api.gowarrant.xyz
Authorization: Bearer wr_test_8f0c1b4e2b1a4d599d0e3a2f7c1b9e44
Idempotency-Key: 2f7c1b9e-4d59-4a1a-8b0c-1e6f2c4c1a9a
Content-Type: application/json

{ "source_url": "https://api.exampledata.io/invoices/8812" }

200

{
"id": "wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK",
"object": "warrant",
"state": "escalated",
"version": 2,
"amount": "8400000",
"asset": "USDC",
"released_bps": null,
"payee": "api.exampledata.io",
"spec_hash": "b1946ac92492d2347c6235b4d2611184",
"spec": { "clauses": [{ "kind": "http.status", "equals": 200 }, { "kind": "data.freshness", "maxAgeSeconds": 60 }] },
"agent_id": null,
"verifier_id": null,
"policy_id": null,
"policy_version": null,
"deadline": "2026-08-16T12:00:00.000Z",
"opened_at": "2026-08-15T12:00:00.000Z",
"settled_at": null,
"created_at": "2026-08-15T12:00:00.000Z"
}
curl -sS https://api.gowarrant.xyz/v1/warrants/wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK/verify \
-H "Authorization: Bearer $WARRANT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "source_url": "https://api.exampledata.io/invoices/8812" }'

Settle directly

Three endpoints, each needing an Idempotency-Key:

EndpointBodyEffect
POST /v1/warrants/:id/releasenonePays the payee in full.
POST /v1/warrants/:id/partialreleased_bpsPays that share; the rest returns to available.
POST /v1/warrants/:id/refundnoneReturns the whole hold.

released_bps must be an integer strictly between 0 and 10000.

An API key cannot settle

These need a signed-in person with the operator role. An API key gets 403 user_session_required. If a key could approve a payment, the passkey threshold above which a human must sign would be decorative — anyone holding a key could route around it.

POST /v1/warrants/wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK/partial HTTP/1.1
Host: api.gowarrant.xyz
Cookie: warrant_session=…
Idempotency-Key: 8b0c1e6f-2c4c-4a9a-9d0e-3a2f7c1b9e44
Content-Type: application/json

{ "released_bps": 5000 }

200

{
"id": "wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK",
"object": "warrant",
"state": "partially_released",
"version": 3,
"amount": "8400000",
"asset": "USDC",
"released_bps": 5000,
"payee": "api.exampledata.io",
"spec_hash": "b1946ac92492d2347c6235b4d2611184",
"spec": { "clauses": [{ "kind": "http.status", "equals": 200 }] },
"agent_id": null,
"verifier_id": null,
"policy_id": null,
"policy_version": null,
"deadline": "2026-08-16T12:00:00.000Z",
"opened_at": "2026-08-15T12:00:00.000Z",
"settled_at": "2026-08-15T12:04:03.000Z",
"created_at": "2026-08-15T12:00:00.000Z"
}
curl -sS https://api.gowarrant.xyz/v1/warrants/wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK/partial \
-b "warrant_session=$WARRANT_SESSION" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "released_bps": 5000 }'

amount stays the full figure and released_bps carries the share paid. The paid amount is the product of the two rather than a third stored number, so the two can never disagree.

The trace

GET /v1/warrants/:id/trace returns every recorded transition. See traces for the payload and for the public /t/:id receipt, which needs no account.

GET /v1/warrants/wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK/trace HTTP/1.1
Host: api.gowarrant.xyz
Authorization: Bearer wr_test_8f0c1b4e2b1a4d599d0e3a2f7c1b9e44

200

{
"object": "list",
"data": [
  {
    "to": "held",
    "from": null,
    "actor": { "kind": "agent", "id": "key_01J8Z3M4YQ7K2V9X" },
    "recorded_at": "2026-08-15T12:00:00.000Z",
    "payload_hash": "b1946ac92492d2347c6235b4d2611184",
    "chain_ref": null
  },
  {
    "to": "released",
    "from": "verifying",
    "actor": { "kind": "system", "id": null },
    "recorded_at": "2026-08-15T12:02:11.000Z",
    "payload_hash": "6f2c4c1a9a3f2b6e5d4c3b2a1e6f2c4c",
    "chain_ref": "rialo:testnet#19189427"
  }
]
}
curl -sS https://api.gowarrant.xyz/v1/warrants/wrt_01J8Z3M4YQ7K2V9XABCDEFGHJK/trace \
-H "Authorization: Bearer $WARRANT_API_KEY"

chain_ref is null until the chain confirms. Anchoring runs after the settlement transaction commits, so a settled-but-not-yet-anchored warrant is a normal, temporary state rather than a fault.