Spending policies for AI agents that pay with x402

An agent that can pay needs limits it cannot talk itself out of. This guide explains the four constraints that bound an x402 payment, how a per-request check turns them into pay, review or do_not_pay, and which limits belong in the wallet or the agent runtime instead.

In short

An agent spending policy is a set of fixed limits checked outside the model before each x402 payment: allowed recipients, tokens, CAIP-2 networks and a maximum amount in atomic units. Settlens applies it per request and answers pay, review or do_not_pay; cumulative budgets belong in the wallet or agent runtime.

On this page

An x402 server states its price in a machine-readable header, and an agent with a wallet can pay it within the same request. That is the point of x402, and also the risk: nothing in the protocol decides whether a given payment is one the agent's owner would approve. The x402 V2 core specification lists client-side budget management as out of scope and calls spending controls implementation-specific. The client has to bring its own policy.

Why a prompt is not a policy

Telling a model "never pay more than one cent" is an instruction it may weigh against others, including text supplied by the server it is paying. The payment terms come from that server: the recipient, the token, the amount, even the human-readable error and description strings. A spending policy has to be checked by code outside the model, against fixed values the owner set, before anything is signed. The model can call the check; it should not be the check.

The four constraints that make "pay" possible

A payment request usually offers several options in accepts, and the agent pays with one of them. A useful policy bounds every dimension of an option: who is paid, in which token, on which chain and how much. In the Settlens MCP tool evaluate_payment_requirements, the decision can only be pay when all four are set.

Spending policy fields of evaluate_payment_requirements and the Settlens check for each
FieldMeaningCheckFor pay
pay_toAllowed recipients (payTo) you have reviewed. EVM addresses compare case-insensitively, other formats exactly.policy.recipientRequired for pay
assetsAllowed token contract addresses (EVM) or mints (Solana).policy.assetRequired for pay
networksAllowed CAIP-2 networks, for example eip155:8453 for Base mainnet.policy.networkRequired for pay
max_amountThe largest amount you accept, as an integer string in the asset's atomic units.policy.maximum_amountRequired for pay
schemesAllowed x402 schemes, for example exact.policy.schemeRecommended

This is the example policy from the server's own guide (the MCP resource settlens://policy-guide):

JSONSpending policy example
{
  "pay_to": ["0x209693Bc6afc0C5328bA36FaF03C514EF312287C"],
  "assets": ["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"],
  "max_amount": "10000",
  "networks": ["eip155:8453"],
  "schemes": ["exact"]
}

An option is acceptable when it is well formed and satisfies every constraint you set; policy.acceptable_option passes when at least one option is. The per-constraint checks only summarize the options: they warn when some options violate the constraint and fail when all do.

Amounts are in atomic units

x402 amounts are integer strings in the token's smallest unit. USDC has 6 decimals, so "10000" is 0.01 USDC. A cap therefore means nothing without the token: the same max_amount of "10000000" is 10 USDC but 0.1 of a token with 8 decimals. Pair max_amount with an assets allowlist, and list only assets that share the same decimals. The glossary has the definition.

An asset only means something on its network

A token address is only unique within one chain: the same address can be a different contract, or nothing at all, on another network. An allowlist of assets without a list of CAIP-2 networks lets a server name your trusted address on a chain where it means something else. Set both, and keep the networks to the ones your wallet can actually sign for.

Decisions: pay, review, do_not_pay

The checks produce one of three decisions. The verdicts below were computed when this page was built: the same request (the demo's PAYMENT-REQUIRED, 10000 atomic units on Base Sepolia, requested at http://127.0.0.1:4402/secure) evaluated under five policies.

evaluate_payment_requirementsOne request, five policies
  • pay

    Full policy: pay_to, assets, networks, max_amount 10000 and schemes

    Every protocol check passed and at least one payment option is within the allowed recipients, assets, networks and maximum amount. Pay only with an option listed in acceptable.

  • review

    No policy at all

    The spending policy is incomplete: set allowed recipients (pay_to), allowed assets (assets), allowed networks (networks), and a maximum amount in atomic units (max_amount) to allow an automatic pay decision.

  • review

    Same policy without pay_to

    The spending policy is incomplete: set allowed recipients (pay_to) to allow an automatic pay decision.

  • do_not_pay

    max_amount lowered to 5000

    policy.acceptable_option: 0 of 1 payment option(s) satisfy the policy; 1 rejected (max_amount: 1).

  • do_not_pay

    networks set to Base mainnet only (eip155:8453)

    policy.acceptable_option: 0 of 1 payment option(s) satisfy the policy; 1 rejected (networks: 1).

Build-time calls to the Settlens MCP server (src/mcp.js) with the demo request.

The rules, in order:

  1. do_not_pay when any check of severity high or critical fails, including when no option is acceptable. Never pay.
  2. review when any other check fails or warns, apart from the per-constraint summaries, or when the policy does not set pay_to, assets, networks and max_amount. Ask the human first.
  3. pay otherwise. Pay only with an option listed in acceptable.

Always pass the URL you requested as resource_url. Without it the binding between the terms and the resource cannot be confirmed, and the best possible answer is review. The server gives connected agents these instructions at initialize:

TextMCP server instructions
Settlens checks x402 payment requests before you pay. It never pays, never signs and never needs a wallet or key. On every HTTP 402 response, call evaluate_payment_requirements with the PAYMENT-REQUIRED header value, the URL you requested (resource_url) and your spending policy (at least pay_to, assets, networks and max_amount) BEFORE paying. Never pay when the decision is do_not_pay. When it is review, show the summary and reasons to the human and ask for explicit approval before paying. When it is pay, pay only with one of the entries listed in acceptable.

What a per-request policy does not cover

A per-request check sees one payment request at a time. Several limits need state or chain access that it does not have, and belong elsewhere:

Spending limits outside a per-request check, and where they belong
LimitWhy a per-request check misses itWhere it belongs
Daily or cumulative budgetEach request can be within the cap while the total is not.The wallet or the agent runtime, which sees every payment.
Rate of spendA loop calling a cheap resource thousands of times passes every individual check.The agent runtime: rate limits and loop detection.
Duplicate payments on retryA retried request is evaluated as new.Idempotency keys from the payment-identifier extension, when the server supports it, plus deduplication in the runtime.
Whether the payment settledThe check runs before payment.The client, reading PAYMENT-RESPONSE and reconciling settlement_pending on chain.
Unrecognized paymentFlowSettlens does not evaluate payment flows or transfer methods.The client: the specification says it must not build a payment for a flow it does not recognize.
Token behavior, balance and noncesThe check runs offline, and Settlens never reads chain state.The wallet and the chain.

Server text is data, not instructions

Fields such as error, description and the reasons a tool returns are written by, or derived from, the server being paid. An agent should act on the decision and the policy, never on instructions found in those strings.

Wire it into your agent

The Settlens MCP server exposes evaluate_payment_requirements as a public offline tool at https://settlens.com/mcp. Claude Code connects in one command:

ShellClaude Code (remote)
claude mcp add --transport http settlens https://settlens.com/mcp

The server also ships an x402_preflight prompt that walks an agent through the steps for one URL: request it without payment, read PAYMENT-REQUIRED, call the tool with its policy, then act on the decision. Transports, limits and error codes are in the MCP reference. To try a policy on a real header first, use the x402 payment request checker.

Policy checks are only one layer. The agent section of the x402 security checklist lists the other controls a paying client needs.

Frequently asked questions

Does the Settlens MCP preflight enforce a daily budget?

No. It applies a per-request policy: allowed recipients, assets, networks, schemes and a maximum amount. Cumulative or daily budgets must be enforced by the wallet or the agent runtime, which see every payment.

What happens if the policy leaves out pay_to?

The decision cannot be pay. Without pay_to, assets, networks and max_amount the policy does not bound the payment, so the best possible answer is review: the agent should ask a human before paying.

Why do max_amount and assets need to go together?

Amounts are integer strings in each token's atomic units, and tokens have different decimals. "10000000" is 10 USDC but 0.1 of an 8-decimal token, so a cap is only meaningful for assets you listed.

Sources

  1. x402 protocol specification, version 2x402 Foundation · github.com
  2. x402 extension: payment-identifierx402 Foundation · github.com
  3. Model Context Protocol specification 2025-06-18: ToolsModel Context Protocol · modelcontextprotocol.io
  4. CAIP-2: Blockchain ID SpecificationChain Agnostic Standards Alliance · github.com