Paying for a call

There is no account, no API key and no invoice. The endpoint tells you the price in its own HTTP response, your client pays it, and the call goes through. This page shows the whole thing, end to end: the raw HTTP first, then the one library call that does it for you.

Ask, and read the price

Every paid route answers 402 Payment Required until it is paid. That answer is free and carries everything needed to pay it:

curl -i https://whaletape.xyz/whales
HTTP/1.1 402 Payment Required
payment-required: eyJ4NDAyVmVyc2lvbiI6Mi...   ← v2, base64

{
  "x402Version": 1,
  "error": "Payment required",
  "accepts": [{
    "scheme": "exact",
    "network": "base",
    "maxAmountRequired": "10000",        ← 0.01 USDC, 6 decimals
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo": "0x…",
    "resource": "https://whaletape.xyz/whales",
    "maxTimeoutSeconds": 300
  }]
}

The price lives in the response, not in a contract you signed last month. It can change per route, and your client always sees the current one before spending anything.

Sign an authorization

Your client signs an EIP-3009 authorization: permission for that exact amount of USDC to move, to that exact address. It is a signature, not a transaction: no gas, no wallet pop-up, no balance to pre-load beyond the USDC itself.

Repeat the call with the signature attached

The signature travels as a header and the same request goes out again. The facilitator settles it on Base and the data comes back. In practice one library does steps 1 to 3 for you:

// npm i @x402/fetch @x402/evm viem
import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";

// Read the key from the environment. Never paste one into a file.
const account = privateKeyToAccount(process.env.BUYER_PRIVATE_KEY as `0x${string}`);

const client = new x402Client()
  .register("eip155:8453", new ExactEvmScheme(account));   // Base mainnet

const fetchWithPay = wrapFetchWithPayment(fetch, client);

const res = await fetchWithPay("https://whaletape.xyz/whales");
const whales = await res.json();
console.log(whales);
On the private key. That wallet spends real money without asking. Keep it in the environment, keep it out of version control, and fund it with what you are willing to spend on data, not with your treasury.
v1 and v2 both work. Newer clients read the requirements from the payment-required header and pay with PAYMENT-SIGNATURE; older ones read the JSON body and pay with X-PAYMENT. We answer both, so an old client will not silently give up on an empty body.

What to call

Prices run from $0.001 to $0.99 per request, listed on the home page. /track-record is free and worth calling first: it publishes the measured accuracy of our own signals. Then comes /coverage, the cheapest route we sell at $0.001: it tells you what history exists before you pay for the history itself.

Endpoint reference x402 manifest llms.txt