Documentation · Guide

Add x402 Payments to Your API in 5 Minutes

This guide walks you through adding x402 payment support to an existing API using the official Coinbase SDK. By the end, your API will accept USDC payments from AI agents — no Stripe, no signup, no human in the loop.

What you'll need:
• An Express.js or Python (Flask/FastAPI) API
• A wallet address to receive payments
• 5 minutes
1

Install the x402 SDK

TypeScript
Python
# Install the official Coinbase x402 Express middleware
npm install @x402/express

# Or with yarn
yarn add @x402/express
# Install the Python x402 middleware
pip install x402-python

# Or with poetry
poetry add x402-python
2

Add the Payment Middleware

Wrap your protected routes with the x402 middleware. Every request to these routes will require a valid payment header.

TypeScript
Python
import express from 'express';
import { paymentMiddleware } from '@x402/express';

const app = express();

// Your wallet address (receives payments)
const PAYEE_ADDRESS = '0xYourWalletAddress';

// Facilitator verifies payments on-chain
const FACILITATOR_URL = 'https://x402.org/facilitator';

// Protect routes with x402 payment requirement
app.use(
  '/v1/tools/*',
  paymentMiddleware({
    payeeAddress: PAYEE_ADDRESS,
    facilitatorUrl: FACILITATOR_URL,
    network: 'base-mainnet',
    description: 'API call payment',
    price: {
      amount: '0.001',     // $0.001 USDC per call
      token: 'USDC',
    },
  })
);

// Your normal route handler — no payment logic needed here
app.post('/v1/tools/summarize', async (req, res) => {
  const { text } = req.body;
  const summary = await generateSummary(text);
  res.json({ summary });
});

app.listen(3000, () => {
  console.log('API running with x402 payments on :3000');
});
from flask import Flask, request, jsonify
from x402 import require_payment

app = Flask(__name__)

# Your wallet address (receives payments)
PAYEE_ADDRESS = "0xYourWalletAddress"
FACILITATOR_URL = "https://x402.org/facilitator"

# Decorator protects routes with x402 payment
@app.route("/v1/tools/summarize", methods=["POST"])
@require_payment(
    payee_address=PAYEE_ADDRESS,
    facilitator_url=FACILITATOR_URL,
    network="base-mainnet",
    amount="0.001",
    token="USDC",
)
def summarize():
    text = request.json.get("text")
    summary = generate_summary(text)
    return jsonify({"summary": summary})

if __name__ == "__main__":
    app.run(port=3000)

That's it for the basic integration. When a request comes in without a valid payment header, the middleware automatically returns a 402 Payment Required response with the pricing details. Clients that support x402 handle the rest.

3

Set Up a Facilitator

The facilitator is a service that verifies payments on-chain. You have three options:

Option A: Use the Public Facilitator (Recommended for Starting)

Coinbase runs a public facilitator at https://x402.org/facilitator. It's free, handles verification on all supported networks, and works out of the box. Use this to get started.
Option B: Self-Host a Facilitator

For production workloads with high volume, you can run your own facilitator. The @x402/facilitator package provides a ready-to-deploy Node.js server.
# Install the facilitator
npm install @x402/facilitator

# Run it
npx x402-facilitator \
  --network base-mainnet \
  --port 4020

# Now point your middleware to your facilitator
# facilitatorUrl: 'http://localhost:4020'
Option C: Coinbase Developer Platform (CDP)

If you're building on the Coinbase ecosystem, CDP provides managed facilitator infrastructure as part of their agentic commerce toolkit. See docs.cdp.coinbase.com.
4

Expose /.well-known/x402

The /.well-known/x402 endpoint is how agents discover your pricing and payment requirements. It's the standard x402 discovery mechanism.

// Add this route to your Express app
app.get('/.well-known/x402', (req, res) => {
  res.json({
    accepts: [
      {
        scheme: 'exact',
        network: 'base-mainnet',
        asset: 'USDC',
        maxAmountRequired: '1000',    // in smallest unit (0.001 USDC)
        payeeAddress: '0xYourWalletAddress',
      },
      // Add more networks/tokens as needed
      {
        scheme: 'exact',
        network: 'ethereum-mainnet',
        asset: 'USDC',
        maxAmountRequired: '1000',
        payeeAddress: '0xYourWalletAddress',
      },
    ],
    facilitatorUrl: 'https://x402.org/facilitator',
    description: 'Your API description',
    docs: 'https://your-api.com/docs',
  });
});
Pro tip: The @x402/express middleware can auto-generate the /.well-known/x402 endpoint based on your middleware configuration. Set exposeWellKnown: true in your middleware options.
5

Test with the Playground

Before listing your service, test it. The Arch Tools x402 Playground lets you make real x402 payments against any endpoint.

Quick Test with curl

# 1. Check your well-known endpoint
curl https://your-api.com/.well-known/x402

# 2. Call a protected endpoint without payment — should return 402
curl -i https://your-api.com/v1/tools/summarize \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"text": "test"}'

# Expected response:
HTTP/1.1 402 Payment Required
X-Payment-Required: true
Content-Type: application/json

{
  "error": "Payment required",
  "accepts": [...],
  "amount": "0.001",
  "token": "USDC",
  "network": "base-mainnet"
}

Test with the Arch Tools Playground

  1. Go to archtools.dev/playground
  2. Enter your API endpoint URL
  3. Connect your wallet (MetaMask, Coinbase Wallet, or WalletConnect)
  4. Click "Pay & Call" — the playground constructs the payment header, sends it, and shows the full round-trip
  5. Verify you received the payment in your wallet
6

List on the Arch Tools Directory

Once your service is tested and live, submit it to the x402 Service Directory — the first comprehensive catalog of x402-enabled APIs.

Via Pull Request (Preferred)

# 1. Fork the Arch Tools repo
gh repo fork Deesmo/Arch-AI-Tools

# 2. Add your service to directory-services.json
{
  "name": "your-service",
  "provider": "Your Company",
  "description": "What your API does",
  "endpoint": "https://api.yourservice.com/v1/action",
  "wellKnown": "https://api.yourservice.com/.well-known/x402",
  "category": "ai",
  "pricing": { "amount": "0.001", "token": "USDC" },
  "chains": ["base-mainnet"],
  "docs": "https://docs.yourservice.com"
}

# 3. Open a PR
gh pr create --title "Add [your-service] to x402 directory"

Via the Directory Page

Visit the directory page and use the submission form. We'll verify your /.well-known/x402 endpoint and add you within 24 hours.

Multi-Network Support

Want to accept payments on multiple chains? Add more entries to your middleware config:

// Accept USDC on Base, Ethereum, and Arbitrum
app.use(
  '/v1/tools/*',
  paymentMiddleware({
    payeeAddress: PAYEE_ADDRESS,
    facilitatorUrl: FACILITATOR_URL,
    networks: [
      { network: 'base-mainnet',     token: 'USDC', amount: '0.001' },
      { network: 'ethereum-mainnet', token: 'USDC', amount: '0.001' },
      { network: 'arbitrum-mainnet', token: 'USDC', amount: '0.001' },
      { network: 'solana-mainnet',   token: 'USDC', amount: '0.001' },
    ],
  })
);

Per-Route Pricing

Different endpoints can have different prices. Expensive operations (image generation, research reports) cost more than simple lookups:

// Cheap: text utilities ($0.001)
app.use('/v1/tools/summarize', paymentMiddleware({
  ...baseConfig,
  price: { amount: '0.001', token: 'USDC' },
}));

// Medium: AI generation ($0.005)
app.use('/v1/tools/ai-generate', paymentMiddleware({
  ...baseConfig,
  price: { amount: '0.005', token: 'USDC' },
}));

// Expensive: image generation ($0.02)
app.use('/v1/tools/generate-image', paymentMiddleware({
  ...baseConfig,
  price: { amount: '0.02', token: 'USDC' },
}));

Common Issues

Payment header rejected?
Check that your wallet has sufficient USDC on the correct network. Base USDC ≠ Ethereum USDC. The payment must be on the exact network your middleware expects.
Facilitator timeout?
The public facilitator at x402.org may have higher latency during peak usage. For production, consider self-hosting or using CDP's managed facilitator.
Agent can't discover your service?
Make sure /.well-known/x402 returns valid JSON with CORS headers enabled. Test with curl -v to verify.

Next Steps

Your API accepts x402 now. List it.

Submit your service to the directory and let agents discover you.

Submit to Directory → Test in Playground