x402 Explained: How an Autonomous Agent Pays for an API Call
Published by call402 — a pay-per-call API store for autonomous agents. Every paid endpoint mentioned below is live; the payment trace in this article is a real one, captured from this site.
Your agent is halfway through a task and needs one piece of paid data: a phone-number check, an exchange rate, a company filing. A human would open a pricing page, create an account, add a card and paste an API key. An agent cannot do most of that. x402 is an open standard that turns the purchase into part of the HTTP exchange itself: the server quotes a price in its response, the agent signs a payment, and the same request is retried with proof of payment attached.
This article explains what x402 is, walks through the negotiation flow message by message, separates negotiation (HTTP headers) from settlement (the on-chain transfer), and ends with a complete worked example using a real endpoint and its real payment requirements — not testnet placeholders.
What x402 is
The x402 specification describes itself as "an open payment standard that enables clients to pay for external resources" (x402 spec v2, section 1). The official docs describe it as "built around the HTTP 402 Payment Required status code" and allowing "clients to programmatically pay for resources without accounts, sessions, or credential management" (docs.x402.org). It is published under the Apache-2.0 license, and the docs state that "x402 as a standard has 0 fees built in" (same page).
The status code it builds on is old. RFC 9110, the current HTTP Semantics standard, still says only: "The 402 (Payment Required) status code is reserved for future use" (RFC 9110, section 15.5.3). x402 gives that code a concrete, machine-readable meaning.
The three parties
The spec defines three components (spec v2, section 3):
- Resource server: the API that wants to be paid. In this article, that is call402.com.
- Client: "any application or agent that requests access to protected resources". This is your agent.
- Facilitator: "a service that handles payment verification and blockchain settlement". call402 settles through Coinbase's CDP facilitator.
The facilitator is optional. The docs call it "optional but recommended" and note that it "does not hold funds or act as a custodian"; it verifies and submits transactions based on payloads the client signed (docs: Facilitator). A server can also verify and settle locally.
Negotiation vs. settlement
This distinction is the most useful mental model for an agent developer.
- Negotiation happens in HTTP. The server says what it accepts, the client answers with a signed authorization. Nothing has moved on any chain yet. In protocol version 2 this uses three headers, each carrying Base64-encoded JSON (HTTP transport v2):
| Header | Direction | Carries |
|---|---|---|
PAYMENT-REQUIRED | server to client, with status 402 | PaymentRequired object |
PAYMENT-SIGNATURE | client to server, on the retry | PaymentPayload object |
PAYMENT-RESPONSE | server to client, with the result | SettlementResponse object |
- Settlement happens on a ledger. The facilitator's
POST /verifyendpoint is defined as read-only: it "MUST NOT commit payment state or write onchain state".POST /settleis the step that "durably commits payment state", typically by broadcasting a transaction (spec v2, sections 7.1 and 7.2).
If you have read older tutorials: protocol version 1 used X-PAYMENT for the client's payload and sent the requirements in the 402 response body. Version 2 renamed the headers and switched to CAIP-2 network identifiers such as eip155:8453 (Base mainnet) (V1 to V2 migration guide).
The flow, step by step
- The agent sends an ordinary request.
- The server answers
402 Payment Requiredwith aPAYMENT-REQUIREDheader listing one or more options inaccepts(scheme, network, amount, asset, payee). - The agent picks an option it supports and builds a
PaymentPayloadfor that scheme. - The agent retries the request with the payload in
PAYMENT-SIGNATURE. - The server calls the facilitator's
/verify(or verifies locally) and gets backisValid. - If valid, the server does the work.
- The server calls
/settle; the facilitator submits the transfer. - The server returns
200with the resource and aPAYMENT-RESPONSEheader containing the transaction hash.
Why the agent never needs gas: EIP-3009
For the exact scheme on EVM chains, the recommended transfer method is EIP-3009 transferWithAuthorization, used by tokens such as USDC (exact scheme on EVM). EIP-3009 lets a token holder sign an EIP-712 message authorizing a transfer, which someone else submits; its abstract lists "delegate the gas payment to someone else" as a goal. Each authorization carries validAfter, validBefore and a random 32-byte nonce rather than a sequential one.
So the agent's wallet signs a message; it does not send a transaction. The facilitator broadcasts it and pays the gas. The x402 EVM scheme spec states that "the Facilitator cannot modify the amount or destination". Replay protection comes from the nonce, which the token contract refuses to reuse, plus the validity window (spec v2, section 10.1).
A worked example, end to end — on a live API
Everything below is real. The endpoint is call402's phone-number lookup, live on Base mainnet, priced at $0.005. You can reproduce step 2 right now with one curl command.
1. The agent asks. POST https://call402.com/api/phone-lookup with body {"number": "+14155552671"} and no payment header.
2. The server quotes. It returns HTTP 402 with a PAYMENT-REQUIRED header. Decoded from Base64, this is the actual response captured from the live server:
{
"x402Version": 2,
"error": "Payment required",
"resource": {
"url": "https://call402.com/api/phone-lookup",
"description": "Parse a phone number locally against the numbering plan using libphonenumber metadata...",
"mimeType": "application/json"
},
"accepts": [{
"scheme": "exact",
"network": "eip155:8453",
"amount": "5000",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0xAc6F1C3C3b17040730F16dC24Ee9993e9565BE4A",
"maxTimeoutSeconds": 300,
"extra": { "name": "USD Coin", "version": "2" }
}]
}
Read it like a price tag: amount is in atomic units — 5000 with USDC's 6 decimals is exactly 0.005 USDC. asset is the USDC contract on Base, payTo is the store's wallet, and extra.name / extra.version are the token's EIP-712 domain values your signature must use.
3. The agent decides and signs. Before signing, a careful agent checks the quote against its own policy: is the network one it holds funds on, is the asset the token it expects, is 0.005 USDC within its per-call budget? The core spec lists "client-side budget management" as out of scope, so the policy belongs to your client implementation. It then signs an EIP-3009 authorization naming the quoted payTo, the quoted amount, a validity window and a random nonce.
4. The agent retries. Same POST, now with the signed payload in the PAYMENT-SIGNATURE header.
5. Verification (no money moves). The server asks the facilitator to verify: signature recovers to the payer, balance covers the amount, amount/window/token/network all match the quote, and a simulated transferWithAuthorization succeeds.
6. The work. The API parses the number against the numbering plan.
7. Settlement (money moves). The facilitator broadcasts the signed authorization; 0.005 USDC moves from the agent's address to payTo on Base.
8. Delivery. The server returns 200 with the result and a PAYMENT-RESPONSE header carrying the settlement transaction hash:
{
"valid": true,
"possible": true,
"e164": "+14155552671",
"international": "+1 415 555-2671",
"country": "US",
"type": "fixed_or_mobile",
"data_source": "numbering plan (libphonenumber)"
}
Total elapsed time for steps 2–8 in production: about a second. No account, no API key, no checkout page — the HTTP exchange is the checkout.
In code
You rarely build these headers by hand. The buyer quickstart shows a fetch wrapper that performs steps 2 to 4 automatically:
import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`);
const client = new x402Client();
client.register("eip155:*", new ExactEvmScheme(signer));
const fetchWithPay = wrapFetchWithPayment(fetch, client);
const res = await fetchWithPay("https://call402.com/api/phone-lookup", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ number: "+14155552671" }),
});
console.log(await res.json()); // the lookup result, paid and settled
What you can buy this way
call402 runs 14 pay-per-call endpoints on this exact flow, $0.002–$0.005 each: text structuring, FX reference rates (ECB), email verification, phone lookup, fear & greed index, SSL and domain checks, SEC company facts, QR generation, DEX quotes and more. The machine-readable catalog — the same one agents read — is at call402.com/pricing.
Going further: the x402 Integration Pack is a paid endpoint on this very store ($0.005, POST /api/x402-integration-pack). It returns production buyer code in TypeScript and Python, a settlement-verification recipe, the failure-reason table with fixes, and a budget-guard pattern for autonomous agents. Buying it is itself an x402 payment — the guide's own checkout is its final worked example.
---
Doc ref: C402-GUIDE-2510 · call402.com · Prices and the payment trace verified live at publication.