Scenarios /

Pay up to a maximum: /t/upto

EndpointGET https://x402testendpoint.com/t/upto
Kindpay: a correct buyer completes the payment
Payment schemeupto
Quoted priceup to 0.05, charged 0.01 dollars, in test USDC
NetworksBase Sepolia (testnet) (default)
Cost to youNothing. Test USDC has no value.

What the seller does

Quotes the "upto" scheme: the buyer authorises up to $0.05 and the seller settles only the $0.01 actually used.

What a correct buyer does

Authorise the maximum with the upto scheme, receive 200, and confirm the settled amount is the smaller one.

Why test this

Usage-based sellers such as model APIs do not know the final cost up front. The upto scheme lets a buyer cap the charge and the seller settle less. A client needs the upto scheme registered and a one-time Permit2 approval for the token, and should check what was actually settled.

Run it

See the quote without paying:

curl -i https://x402testendpoint.com/t/upto

Then point your own client at it, or use the official one:

import { x402Client, x402HTTPClient } from "@x402/core/client";
import { UptoEvmScheme } from "@x402/evm/upto/client";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.BUYER_KEY);
const core = new x402Client().register("eip155:84532", new UptoEvmScheme(account));
const http = new x402HTTPClient(core);

const first = await fetch("https://x402testendpoint.com/t/upto");
const quote = http.getPaymentRequiredResponse((h) => first.headers.get(h));
const headers = http.encodePaymentSignatureHeader(await core.createPaymentPayload(quote));
const paid = await fetch(first.url, { headers });
console.log(paid.status, paid.headers.get("x-test-verdict"));

The wallet needs test USDC on Base Sepolia (testnet) for scenarios that settle. Circle's faucet at https://faucet.circle.com provides it.

The upto scheme moves funds through Permit2, so the wallet must first approve the Permit2 contract to spend its USDC. That is a one-time on-chain transaction needing a little test ETH for gas; createPermit2ApprovalTx from @x402/evm/upto/client builds it.

What you will see

A correct client ends with HTTP 200, a PAYMENT-RESPONSE header carrying the settlement, and x-test-verdict: pass. The JSON body repeats the transaction hash and payer.

If the payment is rejected, the endpoint answers 402 again with the facilitator's reason in the quote's error field. Look the reason up in the error reference.

How the official client behaves

@x402/core 2.31 with default settings: Needs UptoEvmScheme from @x402/evm/upto/client registered for the network. It signs a Permit2 authorisation for the maximum. A wallet that has not approved Permit2, or holds too little, is rejected with a permit2_ error such as permit2_insufficient_balance.

Related errors

Other scenarios