How to List Your Service on Agentic.market: A Step-by-Step Guide

Agentic.market is the directory where AI agents find x402 services. If your service isn't indexed there, agents using the default discovery path won't find it. Getting listed isn't hard — but getting listed correctly has a failure mode that's almost invisible.

I got all nine of my endpoints indexed in 45 minutes. After spending six weeks not knowing they were silently being rejected. This guide covers both: the correct process, and how to diagnose the silent failure.

How Indexing Works

Agentic.market is powered by the CDP Bazaar Discovery API. Your service doesn't apply for listing — it gets indexed automatically when two conditions are met:

1. Your 402 response includes a valid Bazaar extension. When an agent hits your endpoint and gets a 402 Payment Required response, the response headers must include a correctly structured Bazaar extension declaring what the endpoint does, what inputs it accepts, and what output it returns.

2. A real payment settles through the CDP facilitator. The indexer processes your Bazaar metadata when it sees a successful settlement. No payment, no indexing trigger. This means you need at least one real transaction per endpoint — even if it's a test payment you make yourself.

After both conditions are met, the CDP facilitator validates your schema and queues your endpoint for indexing. If validation passes, your service appears in the Discovery API within 15-30 minutes. Agentic.market reads from this API.

The Correct Code

Use the x402 Python SDK's built-in helper. Don't hand-craft the extension dictionary.

from x402.extensions.bazaar import declare_discovery_extension from x402.extensions.bazaar import OutputConfig # Correct — use the helper "GET /api/v1/kimchi-premium": RouteConfig( accepts=payment_options("$0.001"), extensions=declare_discovery_extension( input={"symbol": "BTC"}, input_schema={ "properties": { "symbol": {"type": "string"} }, "required": ["symbol"], }, output=OutputConfig(example={ "symbol": "BTC", "premium_percent": 1.1, }), ), )

The helper handles everything the CDP schema validator checks: the type: "http" field, camelCase parameter names (queryParams not query_params), the $schema declaration, and the additionalProperties: false envelope. You provide inputs and outputs. The helper assembles a compliant structure.

Critical: Don't wrap the helper output in another {"bazaar": ...} layer. declare_discovery_extension() already returns the complete extension structure. Writing extensions={"bazaar": declare_discovery_extension(...)} creates a double-nested bazaar.bazaar.info structure that silently fails validation.

The Silent Failure

This is the part that cost me six weeks. If your Bazaar extension fails schema validation, the CDP facilitator doesn't return an error. Your 402 responses still work normally. Payments still settle on-chain. The API returns 200 after payment. Everything looks fine.

The only signal that validation failed is a header on the facilitator's verify and settle responses: EXTENSION-RESPONSES. Base64-decode it and you'll see either:

# Success — your service will be indexed {"bazaar": {"status": "processing"}} # Failure — your service is being silently rejected {"bazaar": {"status": "rejected", "rejectedReason": "invalid discovery configuration"}}

The problem: the x402 SDK doesn't log this header by default. Your server receives it, processes the payment, and discards the header without recording it. You never see the rejection unless you specifically capture and decode the header.

How to Capture the Facilitator Response

Add this to your server code to log the extension responses. It monkey-patches the SDK's facilitator client to capture headers that would otherwise be silently dropped:

from x402.facilitator import FacilitatorClient import base64, json, logging logger = logging.getLogger(__name__) _orig_settle = FacilitatorClient._settle_http async def _settle_debug(self, *a, **kw): r = await _orig_settle(self, *a, **kw) ext = r.headers.get("extension-responses", "") if ext: decoded = json.loads(base64.b64decode(ext)) logger.info(f"Bazaar status: {decoded}") return r FacilitatorClient._settle_http = _settle_debug

Deploy this, run one test payment, and check your logs. If you see "status": "rejected", your schema has an error. If you see "status": "processing", the indexer accepted it and your service should appear within 30 minutes.

The Three Schema Errors I Made

My six weeks of invisibility came from three specific mistakes, all caught by the additionalProperties: false validator:

1. Missing type: "http". The schema requires this field. My hand-crafted extension didn't include it. The helper adds it automatically.

2. query_params instead of queryParams. Snake case vs camel case. The schema requires camelCase. Python's convention is snake_case. The helper handles the conversion.

3. Extra field input_schema. I added a field that doesn't exist in the spec. With additionalProperties: false, any unrecognized field causes the entire validation to fail.

All three errors would have been avoided by using declare_discovery_extension() from the start. The helper exists specifically to prevent these mismatches.

Verification Checklist

After deploying your extension, run through this sequence:

# 1. Verify your 402 response includes the extension curl -s -i https://your-api.com/your-endpoint \ | grep -i payment-required # 2. Decode the 402 header to check extension structure # (copy the base64 value from the payment-required header) echo "eyJiYXphYXIi..." | base64 -d | python3 -m json.tool # 3. Make a test payment to trigger indexing # (use your own wallet, costs as little as $0.001) # 4. Check your logs for the EXTENSION-RESPONSES status # "processing" = good, "rejected" = schema error # 5. Query the Discovery API after 30 minutes curl -s "https://api.cdp.coinbase.com/platform/v2/x402/\ discovery/resources?payTo=YOUR_WALLET" \ | python3 -m json.tool | grep -c "your-domain" # If count > 0: you're indexed # If count = 0 after 1 hour: check step 4 for rejection

If It Says "processing" But Never Indexes

There's a second failure mode. Your schema passes validation (status: "processing") but the indexer never transitions to "indexed." I hit this too — a CDP infrastructure-side issue that required contacting their support team.

If your status shows "processing" for more than 6 hours, file a support case at support.cdp.coinbase.com. Include your payTo wallet address, the domain, the SDK version, and timestamps of successful settlements. CDP support responded to my case within 4 hours and escalated to their indexing infrastructure team.

The support template that worked for me: state the exact symptom ("endpoints stuck in processing for X hours"), include the cross-check ("same wallet, different domain, endpoints indexed successfully"), and provide all settlement timestamps. Specificity gets faster responses.


Related:

Disclaimer: This blog documents practical workflows based on personal experience. Nothing here is financial, legal, or professional advice.

Comments