Agent Payment Cookbook
Real, copy-pasteable code recipes for AI agents paying each other in USDC on Base L2. No theory โ just working examples.
x-wallet-address / x-payment-tx headers, the /api/x402/โฆ, /api/register and /api/register-service paths, and seller-side /api/x402/verify. In V5: two rails. Trial โ GET /x402/<id>?wallet=0xโฆ plus X-Wallet-Signature and X-Trial-Timestamp headers (5 per signed wallet; a bare ?wallet= with no signature is a hard 400). Paid โ no wallet param at all: read the 402 challenge and retry with a PAYMENT-SIGNATURE header, register with POST /api/v1/register-simple (name + wallet + EIP-191 signature), and publish with POST /api/v1/publish-service. Authoritative reference: llms-full.txt.1. Call Any x402 Service With curl
The fastest way to understand x402: call a live service right now. Paste this into your terminal.
Try the gas oracle (free tier)
# A bare call has no trial โ it returns the 402 challenge. Read the price from it:
curl -s https://minia2a.uk/x402/gas | jq .accepts[0].amount
Returns live Base L2 gas prices. First calls draw from the free shared trial allowance.
Call a paid service (~$0.005 per call)
# First: sign your self-custodied wallet for 5 free trial calls (no registration)
# (needs name + wallet + an EIP-191 signature over "minia2a register: <wallet>")
curl -X POST https://minia2a.uk/api/v1/register-simple \
-H "Content-Type: application/json" \
-d '{"name":"my-first-agent","wallet":"0xYOUR_WALLET","signature":"0xYOUR_SIGNATURE"}'
# Then call a service โ the trial needs BOTH halves (wallet in the query string AND
# the signature headers). Neither half alone works: no signature -> 400, no wallet -> 402.
curl "https://minia2a.uk/x402/token-security?wallet=0xYOUR_WALLET&address=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" \
-H "X-Wallet-Signature: $SIG" -H "X-Trial-Timestamp: $TS" | jq .
-w "\nTime: %{time_total}s" to curl to see response times. Most endpoints return in under 500ms on Base L2.2. Wrap Your API as a Paid x402 Service
You have an API. Agents want to call it. In V5 you publish your endpoint and minia2a handles the x402 challenge, payment verification, and settlement โ you don't write any payment code.
Publish your endpoint
# Sign the exact string "minia2a publish: <your-wallet>" (EIP-191 personal_sign),
# then publish your endpoint with a price:
curl -X POST https://minia2a.uk/api/v1/publish-service \
-H "Content-Type: application/json" \
-d '{"name":"weather","endpoint":"https://your-server.com/weather",
"price_cents":5,"description":"Live weather for any city, 20+ chars here",
"category":"tools","wallet":"0xYOUR_WALLET","signature":"0xYOUR_SIGNATURE"}'
# Returns a service id, callable at /x402/<id>.
# Revenue settles to your publishing wallet. Platform fee 5%.
# Constraints (enforced server-side): price_cents 1โ10000;
# category tools|premium|defi|data; endpoint must be a public URL
# (internal and loopback addresses are rejected โ SSRF guard);
# description must be 20+ characters or the call is rejected 400.
/api/x402/verify, /api/register-service, and the x-wallet-address / x-payment-tx headers are all removed. You no longer verify payments yourself: minia2a verifies the on-chain settlement and pays your wallet automatically.3. Build a Python Agent That Pays for APIs
Your agent needs data from paid APIs. Here's how to make it pay automatically with its minia2a wallet.
# agent.py โ an AI agent that calls paid APIs on minia2a
#
# Two rails, both shown here:
# TRIAL โ 5 free calls per signed wallet. Needs BOTH halves: ?wallet= in the
# query string AND a signature over "minia2a trial:::".
# A bare ?wallet= with no signature is a hard 400, not a 402.
# PAID โ no wallet param and no signature. Read the 402 challenge and pay.
# There is no prepaid balance and no /wallet/ endpoint โ the deposit rail was
# retired; each call settles in USDC straight from your wallet.
import os, time, requests
from eth_account import Account
from eth_account.messages import encode_defunct
WALLET = os.getenv("AGENT_WALLET") # 0x...
KEY = os.getenv("AGENT_PRIVATE_KEY") # used to sign; never transmitted
BASE = "https://minia2a.uk"
class PayingAgent:
def __init__(self, wallet=None, key=None):
self.wallet = wallet or WALLET
self.key = key or KEY
self.trials_left = 5 # per signed wallet, shared across the catalog
def _sign(self, service_id, ts):
msg = encode_defunct(text=f"minia2a trial:{self.wallet}:{service_id}:{ts}")
sig = Account.sign_message(msg, private_key=self.key).signature.hex()
return sig if sig.startswith("0x") else "0x" + sig
def call_service(self, service_id: str, path: str, params: dict):
"""Call a service. Uses a trial while any remain, then pays over x402."""
if self.trials_left <= 0:
return self._pay_and_call(path, params) # your x402 client here
ts = str(int(time.time())) # fresh per call, ยฑ5 min
r = requests.get(
f"{BASE}/x402/{path}",
params={**params, "wallet": self.wallet},
headers={
"X-Wallet-Signature": self._sign(service_id, ts),
"X-Trial-Timestamp": ts,
},
)
if r.status_code == 200:
# On the trial rail the remaining count is a response header, not a body field.
self.trials_left = int(r.headers.get("x-trial-remaining", self.trials_left - 1))
elif r.status_code == 402:
self.trials_left = 0
return r.json()
def research_token(self, address: str):
safety = self.call_service("x402-token-security", "token-security", {"address": address})
dex = self.call_service("x402-dex-price", "dex-price", {"token": address})
return {
"address": address,
"honeypot": safety.get("isHoneypot"),
"open_source": safety.get("isOpenSource"),
"price_usd": dex.get("result", {}).get("priceUsd"),
}
# Usage
agent = PayingAgent()
print(agent.research_token("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"))
4. Pay-Per-Call From TypeScript/Node.js
Type-safe agent payments in TypeScript. Full type definitions included.
// agent.ts โ typed x402 client
//
// No balance endpoint exists. On the trial rail the remaining count arrives as
// the x-trial-remaining response header; past the trials you pay the 402.
const BASE = "https://minia2a.uk";
interface ServiceResult {
ok: boolean;
data?: T;
error?: string;
}
class X402Agent {
private trialsLeft = 5; // per signed wallet, shared across the catalog
constructor(private wallet: string, private sign: (msg: string) => Promise) {}
async call(path: string, serviceId: string, params: Record = {}): Promise> {
if (this.trialsLeft <= 0) {
return { ok: false, error: "Trials exhausted โ answer the 402 with a payment header" };
}
const ts = Math.floor(Date.now() / 1000).toString();
const url = new URL(`/x402/${path}`, BASE);
for (const [k, v] of Object.entries({ ...params, wallet: this.wallet })) url.searchParams.set(k, v);
const r = await fetch(url, {
headers: {
"X-Wallet-Signature": await this.sign(`minia2a trial:${this.wallet}:${serviceId}:${ts}`),
"X-Trial-Timestamp": ts,
},
});
const remaining = r.headers.get("x-trial-remaining");
if (remaining !== null) this.trialsLeft = Number(remaining);
else if (r.status === 402) this.trialsLeft = 0;
const body = await r.json();
// NOTE: a bad parameter returns HTTP 200 with { ok: false, error }.
// Check body.ok, not just the status code.
return { ok: r.status === 200 && body.ok !== false, data: body as T, error: body.error };
}
// Research a token with two paid APIs.
async researchToken(token: string) {
const [safety, price] = await Promise.all([
this.call("token-security", "x402-token-security", { address: token }),
this.call("dex-price", "x402-dex-price", { token }),
]);
return { token, safety: safety.data, price: price.data };
}
}
// Usage
const agent = new X402Agent(process.env.AGENT_WALLET!, signWithYourWallet);
console.log(await agent.researchToken("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"));
5. MCP + x402 โ Monetize Your MCP Server
MCP (Model Context Protocol) servers can charge per tool call. In V5, monetize by publishing the endpoint โ minia2a handles the 402 challenge and settlement; you don't write verify code.
# Publish your tool once; callers pay automatically (402 โ settle โ result):
curl -X POST https://minia2a.uk/api/v1/publish-service \
-H "Content-Type: application/json" \
-d '{"name":"get-weather","endpoint":"https://your-server.com/weather",
"price_cents":3,"description":"Weather for any city, 20+ chars here",
"category":"tools","wallet":"0xYOUR_WALLET","signature":"0xYOUR_SIGNATURE"}'
# Callers reach it via the marketplace MCP server at POST /mcp
# (manifest at /.well-known/mcp.json) or directly at /x402/<id>
# Free trials need the wallet AND the signature headers:
# ?wallet=0x... plus X-Wallet-Signature + X-Trial-Timestamp (see recipe 6)
6. Claude Code / Cursor โ Agent Pays Automatically
When your coding agent needs an API, it pays with minia2a USDC โ no human in the loop.
Claude Code: add to your agent's skill
# In your CLAUDE.md or SKILL.md:
# "When you need token security data, call:
# curl 'https://minia2a.uk/x402/token-security?wallet=$MINIA2A_WALLET&address=' \
# -H "X-Wallet-Signature: $SIG" -H "X-Trial-Timestamp: $TS" # trial half
# Cost: $0.02 โ auto-charged to agent wallet."
# Set your wallet in the agent's environment:
export MINIA2A_WALLET=0xYOUR_WALLET
Cursor: add to .cursorrules
# .cursorrules
# Agent payment config:
# - Wallet: $MINIA2A_WALLET (registered at minia2a.uk)
# - Balance: no per-wallet balance endpoint; remaining balance comes back in each call's 402 response
# - Free trials: ?wallet=$MINIA2A_WALLET PLUS X-Wallet-Signature + X-Trial-Timestamp
# - Auto-pay: no wallet param needed; answer the 402 with a payment header
# - Budget: $0.25/day max
7. Keep Your Agent Funded
There are no top-ups โ the agent holds its own USDC and pays per call. USDC never expires, so you fund the wallet once and it spends as it goes.
| Budget | USDC (in the agent's own wallet) | Calls (avg) | Best For |
|---|---|---|---|
| Starter | Free โ 5 trial calls | ~5 | Testing & development |
| Builder | 10 USDC | ~2,000 | Single agent in production |
| Professional | 100 USDC | ~20,000 | Multiple agents or high-volume |
| Enterprise | 1,000 USDC | ~200,000 | Agent fleets & platforms |
# Fund the agent's own wallet (Base, ~1 second, sub-cent gas):
# 1) Send USDC on Base to the wallet your agent signs with
# 2) Nothing to "confirm" on our side โ it pays from that wallet per call:
#
# No per-wallet balance endpoint โ remaining balance is returned in each call's 402 response.
8. Payments in USDC on Base
minia2a settles in USDC on Base. Buyers pay USDC โ sellers receive USDC.
| Chain | USDC Settlement |
|---|---|
| Base | โ primary |
| Celo | โ |
| Solana | โ |
| Polygon | โ |
| Algorand | โ |
# Fund the agent's own wallet โ send USDC on Base to it:
# Sellers always get USDC on Base (auto-bridged):
# Your wallet: 0x... โ receives 50 USDC on Base (50 - 0% fee through 2026)
Ready to build?
5 free trial calls. 1,673 services. USDC on Base. Zero KYC. Your agent could be earning USDC in 5 minutes.
Sign Wallet โ Get 5 Free Trials โOr learn how the marketplace works ยท payagent integration guide