How to Build an Agent That Pays for Its Own APIs — A Working Example in 50 Lines
Trial → register → pay. No human touches a wallet. No API key. No subscription. Just an agent, a task, and USDC on Base.
Most "agent payments" tutorials start with "first, create a wallet and fund it with USDC." That's the wrong order. The agent doesn't know if the API is worth paying for yet. It shouldn't commit capital before it knows the service works.
Here's the right order: try first, pay when it works. This is what the HTTP 402 Payment Required flow was designed for — and it's what x402 enables in practice.
Below is a complete, runnable example. An agent that needs multi-chain gas prices, discovers the endpoint, tries it for free, registers for credits, and makes a paid call — all in ~50 lines of bash. Every curl command returns real data from a live API.
The Agent's Task
Our agent needs to check gas prices across Ethereum, Base, Arbitrum, Optimism, and Polygon before submitting a transaction. It wants the cheapest chain. It doesn't have a wallet yet — it just has a job to do.
Step 1: Discover the API
The agent queries a service directory to find a gas price endpoint. It gets back structured metadata: what the service does, what it costs, and — critically — whether there's a free trial.
# Agent asks: "What APIs can give me gas prices?"
curl -s https://minia2a.uk/api/services | python3 -c "
import json, sys
svcs = json.load(sys.stdin)['services']
gas = [s for s in svcs if 'gas' in s['id'].lower() and s['active']]
for g in gas:
print(f\"{g['id']}: {g['description'][:80]}\")
print(f\" Price: {g['priceCents']}c | Endpoint: {g['endpoint']}\")
print(f\" Trial: append ?trial=1 to the endpoint URL\")
"
The agent now knows: gas prices are available at /x402/gas, it costs half a cent, and there's a free trial. No wallet needed yet.
Step 2: Try Before You Buy
The agent makes a trial call. It appends ?trial=1 to the endpoint. The API returns real data — the agent evaluates quality before committing any money.
# Agent: "Let me try this first — is the data any good?"
curl -s -X POST https://minia2a.uk/x402/gas?trial=1 \
-H 'Content-Type: application/json' \
-d '{"chain":"ethereum"}'
The data is real. Gas prices, in gwei and USD, with speed tiers. The _trial: true flag and trialsRemaining: 14 counter tell the agent this was a free trial call — and how many it has left.
Step 3: When Trials Run Out, Register
After 15 free trials (per endpoint), the API returns HTTP 402 Payment Required. The agent doesn't stop — it registers to get 500 more credits. One curl, no KYC, no human.
# After 15 trials, the API responds with 402:
HTTP 402 Payment Required
{
"_trial": true,
"message": "⚡ 15 free trials used — unlock 500 more credits + auto-wallet in 10s.
No KYC, no gas. Access 317 pay-per-call services.",
"register": "POST /api/v1/register-simple {name}",
"creditsGranted": 500
}
# Agent registers itself — one line:
curl -s -X POST https://minia2a.uk/api/v1/register-simple \
-H 'Content-Type: application/json' \
-d '{"name":"gas-price-agent"}'
The agent now has a wallet address, 500 credits, and can make paid calls. No human touched MetaMask. No seed phrase. No gas fees for registration. The wallet was created server-side and credited automatically.
Step 4: Make a Paid Call
The agent sends its wallet address in the Authorization header. The server deducts credits. The agent gets the data. Half a cent. Settled.
# Agent: "I need the latest gas prices. Pay from my credits."
curl -s -X POST https://minia2a.uk/x402/gas \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer 0x7a9f...3b2c' \
-d '{"chain":"ethereum"}'
Same data. One credit spent. credits_remaining: 499 confirms the deduction. The agent can now call this endpoint 499 more times before needing more credits.
The Complete Agent Script
Here's the full agent in a single bash script — discovery, trial, registration, and paid calls in ~50 lines:
#!/bin/bash
# gas-price-agent — an agent that pays for its own API calls
# No human. No wallet setup. No API keys.
API="https://minia2a.uk"
ENDPOINT="$API/x402/gas"
# Step 1: Try for free
echo "[agent] Trying gas price endpoint (free trial)..."
RESP=$(curl -s -X POST "$ENDPOINT?trial=1" \
-H 'Content-Type: application/json' \
-d '{"chain":"ethereum"}')
# Check if data looks good
if echo "$RESP" | grep -q '"gas"'; then
echo "[agent] Data looks good: $(echo $RESP | python3 -c \
'import json,sys; d=json.load(sys.stdin); \
print(f\"{d[\"gas\"][\"standard\"][\"gwei\"]}gwei = \
\${d[\"gas\"][\"standard\"][\"usd\"]}\")' 2>/dev/null)"
else
echo "[agent] Bad data or dead endpoint. Skipping."
exit 1
fi
# Step 2: Register if we don't have a wallet yet
WALLET_FILE="$HOME/.agent-wallet"
if [ ! -f "$WALLET_FILE" ]; then
echo "[agent] Registering for credits..."
REG=$(curl -s -X POST "$API/api/v1/register-simple" \
-H 'Content-Type: application/json' \
-d '{"name":"gas-price-agent"}')
WALLET=$(echo "$REG" | python3 -c \
'import json,sys; print(json.load(sys.stdin)["wallet"])' 2>/dev/null)
echo "$WALLET" > "$WALLET_FILE"
echo "[agent] Registered! Wallet: ${WALLET:0:10}... Credits: 500"
else
WALLET=$(cat "$WALLET_FILE")
fi
# Step 3: Make paid calls — agent loops on its own
CHAINS=(ethereum base arbitrum optimism polygon)
for chain in "${CHAINS[@]}"; do
echo "[agent] Fetching $chain gas (paid)..."
RESULT=$(curl -s -X POST "$ENDPOINT" \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $WALLET" \
-d "{\"chain\":\"$chain\"}")
GWEI=$(echo "$RESULT" | python3 -c \
'import json,sys; d=json.load(sys.stdin); \
print(d.get("gas",{}).get("standard",{}).get("gwei","N/A"))' 2>/dev/null)
CREDITS=$(echo "$RESULT" | python3 -c \
'import json,sys; d=json.load(sys.stdin); \
print(d.get("credits_remaining","?"))' 2>/dev/null)
echo "[agent] $chain: ${GWEI}gwei | credits left: $CREDITS"
done
# Step 4: Pick the cheapest chain
echo "[agent] Done. Cheapest chain for this tx: check above."
Save as gas-price-agent.sh, chmod +x, run it. The agent discovers, tries, registers, and pays — all without a human in the loop.
What's Happening Under the Hood
When the agent sends Authorization: Bearer <wallet>, the server:
- Looks up the wallet in its credit ledger
- Verifies sufficient credits for the endpoint's price (0.5¢ for gas)
- Deducts 1 credit
- Forwards the request to the backend service
- Returns the result with
credits_remainingin the response
No on-chain transaction per call. No gas fees per request. Credits are settled in batches. The agent just gets its data.
Why This Pattern Matters
The agent payment stack is converging. Cloudflare Wallets (Aug 4), OSL AgentPay (Aug 7), Zero Hash Agentic Finance Suite (Aug 9), Mastercard AP4M — the infrastructure for agents to pay is being built by every major financial institution simultaneously.
But infrastructure without discovery is a highway with no map. Agents need to:
- Find APIs that solve their specific problem
- Verify those APIs are alive and return good data
- Pay only after verification
The trial-first pattern — ?trial=1 — makes steps 1 and 2 cost zero. Step 3 only happens when the agent is confident. This is not a nice-to-have. In live data across 300+ endpoints, 76% of listed x402 services are unreachable. Without a trial, agents would pay for dead endpoints 3 out of 4 times.
What's Next
The agent above is 50 lines of bash. The next step is wiring this into your agent framework of choice:
- Claude Code / Codex: Register once, store the wallet in your agent's environment, add
Authorization: Bearer $WALLETto your HTTP tool calls - LangChain / CrewAI: Wrap the discovery + trial + pay flow into a custom tool
- Custom agents: The curl commands above work in any language — Python
requests, Nodefetch, Gonet/http
The hard part — payment rails, settlement, wallet management — is handled. Your agent just makes HTTP requests and reads JSON.