Quickstart

x402 Quickstart: First Paid Request End to End

Use this page to learn the first x402 payment loop before you commit to a full seller, agent, or facilitator integration.

The loop you are learning

The first paid request is a normal HTTP request with one extra negotiation step. The buyer tries to fetch a resource. The seller decides that the resource is paid and returns HTTP 402 with payment requirements. The buyer chooses an acceptable requirement, signs a payment payload, retries the request, and receives the resource after the seller verifies and settles the payment.

Keep two boundaries clear. HTTP carries the negotiation. The payment scheme and network decide how a buyer signs and how settlement is executed. x402 can support multiple networks, and the official docs use CAIP-2 identifiers such as eip155:84532 for Base Sepolia and Solana genesis-hash identifiers for Solana networks.

"The buyer prepares and submits a payment payload."
Primary source: x402 docs: Introduction

1. Start with the seller side

The official seller quickstart begins with testnet configuration. That is the right first move because it lets you test wallet addresses, payment requirements, facilitator behavior, and failure handling before real funds are involved. The server advertises what it accepts: scheme, price, network, destination address, description, and response MIME type.

Seller sketch
import express from "express";
import { paymentMiddleware, x402ResourceServer } from "@x402/express";
import { HTTPFacilitatorClient } from "@x402/core/server";
import { ExactEvmScheme } from "@x402/evm/exact/server";

const app = express();
const facilitator = new HTTPFacilitatorClient({
  url: "https://x402.org/facilitator",
});

const resourceServer = new x402ResourceServer(facilitator)
  .register("eip155:84532", new ExactEvmScheme());

app.use(paymentMiddleware({
  "GET /weather": {
    accepts: [{
      scheme: "exact",
      price: "$0.001",
      network: "eip155:84532",
      payTo: process.env.EVM_RECEIVE_ADDRESS,
    }],
    description: "Weather data",
    mimeType: "application/json",
  },
}, resourceServer));

app.get("/weather", (_req, res) => {
  res.json({ report: { weather: "sunny", temperature: 70 } });
});

app.listen(4021);

Treat this as a learning skeleton, not production configuration. Put the receive address in environment configuration, keep route prices small during testing, and confirm the imported package names against the current official docs before shipping. The key design point is that the API route remains ordinary business logic; the payment middleware guards the route before the handler returns paid data.

Unpaid request check
curl -i http://localhost:4021/weather

# Expected shape:
# HTTP/1.1 402 Payment Required
# ...payment requirements are returned by the x402 middleware...

2. Add the buyer retry

On the buyer side, the official docs show payment-aware wrappers for fetch, Axios, Go, and Python clients. The important idea is that the agent or app needs a wallet signer plus a registered scheme for the network it is willing to pay on. The wrapper handles the 402 response and retries with payment headers.

Buyer sketch
import { wrapFetchWithPayment, x402HTTPClient } 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);
const client = new x402Client();
client.register("eip155:*", new ExactEvmScheme(signer));

const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const httpClient = new x402HTTPClient(client);

const response = await fetchWithPayment("http://localhost:4021/weather");
const result = await httpClient.processResponse(response);

console.log(result.paymentStatus, result.body);

In a real agent, this call should sit behind a spending policy. Do not give a general-purpose agent an unlimited wallet and every URL on the internet. Give it an allowlist, a per-request ceiling, a daily budget, logging for payment decisions, and a dry-run mode that prints the payment requirements without paying.

3. Checkpoints before moving on

  1. The unpaid request returns HTTP 402, not a generic 500 or 403.
  2. The 402 response contains enough payment requirements for your buyer client to choose a route.
  3. The paid retry returns the resource and exposes a payment result you can log.
  4. Invalid or underfunded wallet paths fail clearly without serving the paid resource.
  5. Your tutorial notes include which network, token, facilitator, SDK version, and route price you tested.

Once those checks pass, continue to the seller track to make the resource server robust, or the buyer agent track to add policy and idempotent retries.

Sources used

  1. x402 docs: Introduction

    Defines x402 as an open payment standard for charging APIs and content directly over HTTP.

  2. x402 docs: HTTP 402

    Explains how x402 uses HTTP 402 to communicate payment requirements.

  3. x402 docs: Quickstart for Sellers

    Official seller setup, package installation, testnet defaults, and payment middleware examples.

  4. x402 docs: Quickstart for Buyers

    Official buyer setup, client package installation, and fetch/axios payment wrappers.

  5. x402 Foundation GitHub repository

    Open-source SDKs, examples, and the typical x402 request/payment/settlement flow.

  6. RFC 9110: HTTP Semantics, section 15.5.3

    The HTTP specification reserves status code 402 for future use.