x402 Payments (Pay-Per-Request)
Elfa API supports keyless, pay-per-request access via the x402 protocol. Any wallet can call any Elfa endpoint — no API key, no subscription, no registration. Payment is in USDC on Base, Arbitrum, Polygon, Avalanche, or Solana and is verified and settled per-request.
This is ideal for AI agents making autonomous API calls.
x402 payment access is in beta. Endpoints are served at the /x402/v2/ prefix and
speak x402 protocol v2. An x402 v1 client reads its quote from the 402 response
body, which is empty here, so it dead-ends with nothing to sign. Use a v2 client —
the @x402/* packages on 2.x speak v2.
X-PAYMENT is still accepted as an alias for the PAYMENT-SIGNATURE header name,
but the payload it carries must be a v2 payment payload.
How It Works
x402 uses the HTTP 402 Payment Required status code for machine-to-machine payments:
- Request — Send a normal HTTP request to an
/x402/v2/endpoint (no API key needed) - 402 Response — The server responds with payment requirements (price, accepted networks, recipient) in the
PAYMENT-REQUIREDresponse header. The response body is empty — the quote is in the header. - Sign — Your wallet signs a USDC transfer authorization (no gas required)
- Retry — Resend the request with the signed payment in the
PAYMENT-SIGNATUREheader - Verify & Serve — The server verifies payment, serves the response, and settles on-chain
Funds flow directly from your wallet to Elfa's treasury. The facilitator is non-custodial.
Base URL
All x402 endpoints are served under the /x402/v2/ prefix:
https://api.elfa.ai/x402/v2/
These mirror the standard /v2/ endpoints but accept x402 payment instead of an API key.
Pricing
Standard Endpoints
| Endpoint | Credits | USDC Cost |
|---|---|---|
/aggregations/trending-tokens | 1 | $0.0145 |
/account/smart-stats | 1 | $0.0145 |
/data/keyword-mentions | 1 | $0.0145 |
/data/token-news | 1 | $0.0145 |
/data/top-mentions | 1 | $0.0145 |
/aggregations/trending-cas/twitter | 1 | $0.0145 |
/aggregations/trending-cas/telegram | 1 | $0.0145 |
/data/event-summary | 5 | $0.0725 |
/data/trending-narratives | 5 | $0.0725 |
Two notes on that table: /account/smart-stats is legacy and scheduled for
removal on 28 October 2026, and /data/token-news returns X posts from
accounts tagged as news sources, not articles from news outlets.
Chat Endpoint
The /chat endpoint is speed-based, and you choose how you pay for it:
| Speed Mode | exact (flat) | batch-settlement (charged up to) |
|---|---|---|
fast | $1 | $2 |
expert (default) | $2 | $6 |
exactcharges the flat price on every call, whatever the answer costs to produce.batch-settlementpays from a prepaid channel. Your first call deposits USDC into the channel (at least $6, one turn at theexpertcap); later calls are paid with a signed voucher and no new onchain transaction. Each turn is charged what it actually used, which is normally well below the flat price. A long answer with many tool calls can cost more than the flat price, never more than the cap.
Pick batch-settlement if you want to pay for what you use, exact if you want a predictable per-call price. batch-settlement is offered on Base only, and only when the 402 response lists it; your client picks from what the 402 lists.
Unused deposit is returned to your wallet once the channel has been idle for 3 days. You can also withdraw it onchain yourself; a withdrawal completes one hour after you request it.
Every other endpoint is exact only, at the price in the table above.
To avoid confusion:
/x402/v2/chatis speed-based (table above).- Auto-specific x402 pricing is documented on x402 (Auto).
Quick Start
Using @x402/fetch (Recommended)
The easiest way to interact with x402 endpoints is with the @x402/fetch client, which automatically handles the 402 payment flow.
npm install @x402/fetch @x402/evm @x402/core viem
import { wrapFetchWithPayment } from "@x402/fetch";
import { ExactEvmScheme, toClientEvmSigner } from "@x402/evm";
import { x402Client } from "@x402/core/client";
import { createPublicClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";
// Create a signer from your private key
const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY");
const publicClient = createPublicClient({ chain: base, transport: http() });
const signer = toClientEvmSigner(account, publicClient);
// Create an x402 client with the EVM exact scheme for Base
const client = new x402Client().register(
"eip155:8453",
new ExactEvmScheme(signer),
);
// Wrap fetch — payment is handled automatically on 402 responses
const x402Fetch = wrapFetchWithPayment(fetch, client);
// Make a request
const response = await x402Fetch(
"https://api.elfa.ai/x402/v2/aggregations/trending-tokens?timeWindow=24h",
);
const data = await response.json();
console.log("Trending tokens:", data);
To pay on another network, swap the base chain and eip155:8453 for a supported one — e.g. Arbitrum (arbitrum, eip155:42161). Register a scheme for each network you want to pay from; the client uses the first one the server also accepts. See Supported Networks.
Using @x402/axios
npm install @x402/axios @x402/evm @x402/core viem
import { wrapAxiosWithPayment } from "@x402/axios";
import { ExactEvmScheme, toClientEvmSigner } from "@x402/evm";
import { x402Client } from "@x402/core/client";
import { createPublicClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";
import axios from "axios";
const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY");
const publicClient = createPublicClient({ chain: base, transport: http() });
const signer = toClientEvmSigner(account, publicClient);
const client = new x402Client().register(
"eip155:8453",
new ExactEvmScheme(signer),
);
const x402Axios = wrapAxiosWithPayment(axios, client);
const { data } = await x402Axios.get(
"https://api.elfa.ai/x402/v2/data/keyword-mentions",
{ params: { keywords: "bitcoin", timeWindow: "24h" } },
);
Chat Example
const response = await x402Fetch("https://api.elfa.ai/x402/v2/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
message: "What is the current sentiment on BTC?",
analysisType: "chat",
speed: "fast",
}),
});
const data = await response.json();
console.log(data.data.message);
Manual Flow (cURL)
If you prefer to handle the 402 flow manually:
# Step 1: Send request without payment — get 402 with requirements
curl -s https://api.elfa.ai/x402/v2/aggregations/trending-tokens
# Step 2: Sign the payment requirements with your wallet
# (use @x402/core or @x402/evm to create the payment payload)
# Step 3: Resend with payment header
curl -s https://api.elfa.ai/x402/v2/aggregations/trending-tokens \
-H "PAYMENT-SIGNATURE: <base64-encoded-payment-payload>"
Payment Details
| Property | Value |
|---|---|
| Scheme | exact (fixed price per request), plus batch-settlement (prepaid channel, metered) on the chat endpoints on Base |
| Asset | Native USDC on the selected network |
batch-settlement needs no token approval: the deposit is a signed USDC authorization. It is offered on Base only; every other network, including Solana, is exact only.
Supported Networks
The server offers every supported network in the 402 response; your client signs on the first one it's registered for. Register the network(s) you hold USDC on.
| Network | Chain ID | USDC Address | Facilitator |
|---|---|---|---|
| Base | eip155:8453 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | payai.network |
| Arbitrum | eip155:42161 | 0xaf88d065e77c8cC2239327C5EDb3A432268e5831 | payai.network |
| Polygon | eip155:137 | 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 | payai.network |
| Avalanche | eip155:43114 | 0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E | payai.network |
| Solana | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | payai.network |
All are native Circle USDC (6 decimals). Facilitators are non-custodial.
EVM networks use CAIP-2 eip155:* chain IDs; Solana uses the CAIP-2 solana:* identifier with a base58 USDC mint. To pay from Solana, sign with @x402/svm instead of @x402/evm — the facilitator acts as the transaction fee payer, so you don't need SOL for gas.
Errors
Failures come back in more than one body shape, so branch on the HTTP status first and read the body as the refinement. Most rejections return { code, message, errorId, requestId }, but the x402 surface also returns a short { error } with no code at all. requestId is also the x-request-id response header, and that header is present even on the short shape. See Error Responses for all three shapes and the code table.
Two things specific to the Auto endpoints: EQL validation failures return { valid, errors, warnings } — at 422 from POST /v2/auto/queries, and at 200 from POST /v2/auto/queries/validate, where you must read valid rather than the status. Errors raised by the execution engine are passed through unchanged.
Note that a 402 here is the payment handshake described above, not a billing error.
x402 vs API Key
| API Key | x402 | |
|---|---|---|
| Setup | Register, get key | None — just a wallet |
| Auth | x-elfa-api-key header | PAYMENT-SIGNATURE header (x402 v2) |
| Billing | Monthly credits or PAYG | Per-request USDC |
| Identity | API key | Wallet address |
| Rate Limit | Per API key (60-120 RPM) | 1,000 RPM baseline (currently per client IP) |
| Best For | Apps, dashboards | AI agents, bots |
Both access modes are independent. x402 does not consume API key credits. See x402 Rate Limits for implementation details.
Client Libraries
| Package | Description |
|---|---|
@x402/fetch | Drop-in fetch wrapper (auto-handles 402) |
@x402/axios | Axios interceptor |
@x402/core | Core protocol types and utilities |
@x402/evm | EVM payment signing (USDC on Base, Arbitrum, Polygon, Avalanche) |
@x402/svm | Solana payment signing (USDC on Solana) |