Skip to content

merchant: serve OpenAPI spec for x402scan discovery#14

Open
A1igator wants to merge 2 commits into
mainfrom
A1igator/x402scan-openapi-discovery
Open

merchant: serve OpenAPI spec for x402scan discovery#14
A1igator wants to merge 2 commits into
mainfrom
A1igator/x402scan-openapi-discovery

Conversation

@A1igator
Copy link
Copy Markdown
Contributor

Summary

  • Add GET /openapi.json to the AI garbage detector merchant so its demo endpoints are discoverable by agents through x402scan.
  • Each route declares x-payment-info (fixed USD $0.01, protocols: [{ x402: {} }]) and an input schema (parameters) so x402scan classifies them as invocable, not just visible.
  • Handlers honor the documented query params (?location= on /weather, ?seed= on /garbage) so the spec matches actual behavior.
  • New optional PUBLIC_URL env populates the OpenAPI servers field for public deployments; falls back to the request origin.

Why x402scan needs this

x402scan's discovery precedence is OpenAPI first, runtime 402 probe second. Without /openapi.json the AI garbage detector cannot be listed in the marketplace, and endpoints without an input schema are skipped during registration as non-invocable.

Test plan

  • Render buildOpenApi("https://example.com") and validate the output against the spec's required fields (openapi, info.title, info.x-guidance, info.version, paths, per-route x-payment-info + responses.402).
  • Boot the merchant locally and curl http://localhost:4021/openapi.json | jq (requires the usual .env.merchant setup).
  • After deploying with PUBLIC_URL set, submit the deployment URL at https://www.x402scan.com/resources/register and confirm both routes are listed.

🤖 Generated with Claude Code

A1igator added 2 commits May 20, 2026 00:29
Adds GET /openapi.json to the AI garbage detector merchant so the demo
endpoints are discoverable by agents through x402scan. The document
follows the x402scan discovery spec: each route declares x-payment-info
with fixed USD pricing and an input schema (parameters) so endpoints are
classified as invocable, not just visible.

Handlers now honor the documented query parameters (?location= on
/weather, ?seed= on /garbage) so the spec matches actual behavior. A new
optional PUBLIC_URL env populates the OpenAPI servers field for public
deployments; otherwise it falls back to the request origin.

README adds a short discovery section pointing at /openapi.json and the
x402scan registration page.
Two issues surfaced by self-review:

1. Price drift: `paidRoute.accepts[0].price = "$0.01"` and the OpenAPI
   `x-payment-info.amount = "0.010000"` were two unlinked string literals.
   A future price bump would touch one and leave the other stale. Extract
   `PRICE_USD_CENTS` as the single source and derive the display ($0.01)
   and OpenAPI (0.010000) forms from it.

2. PUBLIC_URL path leak: `@agentcash/discovery` (the package x402scan uses
   to ingest OpenAPI docs) does `new URL(servers[0].url).pathname` and
   prepends it to every registered route. So `PUBLIC_URL=https://x.com/api`
   would silently register `/api/weather` instead of `/weather`. Wrap the
   resolved URL in a `toOrigin` helper that collapses to `URL.origin` and
   note the normalization in the README.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant