Guides

Use the Roundhouse facilitator

Settle x402 payments on Base mainnet, whether you are paying or charging, with payers who hold no ETH.

A facilitator is the service that verifies an x402 payment payload and submits the settlement transaction on-chain. It is the piece that makes x402 gasless for the payer: the payer signs an EIP-3009 authorization, the facilitator broadcasts it and pays the gas.

Roundhouse runs a first-party one, on Base mainnet, free to point at.

https://x402.roundhouse.studio

Why you might want ours: the public x402.org/facilitator is EVM testnet only — it serves base-sepolia and has no Base mainnet facilitator at all. A mainnet-priced resource can never settle through it, whatever the payload looks like.

Check what it serves, first#

Not decoration. A facilitator that does not serve your chain answers 500 with No facilitator registered for scheme: exact and network: <x>, which reads like a broken payment and is a configuration problem.

bash
curl -s https://x402.roundhouse.studio/supported
json
{
  "kinds": [
    { "x402Version": 1, "scheme": "exact", "network": "eip155:8453", "extra": { "feePayer": "0x…" } }
  ],
  "signers": { "eip155:*": ["0x…"] }
}

GET / returns a plain-language service descriptor — endpoints, monitored chains, and which dependencies are configured. It is the quickest health check there is.

As a client: you are paying#

An off-the-shelf x402 client needs no facilitator configuration at all — the resource server names its own. You only reach for one directly when you want a supported-kinds list up front, or a settlement receipt of your own.

ts
import { wrapFetchWithPayment } from 'x402-fetch';
import { privateKeyToAccount } from 'viem/accounts';

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const fetchWithPayment = wrapFetchWithPayment(fetch, account);

const res = await fetchWithPayment('https://www.roundhouse.studio/api/v0/test/x402');

Fund the wallet with a little USDC on Base. It needs no ETH — the facilitator submits the transaction and pays the gas.

Note

GET /v0/test/x402 costs $0.01 and hands back an API key with a higher POST /v0/sql rate limit, so the cent is not wasted. It is the cheapest end-to-end proof that your wallet, your client and the settlement path all work.

As a seller: you are charging#

Point your paywall's facilitator URL at Roundhouse and speak the standard x402 wire format.

bash
X402_FACILITATOR_URL="https://x402.roundhouse.studio"
X402_FACILITATOR_FORMAT="standard"

Outside this repo, set whatever your x402 middleware calls its facilitator URL. The endpoints are the standard ones:

EndpointPurpose
GET /Service descriptor — endpoints, chains, configured dependencies
GET /supportedPayment kinds, signers and fee payers per chain
POST /verifyVerify a payment payload against your requirements
POST /settleSettle a verified payment on-chain from the facilitator wallet
GET /test/x402The facilitator's own paywalled test resource, for checking it in isolation

Request bodies are { x402Version, paymentPayload, paymentRequirements }. paymentRequirements must be exactly what you published — the facilitator compares the signed payload against them, so a single changed field reads back as "signature does not authorize this transfer".

The one mistake everybody makes#

paymentPayload is an object, not the base64 X-PAYMENT header value. Base64 is only how the payment travels over HTTP; on a /verify or /settle call it must be the decoded envelope:

json
{
  "x402Version": 1,
  "paymentPayload": {
    "x402Version": 1,
    "scheme": "exact",
    "network": "base",
    "payload": {
      "signature": "0x…",
      "authorization": {
        "from": "0x…",
        "to": "0x…",
        "value": "10000",
        "validAfter": "…",
        "validBefore": "…",
        "nonce": "0x…"
      }
    }
  },
  "paymentRequirements": { "…": "exactly what you published" }
}

Hand it the base64 string instead and a conformant facilitator answers 500 No facilitator registered for x402 version: undefined — it reads x402Version off that object, and a string has no fields.

Two more things that fail the same way and are worth ruling out before you debug a signature:

  • Addresses must be EIP-55 checksummed before anything hashes them. viem validates checksums inside hashTypedData, so a lowercased address fails at the facilitator as "signature does not authorize this transfer" — which cannot be fixed by re-signing.
  • Read the price from the live 402, never from a cached figure. The operator can change it, and a stale quote fails verification.

What running through ours gets you#

  • Your payers need no gas. USDC only, no native token, no top-up step in your onboarding.
  • You find out which endpoint earned it. A settlement we relay carries the resource that was paid for. Read off the chain alone it is a bare USDC transfer to your wallet, so forty endpoints behind one payTo collapse into one line — through ours, each endpoint has its own revenue, price and traffic.
  • You learn who your customers are. Payers resolve to identities where identities exist, and the endpoint each one bought is attached — so repeat buyers, what they spend and which service brings them back are answerable questions rather than a list of addresses.
  • Your service is named across the index, not inferred: a named route on the flow graph instead of "route unknown", and a merchant page listing your endpoints rather than an unattributed wallet. (Named, not ranked — Roundhouse publishes no leaderboards.)
  • Failures are visible. Every verify and settle attempt is captured, successful or not — so a payment that never landed on-chain is still diagnosable. A chain indexer can never do that, because there is nothing on the chain to index.

See it working#

Every settlement relayed by this facilitator is public, like every other:

  • /facilitators/roundhouse — its own record: volume relayed, who it settles for, and how steady it has been.
  • /facilitators — the same figures for every facilitator we can attribute, so "ours" is a comparison you can check rather than a claim.
Agent prompt
Using Roundhouse, set me up to charge for an API over x402 on Base mainnet, settling through the
Roundhouse facilitator at https://x402.roundhouse.studio. Show me the 402 challenge my
endpoint should return, and the verify and settle calls I need to make. Then check the
facilitator is serving my network with GET /supported before we start.

Next steps#