x402lint
A conformance linter for the x402 agent-payments protocol. Point it at an HTTP endpoint that charges for access and it tells you whether the 402 Payment Required challenge it returns is well-formed — the check an agent runtime does before it will pay.
$ x402lint check https://riddlex402.vercel.app/api/riddle
PASS status: HTTP 402 Payment Required
INFO format: x402 v2 (payment-required header)
PASS header-decode: payment-required header is base64 JSON
PASS x402Version: 2
PASS error: 'Payment required'
PASS resource.url: https://riddlex402.vercel.app/api/riddle
PASS accepts: 1 payment option(s)
PASS accepts[0].required: all required fields present
PASS accepts[0].scheme: 'exact'
PASS accepts[0].network: eip155:8453 (CAIP-2)
PASS accepts[0].amount: 2000 atomic unitsPASS accepts[0].payTo: valid EVM address PASS accepts[0].maxTimeoutSeconds: 300 PASS accepts[0].extra: EIP-712 domain: name='USD Coin' version='2' INFO discovery: advertises the 'bazaar' discovery extension
14 pass, 0 warn, 0 fail (CONFORMANT)
## Install
pip install x402lint
The linter (`check` / `decode` / `facilitator` / `survey`) is pure standard
library, Python 3.12+. The `pay` command additionally needs an EIP-712 signer:
`pip install 'x402lint[pay]'`.
## Commands
### `x402lint check <url>`
Fetches `<url>` with no payment header, expects a `402`, and checks the payment
challenge:
- wire format — v2 (payment-required base64 header, the common case today)
or v1 (x402Version: 1 JSON body). Reports which.
- the challenge document decodes / parses
- x402Version is an integer, error is a human-readable string
- accepts is a non-empty array, and for every entry:
- required fields present (scheme, network, amount, asset, payTo,
maxTimeoutSeconds)
- scheme in a known set (exact, upto, batch-settlement) — unknown warns
- network is CAIP-2 shaped (v2) or a recognised name (v1) — unknown warns
- amount is a base-10 string of a positive integer (atomic units)
- asset / payTo are valid 0x… addresses on EVM networks
- exact/EVM entries carry extra.name + extra.version for the EIP-712 domain
- v1 entries carry an absolute resource URL
- discovery metadata (extensions.bazaar / v1 outputSchema) — reported, not required
--json emits a machine-readable report (for CI). Exit code: 0 conformant (warnings allowed), 1 any failure, 2 tool error.
For a POST endpoint that validates its request body before returning the 402 (most LLM gateways), pass a body with --data (implies POST; @file or - reads a file / stdin):
$ x402lint check https://x402.telnyx.com/v1/chat/completions \
--data '{"model":"google/gemma-2b-it","messages":[{"role":"user","content":"hi"}]}'