What you will build
An AI agent that settles payments in USDC on Base, automatically, whenever something it calls asks to be paid. No card, no checkout, no human approving each charge. The agent calls a paid endpoint, the endpoint answers 402 Payment Required, and the x402 client pays in USDC and retries. This works the same whether your agent is a LangChain tool, a background worker, or a plain script, because the payment lives in a fetch wrapper, not in any framework.
This page is the framework-agnostic core. If your agent already has a wallet, you are ready; if not, start with how-to-add-wallet-to-my-agent. The payment API product page is the broader reference.
Prerequisites
- A Blockchain0x account with one agent created, so you have a wallet.
- A
sk_test_API key for this walkthrough. - Node 18 or newer. The SDK targets
>=18.
export B0X_API_KEY=sk_test_... # sk_test_ -> Base Sepolia, sk_live_ -> Base mainnetWire the x402 client
Two packages, one wrapper. Build the client, get a fetch that pays.
import { createClient } from "@blockchain0x/node";
import { createX402Client } from "@blockchain0x/x402/client";
const sdk = createClient({ apiKey: process.env.B0X_API_KEY! });
const fetchWithPay = createX402Client({ sdk });
// Use fetchWithPay exactly where you use fetch.
const res = await fetchWithPay("https://api.example.com/paid-endpoint");
const data = await res.text();That is the whole integration. fetchWithPay behaves like fetch on any request that does not need payment, and on a 402 it does the work for you. There is no separate "pay" call to make and no payment state for your agent to track.
What happens on a 402
It helps to know exactly what the client does, because it is the part people imagine is complicated and is not.
- Your agent calls
fetchWithPay(url). The upstream returns402 Payment Requiredwith a requirement body: theexact-usdcscheme, the network, thepayToAddress, andamountWeiUsdc. - The client reads that requirement and settles the payment in USDC from the agent's wallet on Base.
- The client builds an
X-Payment: exact-usdc:<base64>header carrying the proof and re-issues the same request. - The upstream verifies the header and returns
200with the real response.
Your code awaited one call and got one response. The 402, the settlement, and the retry happened inside fetchWithPay. One number worth internalizing: USDC has 6 decimals, so the amountWeiUsdc on the wire is an integer base unit. A half-cent call quotes 5000, and a one-dollar call quotes 1000000. You never do that conversion yourself, but seeing 5000 in a log and knowing it is half a cent saves confusion later.
Why per-call USDC works
It is worth being concrete about why this rail exists, because it shapes how you price and budget. An agent is not a human checking out once a week. It is a process that may call a paid API hundreds of times an hour, each call worth a fraction of a cent to a few cents. That traffic shape breaks the tools built for people.
A card network charges a fixed fee plus a percentage on every authorization, so a half-cent charge costs far more in fees than the charge itself. You cannot run agent traffic on cards without batching, and batching means credit, reconciliation, and a billing relationship that the agent has no way to establish on its own. A subscription avoids per-charge fees but forces you to guess monthly usage for a workload that is bursty and unpredictable, and it still needs a signup the agent cannot perform.
USDC on Base settles a half-cent payment for a fraction of a cent, with no prior relationship between payer and payee. The agent pays exactly for what it uses, when it uses it, and the payee gets paid at call time rather than after a sales cycle. That is the whole reason per-call stablecoin settlement is the default for agent payments rather than an exotic choice: it is the only model whose unit economics match how agents actually behave.
Fund the wallet with USDC
The agent can only pay what its wallet holds. On sk_test_ the wallet is on Base Sepolia, so send it test USDC from a public Base Sepolia faucet. Copy the wallet address from the dashboard or the agent's public profile at wallet.blockchain0x.com/a/{slug}.
Fund a few dollars first. That covers hundreds of typical sub-cent calls, which is plenty to confirm the loop end to end before you trust it with a real balance. If a paid call later comes back as a non-2xx for insufficient funds, check the wallet balance first rather than assuming the upstream is broken.
Cap what the agent can spend
An autonomous wallet needs a ceiling, and the ceiling has to live somewhere the agent cannot rewrite. You set the spend limit in the dashboard, the wallet enforces it before any payment, and you read it back over the API to confirm:
const res = await fetch(
`https://api.blockchain0x.com/v1/agents/${agentId}/spend-permissions`,
{ headers: { Authorization: `Bearer ${process.env.B0X_API_KEY!}` } },
);
const permissions = await res.json();
// allowance_wei (per period), per_tx_wei (per payment),
// period_seconds (86400 daily / 604800 weekly / 2592000 monthly)A payment that would break the per-transaction cap or exhaust the period allowance is refused before any USDC moves, and your paid call returns a non-2xx you can handle. The full treatment is in how-to-set-up-agent-spending-limits. Set a tight per-transaction cap early; it is your structural protection against a single runaway payment.
Move to mainnet
When the loop works on testnet, going live is a key swap, not a code change. Replace the sk_test_ key with a sk_live_ one and the same code settles on Base mainnet (eip155:8453) instead of Base Sepolia (eip155:84532). The SDK reads the network from the key prefix, so nothing else moves.
Fund the mainnet wallet from your own treasury rather than a faucet, and re-check the spend limit on the live agent, because limits are per agent and your mainnet agent is a different agent from your test one. Confirm the prefix at boot so a test key never runs in production; the server rejects a mismatch with apikey.network_mismatch, but catching it yourself is cleaner.
Common pitfalls
Three traps worth knowing before you ship.
Writing your own 402 handling on top of the client. The client already does the 402, settle, and retry. If you add your own branch that re-pays on a 402, you pay twice for one call. Await the final response and trust the wrapper.
Confusing dollars and base units. Reading 5000 and thinking it is five thousand dollars instead of half a cent leads to wrong alerts and wrong dashboards. Convert base units to decimals at the edge of your logging, and label them.
Shipping without a spend limit. A funded wallet with no cap is the one mistake that can cost real money. Set the limit before the live key, not after the first surprise bill.
What to ship today
Wire fetchWithPay, fund the test wallet with a few dollars, and watch one paid call settle in USDC. That is a paying agent. Then set a spend limit and swap to a sk_live_ key. Production pricing is on the pricing page; the Free tier covers this walkthrough.