Skip to content

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.

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.

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 ceiling
console.log(view.project.x402Enabled); // whether x402 is on
console.log(view.project.agentPolicyDefault); // your current project default
// With agentId — also includes that agent's stored policy
const withAgent = await client.policy.get('trading-bot-1');
console.log(withAgent.agent?.policy);
{
"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"]
}
}
}

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 stop

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.

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.

FieldWhat “exceed” looks like
perTxCapUSD403 per_tx_cap_exceeded. No signature is produced.
perDayCapUSD403 per_day_cap_exceeded once today’s running total + the requested value would exceed the cap. Resets at UTC midnight.
allowedTokens403 Token ... not in agent policy.
allowedChains403 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.

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 call
await client.policy.setProjectDefault({ perTxCapUSD: 5, perDayCapUSD: 50 });
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.`);
  • Agents — create wallets that inherit project defaults.
  • Payments — what happens when caps are hit.
  • Errors — full code list including per_tx_cap_exceeded, per_day_cap_exceeded.