x402.md

August 7, 2026 · View on GitHub

PubFi supports accountless x402 payment on explicitly enabled Registry v2 gateway routes. The caller uses a wallet authorization instead of creating a PubFi account or API key.

Environment And Availability Boundary

PubFi keeps Staging and Production payment networks separate:

EnvironmentAPI originMCP originPermitted x402 network
Staginghttps://api-stg.pubfi.aihttps://mcp-stg.pubfi.aiBase Sepolia eip155:84532
Productionhttps://api.pubfi.aihttps://mcp.pubfi.aiBase mainnet eip155:8453, only when the exact route has x402 enabled

This table is an environment policy. It does not prove that any route or offer is currently available. Inspect GET /v1/capabilities on the selected API origin. Then inspect the exact route's unsigned 402 challenge. The live catalog is the route authority, and the live challenge is the payment-term authority.

Use a different dedicated wallet and private key for each environment. Never reuse a Staging wallet, private key, or payment authorization in Production, or the reverse.

The public Base Sepolia walkthrough is Staging-only. Select its resource from the current catalog:

<GET or POST> https://api-stg.pubfi.ai<exact ready Quantro-priced path>

The selected method must have operations[].billing.mode set to quantro_priced. Exact health operations are free_health; they bypass x402 and are not payment examples.

The example client requires:

FieldExample policy
x402 version2
schemeexact
networkeip155:84532
assetcanonical Base Sepolia USDC
transfer methodEIP-3009
financial valuenone; testnet only

See the Staging guide before you configure endpoints or credentials.

Historical Production Base Mainnet Example

The separate Production example is pinned to the route and payment boundary accepted on 2026-07-27:

FieldRequired value
HTTP resourcehttps://api.pubfi.ai/v1/gateway/quantro/health
MCP endpointhttps://mcp.pubfi.ai
NetworkBase mainnet eip155:8453
Assetcanonical Base USDC 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913
Amount1000 atomic units, or 0.001 USDC
Payee0x35764549c387f6befcbe6d03e6bfbd7ade4543b6
Transfer methodEIP-3009

This is historical acceptance evidence, not a current payment example. Under schema v5, exact health operations are free_health and bypass x402. Do not run the archived paid commands against that route. For a current Production payment, select a ready non-health quantro_priced operation from the complete Production catalog and validate its unsigned challenge with a separately reviewed mainnet wallet policy.

See the Production Base mainnet example for the pinned HTTP and MCP commands.

The Production acceptance run completed on 2026-07-27 with the official x402 clients. The workflow link requires access to the source repository; the Base transactions below are public:

LaneBase transactionVerified result
HTTP0xb011351c…cc594f200, PAYMENT-RESPONSE, signed receipt, exact replay
MCP0x25819c48…3f9934paid tool result, signed receipt, exact structured-content and payment-metadata replay

Both requests used Base mainnet, canonical USDC, and the pinned 0.001 USDC offer. The test kept the buyer key and full payment evidence outside public output.

A bounded Quantro read-only acceptance confirmed one settled settlement and one signed receipt for each lane. Exact replay reused the first settlement and receipt; it did not create a second charge. The underlying Quantro records remain private.

Before You Pay In Staging

The numbered procedure below is Staging-only. A Production client must use the same selection and validation principles with a separate Base mainnet wallet policy; the pinned 2026-07-27 example is historical evidence only.

Prepare:

  • an x402 V2 client;
  • a dedicated Base Sepolia test wallet with test USDC;
  • an independently approved expected PubFi payee;
  • a maximum amount and authorization lifetime; and
  • a secret manager or wallet that keeps the buyer private key outside prompts, source code, logs, issues, and CI output.

The public runnable example rejects payments above 0.01 test USDC and authorizations longer than 300 seconds.

1. Request The Resource Without Auth

export X402_RESOURCE_URL='https://api-stg.pubfi.ai<exact ready Quantro-priced path>'

curl --include \
  "${X402_RESOURCE_URL}"

An eligible unpaid request returns:

  • HTTP 402 Payment Required;
  • a PAYMENT-REQUIRED header;
  • the same payment requirements in the JSON response; and
  • Cache-Control: private, no-store.

The payment requirement contains the exact resource URL, amount, asset, network, payee, scheme, transfer method, and authorization timeout.

2. Validate Before Signing

Use an x402 V2 client and reject the challenge unless every field matches your wallet policy. At minimum, validate:

  • the exact HTTPS resource;
  • x402 version 2 and scheme exact;
  • Base Sepolia network eip155:84532;
  • canonical Base Sepolia USDC;
  • EIP-3009;
  • the expected PubFi payee;
  • the maximum amount you authorize; and
  • the maximum authorization lifetime.

Keep the buyer private key in a secret manager or wallet. Do not place it in a prompt, source file, shell history, log, issue, or CI output.

3. Send The Signed Request

The x402 client repeats the exact request with PAYMENT-SIGNATURE. Do not add Authorization or X-PubFi-Api-Key to that request. The legacy header is not accepted as authentication, but its presence still selects the credential lane. Supplying both payment modes is a conflict and PubFi rejects it.

A successful settled response includes PAYMENT-RESPONSE. Treat the full payment signature, payment payload, and payment response as sensitive payment evidence. Do not log them.

The unsigned challenge includes the official Signed Offers & Receipts offer-receipt extension and its compact Ed25519 JWS Signed Offer. The settled PAYMENT-RESPONSE includes the extension's Signed Receipt. The JWS kid points to PubFi's did:web verification method.

PubFi uses one active private signer. The did:web document can also publish up to eight retained public verification keys. Only the active key signs new offers and receipts. Retained public keys keep supported historical receipts verifiable after key rotation.

4. Replay Safely

If a connection is lost after signing, resend the exact same request with the exact same PAYMENT-SIGNATURE. Do not create a second authorization first.

After settlement, exact replay returns the same bounded response bytes and the same PAYMENT-RESPONSE, including the same signed receipt. It does not create a second provider call, settlement, or wallet charge. A changed method, path, query, body, route, or payment binding is rejected.

Public Runnable Examples

The public repository contains a no-secret challenge inspector and bounded, Staging-only paid HTTP and MCP examples:

sh examples/agents/x402-base-sepolia/show_challenge.sh

The paid examples use pinned official x402 clients. They require a buyer key supplied by the caller's wallet or secret manager and an independently approved expected payTo address.

See the public x402 example for installation, HTTP, MCP, signed receipt, and exact replay commands.

The Staging acceptance run completed both official-client lanes with Signed Offer and Signed Receipt verification and exact replay. The workflow link requires access to the source repository.

An eligible Staging route can use the same accountless payment mode through MCP pubfi.route.execute at https://mcp-stg.pubfi.ai. See MCP Client Setup for the official MCP metadata flow.

The Production example uses the same protocol flow at the Production HTTP and MCP origins. It has a separate Base mainnet policy and does not accept the Staging network, asset, payee, or origins.

Verify The Offer And Receipt

Use a JWS and DID library that supports EdDSA and did:web.

  1. Read the offer JWS from PaymentRequired.extensions["offer-receipt"].info.offers.
  2. Require JWS algorithm EdDSA and resolve the exact kid through its did:web document.
  3. Require the DID document to authorize that Ed25519 verification method for assertions.
  4. Verify the compact JWS over its exact encoded payload bytes. Parse the payload as JSON only after signature verification, then require the payload bytes to match the JSON Canonicalization Scheme form.
  5. Check the signed offer fields against the live payment requirement: version, resource URL, scheme, network, asset, payee, amount, and expiry.
  6. After settlement, read and verify SettlementResponse.extensions["offer-receipt"].info.receipt in the same way.
  7. Check the signed receipt's version, network, resource URL, payer, issuedAt, and optional transaction. Require an exact replay to return the same receipt.

The official receipt has a deliberately narrow payload. It does not by itself sign the amount, asset, payee, request body, response body, route identity, or every internal settlement id. Validate the Signed Offer, the HTTP PAYMENT-RESPONSE or MCP x402/payment-response, the Signed Receipt, and the public transaction together when the transaction is available. Do not infer an account balance or an internal ledger from the receipt.

The Signed Receipt is verifiable payment and execution evidence. It is not proof of a PubFi account balance, Credits balance, wallet top-up, or anonymous deposit.

issuedAt comes from Quantro's durable settledAt settlement time. It is the receipt issuance time, not the earlier provider execution stage time. Exact replay reuses the durable receipt instead of creating a new issuance time.

Operators should use Security And Public Data Boundary for signer and retained public-key configuration rules.

Billing Expectations

The x402 lane:

  • creates no PubFi account;
  • creates no API key;
  • creates no Credits balance;
  • creates no invoice or anonymous billing dashboard; and
  • does not consume a registered account's allowance.

Signed receipts provide portable evidence. They do not create an account, a balance, or a wallet history service. SIWX and wallet-history lookup are not part of the current release.

The caller's USDC balance in the environment-specific wallet is the x402 payment balance. PubFi does not mirror it as Credits or an account balance. For this Staging walkthrough, the wallet balance remains visible through the wallet or Base Sepolia explorer.

Quantro is the common authority for settlement, receipt, purchase, and allocation facts. API-key and Credits execution selects the registered lane; x402 selects the wallet-payment lane. One request cannot debit both.

See Payment And Execution Modes for the boundary between x402, registered purchases, Credits, and API-key execution.

Failure Actions

ResultClient action
Unsigned 402 with PAYMENT-REQUIREDValidate every term, then create at most one authorization.
x402.invalid_payment or x402.claimed_payment_conflictStop. Do not reuse the authorization for a changed request.
Paid retry returns 402 with a fresh payment requirementTreat the submitted authorization as rejected. Validate every new term before deciding whether to sign again.
Lost connection after sending the signed requestReplay the exact same request and authorization. Do not sign again first.
x402.provider_failureTreat the request as failed. Do not assume it settled.
x402.provider_timeout or x402.unavailableKeep the original binding for recovery. Do not submit a second provider request blindly.

See Registry Gateway Examples for the complete public error vocabulary.

Staging Paid Example Limits

Running both paid Staging examples creates two independent payments for the selected route: one through HTTP and one through MCP. Each payment can spend at most 0.01 test USDC. The total maximum is 0.02 test USDC.

The MCP replay check compares the returned structuredContent and result._meta["x402/payment-response"]. It does not compare raw JSON-RPC response bytes.

When MCP payment processing fails with a replacement requirement, the error tool result keeps the official PaymentRequired fields in structuredContent and adds an error message. Treat it as a new challenge. It is not a settlement receipt.