x402 Protocol
HTTP 402 payment-gated API integration — enabling any web service to require payment before serving a response.
Overview
The x402 Protocol is Gao Payment’s implementation of HTTP 402 (Payment Required) for payment-gated web APIs and services. It enables any HTTP endpoint to require proof of payment before serving a response, without requiring the API provider to run payment infrastructure.
x402 is designed for:
-
API monetization — charge per request, per token, or per resource
-
AI agent workflows — agents can autonomously pay for services within their CAP budget
-
Machine-to-machine commerce — services paying services without human involvement
-
Pay-as-you-go content — articles, data feeds, compute resources, premium features
Protocol Flow
Client Server
│ │
│── GET /api/resource ─────────▶️│
│ │
│◀️── 402 Payment Required ──────│
│ X-Gao-Payment-Details: { │
│ intent_template: {...}, │
│ amount: "0.01", │
│ currency: "USDC", │
│ payee_domain: "api.gao", │
│ network: "base", │
│ expires_in: 300 │
│ } │
│ │
│ [Client creates payment │
│ intent + wallet signs] │
│ │
│── GET /api/resource ─────────▶️│
│ X-Gao-Payment-Proof: │
│ <base64url(receipt)> │
│ │
│◀️── 200 OK + resource ─────────│
│ X-Gao-Receipt-Id: rcpt_... │
---
### 402 Response Headers
When a server returns HTTP 402, it includes the `X-Gao-Payment-Details` header:
{
"intent_template": {
"payee_domain": "api.gao",
"amount": "0.01",
"currency": "USDC",
"network": "base",
"metadata": {
"resource": "/api/data/prices",
"request_id": "req_abc123"
}
},
"accepted_capabilities": ["payment:send", "payment:autopay"],
"risk_tier_max": 1,
"expires_in": 300,
"payment_endpoint": "https://pay.gao.systems/v1/intents",
"schema_version": "x402/1.0"
}
Field
Description
`intent_template`
Pre-populated fields for the payment intent the server expects
`accepted_capabilities`
CAP capability types the server will accept as proof
`risk_tier_max`
Maximum risk tier the server will accept in proof (servers may reject high-tier proofs)
`expires_in`
Seconds the payment proof must be received within
`payment_endpoint`
Gao Payment API endpoint for intent creation
---
### Payment Proof Header
The client retries the request with a `X-Gao-Payment-Proof` header containing a base64url-encoded canonical receipt:
X-Gao-Payment-Proof: eyJyZWNlaXB0X2lkIjoicmNwdF9wYXlfYWJjMTIzIiwi...
The decoded value is a full canonical receipt JSON (see Receipt Schema).
#### Proof Validation by Server
The server validates the proof by checking:
1. `receipt.status == "settled"`
2. `receipt.parties.payee_domain == server.payee_domain`
3. `receipt.settlement.amount >= required_amount`
4. `receipt.settlement.currency == required_currency`
5. `receipt.intent.settled_at` is within the `expires_in` window
6. `receipt.receipt_id` has not been used for this resource before (replay prevention)
7. Runtime signature on receipt is valid
Servers **must** implement replay prevention by tracking `receipt_id` values used for resource access.
---
### Server Implementation
**Node.js / TypeScript**
import { x402Middleware } from '@gao/sdk/x402';
app.use('/api/premium', x402Middleware({
payeeDomain: 'myapi.gao',
amount: '0.01',
currency: 'USDC',
network: 'base',
riskTierMax: 1,
onValidReceipt: async (receipt, req) => {
// Optional: log receipt, update usage, etc.
await logUsage(receipt.receipt_id, req.path);
},
}));
app.get('/api/premium/data', (req, res) => {
res.json({ data: 'premium content' });
});
Manual Validation
import { validateX402Proof } from '@gao/sdk/x402';
app.get('/api/resource', async (req, res) => {
const proof = req.headers['x-gao-payment-proof'];
if (!proof) {
return res.status(402).json({
'X-Gao-Payment-Details': {
intent_template: { payee_domain: 'myapi.gao', amount: '0.01', currency: 'USDC', network: 'base' },
expires_in: 300,
payment_endpoint: 'https://pay.gao.systems/v1/intents',
schema_version: 'x402/1.0',
}
});
}
const result = await validateX402Proof(proof, {
payeeDomain: 'myapi.gao',
minAmount: '0.01',
currency: 'USDC',
replayStore: redisClient, // any KV store for receipt_id dedup
});
if (!result.valid) {
return res.status(402).json({ error: result.reason });
}
res.set('X-Gao-Receipt-Id', result.receiptId);
res.json({ data: 'premium content' });
});
Client Implementation (Agent)
For AI agents with payment:autopay capability (Tier 0–1), x402 payments can be fully automated:
import { x402Client } from '@gao/sdk/x402';
const client = x402Client({
payerDomain: 'myagent.gao',
capToken: process.env.GAO_CAP_TOKEN,
maxAutoPayAmount: '0.10', // per-request ceiling for auto-pay
currency: 'USDC',
});
// Automatically handles 402 → pay → retry
const response = await client.fetch('https://api.external.gao/data/prices');
const data = await response.json();
The `x402Client` wrapper:
1. Detects HTTP 402 responses
2. Parses `X-Gao-Payment-Details`
3. Creates a payment intent via the Gao Payment API
4. Waits for settlement confirmation
5. Retries the original request with proof header
6. Throws if amount exceeds `maxAutoPayAmount` (requires human approval)
---
Replay Prevention
Servers must prevent the same receipt from being used to access the same resource more than once.
The receipt `receipt_id` is the replay key. Implementation options:
// Redis example
async function checkAndMarkReceipt(receiptId: string, resourcePath: string): Promise<boolean> {
const key = `x402:used:${receiptId}:${resourcePath}`;
const set = await redis.set(key, '1', 'NX', 'EX', 86400); // 24hr TTL
return set === 'OK'; // true = first use, false = replay
}
For receipts that grant access to a streaming or multi-request resource (e.g., a session), the server issues a session token after first receipt validation and subsequent requests use the session token, not the receipt.
Error Codes
HTTP Status
Code
Description
402
—
Payment required; X-Gao-Payment-Details in body
400
X402_001
Malformed proof header
400
X402_002
Receipt schema version mismatch
402
X402_003
Receipt amount insufficient
402
X402_004
Receipt currency mismatch
402
X402_005
Receipt expired (outside expires_in window)
402
X402_006
Receipt status not settled
409
X402_007
Receipt replay detected
400
X402_008
Invalid runtime signature on receipt
Schema Version
Current schema version: x402/1.0
The schema_version field in the 402 response body and the schema_version in the receipt must match for the proof to be accepted. Version mismatches return X402_002.
The x402 Protocol is a stateless proof-of-payment mechanism built on Gao Payment receipts. Servers never touch user funds — they only validate that a valid, non-replayed settlement receipt exists for the requested resource.