G

x402 Protocol

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.