Skip to main content

x402 on Base

x402 is the Coinbase-originated standard for HTTP-native micropayments. OneSource supports x402 on Base mainnet: every paid endpoint accepts a USDC-on-Base payment signature in place of an API key.

How a call works

  1. Your client calls a OneSource endpoint without any Authorization header.
  2. OneSource returns HTTP 402 with a Payment-Required header containing the price ($0.001 to $0.02 USDC), the payTo address, and the asset (USDC on Base chain ID 8453).
  3. Your client signs an EIP-712 TransferWithAuthorization payload over the price + nonce + deadline.
  4. Your client retries the call with the signed payload in a Payment-Signature header.
  5. OneSource verifies the signature with the x402 facilitator, settles the transfer on Base, and returns the API response plus a Payment-Response header (transaction hash + settled amount).

Total round-trip is typically under one second; the on-chain settlement is async to the response.

Using @x402/fetch

@x402/fetch wraps fetch to handle the 402 → sign → retry loop automatically. OneSource speaks x402 v2, so use the v2 client: register the EVM exact scheme on an x402Client, then wrap fetch with it.

import { x402Client, wrapFetchWithPayment } from '@x402/fetch';
import { registerExactEvmScheme } from '@x402/evm/exact/client';
import { privateKeyToAccount } from 'viem/accounts';

const account = privateKeyToAccount(process.env.X402_PRIVATE_KEY as `0x${string}`);

const client = new x402Client();
registerExactEvmScheme(client, { signer: account });

const paidFetch = wrapFetchWithPayment(fetch, client);

const res = await paidFetch('https://api.onesource.io/api/chain/network-info');
const { data, error } = await res.json();

You call it like normal fetch; the wrapper pays for every paid endpoint it hits.

Use the v2 client

The challenge is carried in the Payment-Required response header, not the response body: the body is only {"error":"Payment required","meta":{…}}. The v1 x402-fetch package reads accepts from the body, so it throws TypeError: Cannot read properties of undefined (reading 'map') before it ever signs. Install @x402/fetch and @x402/evm at ^2.

Using AgentCash

AgentCash is an agent wallet and MCP server that speaks both x402 and MPP. Set it up with:

npx agentcash@latest install

It generates a local wallet on first run; fund it with USDC on Base. Once AgentCash is wired into your assistant (see its setup docs), ask the assistant to fetch https://api.onesource.io/api/chain/network-info and it signs the x402 payment automatically.

Using the OneSource MCP Server with x402

Set X402_PRIVATE_KEY instead of ONESOURCE_API_KEY:

X402_PRIVATE_KEY=0x… npx -y @one-source/mcp@latest

Or in your MCP client config:

{
"mcpServers": {
"onesource": {
"command": "npx",
"args": ["-y", "@one-source/mcp@latest"],
"env": { "X402_PRIVATE_KEY": "0x…" }
}
}
}

The OneSource MCP Server picks up the key and signs payments automatically on every tool call.

To batch many calls through one channel instead of paying per call, add X402_PAYMENT_MODE=batch (and a persistent X402_CHANNEL_DIR): see Batch settlement below.

Pricing

Per-call USDC prices for /api/chain/* routes are published in two places:

  • The x-payment-info.price.amount extension on every API Reference page.
  • The response meta.cost_usdc field on every successful call.

Deepstate market data (/deepstate/v1/*) is priced flat instead ($0.005 per call, $0.02 for the analytics routes) and doesn't carry meta.cost_usdc on a successful call, only in a 402 challenge.

Examples:

EndpointPrice (USDC)
/api/chain/block-number0.001
/api/chain/network-info0.001
/api/chain/live-balance0.003
/api/chain/call0.005
/api/chain/nft-metadata0.008
/api/chain/pending0.010
/deepstate/v1/markets0.005
/deepstate/v1/analytics/makers0.02

Verify the payment

The Payment-Response header on a successful call carries the on-chain transaction hash. You can verify settlement on https://basescan.org with that hash.

Receipts

OneSource also returns settlement metadata on the body's meta object: payment_chain, payment_token, cost_usdc, request_id. Log these for audit / billing reconciliation.

Batch settlement

x402 has a session-like mode that mirrors MPP sessions, but stays on Base/USDC, so you don't bridge to Tempo. Instead of settling every call on-chain, you open a payment channel with a single deposit, satisfy many calls with off-chain signed claims against it, and OneSource settles the cumulative total in batched on-chain claims. For high call volumes this amortizes settlement gas the same way MPP sessions do.

OneSource advertises a batch-settlement scheme alongside the standard exact scheme in the 402 for every /api/chain/* route. OneSource is the channel authorizer (self-managed), claims accrued usage on a short interval, and refunds any unused deposit after a withdraw delay (~1 day on mainnet).

Using it

Batch needs a client that holds channel state across calls: the deposit, the signed vouchers, and the running cumulative total. Two supported paths:

  • The OneSource MCP Server (no code). Set X402_PAYMENT_MODE=batch (and a persistent X402_CHANNEL_DIR) when you run @one-source/mcp in x402 mode, or flip it in-session with the 1s_payment_mode tool. The 1s_refund tool reclaims any unused deposit on demand when you're done. See MCP configuration → Batch settlement. Works in the default stdio (long-lived) transport, not the stateless --http mode.
  • A custom client. Build directly on the @x402/evm SDK. Build an x402 batch-settlement client is a complete, runnable example you can copy.
Exact-only clients keep working

The 402 advertises both schemes on every route, and what happens next is client behavior: a client that implements only the exact scheme ignores the batch challenge and pays per call; nothing fails, it just doesn't batch. The two paths above batch against OneSource out of the box; for any other wallet, its own documentation is the authority on whether it implements batch-settlement. Protocol details: the x402 batch-settlement spec.

Next