Documentation

x402 Payments

Pay per request in USDC with the x402 protocol — no account, no API key. Built for autonomous AI agents on Base and Solana.

x402 is an open protocol that turns HTTP 402 Payment Required into a real payment rail. Instead of signing up for a key, an agent pays a few cents in USDC per request, straight from a wallet. Scanna speaks x402 natively, so an autonomous agent can call the API with no account, no dashboard, and no human in the loop.

Note

Live (beta). x402 settles on-chain on Base and Solana mainnet in USDC. You pay only for successful requests.

API key vs. x402

Scanna accepts either an API key or an x402 payment on a request — never both. They are two independent ways to authorize the same data.

API key (subscription)x402 (pay-per-call)
Headerx-api-keyX-PAYMENT
SignupEmail / Stripe CheckoutNone — just a funded wallet
BillingMonthly (Pro / Max) or custom (Enterprise)Per request, in USDC
Plan gatingPro+ endpoints are gatedBypassed — paying unlocks the call
Rate limitPer-key (plan-dependent)Paced by payment, not a key bucket
Metered usageCounted against your planNot counted
Best forHumans, persistent botsAutonomous agents, one-off calls

If you're a person or a long-running service, get an API key — it's simpler and cheaper at volume. If you're an agent that should pay its own way without a shared secret, use x402.

Supported endpoints

Four endpoints accept x402 today. Everything else on the API still requires an API key.

EndpointWhat you getPrice
POST /heatPer-market heat score$0.01
GET /hotTrending markets feed$0.01
GET /smart-moneySmart money leaderboard$0.02
GET /predictAI prediction for a market$0.05

Prices are charged in USDC per successful request. A failed request (a 4xx/5xx that never returns data) is never settled, so you only pay for results.

How a payment works

x402 is a challenge–response handshake. Your client handles all of it automatically — you just call the URL.

Request with no payment

Your client GETs or POSTs a paid endpoint normally, with no X-PAYMENT header.

Get a 402 challenge

Scanna replies 402 Payment Required with the accepted payment requirements — scheme (exact), network, asset (USDC), amount, and the address to pay.

Sign the payment

Your x402 client signs a USDC transfer authorization for that exact amount with your wallet key. Nothing is broadcast yet.

Resend with X-PAYMENT

The client retries the same request, now carrying the signed payment in the X-PAYMENT header.

Verify, settle, respond

Scanna's facilitator verifies the payment and settles it on-chain, then returns 200 with your data and an X-PAYMENT-RESPONSE settlement receipt.

For the exact request/response shapes, see the x402 API reference.

Set it up

Get a wallet

Use any EVM wallet for Base (a viem account from a private key works well) or a Solana keypair. Keep the key out of source control.

Fund it with USDC

Top up the wallet with USDC on Base or Solana. You also need a little ETH / SOL for gas.

Install an x402 client

Pick the HTTP client you already use:

npm install x402-fetch viem      # fetch-based
# or
npm install x402-axios axios viem

Wrap it with your wallet

The client intercepts every 402, pays, and retries — your call sites don't change.

Call a paid endpoint and verify

A 200 with data means the payment settled. Check the X-PAYMENT-RESPONSE header for the on-chain receipt.

Examples

TypeScript — x402-fetch

import { wrapFetchWithPayment } from "x402-fetch"
import { privateKeyToAccount } from "viem/accounts"

// A wallet funded with USDC on Base.
const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`)

// fetchWithPay transparently handles the 402 → pay → retry handshake.
const fetchWithPay = wrapFetchWithPayment(fetch, account)

const res = await fetchWithPay("https://api.scanna.xyz/hot?limit=5")
const data = await res.json()
console.log(data.markets)

TypeScript — x402-axios

import axios from "axios"
import { withPaymentInterceptor } from "x402-axios"
import { privateKeyToAccount } from "viem/accounts"

const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`)

const api = withPaymentInterceptor(
  axios.create({ baseURL: "https://api.scanna.xyz" }),
  account,
)

const { data } = await api.get("/predict", { params: { market_id: "0xfb1835" } })
console.log(data)

Tip

Building an agent inside Claude Code, Cursor, or another MCP client? Paste Fetch https://docs.scanna.xyz/install.md into the prompt and the agent will set itself up — API key, MCP, SDKs, the plugin, or x402.

See also