x402 Auto-pay
x402 is an open protocol for machine-to-machine payments over HTTP. It uses the 402 Payment Required status code — a part of the HTTP spec that has been reserved since 1996 but rarely used — to enable services to request micropayments inline with API calls.
How it works
- An agent sends a normal HTTP request to a service
- If the resource requires payment, the service responds with
HTTP 402and a payment challenge in theX-Payment-Requiredheader - The agent's wallet evaluates the payment details, deducts the fee, and retries the request with a signed payment receipt in the
X-Paymentheader - The service verifies the receipt on-chain and returns the resource
This entire flow happens in two HTTP round-trips, with no OAuth, no subscription setup, and no API key exchange.
Discovering services
Use orb.x402.discover() to find services registered in OrbMarket:
const services = await orb.x402.discover({
category: 'inference',
})
// Returns:
// [
// { name: 'LLM Inference — Llama 3', url: 'https://...', pricePerCall: '0.002', token: 'USDC' },
// { name: 'Embeddings API', url: 'https://...', pricePerCall: '0.0005', token: 'USDC' },
// ]Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| category | string | Service category: 'inference', 'search', 'storage', 'data', 'compute' |
| query | string | Optional keyword search |
| maxPrice | string | Filter by max price per call in USDC |
Making paid requests
Use agent.fetch() to make an HTTP request that auto-pays any x402 challenge:
const agent = await orb.wallet.get(walletId)
const response = await agent.fetch('https://inference.orbmarket.co/v1/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'llama-3-70b',
messages: [{ role: 'user', content: 'Summarize this document...' }],
}),
maxAmount: '0.10', // refuse to pay more than $0.10 per call
})
const data = await response.json()Options
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| maxAmount | string | '1.00' | Maximum USDC to pay per request |
| token | 'USDC' | 'USDC' | Payment token |
| chain | Chain | 'base' | Chain to pay on |
| dryRun | boolean | false | Simulate payment without sending funds |
Returns: standard Response object (same as fetch)
When the SDK is constructed with a covenant config, a 402 payment challenge is authorized via the Covenant daemon before the payment is signed. The returned X402FetchResult includes spendDecisionId when an authorization was used. See Covenant Spend Authorization.
Full example: paying for inference
import { OrbWallet } from '@orbserv-labs/orb-wallet'
const orb = new OrbWallet({ apiKey: process.env.ORB_API_KEY! })
const agent = await orb.wallet.get(process.env.AGENT_WALLET_ID!)
// Discover available inference services
const services = await orb.x402.discover({ category: 'inference' })
const inferenceUrl = services[0].url
// Call the service — payment is handled automatically
const res = await agent.fetch(`${inferenceUrl}/v1/completions`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'Write a haiku about autonomous agents.',
max_tokens: 100,
}),
maxAmount: '0.05',
})
if (!res.ok) {
throw new Error(`Request failed: ${res.status}`)
}
const completion = await res.json()
console.log(completion.text)Payment receipts
Every successful x402 payment returns a receipt you can inspect:
const receipt = response.headers.get('X-Payment-Receipt')
// A base64-encoded JSON receipt with txHash, amount, timestampReceipts are also logged in agent.history() with type: 'x402'.