How AI agents pay for APIs with x402 and HTTP 402

How AI agents pay for APIs with x402: the 402 response, the signed USDC authorization, verify and settle, and how 402check wires it into one Worker.

An AI agent that needs one company record, one sanctions screen or one archived web page has a payment problem. It cannot fill in a sign-up form, it should not hold your card number, and a monthly plan is the wrong shape for a single call that costs a few cents. x402 is a protocol that answers this inside HTTP itself: the server says what a call costs, the agent pays for that call, and the request goes through. This article walks through the exchange as the specification defines it, then shows how 402check implements it on its paid routes.

The status code that waited for a protocol

HTTP has had a status code for this for a long time. RFC 9110, section 15.5.3 defines it in one sentence: "The 402 (Payment Required) status code is reserved for future use." The status exists, but HTTP never said what a client should do when it receives one.

x402 fills that gap. It keeps 402 as the signal and adds a machine-readable description of the price, a way for the client to attach a payment to its retry, and a third party (the facilitator) that checks and executes the payment, so the API server never touches a private key.

The exchange, step by step

The x402 v2 specification and its HTTP transport describe the default flow, which the spec calls authorization:

  1. The client requests the resource like any other HTTP call.
  2. The server answers 402 and puts the payment requirements, a base64-encoded PaymentRequired object, in the PAYMENT-REQUIRED response header. It names the scheme, the network, the amount, the asset and the address to pay.
  3. The client builds a signed payment authorization and repeats the request with it in the PAYMENT-SIGNATURE header.
  4. The server sends that payload to the facilitator's POST /verify, which is read-only. If it verifies, the server runs the handler, then calls POST /settle to execute the payment, and returns the result with settlement details in the PAYMENT-RESPONSE header.

Two details matter for an agent. First, the price is known before anything is signed: the agent, or the policy around it, can refuse a call that costs more than it expects. Second, in this flow the payment is verified before the work and settled after it, so the server can decline to settle when the work failed.

What the agent actually signs

For EVM networks the spec's exact scheme relies on EIP-3009, "Transfer with Authorization", so the token has to be an ERC-20 that implements it; the spec uses USDC as its example. The agent signs an EIP-712 typed message with these fields:

  • from and to: the payer's address and the address from the requirements
  • value: the amount, in the token's smallest unit
  • validAfter and validBefore: the time window in which the authorization can be used
  • nonce: 32 random bytes, so the same authorization cannot be replayed

The agent never sends a transaction itself. It signs a message that lets someone else move exactly that amount, to exactly that address, within that window, once. The facilitator submits it.

Networks are named with CAIP-2 identifiers, {namespace}:{reference}. The spec lists eip155:8453 as Base mainnet and eip155:84532 as Base Sepolia, the test network.

How 402check uses it

402check offers seven data tools (one coming soon, proof_get free) over plain HTTP and over MCP. The prices live in one file, src/pricing.ts, and every page and payment requirement reads them from there. A Romanian company lookup (ro_company) or an OFAC screen (us_sanctions, coming soon) is $0.01, a SICAP tender search (ro_tenders), a US court search (us_court) or a USPTO trademark search (us_trademark) is $0.02, and archiving a web page as evidence (proof_create) is $0.25. Reading a stored proof back (proof_get) is free.

x402 is one of three ways to pay, and the server decides which one applies to each call, in this order:

  1. A credits key. If the request carries Authorization: Bearer rk_…, the key pays and the free tier is not touched. Keys come from buying $5 or $20 of credits by card at /buy, with no account.
  2. The free tier. Without a key, the first 10 calls a day per IPv4 address (per /64 for IPv6) are free, with a global cap of 5,000 free calls per UTC day. proof_create is never part of the free tier.
  3. x402. Only a call that neither of the above can serve reaches x402. It pays USDC on Base (eip155:8453), and settlement goes through the Coinbase CDP facilitator.

That order is the access middleware in the Worker. Every tool route runs it before its handler:

TypeScript src/access/middleware.ts
export function accessFor(tool: ToolName): MiddlewareHandler<AccessEnv> {
  return async (c, next) => {
    const access = await resolveAccess(c.env, tool, callerOf(c));
    if (access.kind === "coming_soon") {
      await settle(c.env, tool, access, 503);
      return c.json(COMING_SOON_BODY, 503);
    }
    if (access.kind === "key_denied") return c.json(access.denial.body, access.denial.status);
    if (access.kind === "unpaid") return runX402(c, next, tool, access.reason);
    setAccess(c, access.kind, access.payer);
    await next();
    await settle(c.env, tool, access, c.res.status);
  };
}

resolveAccess returns one of five outcomes. Only unpaid touches x402, which means free-tier and key calls never build the payment middleware at all, and a facilitator outage cannot break them. For key calls, settle charges the key only when the handler answered 2xx.

Failure modes we chose on purpose

A paid API has to decide what happens when the payment layer itself misbehaves. These are the rules in the 402check code:

  • Failed calls are free. A key is charged only on a 2xx response, and the x402 path does not settle a non-2xx response. A 502 upstream_error from a data source or a 400 invalid_query costs nothing.
  • The payment check fails closed. If a request reaches the x402 branch on a path that is not in the x402 route map, the server answers 402 payment_required instead of running the handler unpaid.
  • A broken facilitator is a refusal, not a crash. If x402 cannot be initialized (bad credentials, facilitator down), that call gets a plain 402 payment_required JSON body instead of a 500, and the error is logged.
  • A refused keyless call explains itself. When the reason is not the caller's own quota, the 402 body carries a reason: not_in_free_tier for proof_create, free_tier_exhausted_today when the global daily cap is reached.

HTTP and MCP

The same tools are exposed as an MCP server at /mcp (Streamable HTTP, stateless). Payment there is decided per tool call, not per connection, but x402 works only on the /v1 HTTP routes today: over MCP an agent uses the free tier or sends a credits key in the Authorization header. If your agent framework can make HTTP calls with an x402 client, the HTTP routes are the way to pay per call without any prior setup.

On the client side you do not implement the signing yourself. An x402 client such as @x402/fetch reads the requirements from the 402, signs with the agent's wallet and repeats the request. The paid routes are also described for x402 Bazaar discovery, and /openapi.json lists every price in x-price-usd, so an agent can learn what a call costs before making it.

Try it

proof_create is the one tool with no free tier, so a keyless call shows the payment step directly. The response is 402; with x402 enabled, the requirements are in the PAYMENT-REQUIRED header and the JSON body says why the free tier did not apply:

Shell
curl -i -X POST "https://402check.com/v1/proof" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/"}'

Nothing is captured and nothing is charged until a payment or a key comes with the request. The parameters, the response format and the evidence semantics are on the proof_create docs page; prices and payment options are on the pricing page.