Become discoverable
Build once, register reliably, and keep your resources discoverable by agents.
Why This Matters
If agents can't discover your API, they can't call it. Bulletproof discovery turns your endpoint from merely listed to reliably invocable.
When metadata and runtime 402 behavior agree, agents succeed on the first pass. You get fewer failures, less debugging churn, and more real agent traffic.
- Publish OpenAPI as the canonical machine-readable contract.
- Treat runtime
402challenge behavior as the final source of truth.
Copy for Agents
Paste this directly into your coding agent. It should handle discovery implementation and validation end-to-end.
Implement discovery for this server and make it pass.
Discovery strategy:
- OpenAPI is the canonical discovery contract. Publish your spec at /openapi.json.
Schema guidance (important):
- Each invocable route should expose an input schema.
- In OpenAPI, define requestBody.content["application/json"].schema.
- This is required for reliable agent invocation and robust listing behavior.
- TypeScript recommendation (optional): Zod v4 is a good source of truth, but any valid schema pipeline is fine.
- Add high-level guidance in info.x-guidance for user-friendly discovery.
Contact email (recommended):
- Ask the user for their contact email and add it as info.contact.email in the openapi.json.
- This lets them verify ownership of their origin, allows users to contact them, and lets them customize their merchant pages on Poncho.
OpenAPI payable operation must include ALL:
- x-payment-info with:
- price (structured object):
- fixed: { mode: "fixed", currency: "USD", amount: "<amount>" }
- dynamic: { mode: "dynamic", currency: "USD", min: "<min>", max: "<max>" }
- protocols (array of objects):
- { "x402": {} }
- responses: { "402": { description: "Payment Required" } }
SIWX (identity-only) routes:
- Declare a security scheme named "siwx" in components.securitySchemes.
- Reference it on each identity-gated operation: security: [{ "siwx": [] }].
- Do NOT add x-payment-info to SIWX-only routes — that classifies them as paid.
Rules:
- Runtime 402 behavior is authoritative over static metadata.
- OpenAPI x-payment-info.price.amount is decimal USD; runtime x402 v2 accepts[].amount is token atomic units (for USDC, 0.01 => "10000").
- Registration probes must reach a 402 challenge before body/query validation rejects the request.
Registration gate (hard rule):
- Registration creates a public listing that agents will call and pay for. Do NOT register until BOTH are true:
1. The implementation is done and live — deployed at its final public origin, /openapi.json served from that origin, and discovery + probe audits clean against the deployed URL (not localhost, not a preview deployment, not a partial route set).
2. The user has explicitly approved registering that specific origin.
- Implementing and validating automatically is fine. Publishing a listing is not — always stop and ask first.
Workflow:
0) Install the agentcash MCP server:
npx agentcash install
1) Audit discovery and probe failures.
2) Fix discovery metadata and 402 behavior.
3) Re-run audits until clean against the deployed public origin.
4) Ask the user to approve registration. Show them the origin, routes, prices, auth modes, and audit summary. Do not proceed without an explicit yes.
5) Only after approval, use the agentcash MCP fetch_with_auth tool to POST to https://x402scan.com/api/x402/registry/register-origin with body: { "origin": "$TARGET_URL" }.
Validation commands:
npx -y @agentcash/discovery@latest discover "$TARGET_URL"
npx -y @agentcash/discovery@latest check "$ENDPOINT_URL"
Done when:
- resources are discovered from OpenAPI
- no critical parser/probe errors remain
- the implementation is live and the user has been given the registration decisionTest your API
Run discovery against your origin to see what x402scan resolves before you register.
Discovery Strategy
OpenAPI is the canonical discovery format. Use it for the cleanest machine-readable contract and best agent compatibility.
The x-payment-info fields are a superset of the IETF API payment spec. The fields do not collide, so your service is still compatible if you already follow the IETF standard.
Expected location: GET /openapi.json
Requirements
- Top-level fields:
openapi,info.title,info.x-guidance,info.version,paths. - For paid operations:
responses.402andx-payment-info. - Set
x-payment-info.protocolsas an array of protocol objects and one pricing mode (fixedordynamic) withcurrency. - Use OpenAPI
securityandcomponents.securitySchemesfor auth declaration. - Add high-level guidance in
info.x-guidancefor agent-friendly discovery.
Recommended
info.contact.email— your contact email. It lets you verify ownership of your origin, allows users to contact you, and lets you customize your merchant pages on Poncho.
Pricing modes in x-payment-info
- Fixed:
{ price: { mode: "fixed", currency: "USD", amount: "<amount>" } } - Dynamic:
{ price: { mode: "dynamic", currency: "USD", min: "<min>", max: "<max>" } } - OpenAPI
x-payment-info.price.amountis decimal USD; runtime x402 v2accepts[].amountis token atomic units. For USDC,0.01becomes"10000".
Minimal valid example
{
"openapi": "3.1.0",
"info": {
"title": "My API",
"version": "1.0.0",
"x-guidance": "Use POST /api/search for neural web search."
},
"paths": {
"/api/search": {
"post": {
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": { "type": "object" }
}
},
"required": ["results"]
}
}
}
},
"402": { "description": "Payment Required" }
},
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"minLength": 1,
"description": "The query string for the search"
}
},
"required": ["query"]
}
}
}
},
"x-payment-info": {
"price": {
"mode": "fixed",
"currency": "USD",
"amount": "0.010000"
},
"protocols": [{ "x402": {} }]
}
}
}
}
}
Discovery Precedence
x402scan uses the OpenAPI document at /openapi.json to discover your API. It also checks runtime 402 behavior to ensure the payment challenge is valid.
| Order | Source | Expected Location |
|---|---|---|
| 1 | OpenAPI document | /openapi.json |
| 2 | 402 API Response | Correct 402 payment response |
SIWX (Sign-In with X) Routes
SIWX routes are identity-gated, requiring a wallet proof but no payment. Agents with a wallet can call these for free.
- Declare a security scheme named
siwxincomponents.securitySchemes. - Reference it on each identity-gated operation via
security: [{ "siwx": [] }]. - Do not add
x-payment-infoto SIWX-only routes, as that classifies them as paid.
{
"components": {
"securitySchemes": {
"siwx": {
"type": "apiKey",
"in": "header",
"name": "SIGN-IN-WITH-X"
}
}
},
"paths": {
"/api/me": {
"get": {
"summary": "Get current user profile",
"security": [{ "siwx": [] }],
"responses": { "200": { "description": "OK" } }
}
}
}
}
The scheme must be named siwx. Discovery resolves it by name. Routes with both x-payment-info and siwx security are classified as paid, not SIWX.
Free / Public Routes
Free routes don't require payment or identity, but they still need an explicit auth mode declaration so discovery can classify them correctly.
- Add
security: []to each free operation in the OpenAPI spec. - This overrides any global security requirement and tells discovery the endpoint is intentionally open.
- Without it, the endpoint is flagged as having no auth mode during registration.
{
"paths": {
"/api/status": {
"get": {
"summary": "Health check (free, no auth)",
"security": [],
"responses": { "200": { "description": "OK" } }
}
}
}
}
Endpoint-Only Fallback
If no OpenAPI document exists, a single endpoint URL can still be registered. x402scan probes the URL directly with @agentcash/discovery.
- The probe is method-aware and chooses the first response with a valid x402 payment option.
- The endpoint must return a parseable
402challenge with at least one x402 entry. - Request validation should let unauthenticated probes reach the
402challenge before body or query validation rejects the request. - Endpoints without an input schema are non-invocable and are skipped during registration. Publish an OpenAPI schema or a
402body carrying one to make the endpoint registerable. - SIWX endpoints are registered as identity-only. No payment is required, but agents still need a wallet proof to call them.
curl -i -X POST https://yourdomain.com/api/route
curl -i -X GET https://yourdomain.com/api/route
Common Failure Reasons
| Error | Likely Cause | Fix |
|---|---|---|
| Not Found | OpenAPI not found at {origin}/openapi.json | Add an OpenAPI document at {origin}/openapi.json |
| Input/Output Schema Missing | Operation has no input or output schema | Add an input and output schema to the operation |
| No Payment Modes Detected | No payment modes detected in the response | Add a valid x402 payment mode to the response |
| Expected 402, got 400 | Request validation rejected the unauthenticated probe before payment middleware ran | Let probes reach the 402 challenge before body/query validation, or add schemas/examples that let probes send valid input |
| Malformed Runtime Amount | Runtime amount used decimal dollars | Encode runtime amounts in token atomic units |
| No valid x402 response / No 402 challenge | Endpoint is free but not marked as such | Add security: [] to the operation |
For further questions, contact us at merchants@merit.systems.