x402 pricing & payment
Each paid request is paid separately with one USDC transfer on Algorand mainnet, using the x402 v2 protocol.
Prices
Section titled “Prices”| API | Price | Amount (USDC base units) |
|---|---|---|
Web search, /v1/search |
0.01 USDC per query | 10000 |
Page scrape, /v1/scrape |
0.01 USDC per page | 10000 |
Each route has its own price. Read the current price from the route’s 402 response or from its free pricing route: /v1/search/pricing or /v1/scrape/pricing.
Payment parameters
Section titled “Payment parameters”| Field | Value |
|---|---|
| Protocol | x402 v2 |
| Scheme | exact |
| Network | algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73k (Algorand mainnet; the full-genesis-hash form is also accepted) |
| Asset | USDC, ASA 31566704 (6 decimals) |
| Amount | 10000 = 0.01 USDC |
| Receiving address | Listed in every 402 response (payTo) and on the pricing routes |
The payment flow
Section titled “The payment flow”- Request. Call a paid route as usual.
- 402. The API answers
402 Payment Required. ThePAYMENT-REQUIREDheader holds base64-encoded JSON that lists the accepted payments, and the response body holds the same JSON. - Sign. Your client signs one USDC asset transfer for exactly that amount to the
payToaddress. - Retry. Send the same request again with the signed payment in the
PAYMENT-SIGNATUREheader. The API also accepts the olderX-PAYMENTheader. - 200. The API returns the result. The
PAYMENT-RESPONSEheader holds the payment’s transaction id.
Your paying account needs:
- at least 10× the price in USDC
- a little ALGO to cover the network fee
Client example (Node.js)
Section titled “Client example (Node.js)”The official @x402/fetch and @x402/avm packages handle the 402 and the retry. Python users can use the x402 package.
npm install @x402/core @x402/fetch @x402/avmimport { x402Client } from "@x402/core/client";import { wrapFetchWithPayment } from "@x402/fetch";import { ALGORAND_MAINNET_CAIP2, ExactAvmScheme, toClientAvmSigner } from "@x402/avm";
// Base64 secret key of an account funded with USDC and a little ALGOconst signer = toClientAvmSigner(process.env.ALGORAND_SECRET_KEY_B64);const client = new x402Client().register(ALGORAND_MAINNET_CAIP2, new ExactAvmScheme(signer, { algodUrl: "https://mainnet-api.4160.nodely.dev" }));const paidFetch = wrapFetchWithPayment(fetch, client);
const res = await paidFetch("https://x402.api.nodely.io/v1/search", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query: "algorand x402", max_results: 5 }),});console.log(await res.json());What is not charged
Section titled “What is not charged”- A search where no engine returns any results.
- A scrape that fails (
502 scrape_failed) or times out (504 scrape_timeout). - A scrape where the target page answers with HTTP 4xx or 5xx.
- A request rejected before payment, for example invalid input (
400).
You can retry a failed attempt with the same signed payment. The number of free retries is limited.
Errors
Section titled “Errors”Error responses are JSON:
{ "error": { "code": "scrape_failed", "message": "…" }, "request_id": "…" }| Status | Meaning |
|---|---|
400 |
Invalid request (bad fields, a disallowed URL). Not charged. |
402 |
Payment required, or the payment was rejected. The error field says why. |
429 |
Too many requests. |
502 |
Upstream failure, for example scrape_failed. Not charged. |
503 |
Service temporarily unavailable. |
504 |
Scrape timed out (scrape_timeout). Not charged. |