Skip to main content
The x402 Bazaar is the discovery layer for the x402 ecosystem: a machine-readable catalog that helps developers and AI agents find and integrate with x402-compatible API endpoints. Think of it as a search index for payable APIs, enabling autonomous discovery and consumption of services.
The x402 Bazaar is in early development. While our vision is to build the “Google for agentic endpoints,” we’re currently more like “Yahoo search”: functional but evolving. Features and APIs may change as we gather feedback and expand capabilities.

Overview

The Bazaar solves a critical problem in the x402 ecosystem: discoverability. Without it, x402-compatible endpoints are like hidden stalls in a vast market. The Bazaar provides:
  • For Buyers (API Consumers): Programmatically discover available x402-enabled services, understand their capabilities, pricing, and schemas
  • For Sellers (API Providers): Automatic visibility for your x402-enabled services to a global audience of developers and AI agents
  • For AI Agents: Dynamic service discovery without pre-baked integrations. Query, find, pay, and use

How It Works

In x402 v2, the Bazaar has been codified as an official extension in the reference SDK (@x402/extensions/bazaar). This extension enables:
  1. Servers declare discovery metadata (input/output schemas) in their route configuration
  2. Facilitators extract and catalog this metadata when processing payments
  3. Clients query the facilitator’s /discovery/resources endpoint to find available services

v1 vs v2

Aspectv1 (Deprecated)v2 (Current)
Discovery dataoutputSchema field in PaymentRequirementsextensions.bazaar field in route config
Schema validationNoneJSON Schema validation
Input specificationNot supportedFull input/output schema support

Quickstart for Sellers

To make your endpoints discoverable in the Bazaar, you need to:
  1. Register the Bazaar extension on your resource server
  2. Declare discovery metadata in your route configuration

Step 1: Install the Extension Package

npm install @x402/extensions

Step 2: Register the Extension and Declare Discovery Metadata

Full example in the Express server example.
import express from "express";
import { paymentMiddleware } from "@x402/express";
import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server";
import { registerExactEvmScheme } from "@x402/evm/exact/server";
import {
  bazaarResourceServerExtension,
  declareDiscoveryExtension,
} from "@x402/extensions/bazaar";

const app = express();

// Create facilitator client
const facilitatorClient = new HTTPFacilitatorClient({
  url: "https://x402.org/facilitator",
});

// Create resource server and register extensions
const server = new x402ResourceServer(facilitatorClient);
registerExactEvmScheme(server);
server.registerExtension(bazaarResourceServerExtension);

// Configure payment middleware with discovery metadata
app.use(
  paymentMiddleware(
    {
      "GET /weather": {
        accepts: {
          scheme: "exact",
          price: "$0.001",
          network: "eip155:84532",
          payTo: "0xYourAddress",
        },
        extensions: {
          // Declare discovery metadata for this endpoint
          ...declareDiscoveryExtension({
            output: {
              example: {
                temperature: 72,
                conditions: "sunny",
                humidity: 45,
              },
              schema: {
                properties: {
                  temperature: { type: "number" },
                  conditions: { type: "string" },
                  humidity: { type: "number" },
                },
                required: ["temperature", "conditions"],
              },
            },
          }),
        },
      },
    },
    server,
  ),
);

app.get("/weather", (req, res) => {
  res.json({
    temperature: 72,
    conditions: "sunny",
    humidity: 45,
  });
});

app.listen(4021);

Discovery Extension Options

The declareDiscoveryExtension function accepts configuration for different HTTP methods:
// For GET endpoints (query params)
declareDiscoveryExtension({
  input: { city: "San Francisco" },  // Example query params
  inputSchema: {
    properties: {
      city: { type: "string", description: "City name" },
    },
    required: ["city"],
  },
  output: {
    example: { temperature: 72 },
    schema: {
      properties: {
        temperature: { type: "number" },
      },
    },
  },
})

// For POST endpoints (request body)
declareDiscoveryExtension({
  input: { prompt: "Hello world" },  // Example body
  inputSchema: {
    properties: {
      prompt: { type: "string", maxLength: 1000 },
    },
    required: ["prompt"],
  },
  bodyType: "json",  // Signals this is a body method
  output: {
    example: { response: "Hi there!" },
  },
})

Quickstart for Buyers

To discover available services, use the withBazaar wrapper to extend your facilitator client with discovery capabilities.

Step 1: Install Dependencies

npm install @x402/core @x402/extensions @x402/fetch @x402/evm

Step 2: Query the Discovery Endpoint

import { HTTPFacilitatorClient } from "@x402/core/http";
import { withBazaar } from "@x402/extensions/bazaar";
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

// Create facilitator client with Bazaar extension
const facilitatorClient = withBazaar(
  new HTTPFacilitatorClient({ url: "https://x402.org/facilitator" })
);

// Query available services
const discovery = await facilitatorClient.extensions.discovery.listResources({
  type: "http",   // Filter by protocol type
  limit: 20,      // Pagination
  offset: 0,
});

console.log(`Found ${discovery.resources.length} services`);

// Browse discovered resources
for (const resource of discovery.resources) {
  console.log(`- ${resource.url}`);
  console.log(`  Type: ${resource.type}`);
  if (resource.metadata) {
    console.log(`  Metadata:`, resource.metadata);
  }
}

// Select a service and make a paid request
const selectedService = discovery.resources[0];

// Set up x402 client for payments
const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`);
const client = new x402Client();
registerExactEvmScheme(client, { signer });

const fetchWithPayment = wrapFetchWithPayment(fetch, client);

// Call the discovered service
const response = await fetchWithPayment(selectedService.url);
const data = await response.json();
console.log("Response:", data);

API Reference

Discovery Endpoint

Facilitators that support the Bazaar extension expose a discovery endpoint:
GET {facilitator_url}/discovery/resources

Query Parameters

ParameterTypeDescription
typestringFilter by protocol type (e.g., "http")
limitnumberNumber of resources to return (default: 20)
offsetnumberOffset for pagination (default: 0)

Response Schema

{
  "resources": [
    {
      "url": "https://api.example.com/weather",
      "type": "http",
      "metadata": {
        "description": "Weather data API",
        "input": { ... },
        "output": { ... }
      }
    }
  ],
  "total": 42,
  "limit": 20,
  "offset": 0
}

CDP Facilitator Discovery Endpoint

The CDP facilitator’s discovery endpoint:
GET https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources
The default limit is 100 results per request. Use pagination parameters to retrieve additional results.

Extension Architecture

The Bazaar extension follows the x402 v2 extensions pattern:
// Extension structure
{
  bazaar: {
    info: {
      input: {
        type: "http",
        method: "GET",
        queryParams: { ... }
      },
      output: {
        type: "json",
        example: { ... }
      }
    },
    schema: {
      // JSON Schema validating the info structure
      $schema: "https://json-schema.org/draft/2020-12/schema",
      type: "object",
      properties: { ... }
    }
  }
}

Key Components

ComponentPurpose
bazaarResourceServerExtensionServer extension that enriches declarations with HTTP method info
declareDiscoveryExtension()Helper to create properly structured extension declarations
withBazaar()Client wrapper that adds discovery query methods
extractDiscoveryInfo()Facilitator helper to extract discovery data from payments

Best Practices

For Sellers

  1. Provide clear examples: Include realistic output.example values that demonstrate your API’s response format
  2. Document inputs: Use inputSchema with descriptions to help clients understand required parameters
  3. Use appropriate types: Specify correct JSON Schema types (string, number, boolean, array, object)

For Buyers

  1. Cache discovery results: Don’t query discovery on every request
  2. Handle pagination: Use offset and limit for large result sets
  3. Validate compatibility: Check that discovered services support your payment network

Support

FAQ

Q: How do I get my service listed in the Bazaar? A: Register the bazaarResourceServerExtension on your resource server and include declareDiscoveryExtension() in your route configuration. The facilitator will automatically catalog your service when it processes payments. Q: Can I opt out of discovery? A: Yes, simply don’t include the Bazaar extension in your route configuration. Only routes with the extension will be discoverable. Q: What networks are supported? A: The Bazaar is network-agnostic. It catalogs services regardless of which payment networks they accept. Q: How often is the discovery catalog updated? A: Services are cataloged when the facilitator processes payments. The catalog is refreshed as transactions occur.