The policy engine is the enforcement core of Mandate. It runs a sequential series of checks — agent status, mandate validity, merchant allowlist, category allowlist, per-transaction limit, and total budget — and returns a machine-readable decision. Two endpoints expose the engine:Documentation Index
Fetch the complete documentation index at: https://docs.usemandate.io/llms.txt
Use this file to discover all available pages before exploring further.
POST /v1/policy/evaluate for full evaluation (which also creates a transaction record), and POST /v1/verify-agent for a read-only pre-flight check.
Policy checks
The engine runs these checks in order. The first failure terminates evaluation and returns the corresponding reason code.| # | Check | Failure reason code |
|---|---|---|
| 1 | Agent exists | agent_revoked |
| 2 | Agent status is "active" | agent_revoked |
| 3 | Mandate exists and belongs to the agent | mandate_expired |
| 4 | Mandate status is "active" | mandate_expired |
| 5 | Mandate expires_at is in the future | mandate_expired |
| 6 | merchant_domain is in allowed_sellers, or allowlist contains "*" | merchant_not_allowed |
| 7 | category is in allowed_categories, or allowlist contains "*", or allowlist is empty | merchant_not_allowed |
| 8 | amount ≤ max_spend_per_transaction | amount_exceeds_per_transaction_limit |
| 9 | spent_total + amount ≤ max_spend_total | total_budget_exceeded |
An empty
allowed_categories array ([]) means no category restriction — all categories are permitted. Pass ["*"] or an explicit list to enforce category-level control.Evaluate policy
pending transaction is created and transitions to approved. If denied, the transaction transitions to denied and the endpoint returns HTTP 402.
The Mandate SDK calls this endpoint automatically as part of the fetchWithPayment() flow. You can also call it directly for custom payment orchestration or to pre-validate a request before generating a proof.
Request body
The agent attempting the payment.
The mandate authorizing this payment.
The domain of the merchant being paid, e.g.
"api.example.com". Checked against the mandate’s allowed_merchants list.The payment amount as a decimal string, e.g.
"0.10". Checked against max_spend_per_transaction and the remaining budget.The currency for this payment. Currently
"USDC" only.The full URL of the resource being purchased, e.g.
"https://api.example.com/data/companies/AAPL". Stored on the resulting transaction record.Optional resource category label, e.g.
"data". Checked against the mandate’s allowed_categories list.200 — approved
"approved" when all policy checks pass."within_policy" when approved.Human-readable explanation.
null when approved.The agent ID from the request.
The mandate ID from the request.
The ID of the transaction record created for this evaluation.
Example response — approved
402 — denied
Example response — denied
reason_code values on denial: agent_revoked, mandate_expired, merchant_not_allowed, amount_exceeds_per_transaction_limit, total_budget_exceeded.
Verify agent
POST /v1/policy/evaluate but does not create a transaction record or charge the mandate. Use this for pre-flight checks — for example, to validate that an agent’s mandate is still active and has sufficient budget before starting a multi-step workflow.
Returns HTTP 200 when the agent is authorized and 403 when denied.
Request body
Same fields as POST /v1/policy/evaluate.
The agent to verify.
The mandate to check authorization against.
The merchant domain to validate against the allowlist.
The intended payment amount as a decimal string.
The currency for the intended payment.
The URL of the resource the agent intends to access.
Optional resource category to check against the mandate’s category allowlist.
200 — authorized
true when the agent exists and is active.true when all policy checks pass.true when the agent is ready to make a payment under this mandate."accept" when authorized, "deny" when not."within_policy" when authorized. One of agent_revoked, mandate_expired, merchant_not_allowed, amount_exceeds_per_transaction_limit, total_budget_exceeded when denied.Example response — authorized
403 — denied
Same structure as the 200 response but with authorized: false, payment_ready: false, recommendation: "deny", and the appropriate reason_code.
Example response — denied

