Charge for an API call
Put an x402 paywall in front of your API and take the first paid call in five minutes.
You have an endpoint. Agents want to call it. This guide puts Gate, the x402 gateway, in front of it: an unpaid call gets an HTTP 402, a paid call settles USDC to a wallet you choose and is proxied to your backend with a sealed receipt. The caller creates no account, holds no card, opens no session. Gate is live on Base mainnet.
Four steps: create a paywall, read the 402 with your own eyes, pay it, read the earnings.
Prerequisites
- A CodeSpar API key with the admin role. Mint one at Dashboard → API Keys. A
csk_test_key creates paywalls that settle on Base Sepolia; acsk_live_key settles real USDC on Base mainnet. - A public
httpsendpoint to charge for. The gateway fetches it server-side on every paid call, so localhost and private hosts are rejected at create time. - For step 3, something that can pay: the CodeSpar CLI (shown below) or any x402 v2 client such as
@x402/fetchor an agent on the CDP Bazaar.
No endpoint handy? curl -i https://gw.codespar.dev/e2e-live hits a permanent live paywall priced at $0.01. Every step below works against it, except that the money lands with us.
Create a paywall
One POST /v1/paywalls names your upstream, sets the price, and says where the money lands (full reference). Prefer clicking? The dashboard's Machine payments page has a create drawer with the same fields.
curl -X POST https://api.codespar.dev/v1/paywalls \
-H "authorization: Bearer $CODESPAR_API_KEY" \
-H "content-type: application/json" \
-d '{
"slug": "market-data",
"name": "Market data API",
"upstream_url": "https://api.yourservice.com/quote",
"price": "0.01",
"payto": { "kind": "provisioned" },
"consumer_id": "you"
}'payto decides who gets paid. provisioned settles into the CodeSpar-derived wallet of the consumer_id you pass, a governed wallet your own agent can later spend from; it is a CDP account created under the CDP credentials connected for your org, falling back to CodeSpar's own, so whoever holds that CDP wallet secret is who can sign its transfers. { "kind": "byo", "address": "0x..." } settles straight to an EVM address you already hold, and CodeSpar has no key for it.
The 201 response carries the URL you share with the world:
{
"id": "pw_9f81c2",
"slug": "market-data",
"price": "0.01",
"currency": "USDC",
"pricing_model": "flat",
"gateway_url": "https://gw.codespar.dev/market-data",
"active": true
}Flat pricing is the default. Tiered price curves and dynamic per-request pricing are live too; post-paid metered pricing is in beta, see Meter. Slugs are a global namespace, and gw.codespar.dev/market-data/<path> forwards the trailing path to your upstream, so one paywall can front a whole API surface.
Curl it and read the 402
curl -i https://gw.codespar.dev/market-dataHTTP/2 402
payment-required: eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJwYXltZW50IHJlcXVpcmVkIi...The challenge arrives base64-encoded in the PAYMENT-REQUIRED response header; the JSON body of the 402 is only a human-readable hint. Decode the header and you get an x402 version 2 challenge:
curl -sD - -o /dev/null https://gw.codespar.dev/market-data \
| awk 'tolower($1)=="payment-required:" {print $2}' | base64 -d{
"x402Version": 2,
"error": "payment required",
"resource": {
"url": "https://gw.codespar.dev/market-data",
"mimeType": "application/json",
"description": "Market data API"
},
"accepts": [
{
"scheme": "exact",
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "10000",
"payTo": "0x15cA...9E41",
"maxTimeoutSeconds": 120,
"extra": { "name": "USD Coin", "version": "2" }
}
]
}amount is atomic USDC (6 decimals), so 10000 is your $0.01. network follows the paywall's environment: eip155:8453 (Base mainnet) on live, eip155:84532 (Base Sepolia) on test. Nothing has reached your upstream yet, and nothing will until a payment verifies.
Pay it
An x402-capable client reads the header, signs the payment, and retries the call.
The CLI pays under a signed mandate, so the spend is capped and receipted on the buyer side too. It uses the same CODESPAR_API_KEY (run codespar login once, or export the key):
npx @codespar/cli mandate create \
--consumer you --agent smoke-test \
--purpose "first paid call on my own paywall" \
--payee https://gw.codespar.dev/market-data \
--cap 10 --per-tx-cap 1
codespar spend --mandate cm_xxx --agent smoke-test \
--payee https://gw.codespar.dev/market-data --amount 1CLI amounts are minor units (cents): --amount 1 pays the $0.01 challenge. The response is your upstream's 200 body; the settlement result rides back in the PAYMENT-RESPONSE header.
Any client that speaks x402 version 2 works: decode PAYMENT-REQUIRED, sign an EIP-3009 USDC authorization for amount to payTo on the advertised network, and retry with the signed payment in the PAYMENT-SIGNATURE request header (X-PAYMENT is accepted for v1 compatibility). @x402/fetch wraps this into a drop-in fetch; agents on the CDP Bazaar discover and pay 402 endpoints on their own.
Either way, the gateway verifies the signature, settles the exact amount on-chain to your payTo, seals a hash-chained receipt, and only then proxies the request to your upstream.
Read the receipt and the earnings
curl https://api.codespar.dev/v1/paywalls/pw_9f81c2/stats \
-H "authorization: Bearer $CODESPAR_API_KEY"{
"paywall_id": "pw_9f81c2",
"slug": "market-data",
"currency": "USDC",
"settled_count": 1,
"gross_atomic": "10000",
"gross": "0.01",
"refunded_atomic": "0",
"refunded": "0",
"net_atomic": "10000",
"net": "0.01",
"last_settled_at": "2026-08-06T18:22:41Z"
}net is what landed and stayed. On flat, tiered, and dynamic paywalls gross equals net; on a metered paywall the gap is the on-chain refund of unused ceiling, which is the feature working, not revenue lost (Meter). The same figures show inline on each paywall in Machine payments, and every settlement seals a receipt in the audit chain.
Drive it from your coding agent
The wallet a provisioned paywall settles into is a governed wallet your own agent can hold. Add the CodeSpar MCP server to the coding agent you already use:
claude mcp add codespar --env CODESPAR_API_KEY=csk_live_your_key -- npx -y @codespar/mcp@0.5.8 serveThen ask it "what's my wallet balance?" and watch the earnings arrive (codespar_wallet), or send them onward under a mandate (codespar_pay). Earning and spending are two halves of the same loop; the other half is the buyer quickstart.
Where to go next
Agent loop in Python
Get a CodeSpar commerce agent running in Python — sync for scripts and Django, async for FastAPI and LangChain. Under 5 minutes.
Buy with an agent, no code
Give your coding agent the power to shop and pay in Brazil — MCP-first, no code. Search a real store, hold a governed wallet, pay under a signed mandate.