Protocol Reference

Welcome to the NZRT Wiki Podcast. Today we’re looking at Protocol Reference.

This episode walks you through the x402 payment protocol — the HTTP headers involved, what the payment objects contain, how the facilitator API works, and how to wire it all up with the official SDK. Let’s get into it.

Start with the headers, because they’re the backbone of the whole flow. When your client hits a protected endpoint without having paid, the server returns a 402 response. That response includes a header called X-Payment-Requirements, which carries a Base64-encoded block describing exactly what payment is needed. Once your client has sorted out the payment, it retries the original request with a header called X-Payment — also Base64-encoded — containing the payment details. If everything checks out, the server comes back with a 200, and includes a third header: X-Payment-Response, a Base64-encoded settlement confirmation. So to recap: requirements come down from the server, payment goes up from your client, and the settlement confirmation comes back down.

Now let’s look at what’s inside those Base64 blobs. The payment requirements object — the one you get in the 402 — contains a version number and an array of accepted payment options. Each option in that array tells you the payment scheme, which is called “exact”, the network identifier, the maximum amount required expressed in atomic units — and worth noting here, USDC uses six decimal places — the full URL of the protected endpoint, a human-readable description, the expected response type, the payee’s Ethereum address, a timeout window in seconds, the USDC contract address on that network, and optionally a name and version identifying the token. For USDC that version is two, following the EIP-3009 standard.

The payment payload — what your client sends back in that X-Payment header — also has a version number and a scheme field. The core of it is a payload section with two parts. First, a signature: a hex-encoded cryptographic signature proving you authorised the transfer. Second, an authorization block containing the payer’s address, the payee’s address, the amount in atomic units, two timestamps marking when the authorization becomes valid and when it expires, and finally a random nonce — a 32-byte hex value that ensures the same authorization can’t be replayed in a future request.

Moving on to the Facilitator API, hosted at x402.org/facilitator. This is the service that verifies and settles payments on your behalf, and it exposes two endpoints. The first is the verify endpoint. You post to it with the payment payload and the payment requirements, and it responds with a simple result: either the payment is valid, or it is not, along with a reason string if something went wrong. The second endpoint is settle. Same input structure, and if successful, the response tells you the transaction was successful, gives you the transaction hash, and confirms which network the settlement occurred on.

On the subject of error codes, here are the HTTP status codes you’ll encounter. A 402 with the requirements attached means you need to pay before proceeding. A 400 means your payment header was malformed and couldn’t be parsed at all. Another 402 can come back even after you’ve submitted payment, if the signature check failed. And a 200 means you’re good — content is returned. On the facilitator side, when a payment comes back as invalid, the reason will be one of five values: invalid signature, insufficient amount, expired, nonce already used, or invalid network.

Now for the cryptographic layer underneath all of this. x402 uses a standard called EIP-3009, specifically a typed data structure called TransferWithAuthorization. The signing domain is set up for USD Coin version two, on chain ID 8453 — that’s the Base network — pointing to the USDC contract address on that chain. The typed data itself defines six fields: the from and to addresses, the value as a large unsigned integer, two timestamp fields for the valid-after and valid-before window, and the nonce as a 32-byte value. This is the structure that the payer signs to produce the signature you saw in the payment payload object earlier.

Finally, if you’re working in TypeScript or JavaScript, there’s an official SDK available through npm. You import a middleware function from the x402 package, attach it to your Express application with your wallet address and a configuration object that maps your API routes to their prices and target networks, and the middleware handles everything from there — generating the 402 responses, calling the facilitator to verify incoming payments, and settling them automatically. You don’t need to manually wire up any of the facilitator calls if you’re using the SDK.

That’s it for this episode of the NZRT Wiki Podcast. Thanks for listening.