x402 Protocol

x402 is an open standard that uses HTTP 402 Payment Required to enable per-call API payments in USDC on Base. No signup, no API key — the payment is the authentication.

x402 Protocol

x402 is an open standard for machine-native API payments. It uses HTTP's long-dormant 402 Payment Required status code to implement a request-pay-retry cycle where the payment itself acts as the authentication credential.

Proxagora is built on x402. Every API call goes through this flow.

Background: HTTP 402

HTTP defines status codes as part of RFC 7231. Status 402 was reserved in 1996 with the description "Payment Required" and the note: "reserved for future use." For almost three decades it sat unused — every web server treated it as hypothetical.

In 2025, the x402 specification (developed by Coinbase and the Base ecosystem) filled that gap. The spec defines how a server should communicate payment requirements in a 402 response, and how a client should construct a valid payment proof to retry the request.

The result: a payment flow that requires zero prior account setup, zero API keys, and zero human involvement.

How x402 Works

The complete request lifecycle:

┌─────────────┐                         ┌─────────────────┐
│   AI Agent  │                         │    Proxagora    │
└──────┬──────┘                         └────────┬────────┘
       │                                         │
       │  POST /api/ip-geo                       │
       │  {"ip": "1.2.3.4"}                      │
       │ ──────────────────────────────────────► │
       │                                         │
       │  402 Payment Required                   │
       │  {                                      │
       │    "payTo": "0xProxagora...",            │
       │    "amount": "1000",  // 0.001 USDC     │
       │    "asset": "0xUSDC_on_Base",           │
       │    "network": "base-mainnet",           │
       │    "nonce": "0xabc123...",              │
       │    "memo": "proxagora:ip-geo"           │
       │  }                                      │
       │ ◄────────────────────────────────────── │
       │                                         │
       │  [Agent signs EIP-712 payment auth]     │
       │                                         │
       │  POST /api/ip-geo                       │
       │  {"ip": "1.2.3.4"}                      │
       │  X-Payment: {sig, from, amount, nonce}  │
       │ ──────────────────────────────────────► │
       │                                         │
       │  [Proxagora verifies signature +        │
       │   on-chain USDC balance/allowance]      │
       │                                         │
       │  200 OK                                 │
       │  {"country": "US", "city": "...", ...}  │
       │ ◄────────────────────────────────────── │
       │                                         │

Two HTTP requests. One payment authorization. No accounts.

402 Response Structure

When Proxagora receives an unauthenticated API call, it returns:

HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "payTo": "0x742d35Cc6634C0532925a3b8D4C9B7E2b8c2D5e4",
  "amount": "1000",
  "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  "network": "base-mainnet",
  "nonce": "0x5f8e1a2b3c4d5e6f7a8b9c0d1e2f3a4b",
  "memo": "proxagora:ip-geo",
  "expiresAt": 1742688000
}

| Field | Description | |-------|-------------| | payTo | Proxagora's USDC receiving address | | amount | USDC amount in 6-decimal units (1000 = $0.001) | | asset | USDC contract address on Base | | network | base-mainnet or base-sepolia | | nonce | Unique per-request nonce — prevents replay attacks | | memo | Request identifier (included in payment proof) | | expiresAt | Unix timestamp — nonce expires, preventing delayed replays |

Payment Proof (X-Payment Header)

The client constructs a payment proof by signing an EIP-712 structured message with its Base wallet:

{
  "signature": "0x1b2c3d...",
  "from": "0xAgentWallet...",
  "payTo": "0xProxagoraTreasury...",
  "amount": "1000",
  "nonce": "0x5f8e...",
  "memo": "proxagora:ip-geo"
}

This is sent as a JSON-encoded X-Payment header on the retry request.

Important: The x402 payment proof is an authorization, not an on-chain transaction. Proxagora verifies:

  1. The signature is valid and matches the from address
  2. The from address has sufficient USDC balance on Base
  3. The nonce hasn't been used before (replay prevention)
  4. The expiresAt hasn't passed

If all checks pass, Proxagora sweeps the authorized amount and fulfills the request. The on-chain settlement happens asynchronously via batch transfers to reduce gas cost.

Base Blockchain + USDC

x402 on Proxagora runs on Base, an Ethereum L2 built by Coinbase.

Why Base:

  • Gas costs ~$0.001–0.005 per transaction (vs $1–20+ on Ethereum mainnet)
  • Sub-second finality for signature verification
  • USDC is native (Circle's official deployment)
  • EVM-compatible — any Ethereum wallet works

USDC contract addresses:

  • Mainnet: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
  • Sepolia (testnet): 0x036CbD53842c5426634e7929541eC2318f3dCF7e

Wallet Setup

You need a Base-compatible wallet funded with USDC. Any EVM wallet works — MetaMask, Coinbase Wallet, a locally generated keypair.

For development (Base Sepolia testnet):

# Generate a new keypair (Node.js)
node -e "
const {ethers} = require('ethers');
const w = ethers.Wallet.createRandom();
console.log('address:', w.address);
console.log('privateKey:', w.privateKey);
"

# Get testnet ETH (for gas)
# https://www.alchemy.com/faucets/base-sepolia

# Get testnet USDC
# https://faucet.circle.com/

For production (Base mainnet):

Fund your wallet with USDC via:

  • Coinbase (direct on-ramp to Base)
  • Bridge from Ethereum: bridge.base.org
  • Onchain exchange: Uniswap on Base

Minimum balance recommendations:

  • Testing: 5 USDC on Sepolia (free)
  • Light production use: 10-50 USDC
  • High-volume agents: maintain 100+ USDC to avoid mid-operation failures

x402 vs API Keys

| | API Keys | x402 (Proxagora) | |---|---|---| | Setup | Manual account creation + billing | Fund a wallet | | Per-API friction | New account per provider | Universal | | Works for agents | ❌ Requires human signup | ✅ Fully autonomous | | Payment model | Monthly subscription or rate limit | Pay per call | | Credential rotation | Manual, human task | No credentials to rotate | | Auditability | Depends on provider logging | On-chain receipts | | Multi-agent | Key sharing/leaking risk | Each agent has its own wallet | | Offline provisioning | Impossible | Wallet can be generated offline |

The fundamental difference: API keys are designed for accounts (long-lived identity). x402 is designed for transactions (one-time authorization). Agents are better modeled as transaction issuers than account holders.

Security Properties

Replay prevention: Every 402 response includes a unique nonce and expiry. A payment proof is valid exactly once and for a limited time window.

No credential storage: The agent never stores a long-lived secret. Private keys are used to sign, but the payment proofs themselves are single-use.

Payment-before-data: Proxagora verifies payment authorization before calling any upstream API. No data is returned without verified authorization.

Wallet isolation: Different agents can use different wallets. A compromised sub-agent wallet doesn't affect the parent agent's credentials.

Mermaid Sequence Diagram

sequenceDiagram
    participant A as AI Agent
    participant P as Proxagora
    participant B as Base L2
    participant U as Upstream API

    A->>P: POST /api/endpoint {params}
    P-->>A: 402 {payTo, amount, nonce, asset}

    Note over A: Sign EIP-712 payment auth

    A->>P: POST /api/endpoint {params}<br/>X-Payment: {sig, nonce, amount}
    P->>B: Verify USDC balance & signature
    B-->>P: Valid
    P->>U: Forward API call
    U-->>P: Response
    P-->>A: 200 OK {result}
    P->>B: Batch settle USDC transfer

Error Codes

| Code | Meaning | |------|---------| | 402 | Payment required — first call without payment | | 400 invalid_payment | Malformed X-Payment header | | 401 signature_invalid | Signature doesn't match from address | | 402 insufficient_balance | Wallet USDC balance too low | | 402 nonce_expired | Payment nonce has expired (>5 min) | | 409 nonce_used | Nonce already consumed — replay rejected |

Specification

The x402 specification is maintained at x402.org. Proxagora implements x402 v1 with Base Sepolia and Base mainnet support.

For the Proxagora-specific payment flow, see Calling APIs and Authentication & Payments.

Authentication & PaymentsDiscovery