A mandate is the on-record spending rulebook for one agent. Every payment is authorized against it before execution; an amount outside the rules is rejected and no money moves.
Create a mandate
Requires completed KYC (403 KYC_NOT_VERIFIED otherwise). agent_id must be the
canonical agent_… identifier from registration — a record UUID gets an immediate
422 AGENT_ID_MALFORMED, an agent outside your organization a 404 AGENT_NOT_FOUND.
curl -X POST https://api.regentprotocol.org/v1/organizations/<org>/mandates \
-H "Authorization: Bearer rgnt_..." -H "content-type: application/json" \
-d '{
"agent_id": "agent_688b10bc62aef…",
"owner_id": "<responsible_party_id from registration>",
"currency": "USD",
"limits": {
"per_tx_limit": "50",
"daily_limit": "300",
"monthly_limit": "5000"
}
}'Limit fields
| Field | Meaning |
|---|---|
per_tx_limit | Maximum for a single authorization |
daily_limit / monthly_limit | Rolling usage ceilings (settle adjusts them) |
entity_key + per_entity_limit | Per-entity sub-budget (e.g. entity_key: "customer", at most N per customer/month) — each authorize must then carry entity_id |
relational_cap | Bound the action by a referenced anchor’s amount (e.g. a refund must not exceed the original charge) — authorize must then carry reference + reference_amount |
Optional: expires_at, metadata. settlement_chain is solana (the only live anchor).
The response includes the mandate id, status: active, and a terms_commitment in
metadata — the on-chain anchor gets a commitment to the terms, never the ceilings
themselves.
Authorize a payment
curl -X POST https://api.regentprotocol.org/v1/organizations/<org>/mandates/<mandate_id>/authorize \
-H "Authorization: Bearer rgnt_..." -H "content-type: application/json" \
-d '{"amount": "25", "currency": "USD"}'Optional fields: idempotency_key, entity_id (per-entity budgets), reference +
reference_amount (relational cap), caller_agent_id (when set, must equal the
mandate’s agent — stops one agent spending against another’s mandate; the control
gate always sends it).
Success returns the authorization with a short-lived JWT proof:
{
"id": "de35ead1-…",
"mandate_id": "…",
"agent_id": "agent_688b…",
"amount": "25.000000",
"currency": "USD",
"status": "authorized",
"jwt_token": "…",
"jti": "…",
"guardian_score": 0.12,
"authorized_at": "…"
}A refusal is 402 with detail.code — the full ladder is in the
error reference. The two you must handle: MANDATE_LIMIT_EXCEEDED
(don’t retry the same amount) and MANDATE_SUSPENDED (the kill switch — stop).
Settle
After the real charge lands, reconcile the difference between approved and settled:
POST /v1/organizations/<org>/mandates/<mandate_id>/settle
{"delta": "-3.50"} // settled − approved; negative = came in lower / refundReturns updated daily_used / monthly_used.
Revoke a mandate
POST /v1/organizations/<org>/mandates/<mandate_id>/revokeIndependent of agent revocation: revoking the agent suspends all its mandates; revoking one mandate leaves the agent (and other mandates) alone.