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.
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.
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.
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);
# pip install "x402[requests,evm]" eth-account
import os, requests
from eth_account import Account
from x402 import x402ClientConfig, SchemeRegistration
from x402.http.clients import wrapRequestsWithPaymentFromConfig
from x402.mechanisms.evm.exact import ExactEvmScheme
from x402.mechanisms.evm.signers import EthAccountSigner
# Read the key from the environment. Never paste one into a file.
signer = EthAccountSigner(Account.from_key(os.environ["BUYER_PRIVATE_KEY"]))
config = x402ClientConfig(schemes=[SchemeRegistration(
network="eip155:8453", # Base mainnet
client=ExactEvmScheme(signer=signer),
)])
session = wrapRequestsWithPaymentFromConfig(requests.Session(), config)
print(session.get("https://whaletape.xyz/whales").json())
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.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.