A Mandate is an AI agent’s spending rulebook. It defines the limits within which the agent can act autonomously — anything outside those limits is denied at the protocol level.
Think of a Mandate as a corporate spending policy that the network enforces, not the agent’s own code.
Three limit types
Every Mandate carries three limit fields:
| Field | Example | What it bounds |
|---|---|---|
| Per-transaction | $50 | Single action’s amount cannot exceed this |
| Daily | $300 | Cumulative spend in a UTC day cannot exceed this |
| Monthly | $5,000 | Cumulative spend in a UTC month cannot exceed this |
Each is independently optional. A mandate with only a monthly limit allows any single transaction up to the monthly cap.
Authorization flow
When an agent wants to perform an action, it calls Authorize first. The mandate decides yes or no.
On success, the agent receives a one-time authorization JWT — a token proving the mandate consented to this specific amount at this specific moment. The jti (JWT ID) is recorded in every subsequent audit event so the on-chain authorization trail is observable.
Why on-chain
The mandate ID, agent binding, and limit values are also written to Solana via the MandateRegistry program. Like AgentID anchoring, this is for tamper-evidence:
- An auditor can confirm the mandate’s limits at the time of any disputed action
- A compromised Regent database cannot retroactively widen limits
- A regulator can verify the mandate existed and was bound to the right agent
Atomic enforcement
Daily and monthly counters use Redis INCRBYFLOAT with rollback on rejection, ensuring no race conditions under concurrent authorization calls. Two simultaneous authorizes that would each fit alone but exceed the limit together are correctly handled — only one succeeds.
Lifecycle
Created
Responsible party creates the mandate. Status starts as pending.
Anchored on Solana
blockchain-worker submits the mandate to MandateRegistry. On confirmation, status flips to active.
Active
The agent can call /authorize against this mandate. Each call returns a JWT or a structured rejection code.
Suspended (automatic)
If the agent is revoked, all its active mandates are immediately suspended via the agent.revoked event consumer.
Revoked (explicit)
Responsible party can revoke a mandate explicitly while keeping the agent active.
Standard rejection codes
| Code | Meaning |
|---|---|
MANDATE_LIMIT_EXCEEDED | Action would exceed per-tx, daily, or monthly limit |
MANDATE_SUSPENDED | Mandate suspended (typically because agent was revoked) |
MANDATE_NOT_FOUND | Mandate ID is unknown |
AGENT_NOT_ACTIVE | Underlying agent is revoked or never reached active |
CURRENCY_MISMATCH | Request currency doesn’t match mandate currency |
The full error format is documented in REST API → Errors.