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, and the mandate decides yes or no. Regent confirms the agent is active and the mandate is active, then evaluates the requested amount against the per-transaction, daily, and monthly limits.
- Within limits → the agent receives a one-time authorization JWT — a token proving the mandate consented to this specific amount at this moment.
- Over a limit → a structured rejection (
MANDATE_LIMIT_EXCEEDED), with no token issued.
The jti (JWT ID) is recorded in every subsequent audit event so the authorization trail is observable end-to-end.
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
Concurrency-safe enforcement
Spend counters are enforced atomically, server-side, so concurrent authorize calls cannot race past a limit. Two simultaneous authorizations that would each fit alone but exceed the cap together are handled correctly — 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.