Quickstart (5 minutes)
Goal
Make a request, receive a 402 challenge, then pay and retry to get a 200 response.
Prerequisites
A wallet funded with USDC on Base or Solana (v2 endpoints support both; v1 is Base/EVM-only).
A runtime (Node.js 18+ or Python) and a safe place to store a private key (never commit it).
1) Trigger a 402 challenge
402 challengeUse -i so you can see the PAYMENT-REQUIRED header:
curl -i https://sentiment-api.kytona.com/v2/snapshot/globalYou’ll receive 402 Payment Required plus:
Header:
PAYMENT-REQUIRED(source of truth)Body: a JSON representation of the same requirements (for convenience)
2) Pay and retry (TypeScript, Base/EVM)
npm i @x402/core @x402/evmimport { decodePaymentRequiredHeader } from "@x402/core/http";
import { ExactEvmScheme } from "@x402/evm";
const url = "https://sentiment-api.kytona.com/v2/snapshot/global";
const challenge = await fetch(url);
if (challenge.status !== 402) throw new Error(`Expected 402, got ${challenge.status}`);
let requirements: any = null;
try {
requirements = await challenge.json();
} catch {
// Some clients/proxies strip bodies; fall back to decoding the header.
}
if (!requirements?.accepts?.length) {
const header = challenge.headers.get("PAYMENT-REQUIRED");
if (!header) throw new Error("Missing PAYMENT-REQUIRED header");
requirements = decodePaymentRequiredHeader(header);
}
const scheme = new ExactEvmScheme({
privateKey: process.env.EVM_PRIVATE_KEY!,
network: "eip155:8453", // Base mainnet
});
const { encodedSignature } = await scheme.sign(requirements);
const paid = await fetch(url, {
headers: { "PAYMENT-SIGNATURE": encodedSignature },
});
if (!paid.ok) throw new Error(`Paid request failed: ${paid.status} ${await paid.text()}`);
const data = await paid.json();
console.log(data.cryptoPulse.moodIndex);Solana/SVM (v2 only)
3) Make it cheaper to run (compact trading format)
For trading/bot loops, request the compact payload:
Troubleshooting
400 INVALID_FORMAT:formatonly supportscompact_trading(omitformatfor the full response).400 INVALID_COMPACT_FIELDS: use the allowlist shown in Endpoints.402even after paying: ensure you are using the v2 header namePAYMENT-SIGNATUREand that you signed the same requirements you were challenged with.429 RATE_LIMITED: back off and retry after theretry_aftervalue.
Last updated
