# Method — x402 Client-Compatibility Census (Base + Ethereum, 2026-10-12)

Companion to `dataset.csv`, `dataset.jsonld`, and the raw JSON at
`https://onchainagentintel.io/data/x402-client-compat-census-2026-10-12.json`.
Documents what was probed, how each body was parsed, and what the recorded
fields mean. The companion narrative is the blog post at
`https://onchainagentintel.io/blog/x402-client-compatibility-census-2026-10`.

## What we probed

For every advertised x402 endpoint on an ERC-8004 agent on Base or Ethereum,
we issued one unauthenticated HTTP request at `2026-10-12T16:43:01Z` and
captured the response. We then fed the response body — verbatim — to three
open-source x402 parsers and recorded whether each parser accepted it.

The population behind the 280 rows:

- **280 endpoints** total — one row per advertised endpoint.
- **36 distinct agents** (`agent_key` unique over `chain:agent_id`).
- **Chain split:** 261 on Base (`chain_id` 8453), 19 on Ethereum (`chain_id` 1).
- **HTTP-status distribution at probe time:** 272 × `402`, 1 × `503`, and 7
  rows with no HTTP response captured (connect / DNS / TLS failure within
  the probe timeout). The 7 no-response rows are kept so the per-endpoint
  table is complete; they contribute `0` to all `parses_*` counters by
  definition (there is nothing to parse).

Nothing on this page is synthesised. Every count is a direct reduction of
the `per_endpoint[]` list in the raw JSON.

## Parsers used

We parsed each body under three toolchains at pinned package versions:

1. **v1 (frozen legacy)** — `x402-fetch@1.2.0`'s `PaymentRequirementsSchema`.
   Last published to npm 2026-04-16. v1 counts were measured during probing
   (280 bodies were run through the v1 schema), but v1-specific columns are
   **not** materialised in `dataset.csv`. Readers who want to reproduce the
   v1 breakdown can rerun the parsers from the companion blog's methodology
   section directly against the raw JSON — the body shape is captured there.
2. **v2 all-accepts** — `@x402/core@2.28.0`'s `PaymentRequirementsSchema`
   applied **per entry** inside `accepts[]`. Shipped 2026-09-29.
3. **v2 top-level** — `@x402/core@2.28.0`'s `parsePaymentRequired`, the
   full-body discriminated-union parser. Same 2026-09-29 release.
4. **python** — `x402==2.25.0`. Also measured against every body during
   probing; python-specific per-row columns are not materialised in
   `dataset.csv` for the same reason as v1 (companion blog carries that
   breakdown).

The two columns the CSV materialises per row are therefore
`parses_v2_all_accepts` and `parses_v2_top_level`, plus the first schema
issue observed by the v2 top-level parser in `v2_top_level_first_issue`.

## Inclusion rule

An endpoint is listed if the probe captured **any** HTTP response at the
agent-advertised URL, even if the response was non-402 or non-JSON. The
seven rows where `http_status` is empty (serialised from `null` in the raw
JSON) represent endpoints that never answered within the probe timeout
window. They are kept so that `per_endpoint[]` and `dataset.csv` are a
complete, lossless listing of what we tried, not just what responded.

This is a departure from the sibling 2026-10-11 payable-endpoints wrap,
whose inclusion rule required a valid 402. Here we want the schema-
conformance breakdown to count against the **full set of advertised
endpoints**, including the ones that produced no body to parse.

## Aggregate numbers (verbatim from the raw JSON)

| Metric | Value |
|---|---|
| Total 402 endpoints measured | **280** |
| Parses under v2 all-accepts (per-entry) | **249** |
| Parses under v2 top-level (full-body) | **228** |
| Total `accepts[]` entries across all bodies | **818** |
| `accepts[]` entries parsed by v2 per-entry | **787** |
| % parses v2 all-accepts | **88.93%** |
| % parses v2 top-level | **81.43%** |

The two percentages are reported verbatim from the raw JSON's
`aggregate` block; they are the point estimates computed by the probe at
`2026-10-12T16:43:01Z` and are not rounded further.

## What this is not

- **Not a readiness score.** Nothing in `dataset.csv` or the raw JSON
  feeds into the Readiness or Trust methodology published at
  `https://onchainagentintel.io/methodology`. The columns here are
  schema-shape flags, not quality judgements.
- **Not a ranking.** There is no sort key, no bucketing, no cut-off; the
  rows preserve the probe-order ordering of `per_endpoint[]`.
- **Not a judgement of agent quality.** Many of the 31 bodies that failed
  the v2 top-level parser trace back to small formatting issues in a
  single seller's endpoints — one seller is responsible for 14 of the
  `v2_entry_bad_asset` rows (empty-string `asset` field, single character
  fix on the server side), and another seller is responsible for 10 of
  the `no_accepts_array` rows (the endpoint simply does not implement
  x402 at this URL). See the companion blog for the per-seller breakdown.
- **Not an endorsement.** The schema-conformance signal is a technical
  measurement; it does not express a preference for any agent, parser,
  or protocol version.
- **Not a payment outcome.** No request in this probe paid or verified
  that a settled EIP-3009 transfer would be honoured by the agent. The
  pilot evidence that paid-and-measured delivery lives in the sibling
  payability-funnel dataset.

## Known limitations

1. **One-shot probe at `2026-10-12T16:43:01Z`.** Any agent may have
   redeployed a fixed body since. The dated snapshot is the whole point;
   the parser results tie to the body shape at that instant and no later.
2. **Parse definitions tie to the exact package versions above.** A
   later release of `@x402/core`, `x402-fetch`, or the python `x402`
   library may relax or tighten the schema. Rerunning the parsers at a
   newer version will likely produce different `parses_*` counts even
   against the same body JSON.
3. **`failure_reasons` is the raw array captured at probe time, not a
   canonicalised taxonomy.** Five distinct values were observed across
   the full dataset: `no_accepts_array`, `non_object_body`,
   `v2_entry_bad_asset`, `v2_top_level:too_small:accepts.12.asset`, and
   `x402Version_not_1_or_2`. The first four are shape issues the parser
   can describe in one token; the fifth is a Zod issue path from the v2
   top-level parser pointing at a specific accepts-entry index.
4. **Not an endorsement — see "What this is not" above.** Repeated here
   because the schema-conformance frame is easy to mis-read as a quality
   signal, and it is not one.

## Reproducing a row

Given an endpoint URL and the probe timestamp, you can reproduce the
inclusion decision and the two `parses_*` flags by:

1. Issuing one unauthenticated HTTP GET (or whatever method the agent
   advertises) to the URL.
2. Feeding the response body (verbatim, as JSON) to
   `@x402/core@2.28.0`'s `PaymentRequirementsSchema` for the
   `parses_v2_all_accepts` flag (true when every entry inside the body's
   `accepts[]` array parses).
3. Feeding the same body to `@x402/core@2.28.0`'s `parsePaymentRequired`
   for the `parses_v2_top_level` flag (true when the full body parses
   under the discriminated-union parser).
4. If the body did not parse under the top-level parser, the first Zod
   issue path is captured verbatim in `v2_top_level_first_issue`.

## License

[Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/).
Free to reuse, remix, and redistribute — including commercially — with
attribution.

> On-Chain Agent Intel (2026). x402 Client-Compatibility Census — 280 live 402 bodies parsed under v1 vs v2 vs python, 2026-10-12. CC BY 4.0. https://onchainagentintel.io/data/x402-client-compat-census-2026-10-12/
