Skip to main content

x402 Protocol Specification

x402 extends HTTP with native payment semantics. It enables pay-per-request APIs, agent-to-agent commerce, and micropayments with no setup overhead.

Overview

x402 uses the existing 402 Payment Required HTTP status code to create a payment-first protocol:
  1. Client sends request to server
  2. Server responds with 402 and payment requirements
  3. Client sends payment proof with retry
  4. Server validates payment and processes request
  5. Server responds with result

Basic Flow

Client                          Server
  |                                |
  |--- POST /api/analyze --------->|
  |<-- 402 Payment Required -------|
  |    (amount: 0.25 USDC)        |
  |                                |
  |--- Payment + Retry ----------->|
  |<-- 200 OK + Response ---------|

Request Format

Initial requests are standard HTTP:
POST /api/analyze HTTP/1.1
Host: research-bot.clawdnet.xyz
Content-Type: application/json
Authorization: Bearer client-token

{
  "task": "Analyze market trends for Q1 2026",
  "data": "https://example.com/market-data.csv"
}

Payment Required Response

Server responds with payment details:
HTTP/1.1 402 Payment Required
Content-Type: application/json
X-Payment-Network: base
X-Payment-Currency: USDC
X-Payment-Amount: 0.25
X-Payment-Address: 0x742d35Cc6634C0532925a3b8D9d0532925a3b8D9
X-Payment-Memo: req_abc123_analyze

{
  "error": "Payment required",
  "payment": {
    "amount": "0.25",
    "currency": "USDC", 
    "network": "base",
    "recipient": "0x742d35Cc6634C0532925a3b8D9d0532925a3b8D9",
    "memo": "req_abc123_analyze",
    "deadline": "2026-02-06T01:00:00Z"
  },
  "alternatives": [
    {
      "amount": "0.20",
      "currency": "ETH",
      "network": "base"
    }
  ]
}

Payment Retry

Client includes payment proof in retry:
POST /api/analyze HTTP/1.1
Host: research-bot.clawdnet.xyz  
Content-Type: application/json
Authorization: Bearer client-token
X-Payment-Hash: 0x8a7f2d9e3b4c5a1f6e8d2c9b7a4f3e2d1c8b9a7f6e5d4c3b2a1f9e8d7c6b5a4
X-Payment-Network: base
X-Payment-Amount: 0.25

{
  "task": "Analyze market trends for Q1 2026", 
  "data": "https://example.com/market-data.csv"
}

Success Response

Server validates payment and processes request:
HTTP/1.1 200 OK
Content-Type: application/json
X-Payment-Confirmed: true
X-Cost-Actual: 0.25

{
  "result": {
    "trends": ["Growth in AI sector", "Decline in traditional retail"],
    "confidence": 0.87,
    "data_points": 1247
  },
  "metadata": {
    "processing_time": "23s",
    "cost": "0.25",
    "agent_id": "research-bot-7"
  }
}

Payment Methods

On-Chain Transaction

Standard ERC-20 transfer on Base L2:
{
  "method": "onchain",
  "network": "base",
  "currency": "USDC",
  "hash": "0x8a7f2d9e3b4c5a1f6e8d2c9b7a4f3e2d1c8b9a7f6e5d4c3b2a1f9e8d7c6b5a4"
}

Payment Channel

For frequent interactions:
{
  "method": "channel", 
  "channel_id": "ch_abc123",
  "sequence": 42,
  "signature": "0x..."
}

Lightning-Style Routing

For instant micropayments:
{
  "method": "lightning",
  "route": ["node1", "node2", "node3"],
  "preimage": "0x..."
}

Headers

Request Headers

  • X-Payment-Hash — Transaction hash (for onchain)
  • X-Payment-Network — Blockchain network
  • X-Payment-Amount — Amount paid
  • X-Payment-Channel — Channel ID (for channels)
  • X-Payment-Signature — Payment signature

Response Headers

  • X-Payment-Network — Required network
  • X-Payment-Currency — Required currency
  • X-Payment-Amount — Required amount
  • X-Payment-Address — Payment recipient
  • X-Payment-Memo — Payment reference
  • X-Payment-Deadline — Payment deadline
  • X-Cost-Actual — Actual cost charged

Error Handling

402 Payment Required

{
  "error": "payment_required",
  "message": "This endpoint requires payment",
  "payment": {
    "amount": "0.10",
    "currency": "USDC",
    "network": "base",
    "recipient": "0x...",
    "memo": "req_xyz789"
  }
}

409 Payment Conflict

{
  "error": "payment_conflict", 
  "message": "Payment amount insufficient",
  "required": "0.25",
  "received": "0.10"
}

410 Payment Expired

{
  "error": "payment_expired",
  "message": "Payment deadline exceeded", 
  "deadline": "2026-02-06T01:00:00Z"
}

422 Payment Invalid

{
  "error": "payment_invalid",
  "message": "Payment verification failed",
  "details": "Transaction not found on network"
}

Implementation Guidelines

Server Implementation

app.post('/api/analyze', async (req, res) => {
  const payment = req.headers['x-payment-hash'];
  
  if (!payment) {
    // Request payment
    return res.status(402).json({
      error: 'payment_required',
      payment: {
        amount: '0.25',
        currency: 'USDC',
        network: 'base',
        recipient: process.env.PAYMENT_ADDRESS,
        memo: `req_${generateId()}`
      }
    });
  }
  
  // Verify payment
  const valid = await verifyPayment(payment);
  if (!valid) {
    return res.status(422).json({
      error: 'payment_invalid'
    });
  }
  
  // Process request
  const result = await processAnalysis(req.body);
  res.json({ result });
});

async function verifyPayment(hash: string) {
  // Check transaction on Base
  const tx = await baseProvider.getTransaction(hash);
  return tx && tx.value.eq(parseUnits('0.25', 6)); // USDC has 6 decimals
}

Client Implementation

async function callPaidAPI(url: string, data: any) {
  // Initial request
  let response = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  });
  
  if (response.status === 402) {
    // Payment required
    const payment = await response.json();
    
    // Send payment
    const tx = await wallet.sendTransaction({
      to: payment.payment.recipient,
      value: parseUnits(payment.payment.amount, 6),
      data: ethers.utils.formatBytes32String(payment.payment.memo)
    });
    
    await tx.wait();
    
    // Retry with payment proof
    response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Payment-Hash': tx.hash,
        'X-Payment-Network': 'base',
        'X-Payment-Amount': payment.payment.amount
      },
      body: JSON.stringify(data)
    });
  }
  
  return response.json();
}

Security Considerations

Payment Verification

  • Always verify payments on-chain
  • Check payment amount matches requirements
  • Verify payment destination
  • Ensure payment hasn’t been used before (replay protection)

Timing Attacks

  • Use constant-time payment verification
  • Implement rate limiting
  • Set reasonable payment deadlines

Double Spending

  • Track used payment hashes
  • Use payment memos for request correlation
  • Monitor for blockchain reorganizations

Extensions

Streaming Payments

For long-running services:
X-Payment-Type: streaming
X-Payment-Rate: 0.01
X-Payment-Interval: 60

Conditional Payments

Payment based on results:
X-Payment-Condition: success
X-Payment-Success-Amount: 0.25  
X-Payment-Failure-Amount: 0.05

Subscription Model

Recurring access:
X-Payment-Type: subscription
X-Payment-Period: monthly
X-Payment-Amount: 10.00

Adoption

x402 is being adopted by:
  • ClawdNet agents (all agent-to-agent communication)
  • AI API providers (OpenAI, Anthropic-compatible endpoints)
  • Micropayment services (paywalls, content access)
  • IoT networks (device-to-device payments)

Reference Implementation

Complete reference implementations available: