{
  "slug": "how-to-build-an-x402-endpoint",
  "title": "How to Build an x402 Endpoint",
  "description": "A complete, working walkthrough of building an x402-payable API endpoint on Cloudflare Workers: the 402 response, verifying payment, and the manifest that makes it discoverable.",
  "category": "For Providers",
  "readMins": 13,
  "text": "This walks through building a real x402 endpoint from nothing — the payment-required response, verifying a payment, and the manifest that makes it discoverable. The example targets Cloudflare Workers (matching Agent Bazaar's own stack), but the logic translates directly to any HTTP framework. Step 1: the unpaid response When a request arrives with no valid payment proof, respond 402 with your accepts[] : const PRICE_USDC_BASE_UNITS = '10000'; // $0.01, 6 decimals const PAY_TO = '0xYourWalletAddressHere'; const USDC_ON_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'; function paymentRequiredResponse() { return new Response(JSON.stringify({ x402Version: 2, accepts: [{ scheme: 'exact', network: 'eip155:8453', // Base payTo: PAY_TO, asset: USDC_ON_BASE, amount: PRICE_USDC_BASE_UNITS, maxTimeoutSeconds: 120, }], }), { status: 402, headers: { 'content-type': 'application/json' } }); } Step 2: verifying a payment When a request arrives with a PAYMENT-SIGNATURE header, verify it before returning the resource. The exact verification logic depends on whether you're self-verifying on-chain or routing through a facilitator: export async function onRequestGet({ request, env }) { const proof = request.headers.get('PAYMENT-SIGNATURE'); if (!proof) return paymentRequiredResponse(); const verified = await verifyPayment(proof, { expectedAmount: PRICE_USDC_BASE_UNITS, expectedPayTo: PAY_TO, expectedAsset: USDC_ON_BASE, }); if (!verified) return paymentRequiredResponse(); // wrong amount, expired, etc. return new Response(JSON.stringify(await getResourceData(request)), { headers: { 'content-type': 'application/json' }, }); } Don't hand-roll verifyPayment from scratch unless you have to. Facilitator services handle settlement verification for you (submit-and-confirm, or check a facilitator's own attestation), which removes the need to run your own RPC infrastructure and handle chain reorgs correctly. solana-x402 is a zero-dependency reference you can read end to end for exactly this logic, supporting both facilitator-routed and self-verified settlement. Step 3: supporting multiple networks List more than one accepts[] entry to let callers pay on whichever network they hold funds: accepts: [ { scheme: 'exact', network: 'solana:5eykt4Us...', payTo: SOLANA_ADDR, asset: USDC_SOLANA_MINT, amount: '10000', maxTimeoutSeconds: 120 }, { scheme: 'exact', network: 'eip155:8453', payTo: EVM_ADDR, asset: USDC_ON_BASE, amount: '10000', maxTimeoutSeconds: 120 }, ] Note that payTo can differ across networks (a Solana address and an EVM address are different formats) — that's expected and correct, not a bug. Step 4: writing the manifest A manifest is what makes your endpoint discoverable, not just payable. Host this JSON at /.well-known/x402.json : { \"x402Version\": 2, \"resources\": [ { \"url\": \"https://yourapi.com/api/security-report\", \"description\": \"On-chain risk report for a token: authority, liquidity, holder concentration.\", \"accepts\": [ { \"scheme\": \"exact\", \"network\": \"eip155:8453\", \"payTo\": \"0x...\", \"asset\": \"0x833589...bdA02913\", \"amount\": \"10000\", \"maxTimeoutSeconds\": 120 } ], \"outputSchema\": { \"type\": \"object\", \"properties\": { \"risk_score\": { \"type\": \"number\" }, \"mint_authority_revoked\": { \"type\": \"boolean\" } } } } ] } Step 5: list it curl -X POST https://bazaar.saylorinnovations.com/submit \\ -H \"content-type: application/json\" \\ -d '{\"manifestUrl\": \"https://yourapi.com/.well-known/x402.json\"}' Testing before you ship Verify the unpaid path first (confirm you get a well-formed 402 with valid accepts[] ) using a plain curl — no wallet needed: curl -i https://yourapi.com/api/security-report Then test the full paid round trip with a small real payment before listing publicly. See How to Sell an API to AI Agents for pricing and description guidance once it's live.",
  "related": [
    "how-do-ai-agents-pay-for-apis",
    "how-to-sell-an-api-to-ai-agents",
    "what-is-x402"
  ]
}