# Constrain spend. Export evidence.

AP2 mandates set cryptographic spend budgets for each agent. Policies apply routing rules across the account. Every decision produces a deny code or an evidence bundle.

[Create mandate](/content/dashboard/mandates/index.html) [Mandate reference](/content/docs/mandates/index.html)

## Agent spending authority

A mandate is a user-signed authorization granting an agent permission to spend on their behalf — within defined constraints. Budget, categories, and expiry are cryptographically enforced.

`max_amount_usd`

Hard spending ceiling. Exceeded → MANDATE_BUDGET_EXCEEDED.

`allowed_categories`

Whitelist of spend categories. Others → MANDATE_CATEGORY_DENIED.

`valid_until`

ISO 8601 expiry. Past → MANDATE_EXPIRED immediately.

`agent_did`

The specific agent DID this mandate grants. Non-matching agent → MANDATE_NOT_FOUND.

## Create mandate

```
curl -X POST https://p402.io/api/a2a/mandates \
  -H "Authorization: Bearer $P402_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{\n    "type": "payment",\n    "user_did": "did:key:z6Mk...",\n    "agent_did": "did:p402:agent_01...",\n    "constraints": {\n      "max_amount_usd": 50.00,\n      "allowed_categories": [\
        "llm-inference",\
        "data-retrieval"\
      ],\n      "valid_until": "2025-02-01T00:00:00Z"\n    }\n  }'
```

### Response:
{
  "id": "mnd_01HX...",
  "status": "active",
  "amount_spent_usd": 0,
  "constraints": { ... }
}

## Create policy

```
curl -X POST https://p402.io/api/v2/governance/policies \
  -H "Authorization: Bearer $P402_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{\n    "name": "Production limits",\n    "max_spend_usd": 500,\n    "allowed_models": [\
      "gemini-2.0-flash",\
      "gpt-4o-mini",\
      "deepseek-v3"\
    ],\n    "enforce": true\n  }'
```

## Policies

### Account-level routing rules

Policies apply to all routing decisions in the account. They run before mandate checks — if a policy denies a request, the mandate is never evaluated.

#### Evaluation order

1. Policy spend limit check
2. Policy allowed_models check
3. Mandate budget check
4. Mandate category check
5. Mandate signature check
6. Route to provider

### Deny codes

## Full deny code list

`MANDATE_NOT_FOUND` Mandate ID does not exist in this account.

`MANDATE_INACTIVE` Mandate status is exhausted, expired, or revoked.

`MANDATE_EXPIRED` valid_until timestamp has passed.

`MANDATE_BUDGET_EXCEEDED` amount_spent_usd + requested > max_amount_usd.

`MANDATE_CATEGORY_DENIED` Requested category not in allowed_categories.

`MANDATE_SIGNATURE_INVALID` Mandate signature does not match public_key.

`POLICY_SPEND_LIMIT` Request would exceed policy max_spend_usd.

`POLICY_MODEL_DENIED` Requested model not in policy allowed_models.

All deny responses include a `requestId`. Denied requests are visible in the Audit log with the reason code attached.

## Integration audit

### Evidence for risk review

Run an integration audit from the dashboard or API. The audit checks your x402 implementation against known failure patterns and exports a signed evidence bundle for compliance review.

### Integration correctness checks

- Security rule validation
- Mandate and policy consistency
- Export as JSON evidence bundle
- Findings table with severity rubric

[Run audit](/content/dashboard/audit/index.html) [Trust Center](/content/trust/index.html)

### Evidence bundle fields

`requestId`

`tenantId`

`payer + payTo`

`asset + amount + chainId`

`txHash`

`receiptId, mandateId, policyId`

`denyCode (if rejected)`

`timestamps per event`

`trace events summary`

`audit findings summary`
