# Use the Roundhouse facilitator

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

Section: Guides
Source: https://www.roundhouse.studio/docs/guides/use-the-roundhouse-facilitator

---

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:

| Endpoint | Purpose |
| --- | --- |
| `GET /` | Service descriptor — endpoints, chains, configured dependencies |
| `GET /supported` | Payment kinds, signers and fee payers per chain |
| `POST /verify` | Verify a payment payload against your requirements |
| `POST /settle` | Settle a verified payment on-chain from the facilitator wallet |
| `GET /test/x402` | The 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`](https://www.roundhouse.studio/facilitators/roundhouse) — its own record: volume relayed, who it
  settles for, and how steady it has been.
- [`/facilitators`](https://www.roundhouse.studio/facilitators) — the same figures for every facilitator we can attribute, so
  "ours" is a comparison you can check rather than a claim.

```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

- [Your first x402 payment](https://www.roundhouse.studio/docs/guides/first-x402-payment) — pay a cent, with every header shown.
- [Charge for your API](https://www.roundhouse.studio/docs/guides/charge-for-your-api) — the seller side end to end.
- [Pay an agent without gas](https://www.roundhouse.studio/docs/guides/pay-an-agent-without-gas) — the same EIP-3009 mechanism,
  used to forward USDC rather than to buy something.

---

Every page in these docs is available as markdown at its own URL plus `.md`.
Full index: https://www.roundhouse.studio/docs.md
