Every price, cap, and version below was checked against a live endpoint, a shipped package, or a first-party doc on 2026-09-02. Where a vendor documents nothing, the table says so.
Look before you pay
Start with a free call. A well-built x402 service tells you what it sells before it asks for money:
curl -sS https://penny402.fun/penny | jq '.attractions[] | {id, path, price}'
Then read the price without paying it. An unpaid request to a paid route
returns 402 with the terms in the body:
curl -sS -X POST https://penny402.fun/oracle \
-H 'content-type: application/json' -d '{}' | jq '.accepts[0]'
{
"scheme": "exact",
"network": "base",
"maxAmountRequired": "2500",
"resource": "https://penny402.fun/oracle",
"payTo": "0x9d0bb5dA24cADe855DeE8d1231A1c416e0bB2FFe",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"maxTimeoutSeconds": 60,
"extra": { "name": "USD Coin", "version": "2" }
}
maxAmountRequired is in atomic units. USDC has 6 decimals, so 2500 is
$0.0025 — a quarter of a penny. Read that number yourself before you let
anything sign for it.
Disclosure: penny402 is our own service. It is used here because we control it, know what it charges, and can point you at the settlement. Every technique on this page works against any x402 endpoint.
Who this is for
You run an agent — Claude Code, Cursor, Codex, a script you wrote — and you want it paying for things on its own. Not many things. Five dollars of things, on Base, in USDC, under a cap you chose. You don’t need to understand blockchains; you need about five details right, and this page is those five.
Four routes, compared
| Route | Steps | Custody | Minimum | Fees | Spend control | Best when |
|---|---|---|---|---|---|---|
| AgentCash credit | npx agentcash@latest onboard | Yours. Keys at ~/.agentcash/, mode 600; their docs say it plainly — “Private keys are stored in plaintext on disk” | “There is no minimum balance requirement.” Onboarding pays a socially-scored bonus of up to $25 in USDC on Base — a claim code, not a flat grant | No take rate or markup published anywhere in their docs; no pricing page exists (checked 2026-09-02) | One documented cap: --max-amount <usd> on agentcash fetch, per call | You want to be paying for something in five minutes, and a plaintext key file on your laptop is an acceptable risk for $5 |
Own CDP server wallet + @x402/fetch | API key → new CdpX402Client() → fund the address → wrap fetch | Coinbase holds the signing key; the account and the money are yours | Whatever you send | Coinbase charges “a fee based on our estimate of the prevailing network fees” on on-chain sends, “disclosed at the time of the transaction” (fee disclosures) — read it off Preview Send. No per-call fee after that | spendControls in the SDK: per-payment cap, cumulative cap, time window, network allowlist | Recommended. You want the wallet, the caps, and the receipts to be yours, and no key file on disk |
| Poncho | Sign up, then opt into Advanced | Free/Pro hold nothing for you — those wallets are “an implementation detail”. The paid Advanced wallet is “user-controlled wallet infrastructure” via Privy or another provider; Merit “does not take custody” (Terms §4, 2026-06-09) | Not documented publicly (checked 2026-09-02) — the word minimum appears nowhere in their terms | Free tier; Pro $20/mo; Team $20/seat/mo. Premium tools are usage-billed through AgentCash, and “every premium tool quotes its price before it runs” | Optional per-member spend limits, Team tier only. No per-call or per-day cap documented; the pre-run quote and your confirmation are the actual guard | You want a marketplace of pre-integrated tools rather than raw endpoints |
| Coinbase account → your own key | Buy $5 USDC, withdraw on Base to a key you generated | Entirely you, including the failure modes | Not documented publicly for the retail app (checked 2026-09-02). Coinbase Exchange — a different product — publishes 0.01 USDC on Base through its currencies API | Same estimated network fee, disclosed on the same preview screen | Only what you code | You already run a wallet and want no third party in the middle |
Spend controls are the least documented part of this market — AgentCash’s marketing page advertises per-call, per-task, and total ceilings its own reference docs never define. Treat any cap you haven’t found in an API reference as absent. Rows 2 and 4 share the same funding step: the table is about who holds the money, and the mechanics below are the same either way.
The recommended path, end to end
1. Get CDP credentials. Create an API key at https://portal.cdp.coinbase.com/access/api, and create a Wallet Secret in the same portal. Three values go in your environment:
export CDP_API_KEY_ID="..."
export CDP_API_KEY_SECRET="..."
export CDP_WALLET_SECRET="..."
2. Install and provision the wallet. The x402 packages are optional peer dependencies of the CDP SDK — install them explicitly:
npm install @coinbase/cdp-sdk @x402/core @x402/evm @x402/fetch
import { CdpX402Client } from '@coinbase/cdp-sdk/x402';
// Pass { environment: "development" } to use Base testnet instead.
const client = new CdpX402Client();
const { evmAddress } = await client.getAddresses();
console.log('Fund this address:', evmAddress);
getAddresses() provisions the wallet eagerly — a CDP Server Wallet
named x402-client-wallet-1 — rather than waiting for the first payment,
which is what you want when the next step is sending it money. The
default is Base mainnet: real money.
3. Send it $5 of USDC on Base. In the Coinbase app: buy $5 of
USDC, choose Send, paste the evmAddress above, and — the step that
matters — set the network dropdown to Base, not Ethereum, not
Solana. Confirm the asset reads USDC, not USDbC.
Use Preview Send and read the fee there. Coinbase charges an estimated network fee on on-chain sends, disclosed at transaction time; no first-party page documents a Base-specific fee, a retail minimum, or a settlement time. The “free USDC sends on Base” quoted around the web belong to Coinbase Wallet or Coinbase International Exchange, not the retail app. Believe the confirmation screen, not a figure quoted elsewhere — this page included.
4. Confirm it arrived. Do not trust the app; read the chain at
https://base.blockscout.com/address/<your address>. You want a USDC
token balance on that page. If it is empty, the money is somewhere else —
read the next section before sending more.
5. Wrap fetch and pay.
import { wrapFetchWithPayment } from '@x402/fetch';
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
Five ways to lose the $5
| Mistake | What happens | The one-line check |
|---|---|---|
| Wrong chain | You pick Ethereum or Solana in the withdraw dropdown. The USDC exists, at your address, on a chain your x402 client is not registered for | Before confirming, the network dropdown must read Base |
| USDbC instead of native USDC | Bridged USDC on Base (USDbC, 0xd9aAEc86…) is a different contract from native USDC (0x833589fC…). @x402/[email protected] ships exactly one default asset for eip155:8453, and spend controls reject anything else unless you opt in via allowedAssets. Circle’s own warning is blunter: do not send bridged USDbC to a Circle Mint account, “as it may not be recoverable and could result in a loss of funds” | The token on your Blockscout page must read USDC at 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 — the same address the 402 names |
| Buying ETH “for gas” | Probably wasted. On the exact/EIP-3009 path the x402 spec says the facilitator pays the gas and “cannot modify the amount or destination”; your wallet only signs. penny402’s payTo address holds a 0 ETH balance and has been paid many times. (x402’s FAQ has one line advising ETH for gas on mainnet; in context it is ambiguous whose wallet it means. A few cents of ETH costs nothing if you want the hedge) | Fund with USDC first, pay once, and only add ETH if that call actually fails |
| Key in the wrong place | A wallet secret in a repo, a chat message, a CI log, or a .env you later commit | CDP_WALLET_SECRET lives in your shell or an ignored .env, never in an argument, never pasted to a service |
| Paying a spoofed resource URL | A 402 envelope names its own resource and payTo. A hostile or proxied response can name a URL you never called | Assert accepts[i].resource equals the URL you requested before signing — and log the payTo you paid |
Spend control
Two caps, both from the shipped SDK, both worth setting before the first
call. Verified against @coinbase/[email protected]:
import { CdpX402Client, SpendControlError } from '@coinbase/cdp-sdk/x402';
const USDC_BASE = '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913';
const client = new CdpX402Client({
spendControls: {
maxAmountPerPayment: { atomic: 10_000n, asset: USDC_BASE }, // $0.01
maxCumulativeSpend: { atomic: 50_000n, asset: USDC_BASE }, // $0.05
maxCumulativeSpendWindow: '24h',
allowedNetworks: ['eip155:8453'],
},
});
A blocked payment throws SpendControlError with a machine-readable
code. Two honest caveats: the cumulative ledger’s default store is
in-memory, so a per-day cap does not survive a process restart unless
you pass a persistent store; and these are client-side caps, so they
bound what this client signs, not what the key could sign elsewhere.
Without the CDP client, the equivalent lives in @x402/core’s
x402ClientConfig.spendControls, where maxAmountPerPayment is a
dollar string rather than atomic units:
const client = x402Client.fromConfig({
schemes: [{ network: 'eip155:*', client: new ExactEvmScheme(signer) }],
spendControls: { maxAmountPerPayment: '$0.01' },
});
It defaults to "$1" per payment, and only assets the library recognizes
as USD-pegged defaults are allowed — which is why USDbC pays for nothing.
Watch the version. The older [email protected] had a different shape:
maxValue as a positional bigint, defaulting to 100000n ($0.10).
If a tutorial hands you maxValue, it is a v1 tutorial — and v1 is
“deprecated and will only receive security patches”.
The cap that actually holds is the balance. Keep the agent’s wallet at $5. A cap you wrote in code is a bug away from wrong; a wallet with $5 in it cannot spend $50.
The worked example
One real purchase, $0.0025, USDC on Base:
const res = await fetchWithPayment('https://penny402.fun/oracle', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ question: 'should I ship it?' }),
});
console.log(await res.json());
The response body’s shape, as the endpoint’s own 402 advertises it:
{
"fortune": "A short oblique line, drawn for your address and this date.",
"question": "should I ship it?",
"date": "2026-09-02",
"payer": "0x0000000000000000000000000000000000000000",
"mechanic": "the oracle answers the day, not the question — yet"
}
payer is your wallet. The reading is keyed to it and stable until
midnight UTC, so the same wallet asking twice today gets the same line —
itself a check that you paid as who you think you are.
Now read your own settlement at
https://base.blockscout.com/address/<your address>, newest ERC-20
transfer out: a USDC transfer of 2500 to
0x9d0bb5dA24cADe855DeE8d1231A1c416e0bB2FFe. Click through to
https://base.blockscout.com/tx/<hash>. That link is the thing worth
keeping — a receipt nobody has to take your word for.
For the whole exchange written out step by step — the unpaid request, the challenge, the authorization, the facilitator’s verify and settle, and the receipt on chain, on Base and on Solana — see Step 4: A settled round trip on both rails.
If that call had timed out and your agent had retried it, whether the same authorization bought a second answer or was refused as already spent is the seller’s design, not yours — Step 6: The idempotency receipt is the pattern that gets it right in both directions.
What to buy next
Honest prices, all ours, all disclosed as ours — and if you sell over x402 yourself, Step 2 is how to keep your own drills out of your revenue numbers:
- lemon-toolshed — file and
format conversions, $0.002–$0.006 a call;
/convert/md-htmlquotes4000atomic ($0.004). No free tier. - 10x402 — x402 conformance lint.
GET /checkis free and lists every check and price;POST /lint/envelope/oneis $0.004,POST /lintis $0.10. - kino402 — video generation and TTS.
GET /v1/modelsis free and carries the price formulas; the prompt compiler is a flat $0.008; renders are priced per model. - parallax — x402 market data from the
settlement graph.
GET /v1/statsis free; per-fact endpoints like/v1/sellerquote30000atomic ($0.03).
Don’t let the list end with us. The public catalogs hold the rest of the market: the CDP Bazaar index (https://docs.cdp.coinbase.com/x402/bazaar), x402scan (https://www.x402scan.com), and x402-list (https://x402-list.com). Point your agent at those, read a few 402 envelopes for free, and spend the rest of the $5 on someone else’s work.