# ToolMint x402 Listing Doctor

> Lint any x402 endpoint the way buyer agents and Bazaar catalogs see it: unpaid probe, decoded 402, accepts/bazaar/well-known/openapi checks, scored fix list (GET /check?url=https://...)

- Status: Coming soon
- Price: $0.01 / call (x402 exact, USDC on Base eip155:8453, payTo 0xfbF7413bcB3a604936775C96FDbe0b0C9c9E37F5)
- Planned URL: https://toolmint-x402-doctor.toolmint.workers.dev
- OpenAPI: https://toolmint.toolmint.workers.dev/tools/x402-doctor/openapi.json

## Routes

- `GET /check` $0.01: Lint any x402 endpoint the way buyer agents and Bazaar catalogs see it: unpaid probe, decoded 402, accepts/bazaar/well-known/openapi checks, scored fix list (GET /check?url=https://...)

## What question it answers

"If a buyer agent or a catalog (CDP Bazaar, PayAI, agent402) looks at my paid x402 route, what would they see, and what should I fix?" You give the URL of one paid GET route. The tool makes one unpaid request to it, then reads `/.well-known/x402` and `/openapi.json` on the same site, and returns a 0 to 100 score, an A to F grade, and a list of pass / warn / fail checks, each with a fix line.

## When to use it

- You run an x402 seller and want a pre-launch or periodic check of your 402 response and discovery files.
- You operate a directory and want a quick read on a submitted listing.

## When not to

- It is a lint, based on the public x402 v2 spec and catalog behaviour observed on 2026-10-31. A high score does not mean any catalog will list your resource, and a low one does not prove buyers cannot pay.
- It never pays and never sends a payment header, so it cannot test settlement or your real response.
- GET routes only, one URL per call. Only https on port 443, public DNS names only. IP addresses, localhost and internal hostnames are refused.
- It does not monitor over time or keep history.

## Example

```bash
curl -i "https://toolmint-x402-doctor.toolmint.workers.dev/check?url=https://toolmint-nws-alerts.toolmint.workers.dev/alerts?area=TX"
```
```json
{
  "tool": "x402-listing-doctor",
  "version": "0.1.0",
  "target": "https://toolmint-nws-alerts.toolmint.workers.dev/alerts?area=TX",
  "finalUrl": "https://toolmint-nws-alerts.toolmint.workers.dev/alerts?area=TX",
  "fetchedAt": "2026-10-31T...Z",
  "httpStatus": 402,
  "score": 95,
  "grade": "A",
  "summary": { "pass": 12, "warn": 1, "fail": 0 },
  "checks": [
    { "id": "status", "level": "pass", "message": "Unpaid request returns HTTP 402" },
    { "id": "body.mirror", "level": "warn",
      "message": "Requirements are only in the header; body-only clients see no accepts/bazaar",
      "fix": "Mirror the PaymentRequired object in the JSON body (unpaidResponseBody)." }
  ],
  "offers": [{ "networkName": "Base mainnet", "assetIsUsdc": true, "priceUsd": 0.005, "scheme": "exact",
               "network": "eip155:8453", "amount": "5000",
               "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
               "payTo": "0xfbF7413bcB3a604936775C96FDbe0b0C9c9E37F5" }],
  "decoded": { "header": { "x402Version": 2, "accepts": ["..."] }, "body": null },
  "sources": [ { "url": "https://toolmint-nws-alerts.toolmint.workers.dev/alerts?area=TX", "status": 402 },
               { "url": "https://toolmint-nws-alerts.toolmint.workers.dev/.well-known/x402", "status": 200 },
               { "url": "https://toolmint-nws-alerts.toolmint.workers.dev/openapi.json", "status": 200 } ],
  "disclaimer": "Unpaid, read-only probe (3 GETs at most). No payment was sent. ...",
  "cached": false
}
```
`level` is one of `pass`, `warn`, `fail`, `info`. Each fail costs 15 points, each warn 5. If the target returns no readable payment requirements, the score is capped at 20 (grade F). The `sources` list shows every URL fetched and its HTTP status.

## Data source and licence

The data is the response of the URL you give, plus that site's `/.well-known/x402` and `/openapi.json`. Nothing else is used. The lint rules are ToolMint's own reading of the public x402 v2 spec. The tool sends a request with its own User-Agent to the target, so the target's operator will see it.

## Freshness and limits

- At most 3 fetches per check, 8 second timeout each, 512 KB body cap, up to 3 redirects.
- Results are cached 10 minutes per exact URL on a warm Worker instance (a cached answer is charged and shows `cached: true`).
- Checks reflect catalog behaviour as of 2026-10-31 and may drift.
