X402.
PAY PER CALL.
Pay direct from any Solana wallet, per inference call. No Bourse account, no API key, no prepaid balance to manage. The facilitator settles USDC on-chain in the same request, then the prompt routes through the same multi-provider stack as the API-key rail. Built for agents.
// TRY_IT
The widget below is sandboxed on devnet so you can try x402 without spending real USDC. We pre-fund the demo wallet, you click RUN, the facilitator settles a 0.01 devnet-USDC payment on-chain, and your prompt routes. The production rail at /api/x402/v1/chat/completions runs on mainnet — same flow, real Circle USDC.
Click RUN. We sign + send a 0.01 USDC payment from a server-funded devnet wallet, the x402 facilitator settles it on-chain, then your prompt routes to the cheapest provider. You see the model response + the on-chain tx in <5 seconds.
// THE_FLOW
- 1. POST without payment. Bourse responds
402 Payment Requiredwith payment terms (network, asset, recipient, amount). - 2. Sign the payment. Your client signs a Solana token-transfer transaction matching the terms and base64-encodes it.
- 3. POST again with X-PAYMENT. Bourse forwards the signed payment to the facilitator, which verifies and settles on-chain in the same request.
- 4. Inference routes + responds. Once payment is settled, the request resolves to the cheapest provider, response streams back. Failover applies same as Rail 1.
// CODE
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { registerExactSvmScheme } from "@x402/svm/exact/client";
import { createKeyPairSignerFromBytes } from "@solana/kit";
import { readFileSync } from "fs";
// Devnet keypair JSON (e.g. from `solana-keygen new`).
// Fund the wallet with devnet USDC: https://faucet.payai.network
const bytes = new Uint8Array(JSON.parse(readFileSync("./wallet.json", "utf8")));
const signer = await createKeyPairSignerFromBytes(bytes);
const client = new x402Client();
registerExactSvmScheme(client, { signer });
const fetchWithPay = wrapFetchWithPayment(globalThis.fetch, client);
const res = await fetchWithPay(
"https://usebourse.xyz/api/x402/v1/chat/completions",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
model: "google/gemma-3-27b-it",
messages: [{ role: "user", content: "Hello, agent." }],
}),
},
);
const json = await res.json();
console.log(json.choices[0].message.content);
console.log("tx:", res.headers.get("x-payment-response"));The TypeScript example uses the official @x402/fetch wrapper, which transparently handles the 402-then-retry dance. Same code works against any x402-compatible service.
// PARAMETERS
// WHERE_THE_MONEY_GOES
Unique to Bourse: the per-call USDC destination is dynamic per model.
- › If the model is tokenized on-chain, USDC lands in that model's revenue vault and feeds buyback-and-burn on the model's token. See /docs/creators for the full vault + buyback flow.
- › If the model is not yet tokenized, USDC lands in the protocol treasury and is held until the model lists. The demo on this page uses a non-tokenized example for reliability — the routing primitives are identical either way.
- › Either way: every paid call mechanically connects to the on-chain economy of the model that served it. No accounting layer. The wire is the ledger.