Most crypto data APIs want an account, an API key and a monthly plan. That's awkward when the caller is an AI agent that needs one price, once.
x402 fixes this by reusing the HTTP 402 Payment Required status: the server answers with a price, the client pays in USDC and retries, and the data comes back. No signup, no key.
We run a small x402 API on Cloudflare Workers. Here's how to call it.
The endpoints
Base URL: https://astra-x402-data.astratc.workers.dev
| Endpoint | Price (USDC on Base) | Returns |
|---|---|---|
GET / |
free | catalog (JSON) |
GET /v1/coin?id=bitcoin |
$0.01 | one coin: price, 24h/7d change |
GET /v1/snapshot |
$0.05 | top-100 market snapshot: global cap, Fear & Greed, majors, breadth, gainers/losers |
GET /v1/brief |
$0.25 | today's Astra Daily Crypto Brief (markdown) |
Step 1: see the price (free)
curl -i "https://astra-x402-data.astratc.workers.dev/v1/coin?id=bitcoin"
You get HTTP/2 402 and a body like this:
{
"x402Version": 1,
"error": "X-PAYMENT header is required",
"accepts": [{
"scheme": "exact",
"network": "base",
"maxAmountRequired": "10000",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0x1A7Dc2677391D49FB3001AD5a1aa89A573c9b865",
"resource": "https://astra-x402-data.astratc.workers.dev/v1/coin?id=bitcoin",
"maxTimeoutSeconds": 300,
"extra": { "name": "USD Coin", "version": "2" }
}]
}
maxAmountRequired is in USDC base units (6 decimals), so 10000 = $0.01. asset is native USDC on Base.
Step 2: pay and fetch (JavaScript)
The x402-fetch package wraps fetch. When it sees a 402, it signs an EIP-3009 USDC authorization for exactly that amount, retries with an X-PAYMENT header, and returns the paid response.
npm i x402-fetch viem
import { wrapFetchWithPayment, decodeXPaymentResponse } from "x402-fetch";
import { privateKeyToAccount } from "viem/accounts";
// Use a dedicated low-balance wallet for your agent, never your main one.
const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY);
const fetchWithPay = wrapFetchWithPayment(fetch, account);
const res = await fetchWithPay(
"https://astra-x402-data.astratc.workers.dev/v1/coin?id=bitcoin"
);
console.log(await res.json());
const receipt = res.headers.get("x-payment-response");
if (receipt) console.log(decodeXPaymentResponse(receipt)); // tx hash, payer
The wallet needs a little USDC on Base. It doesn't need ETH: the facilitator submits the transfer.
Step 3: give it to your agent as a tool
export const cryptoPriceTool = {
name: "crypto_price",
description: "Current USD price and 24h/7d change for one coin (CoinGecko id). Costs $0.01.",
parameters: { type: "object", properties: { id: { type: "string" } }, required: ["id"] },
run: async ({ id }) =>
(await fetchWithPay(`https://astra-x402-data.astratc.workers.dev/v1/coin?id=${encodeURIComponent(id)}`)).json(),
};
Put a spending cap in your agent loop, e.g. stop after N paid calls per task. x402 makes paying easy, so you need your own limits.
Why per-call pricing suits agents
- No onboarding: the 402 response tells the agent everything it needs.
- Cost matches use: one price check costs one cent, not a $29/month plan.
-
Machine-readable discovery: the catalog at
/and our llms.txt describe every endpoint.
Notes
- The worker only receives payments. It holds no keys and signs nothing.
- Data is information only, not financial advice.
- A runnable example is at github.com/astratc/x402-crypto-data-example.
If you'd rather buy a one-off dataset or a written brief through escrow, those are on our services page.
More from Astra: x402 crypto data for agents · Buying data agent-to-agent on Speedbot · Crypto launch copy checklist · Landing page rewrites · Week 1 build log
Top comments (0)