Policy
Policy answers one question: how much can each agent spend, on which chains, in which tokens?
It’s structured as a three-level hierarchy, with the platform enforcing the strictest applicable value at sign time.
The hierarchy
Section titled “The hierarchy”tier ceiling ⊇ project default ⊇ per-agent override- Tier ceiling. Hard maximum for your plan. Free is
$5/call, $50/day, Fuji only. Builder is$50/call, $500/day, Avalanche + Fuji. Enterprise is whatever you negotiate. - Project default. A weaker policy you set that applies to new agents you create after the change. Existing agents are not affected.
- Per-agent override. A weaker policy you set for one specific agent. Doesn’t affect any other agent.
The platform silently clamps every value you set to the next-stricter level. You cannot raise a cap above your tier ceiling, and you cannot raise a per-agent override above your project default.
Want to verify what’s actually stored?
client.policy.get()always returns the post-clamp values.
policy.get(agentId?)
Section titled “policy.get(agentId?)”Read the full policy view for the project, optionally including a specific agent’s effective policy.
const view = await client.policy.get();console.log(view.tier); // 'free' | 'builder' | 'enterprise'console.log(view.tierMax); // the hard ceilingconsole.log(view.project.x402Enabled); // whether x402 is onconsole.log(view.project.agentPolicyDefault); // your current project default
// With agentId — also includes that agent's stored policyconst withAgent = await client.policy.get('trading-bot-1');console.log(withAgent.agent?.policy);Returns
Section titled “Returns”{ "projectId": "proj_7f7c8906ce5d1bad", "tier": "builder", "tierMax": { "maxAgents": 20, "perTxCapUSD": 50, "perDayCapUSD": 500, "allowedTokens": ["USDC", "XSGD"], "allowedChains": ["avalanche", "fuji"], "requireMainnetCredit": false }, "project": { "x402Enabled": true, "agentPolicyDefault": { "perTxCapUSD": 10, "perDayCapUSD": 100 } }, "agent": { // only when agentId was passed "agentId": "trading-bot-1", "address": "0xb0e6...dd2b", "displayName": "Arb trading bot", "chain": "avalanche", "status": "active", "tierAtCreate": "builder", "policy": { "perTxCapUSD": 8, // agent-specific override "perDayCapUSD": 100, "allowedTokens": ["USDC", "XSGD"], "allowedChains": ["avalanche", "fuji"] } }}Project-level policy
Section titled “Project-level policy”policy.enableX402() / policy.disableX402()
Section titled “policy.enableX402() / policy.disableX402()”x402 is opt-in per project. Calling enableX402() is required before you can create any agent in the project. Disabling later doesn’t delete existing agents — they continue to work for signing until their validBefore expires, but no new payments can be signed.
await client.policy.enableX402();await client.policy.disableX402(); // emergency stoppolicy.setProjectDefault(policy)
Section titled “policy.setProjectDefault(policy)”Sets the default policy that new agents in the project inherit. Existing agents keep their stored policy unchanged.
await client.policy.setProjectDefault({ perTxCapUSD: 10, // any number ≤ tier ceiling perDayCapUSD: 100, allowedTokens: ['USDC', 'XSGD'], // intersected with tier ceiling (all tiers allow both) allowedChains: ['fuji'], // intersected with tier ceiling});If you try to set a value above the tier ceiling, the platform clamps it. Your request still returns 200; just check the returned values.
Per-agent overrides
Section titled “Per-agent overrides”policy.setAgent(agentId, policy)
Section titled “policy.setAgent(agentId, policy)”Override the policy on one specific agent. Clamped to min(project default, tier ceiling) per field.
await client.policy.setAgent('trading-bot-1', { perTxCapUSD: 8, // tighter than project's 10});Pass any subset of fields — what you don’t pass is left unchanged. To remove an override and fall back to the project default, set the field explicitly to the project default value.
Caps in practice
Section titled “Caps in practice”| Field | What “exceed” looks like |
|---|---|
perTxCapUSD | 403 per_tx_cap_exceeded. No signature is produced. |
perDayCapUSD | 403 per_day_cap_exceeded once today’s running total + the requested value would exceed the cap. Resets at UTC midnight. |
allowedTokens | 403 Token ... not in agent policy. |
allowedChains | 403 Chain ... not in agent policy. |
Daily spend is tracked per agent per UTC day. Each successful sign updates the running total atomically. A failed sign (revert, RPC error) does not consume the day’s quota — the platform rolls back the increment.
Patterns
Section titled “Patterns”Tighten one agent without affecting others
Section titled “Tighten one agent without affecting others”await client.policy.setAgent('intern-bot', { perTxCapUSD: 1, perDayCapUSD: 10,});Set a project-wide default for new agents only
Section titled “Set a project-wide default for new agents only”// Affects only agents created AFTER this callawait client.policy.setProjectDefault({ perTxCapUSD: 5, perDayCapUSD: 50 });Inspect agent caps before signing
Section titled “Inspect agent caps before signing”const view = await client.policy.get('trading-bot-1');const max = view.agent?.policy.perTxCapUSD ?? view.tierMax.perTxCapUSD;console.log(`This agent can spend up to $${max} per call.`);