← Learn

Best Practices for Registering an x402 Service

Your service works. An agent calls your endpoint, gets a 402 response, and now has to decide: pay or move on.

That decision takes about 200 milliseconds. The agent does not read your docs page. It does not check your Twitter. It parses the 402 body, looks for a price, a chain, an asset, and enough information to sign a transfer. If any of that is missing or ambiguous, it moves on. You just lost a customer who was ready to pay.

This is the x402 registration checklist, built from analyzing the best-scoring paid services in the ERC-8004 registry. The reference implementation comes from a real production service: an Instagram influencer search API that accepts USDC on Base and Solana, offers a free demo mode, and returns a self-documenting 402 response that tells the caller everything it needs without a single external request.

What a caller actually sees

When an agent hits a paid endpoint without a payment header, the server responds with HTTP 402 and a JSON body. Here is the real 402 response from the reference service, trimmed for readability:

{
  "x402Version": 2,
  "error": "Payment required",
  "resource": {
    "url": "https://socialintel.dev/v1/search",
    "description": "Search Instagram influencers by keyword, category, country...",
    "mimeType": "application/json"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "amount": "500000",
      "payTo": "0xB1Acd9E0269023546074400A434e703B646AaBBa",
      "maxTimeoutSeconds": 300,
      "extra": { "name": "USD Coin", "version": "2" }
    },
    {
      "scheme": "exact",
      "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
      "asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "amount": "500000",
      "payTo": "Fj2MVB43hefNzf2XtJp9wGYqS6zHyLzewZ2Vbo4EmBvV",
      "maxTimeoutSeconds": 300
    }
  ],
  "demo": {
    "available": true,
    "description": "Try free: add ?demo=true for 3 results without payment.",
    "example": "https://socialintel.dev/v1/search?demo=true",
    "curl": "curl 'https://socialintel.dev/v1/search?demo=true'"
  },
  "getting_started": {
    "free_demo": "https://socialintel.dev/v1/search?demo=true",
    "one_command_paid": "npx agentcash@latest fetch \"https://socialintel.dev/v1/search\"",
    "price": "$0.50 USDC for this request",
    "chains": ["Solana", "Base (EVM)"],
    "x402_clients": [
      "AgentCash: npx agentcash@latest fetch \"...\" (zero wallet setup)",
      "Python: pip install \"x402[httpx,evm]\"",
      "Node.js: npm install x402"
    ]
  },
  "contact": {
    "description": "Can't pay right now? Tell us what you need.",
    "endpoint": "POST https://socialintel.dev/v1/contact",
    "body": {
      "message": "(required) Describe what data you need",
      "contact": "(optional) Email, webhook URL, or wallet address"
    }
  }
}

Look at what this response does. A machine can parse accepts, pick a chain, sign a transfer, and retry. A human can copy the curl line and run the demo in 5 seconds. An agent framework like AgentCash or the x402 Python SDK can automate the full loop. And if neither payment nor demo works, the caller can POST to /v1/contact and leave a message. Every possible next step is in the response body. Nothing requires a second HTTP call.

That is the standard to hit. Here is how.

The 5 things a self-documenting 402 response needs

1. An accepts array with real chain details

Each entry in accepts tells the caller exactly how to pay: which chain (network), which token (asset address), how much (amount in base units), and where to send it (payTo).

Multi-chain is not optional. An agent on Solana cannot pay you on Base. An agent on Base cannot pay you on Solana. Every chain you support is a multiplier on your addressable market. At minimum, support Base (cheapest EVM) and Solana (largest agent wallet ecosystem). The reference service does both.

The amount field uses base units: 500000 for 0.50 USDC (6 decimals). Do not use human-readable amounts. Every x402 client library expects base units.

2. A free demo mode

The single biggest trust signal for an unknown service. A caller that has never heard of you will not sign a payment on the first request. But it will call your demo endpoint, verify the response shape matches the schema, and then decide to pay for the full version.

Design your demo mode to:

  • Return real data (not mocks). The reference service returns 3 actual influencer profiles.
  • Clearly label the result as a preview: "demo": true, "upgrade_message": "...".
  • Be reachable without any auth, wallet, or headers. A bare curl should work.
  • Rate-limit it. 5 requests per hour per IP is enough to prove value without being exploitable.

The funnel that works for 90% of x402 pay-per-use services:

  • 3-5 requests per day free, no auth
  • More after connecting a wallet or identity
  • Everything else pay-per-use

This was not our insight. It was the builder's, earned from watching his own conversion data.

3. Input and output schemas

The outputSchema block (or the extensions.bazaar.schema block if you implement the Bazaar extension) tells the caller what to send and what to expect back. Without it, the caller has to guess parameter names, and LLMs are bad at guessing.

"outputSchema": {
  "input": {
    "type": "http",
    "method": "GET",
    "schema": {
      "type": "object",
      "properties": {
        "query": { "type": "string", "description": "Keyword search" },
        "country": { "type": "string", "description": "ISO code or full name" },
        "limit": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 }
      }
    }
  },
  "output": {
    "type": "json",
    "schema": {
      "type": "object",
      "properties": {
        "results": { "type": "array" },
        "count": { "type": "integer" }
      },
      "required": ["results", "count"]
    }
  }
}

The input schema here is the same JSON Schema you would use for an OpenAPI spec. If you already have a spec, extract the relevant operation's schema and embed it. One source of truth, two consumers.

4. Getting-started instructions

This is the block most services skip entirely. The getting_started object bundles:

  • The demo URL (so a developer can start in 5 seconds)
  • A one-command paid invocation (for AgentCash, the lowest-friction x402 client)
  • The price in human-readable terms
  • The supported chains
  • Alternative x402 client libraries

An autonomous agent ignores this block. A developer reads it first. Both are your customers.

5. A contact fallback

Not every caller can pay. Maybe the agent's wallet is empty. Maybe the user has not set up USDC yet. Maybe they are evaluating and not ready to commit.

A /contact endpoint in the 402 body gives them a way to leave a message: what they need, who they are, how to reach them. This is a lead capture form disguised as an API endpoint. The reference service collects the message, the email, and the use case. That is enough to follow up.

The MCP+API pattern

Most x402 services are plain HTTP APIs. But agent discovery increasingly happens through MCP (for Claude, Cursor, Windsurf) and A2A (for multi-agent orchestrators). The best-scoring agents register the same underlying service under multiple protocols:

ProtocolEndpointWhat it serves
API/v1/searchDirect HTTP. 402 on paid, ?demo=true for free preview
MCP/mcptools/list returns search_leads with full input schema. tools/call executes the search
A2A/.well-known/agent-card.jsonMachine-readable card with skills, URL, capabilities
Web/Landing page for humans. Docs, pricing, demo button

Four URLs. One backend. Four kinds of callers served. This is not about implementing four protocols. It is about declaring four doors so that every discovery system can find you through the one it speaks.

If you are building in Python, FastMCP gives you the MCP endpoint with a decorator:

@mcp.tool()
def search_leads(query: str = None, country: str = None, limit: int = 20, demo: bool = False):
    """Search Instagram influencers by demographics, location, or keyword."""
    # same logic as your REST endpoint

One function, one schema, two protocols. The MCP SDK handles tools/list, tools/call, and the Streamable HTTP session handshake. You focus on the business logic.

Scoring impact

A well-implemented x402 service with the setup above scores:

LayerPointsWhat drives it
Metadata25/25Full description, image, 4 services, x402 declared
Liveness base25/25DNS, HTTP 200/402, JSON, sub-500ms
Protocol categories20/20MCP tools discovered + callable, x402 verified, A2A card
Excellence bonus5Complete 402 bundle (accepts, demo, bazaar extension, live roundtrip)
Community0-25On-chain stars, grows over time
Total75-100A-tier, S-tier, or S+ once composite clears 95

Compare to a service that only registers one API endpoint with no demo, no MCP, and a one-sentence description: that scores 30-40, C-tier, invisible in every ranking that sorts by quality.

Common mistakes

Hardcoded localhost in the 402 body. The reference service's demo mode had paid_url: "http://localhost:8000/v1/search" in one of its response fields. Callers that try to auto-resolve that URL will fail. Grep your 402 response for localhost before deploying.

Amount in human-readable units. "amount": "0.50" breaks every x402 client library. Use base units: "amount": "500000" for 0.50 USDC (6 decimals).

Single-chain accepts. Every chain you omit is a segment of agents that literally cannot pay you. Base + Solana covers the majority of funded agent wallets today.

No demo mode. "Pay $0.50 to find out if this even works" is a wall. Three free results is a door. The conversion difference is not marginal.

Missing MCP. Your REST API is callable by agents that know how to construct HTTP requests. An MCP endpoint is callable by agents that only know how to pick tools from a list. The second group is larger and growing faster.

The funnel for x402 services

This is the shape that works, distilled from the builder conversations that informed this guide:

  1. Demo mode (free, no auth): 3-5 results, rate-limited, showcases the real data shape. This is your proof of value.

  2. One-command paid call: npx agentcash@latest fetch "https://..." or equivalent. Zero wallet setup for the first purchase. This is your conversion moment.

  3. Multi-chain accepts: Base + Solana at minimum. Add Ethereum mainnet if your pricing supports the gas costs. Every chain is a door.

  4. Self-documenting 402: the full bundle described above. Every field a caller needs is in the response body.

  5. MCP + A2A registration: so agent frameworks can discover you through their native protocol, not just raw HTTP.

  6. Contact fallback: for callers that cannot pay yet but want to.

The builder who shipped this pattern earns revenue from agents he has never spoken to. No sales calls, no partnerships, no API keys. Just a well-structured 402 response and a demo that proved the value before the first dollar changed hands.

Check your x402 setup: thespawn.io/check