Skip to main content
AgentDoor integrates with the x402 payment protocol to enable AI agents to pay for API access programmatically. Agents can attach micropayments to individual requests, enabling usage-based pricing without manual billing.

What is x402?

x402 is a protocol for HTTP-native micropayments. It extends HTTP with payment headers, allowing clients to pay for API requests in real-time using blockchain transactions. Key features:
  • Per-request payments - Agents pay only for what they use
  • Blockchain-native - Payments on Base, Solana, or other networks
  • Stablecoin support - USDC, USDT, SOL, etc.
  • No accounts required - Agents authenticate via wallet signatures
  • Sub-cent pricing - Support for $0.001/request and below
Learn more: x402.org

How It Works

Payment Flow

Request with Payment

// Agent makes a paid request
const response = await fetch('https://api.example.com/weather/forecast?city=sf', {
  headers: {
    'Authorization': 'Bearer agk_live_...',
    'X-Payment': 'x402 base:USDC:0.001:0x1234...signature'
  }
});

const data = await response.json();
// Agent paid $0.001 for this request
Payment header format:
X-Payment: x402 {network}:{currency}:{amount}:{signature}
Example:
X-Payment: x402 base:USDC:0.001:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb...

Enabling x402 in AgentDoor

Configuration

Add x402 config to your AgentDoor setup:
const agentdoor = require('@agentdoor/express');

app.use(agentdoor({
  scopes: [
    { 
      id: 'weather.read', 
      description: 'Read weather data',
      price: '$0.001/req'  // Per-request pricing
    },
    {
      id: 'weather.write',
      description: 'Submit weather observations',
      price: '$0.01/req'
    }
  ],
  
  // x402 payment configuration
  x402: {
    network: 'base',                    // Blockchain network
    currency: 'USDC',                   // Payment currency
    paymentAddress: '0xYourWallet...',  // Your wallet address
    facilitator: 'https://x402.org/facilitator'  // Optional: custom facilitator
  }
}));
Configuration options:
x402.network
string
required
Blockchain network. Supported: "base", "solana", "ethereum", "polygon"
x402.currency
string
required
Payment currency. Examples: "USDC", "USDT", "SOL", "ETH"
x402.paymentAddress
string
required
Your wallet address for receiving payments.Example: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
x402.facilitator
string
x402 facilitator URL. Defaults to https://x402.org/facilitator.Facilitators verify payment proofs and handle blockchain interactions.

Type Definition

interface X402Config {
  network: 'base' | 'solana' | string;  // Blockchain network
  currency: 'USDC' | string;            // Payment currency
  paymentAddress: string;               // Your wallet address
  facilitator?: string;                 // Facilitator URL (optional)
}

Discovery Document Integration

When x402 is configured, AgentDoor automatically includes payment info in the discovery document:
{
  "agentdoor_version": "1.0",
  "service_name": "Weather API",
  "scopes_available": [
    {
      "id": "weather.read",
      "description": "Read weather data",
      "price": "$0.001/req",
      "rate_limit": "1000/hour"
    }
  ],
  "payment": {
    "protocol": "x402",
    "version": "2.0",
    "networks": ["base"],
    "currency": ["USDC"],
    "facilitator": "https://x402.org/facilitator",
    "deferred": false
  }
}
Agents automatically detect payment requirements and configure wallets accordingly.

Agent-Side Payment

Agents using the AgentDoor SDK automatically handle x402 payments:
import { AgentDoor } from '@agentdoor/sdk';

const agent = new AgentDoor({
  keyPath: '~/.agentdoor/keys.json',
  x402Wallet: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb'  // Agent's wallet
});

// Connect to service (discovers payment requirements)
const session = await agent.connect('https://api.example.com');

// Make paid request (payment attached automatically)
const data = await session.get('/weather/forecast', {
  params: { city: 'sf' },
  x402: true  // Enable payment for this request
});

// SDK signs and attaches X-Payment header automatically

Manual Payment Header

For custom implementations:
import { buildSignedPaymentHeader } from '@agentdoor/sdk';

const paymentHeader = await buildSignedPaymentHeader({
  network: 'base',
  currency: 'USDC',
  amount: 0.001,
  recipient: '0xYourWallet...',
  wallet: {
    address: '0x1234...',
    sign: async (message: string) => {
      // Sign with wallet private key
      return signMessage(message, agentWalletPrivateKey);
    }
  }
});

const response = await fetch('https://api.example.com/weather/forecast', {
  headers: {
    'Authorization': 'Bearer agk_live_...',
    'X-Payment': paymentHeader  // "x402 base:USDC:0.001:0x..."
  }
});

Server-Side Payment Verification

AgentDoor middleware automatically verifies x402 payments:
app.get('/api/weather/forecast', (req, res) => {
  // Payment already verified by middleware
  if (req.payment) {
    console.log('Payment received:', {
      amount: req.payment.amount,      // 0.001
      currency: req.payment.currency,  // "USDC"
      network: req.payment.network,    // "base"
      txHash: req.payment.txHash       // Blockchain transaction hash
    });
  }
  
  res.json({ forecast: 'sunny' });
});
Payment context:
interface PaymentContext {
  amount: number;         // Payment amount (e.g., 0.001)
  currency: string;       // Currency code (e.g., "USDC")
  network: string;        // Blockchain network (e.g., "base")
  txHash: string;         // Transaction hash
  sender: string;         // Sender wallet address
  recipient: string;      // Your wallet address
  timestamp: number;      // Payment timestamp
  verified: boolean;      // Whether payment was verified
}

Pricing Models

Per-Request Pricing

Charge a fixed amount per API call:
scopes: [
  {
    id: 'weather.read',
    description: 'Read current weather',
    price: '$0.001/req'  // $0.001 per request
  }
]

Tiered Pricing

Different prices for different scopes:
scopes: [
  {
    id: 'data.basic',
    description: 'Basic data access',
    price: '$0.001/req'
  },
  {
    id: 'data.premium',
    description: 'Premium data with real-time updates',
    price: '$0.01/req'  // 10x more for premium
  },
  {
    id: 'compute.intensive',
    description: 'Run ML inference',
    price: '$0.50/req'  // Higher price for compute
  }
]

Monthly Subscriptions

Charge a flat monthly rate:
scopes: [
  {
    id: 'unlimited',
    description: 'Unlimited access for one month',
    price: '$10/month'
  }
]

Dynamic Pricing

Compute price based on request parameters:
app.use(agentdoor({
  scopes: [{ id: 'compute', description: 'ML inference' }],
  x402: {
    network: 'base',
    currency: 'USDC',
    paymentAddress: '0x...',
    // Custom pricing function
    computePrice: (req) => {
      const model = req.query.model;
      const tokens = parseInt(req.query.tokens || '100');
      
      // Price scales with token count
      const basePrice = model === 'gpt-4' ? 0.03 : 0.01;  // per 1K tokens
      return (tokens / 1000) * basePrice;
    }
  }
}));

Payment Tracking

AgentDoor automatically tracks payments per agent:
// Get agent's payment history
const agent = await storage.getAgent(agent_id);

console.log('Total paid:', agent.totalX402Paid);  // e.g., 1.234 USDC
console.log('Total requests:', agent.totalRequests);  // e.g., 1234 requests

const avgCost = agent.totalX402Paid / agent.totalRequests;
console.log('Average cost per request:', avgCost);  // e.g., $0.001
Agent record:
interface Agent {
  id: string;
  publicKey: string;
  x402Wallet?: string;        // Agent's wallet address
  scopesGranted: string[];
  totalRequests: number;      // Total API calls
  totalX402Paid: number;      // Total amount paid (in currency)
  // ...
}

Stripe Integration

Reconcile x402 payments with Stripe invoices using the @agentdoor/stripe package:
import { reconcileX402WithStripe } from '@agentdoor/stripe';

// Aggregate x402 payments and create Stripe invoices
await reconcileX402WithStripe({
  agentdoorConfig,
  stripeSecretKey: process.env.STRIPE_SECRET_KEY,
  billingPeriod: 'monthly',  // or 'weekly', 'daily'
  onInvoiceCreated: (invoice) => {
    console.log('Created Stripe invoice:', invoice.id);
  }
});
This creates a Stripe invoice for each agent based on their x402 usage, enabling traditional billing workflows alongside crypto payments.

x402 Bazaar Integration

List your service on the x402 Bazaar marketplace:
import { registerWithBazaar } from '@agentdoor/bazaar';

await registerWithBazaar({
  agentdoorConfig,
  category: 'weather',
  tags: ['weather', 'forecast', 'real-time'],
  featured: true
});
Agents can discover your service through the Bazaar and connect automatically.

x402 Wallet as Identity

Agents can use their x402 wallet as both payment source and authentication identity:
// Agent registers with wallet address
const registration = await fetch('/agentdoor/register', {
  method: 'POST',
  body: JSON.stringify({
    public_key: keypair.publicKey,
    x402_wallet: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',  // Wallet = identity
    scopes_requested: ['weather.read']
  })
});

// Server stores wallet address
// Future payments verified against registered wallet
Benefits:
  • Single identity for auth + payments
  • Wallet signature = auth signature (secp256k1)
  • Payment history tied to agent identity

Security Considerations

Payment verification is critical. Always verify payments server-side before serving data.

Payment Verification Checklist

  • Verify signature - Ensure payment was signed by the claimed sender
  • Check amount - Verify payment meets the required price
  • Validate recipient - Ensure payment is addressed to your wallet
  • Check timestamp - Reject old payments (prevent replay attacks)
  • Query blockchain - For high-value requests, verify on-chain

Handling Failed Payments

app.use(agentdoor({
  x402: { /* ... */ },
  onPaymentFailed: (req, error) => {
    console.error('Payment verification failed:', error.message);
    
    // Log the attempt
    await logFailedPayment({
      agentId: req.agent.id,
      amount: req.headers['x-payment'],
      error: error.message,
      timestamp: new Date()
    });
    
    // Return 402 Payment Required
    return {
      status: 402,
      body: {
        error: 'payment_required',
        message: 'Payment verification failed',
        required_amount: 0.001,
        currency: 'USDC',
        network: 'base'
      }
    };
  }
}));

Rate Limiting with Payments

Combine x402 payments with rate limits:
app.use(agentdoor({
  scopes: [{ id: 'data.read', description: 'Read', price: '$0.001/req' }],
  rateLimit: {
    requests: 1000,    // Max requests per window
    window: '1h'
  },
  x402: { /* ... */ },
  // Allow paying agents to exceed rate limits
  rateLimitExempt: (req) => {
    return req.payment && req.payment.verified;
  }
}));

Next Steps

How It Works

Understand the complete AgentDoor architecture

Authentication

Deep dive into Ed25519 challenge-response

Build docs developers (and LLMs) love