> ## Documentation Index
> Fetch the complete documentation index at: https://docs.celo.org/llms.txt
> Use this file to discover all available pages before exploring further.

# x402: Get your endpoint discovered

> Make an x402 endpoint on Celo findable by agents with a self-describing 402 response, index registrations, and an ERC-8004 identity

This page is for developers who sell an API, a tool, or content over [x402](/build-on-celo/build-with-ai/x402) on Celo and want agents to find it. A working 402 endpoint is invisible until it is described in a way agents can read and listed where agents look. There is no single index. Each one has its own entry rule, and this page lists them.

## Prerequisites

* A resource server that returns `402 Payment Required` on Celo. Set one up on the [x402 page](/build-on-celo/build-with-ai/x402#pointing-a-resource-server-at-it) first.
* A public HTTPS origin. Indexes probe your endpoint from the outside, and some probe it every hour.
* Node.js 20 or later and the v2 packages: `@x402/express`, `@x402/core`, `@x402/evm`, `@x402/extensions`.

## How it works

Discovery has two halves.

1. **Self-description.** The x402 `bazaar` extension lets your 402 response carry the shape of the endpoint: the HTTP method, an example input, a JSON schema for it, and an example output. Facilitators and crawlers that understand the extension catalog the endpoint from the 402 itself, so an agent can call it correctly the first time.
2. **Registration.** Each index decides what it lists. Some crawl an origin you submit, one lists only endpoints that settle through its own facilitator, and one reads on-chain agent identities.

| Index | How an endpoint gets in | What it requires |
| - | - | - |
| [agent402.tools](https://agent402.tools/sell) | One `POST` with your origin; the crawler probes it hourly | A public origin that answers with a 402 |
| [Coinbase x402 discovery](https://docs.cdp.coinbase.com/x402/seller/get-discovered) | Automatic after a paid call settles through Coinbase's facilitator | Coinbase's facilitator settles on Base, Base Sepolia, Polygon, Arbitrum, World and Solana. Listings without a settlement for 30 days are removed |
| [x402scan](https://www.x402scan.com/resources/register) | Submit the URL; it is added if it returns a valid challenge | Registration accepts Base and Solana resources |
| [8004scan](https://8004scan.io) | Register an [ERC-8004](/build-on-celo/build-with-ai/8004) identity whose registration file lists your endpoints and sets `x402Support` | An identity on Celo |
| [Buy catalog](https://usebuy.ai) | Ask for a listing with the [buy-skill issue form](https://github.com/celo-org/buy-skill/issues/new?template=list-your-service.yml) | A public origin, a description, a price, and the networks and tokens you accept |

## Describe your endpoint in the 402

Register the `bazaar` extension on the resource server and declare the shape of each route. The block below runs against the Celo facilitator and answers an unpaid request with a 402 that carries the description.

```ts theme={null}
// Celo mainnet (42220). Node 20+. npm i express @x402/express @x402/core @x402/evm @x402/extensions
import express from "express";
import { paymentMiddleware, x402ResourceServer } from "@x402/express";
import { HTTPFacilitatorClient, type RoutesConfig } from "@x402/core/server";
import { ExactEvmScheme } from "@x402/evm/exact/server";
import { bazaarResourceServerExtension, declareDiscoveryExtension } from "@x402/extensions/bazaar";

const facilitator = new HTTPFacilitatorClient({
  url: "https://api.x402.celo.org",
  createAuthHeaders: async () => {
    const h = { "X-API-Key": process.env.X402_API_KEY! };
    return { verify: h, settle: h, supported: h };
  },
});

const server = new x402ResourceServer(facilitator)
  .register("eip155:42220", new ExactEvmScheme())
  .registerExtension(bazaarResourceServerExtension);

const routes: RoutesConfig = {
  "GET /weather": {
    accepts: {
      scheme: "exact",
      network: "eip155:42220",
      payTo: "0xYourSellerPayoutAddress",
      price: {
        amount: "10000", // $0.01; USDC has 6 decimals
        asset: "0xcebA9300f2b948710d2653dD7B07f33A8B32118C", // Celo mainnet USDC, 6 decimals
        extra: { name: "USDC", version: "2" },
      },
    },
    description: "Current weather for a city",
    mimeType: "application/json",
    extensions: declareDiscoveryExtension({
      input: { city: "Lagos" },
      inputSchema: { properties: { city: { type: "string" } }, required: ["city"] },
      output: { example: { city: "Lagos", tempC: 31, sky: "haze" } },
    }),
  },
};

const app = express();
app.use(paymentMiddleware(routes, server));
app.get("/weather", (req, res) => res.json({ city: req.query.city, tempC: 31, sky: "haze" }));
app.listen(3000);
```

An unpaid `GET /weather?city=Lagos` returns `402` with an empty `{}` body. The payment requirements travel base64-encoded in the `PAYMENT-REQUIRED` response header. Decoded (abridged here), that header carries the price in `accepts` and the description in `extensions.bazaar`:

```json theme={null}
{
  "resource": { "url": "http://localhost:3000/weather?city=Lagos", "description": "Current weather for a city", "mimeType": "application/json" },
  "accepts": [{ "network": "eip155:42220", "amount": "10000", "asset": "0xcebA9300f2b948710d2653dD7B07f33A8B32118C" }],
  "extensions": {
    "bazaar": {
      "info": {
        "input": { "type": "http", "method": "GET", "queryParams": { "city": "Lagos" } },
        "output": { "type": "json", "example": { "city": "Lagos", "tempC": 31, "sky": "haze" } }
      },
      "schema": { "...": "JSON Schema generated from the declaration" }
    }
  }
}
```

Write the `description` for an agent that is deciding whether to call you: what the endpoint returns and when to use it, in under 500 characters. The HTTP method comes from the route key, so `"GET /weather"` declares a `GET`. For a `POST` route, use a key such as `"POST /summarize"`, and pass `bodyType: "json"` and the example body as `input`.

## Register with agent402.tools

One request lists your origin. The crawler probes the x402 surface hourly and ranks listings by health.

```bash theme={null}
curl -X POST https://agent402.tools/api/index/register \
  -H 'content-type: application/json' \
  -d '{"origin":"https://api.example.com"}'
```

## List in Coinbase's discovery index

Coinbase's index adds an endpoint automatically after a paid call has settled through Coinbase's facilitator. It removes resources that go 30 days without a settlement, and endpoints that stop returning `402`. That facilitator settles on Base, Base Sepolia, Polygon, Arbitrum, World and Solana, so an offer that only settles on Celo is not listed. To appear there:

1. Follow [Coinbase's seller guide](https://docs.cdp.coinbase.com/x402/seller/get-discovered) to add an offer on one of those networks and settle it through Coinbase's facilitator.
2. Keep at least one paid call a month on the offer that settles there.

## Register on x402scan

Submit the endpoint URL at [x402scan.com/resources/register](https://www.x402scan.com/resources/register). It is added when the URL returns a valid x402 challenge. Registration accepts resources on Base and Solana, so an endpoint that only offers Celo is not accepted there.

## Register an ERC-8004 identity

Agents that look up sellers on [8004scan](https://8004scan.io) read the on-chain registry. Register an identity on Celo, list your endpoints under `services` in the registration file, and set `x402Support` to `true`. The [ERC-8004 page](/build-on-celo/build-with-ai/8004) covers registration and the registry addresses.

## Ask for a listing in the Buy catalog

Buy's catalog is curated. Open a listing request with the [buy-skill issue form](https://github.com/celo-org/buy-skill/issues/new?template=list-your-service.yml) with your origin, a one-paragraph description, the price, and the networks and tokens you accept.

## Troubleshooting

| Symptom | Cause | Fix |
| - | - | - |
| The 402 has no `extensions` block | The extension is not registered on the server, or the route has no `extensions` entry | Call `registerExtension(bazaarResourceServerExtension)` and add `extensions: declareDiscoveryExtension(...)` to the route |
| agent402.tools shows nothing after an hour | The origin needs authentication before it answers 402, or it is not reachable from the public internet | Return the 402 to an unauthenticated request; check the origin from outside your network |
| A Coinbase listing disappeared | No settlement through Coinbase's facilitator for 30 days, or the endpoint stopped returning `402` | Make a paid call on the offer that settles there, and return `402` to unpaid requests. A failed health probe only drops a curated endpoint from the featured tier; it stays in the general Bazaar and returns when it recovers |
| x402scan rejects the URL | Registration accepts Base and Solana resources | Add an offer on one of those networks, or use the other indexes |

## Resources

| Resource | Link |
| - | - |
| x402 `bazaar` extension specification | [github.com/x402-foundation/x402](https://github.com/x402-foundation/x402/blob/main/specs/extensions/bazaar.md) |
| `@x402/extensions` on npm | [npmjs.com/package/@x402/extensions](https://www.npmjs.com/package/@x402/extensions) |
| Coinbase seller guide | [docs.cdp.coinbase.com/x402/seller/get-discovered](https://docs.cdp.coinbase.com/x402/seller/get-discovered) |
| agent402.tools seller page | [agent402.tools/sell](https://agent402.tools/sell) |
| x402scan resource registration | [x402scan.com/resources/register](https://www.x402scan.com/resources/register) |
| 8004scan | [8004scan.io](https://8004scan.io) |
| Buy | [usebuy.ai](https://usebuy.ai) |

## Related

* [x402: Agent Payments](/build-on-celo/build-with-ai/x402) - Set up the resource server this page assumes
* [ERC-8004: Agent Trust Protocol](/build-on-celo/build-with-ai/8004) - Identity and reputation for the seller behind the endpoint
* [Attribution Tags](/build-on-celo/attribution-tags) - Credit on-chain activity back to your app
* [MPP](/build-on-celo/build-with-ai/mpp) - Machine Payments Protocol: charge USDC per request over HTTP


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.