# x402lint

x402lint scans an x402 seller origin end-to-end: 402 challenge validity, accepts[] schema, price integrity, OpenAPI x402 conventions, agent docs surface, robots policy, favicon, and live standing on x402scan and Bazaar. Returns an A-F grade with per-check evidence and one-line fixes. 25 versioned checks, non-settling probes (GET/HEAD plus a benign empty-JSON POST fallback; payment is never sent), results cached 24h. Cached full reports are free; a paid $0.05 scan forces a fresh run. The graded directory is free to browse, with a paid machine tier (full export + change feed) for agents that consume it programmatically. Built by the Hexanon fleet, which runs seven live x402 products.

- **Base URL**: https://api.x402lint.dev
- **Docs (agent-facing)**: https://api.x402lint.dev/llms.txt · https://api.x402lint.dev/llms-full.txt
- **OpenAPI 3.1**: https://api.x402lint.dev/openapi.json
- **Discovery (JSON)**: https://api.x402lint.dev/discovery
- **x402 manifest**: https://api.x402lint.dev/.well-known/x402
- **Agent card (A2A)**: https://api.x402lint.dev/.well-known/agent-card.json
- **Terms**: https://api.x402lint.dev/terms.txt

## Free (no auth, no payment)

| Method | Path | What |
|--------|------|------|
| GET | /health | Liveness + payment mode |
| GET | /v1/status | Free. Returns whether an origin has been scanned, scan freshness, and the grade summary (grade, score, pass/warn/fail counts) — no per-check findings. Real data from prior scans; full findings are free at GET /v1/report while a fresh result exists; POST /v1/scan runs a fresh scan. (rate limit 30/min) |
| GET | /v1/checks | Free. The full conformance check catalog: every check's id, title, severity, and category, plus category summaries. Per-origin results (pass/warn/fail, evidence, one-line fixes) are delivered by the paid scan (POST /v1/scan) and cached report (GET /v1/report). (rate limit 30/min) |
| GET | /v1/report | Free. Returns the full cached scan report (same shape as POST /v1/scan) if a fresh (<24h) result exists; otherwise an uncharged 404 pointing at POST /v1/scan. The zero-cost way to read any origin's latest findings — scan reports land here for 24h. (rate limit 30/min) |
| GET | /v1/directory | Free. Paginated list of origins x402lint has scanned and graded, with conformance grade, auto-collected UNVERIFIED third-party branding, and ecosystem legitimacy signals. Sort by recency (default) or grade; filter by category, verification, or host substring. A grade measures protocol conformance only and is NOT an endorsement or a safety/legitimacy assessment. hasRecentSettlement is true or null (null = not observed in a bounded most-active-sellers walk, not proof of no settlements). (rate limit 30/min) |
| GET | /v1/featured | Free. Origins that scored an A on their most recent scan within the last 30 days, recency-ranked. Featured placement is a free consequence of a recent A-grade scan; it expires 30 days after the scan (re-scan to refresh). Conformance only — NOT an endorsement. hasRecentSettlement is true or null (null = not observed in a bounded most-active-sellers walk, not proof of no settlements). (rate limit 30/min) |
| GET | /v1/project | Free. The public directory record for one origin (grade, branding, legitimacy signals, verification + featured status). 404 uncharged if the origin is unknown or has opted out. hasRecentSettlement is true or null (null = not observed in a bounded most-active-sellers walk, not proof of no settlements). (rate limit 30/min) |
| POST | /v1/verify/start | Free. Begin domain-control verification of an origin you operate. Returns a one-time token to place at /.well-known/x402lint-challenge on that origin, then call POST /v1/verify/confirm. (rate limit 10/min) |
| POST | /v1/verify/confirm | Free. x402lint fetches /.well-known/x402lint-challenge over HTTPS and, if it matches the unexpired token from /v1/verify/start, marks the origin owner-verified. (rate limit 10/min) |
| POST | /v1/listing | Free. For owner-verified origins only (else 403). Opt the origin out of the public directory (listed=false) and/or suppress auto-collected branding (suppressEnrichment=true). (rate limit 10/min) |
| GET | /terms.txt · /terms.json | Terms of Service |

## Paid (x402 V2 — USDC on eip155:8453, per-call)

| Method | Path | Price | What |
|--------|------|-------|------|
| POST | /v1/scan | $0.05 | Paid ($0.05). ALWAYS runs a fresh 25-check scan of the origin (non-settling GET/HEAD + benign empty-POST probes), bypassing the 24h cache — use free GET /v1/report to read the cached result. Concurrent requests for the same origin join the in-flight scan rather than double-scanning. Returns grade, score, per-check status + evidence + fix instructions, and a shareable report URL. Unreachable/broken origins are a valid graded result (F). 504 processing responses and errors are never charged. |
| GET | /v1/directory/export | $0.1 | Paid ($0.10). The entire graded directory in one machine-shaped response: every listed origin with grade, score, grade history, legitimacy signals, branding, verification and featured status — the same record shape as /v1/directory plus gradeHistory, firstSeenAt, and scanCount. Capped at 10,000 records (truncated:true if hit). Grades measure protocol conformance only and are NOT endorsements. |
| GET | /v1/changes | $0.03 | Paid ($0.03). Everything that changed in the graded directory since a timestamp: newly listed origins (changeType "new"), grade changes ("grade_changed", with previousGrade/previousScore), and plain re-scans ("rescanned"). Poll this to keep a local copy of the directory fresh without re-buying the full export. An invalid since/limit is an uncharged 400. |

Prices are USD, settled as USDC (6 decimals). Compute-first / settle-after: you are never
charged for errors.

## Quickstart — pay per call (x402, USDC)

```
# 1) Call a paid route with no payment → 402 challenge
#    Paid routes are POST with a JSON body; e.g. POST /v1/scan {"url":"https://api.example.dev"}.
curl -s -X POST "https://api.x402lint.dev/v1/scan" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://api.example.dev"}'
# → { "x402Version": 2, "accepts": [ { "scheme": "exact", "network": "eip155:8453",
#     "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
#     "amount": "50000", "payTo": "0x…" }, … ] }

# 2) Sign an x402 'exact' USDC authorization for one accepts[] rail, then retry.
#    Standard @x402 V2 clients send PAYMENT-SIGNATURE; legacy clients send X-PAYMENT.
curl -s -X POST "https://api.x402lint.dev/v1/scan" \
  -H "Content-Type: application/json" \
  -H "PAYMENT-SIGNATURE: <payload>" \
  -d '{"url":"https://api.example.dev"}'
# → 200 { …, "charged": true }
```

## Links
- Docs: https://api.x402lint.dev/llms.txt
- Full: https://api.x402lint.dev/llms-full.txt
- OpenAPI: https://api.x402lint.dev/openapi.json
- Discovery: https://api.x402lint.dev/discovery
- Agent card: https://api.x402lint.dev/.well-known/agent-card.json
