Build once, register reliably, and keep your resources discoverable by agents.
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.
402 challenge behavior as the final source of truth.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.
- Add high-level guidance in info.x-guidance for user-friendly discovery. This document should explain to an agent how to use your API at a high level.
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):
- { "mpp": { "method": "", "intent": "", "currency": "" } }
- 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.
Free / public routes:
- If your spec has a global security requirement, free routes need an explicit override: security: []
- This tells discovery the endpoint is intentionally open — without it, the endpoint is flagged as having no auth mode.
- Even without global security, adding security: [] to free routes makes the auth mode unambiguous.
Rules:
- Runtime 402 behavior is authoritative over static metadata.
- "amount" is for both runtime accepts and x-payment-info fixed pricing.
Workflow:
1) Audit discovery and probe failures.
2) Fix discovery metadata and 402 behavior.
3) Re-run audits until clean.
4) Register on MPPScan at https://mppscan.com/register.
Validation commands:
npx -y @agentcash/discovery@latest discover "$TARGET_URL"
npx -y @agentcash/discovery@latest check "$ENDPOINT_URL"
These yield warnings regarding the discovery document and how it can be improved.
Done when:
- resources are discovered from OpenAPI
- no critical parser/probe errors remain
- server is registered on MPPScan with no failed resourcesRun discovery against your origin to see what MPPScan resolves before you register.
Runs discoverOriginSchema against the origin and probes each discovered route. Nothing is registered.
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
openapi, info.title, info.x-guidance, info.version, paths.responses.402 and x-payment-info.x-payment-info.protocols (array of protocol objects) and one pricing mode (fixed or dynamic) with currency.security + components.securitySchemes for auth declaration.info.x-guidance for agent-friendly discovery.info.contact.email — your contact email. Lets you verify ownership of your origin, allows users to contact you, and lets you customize your merchant pages on Poncho.x-payment-info{ price: { mode: "fixed", currency: "USD", amount: "<amount>" } }{ price: { mode: "dynamic", currency: "USD", min: "<min>", max: "<max>" } }{
"openapi": "3.1.0",
"info": {
"title": "My API",
"version": "1.0.0",
"description": "example demo server",
"x-guidance": "Use POST /api/search for neural web search. Accepts a JSON body with a 'query' field.",
"contact": {
"email": "you@example.com"
}
},
"x-discovery": {
"ownershipProofs": ["<proof-1>"]
},
"paths": {
"/api/search": {
"post": {
"operationId": "search",
"summary": "Search - Neural search across the web",
"tags": ["Search"],
"x-payment-info": {
"price": {
"mode": "fixed",
"currency": "USD",
"amount": "0.010000"
},
"protocols": [
{
"x402": {}
},
{
"mpp": {
"method": "",
"intent": "",
"currency": ""
}
}
]
},
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"query": { "type": "string", "minLength": 1, "description": "The query string for the search" }
},
"required": ["query"]
}
}
}
},
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"results": { "type": "array", "items": { "type": "object" } }
},
"required": ["results"]
}
}
}
},
"402": { "description": "Payment Required" }
}
}
}
}
}MPPScan uses the OpenAPI document at /openapi.json to discover your API. It will also check the runtime 402 challenge behavior to ensure it is correct.
| Order | Source | Expected Location |
|---|---|---|
| 1 | OpenAPI document | /openapi.json |
| 2 | 402 API Response | Correct 402 header response |
SIWX routes are identity-gated, requiring a wallet proof but no payment. Agents with a wallet can call these for free.
siwx in components.securitySchemes.security: [{ "siwx": [] }].x-payment-info to 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 routes don't require payment or identity, but they still need an explicit auth mode declaration so discovery can classify them correctly.
security: [] (empty array) to each free operation in the OpenAPI spec.{
"paths": {
"/api/status": {
"get": {
"summary": "Health check (free, no auth)",
"security": [],
"responses": { "200": { "description": "OK" } }
}
}
}
}If no OpenAPI document exists, a single endpoint URL can still be registered. MPPScan probes the URL directly via checkEndpointSchema from @agentcash/discovery.
POST first, then GET, PUT, PATCH, DELETE, and picks the first response with a valid MPP payment option.402 challenge with at least one MPP entry.402 body that carries one) to make the endpoint registerable.curl -i -X POST https://yourdomain.com/api/route
curl -i -X GET https://yourdomain.com/api/routeThese are the most frequent errors seen during registration.
| 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 payment mode to the response (MPP) |
| No Auth Mode | Endpoint has no security declaration in the spec | Add security: [] for free routes, or security: [{ "siwx": [] }] for identity-gated routes |
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 payment mode to the response (MPP)
No Auth Mode
Endpoint has no security declaration in the spec
Add security: [] for free routes, or security: [{ "siwx": [] }] for identity-gated routes
For further questions, contact us at merchants@merit.systems.