vulnfeedby Novadyne

x402 Explained: How HTTP 402 Enables Payments for AI Agents

HTTP has had a payment status code since 1997. 402 Payment Required was reserved in the original HTTP/1.1 spec “for future use.” For almost 30 years, nobody used it.

That changed with x402 — an open protocol that gives 402 a real meaning. When an API returns 402, the response body tells the client exactly how to pay: what token, what network, how much, and where to send it. The client signs a payment, attaches it to the next request, and gets the response. No accounts. No API keys. No invoices.

This article explains how x402 works, why it matters for AI agents, and how we use it in production.

The problem: AI agents can't sign up for things

Traditional APIs require authentication — create an account, get an API key, maybe enter a credit card. That works for humans. It doesn’t work for autonomous agents.

An AI agent that needs to call an unfamiliar API faces a chicken-and-egg problem: it needs credentials to make requests, but getting credentials requires human intervention. Every new service is a manual setup step.

x402 removes that step entirely. The agent makes a request, gets a 402 response with payment terms, pays with a crypto wallet, and gets the data. The entire flow is machine-readable. No signup forms, no OAuth flows, no humans in the loop.

How x402 works

The protocol is straightforward. Here’s what happens when a client hits an x402-enabled endpoint:

1
Client sends a normal HTTP request. No special headers needed on the first attempt.
2
Server returns 402 Payment Required. The response body includes a JSON object with the payment requirements: recipient wallet address, token contract (USDC), network (Base), and price.
3
Client signs a payment authorization. Using an EVM wallet, the client creates a signed payment message and sends it to a facilitator — a third-party service that verifies the signature and handles settlement.
4
Client retries with X-PAYMENT header. The signed payment token goes in a standard HTTP header. The server verifies it with the facilitator, then returns the actual response.

Here’s what a 402 response looks like in practice:

HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "x402Version": 1,
  "accepts": [
    {
      "scheme": "exact",
      "network": "base-mainnet",
      "maxAmountRequired": "10000",
      "resource": "GET /vulnscan/query",
      "description": "Dependency vulnerability scan",
      "payTo": "0xBEccE6dd106Cfa910F78fea188B2fcCEb73bdD0F",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "extra": {}
    }
  ]
}

Everything the client needs to pay is right there: the network (base-mainnet), the token (USDC contract address), the amount (in token base units — 10000 = $0.01 USDC), and the recipient address.

USDC on Base: why this combination

x402 settles in USDC (a dollar-pegged stablecoin) on Base (Coinbase’s L2 network). This isn’t arbitrary:

For micropayments — the kind of payments AI agents make (a cent per API call) — this combination works where credit cards can’t. Stripe’s minimum charge is $0.50, and they take 2.9% + $0.30 per transaction. That makes a $0.01 API call impossible with traditional payment rails.

The facilitator

The facilitator is the trusted middleman that makes x402 practical. When a client presents a signed payment, the server doesn’t verify the blockchain transaction directly. Instead, it sends the payment token to a facilitator, which:

  1. Verifies the client’s signature is valid
  2. Checks the client has sufficient USDC balance
  3. Settles the payment on-chain (transfers USDC from client to server)
  4. Returns a verification receipt to the server

This keeps the server simple. Your API doesn’t need to interact with the blockchain — it just talks HTTP to the facilitator. xpay.sh is one facilitator that supports Base mainnet with zero fees and gas-sponsored settlement.

Discovery: how agents find x402 services

For x402 to work with autonomous agents, services need to be discoverable. The protocol defines two mechanisms:

An agent that knows about x402 can discover a service, read its pricing from the 402 response, decide whether to pay, and complete the transaction — all without human intervention.

Building an x402-enabled API

From the server side, implementing x402 requires three things:

  1. Return 402 for unpaid requests. Include the payment requirements JSON in the response body.
  2. Check the X-PAYMENT header. When present, send it to the facilitator for verification. If valid, process the request normally.
  3. Publish discovery metadata. Add x-payment-info to your OpenAPI spec so agents can find your pricing before hitting the endpoint.

The client side is even simpler if you use a library like @x402/fetch. It wraps the standard fetch API and handles the 402 negotiation automatically:

import { paymentFetch } from "@x402/fetch";
import { createWalletClient } from "viem";

const response = await paymentFetch(
  "https://vulnfeed-api.novadyne.ai/vulnscan/query",
  {
    method: "POST",
    body: JSON.stringify({ packages: ["[email protected]"] }),
  },
  { walletClient }
);

const data = await response.json();

If the server returns 402, paymentFetch reads the payment requirements, signs the transaction with the provided wallet, and retries with the payment attached. The calling code just sees a normal response.

x402 in practice: VulnFeed and Ledger

We run two x402-enabled services in production:

Both are listed on x402scan.com with verified ownership proofs. Both support the same protocol, the same facilitator (xpay.sh), and the same USDC-on-Base settlement.

The combination of subscription and x402 is deliberate. Human developers prefer the predictability of a monthly subscription. AI agents prefer the simplicity of paying per request with no signup. Offering both means the service is accessible to both audiences.

What x402 isn’t

A few things to be clear about:

Getting started

If you want to experiment with x402:

The protocol is simple enough that a single developer can implement both sides in a day. We did.