# x402 and HTTP 402: what the payment row means, who needs it, and how to advertise it

The Mega Analyzer&#39;s x402 row reads two homepage headers and never turns red. What HTTP 402 and x402 v2 do, who needs them, and how to advertise a paid endpoint.

Author: J.A. Watte
Published: September 21, 2026
Source: https://jwatte.com/blog/blog-mega-analyzer-x402-payment-advertisement/

---

The Mega Analyzer row **x402 v2 advertisement (Coinbase-led HTTP 402 protocol)** sits among the agent-readiness rows of the Crawl Health panel with an info icon, and most sites should read it once and move on. What it measures is narrow: whether the response headers on your homepage tell an agent that somewhere on this origin there is a resource it can buy one request at a time over HTTP 402. It does not test whether you take payments, and it cannot see the paid endpoint itself.

## What the check actually tests

The gate comes first, and it decides more than the heuristic does. The row is only added when the analyzer classifies the site as a commerce surface or a developer surface, and both classifications are read off the homepage.

A commerce surface means three things are true at once. The homepage carries a payment-flow signal: a Stripe or Shopify script tag, or checkout language such as "add to cart", "buy now" or "proceed to checkout" in the first 50,000 characters of body text. No service-business type is declared in the JSON-LD (LocalBusiness, LodgingBusiness, Hotel, SelfStorageFacility, Restaurant, Dentist, LegalService and that family, which declare Offers to display inventory, not to sell to agents). And it is not a marketplace funnel: a site whose JSON-LD Offer URLs all point off-origin, with no Stripe or Shopify SDK loaded, is excluded. That rule exists for book funnels and affiliate sites, where the marketplace owns the checkout.

A developer surface means the analyzer already found an agent manifest (an API catalog at /.well-known/api-catalog, an MCP server card, an Agent Skills index, an A2A agent card or an ai-plugin.json), or the site looks agent-callable by its schema, hostname or copy, or it links to paths containing /docs, /developer, /api-docs or /reference. A local-service schema type (or a `Local-*` vertical from the keyword classifier) cancels that, and so does an editorial or generic page type (Article, BlogPosting, NewsArticle, and also WebPage, CollectionPage and ItemList) with no SoftwareApplication, WebApplication, APIReference or WebAPI type beside it. The WebPage case is the one to know about: a plain WebPage node is enough to keep a documentation site out of the developer gate unless one of those four types sits beside it.

When the gate opens, the signal is two response headers on the fetch of the audited URL (the homepage, in a normal run) and nothing else:

- **Link**: passes if the header value contains the token `payment-required`, case-insensitive, with a word boundary on each side.
- **Accept-Payment**: passes if the header value contains `x402` anywhere.

There are three outcomes. Met: "Origin advertises x402 payment requirements via response headers." Not applicable, which is what a developer surface without a commerce surface gets: the detail opens with "Not applicable" and continues "no commerce surface detected. x402 v2 lets agents pay per-request via HTTP 402 + base64 PAYMENT-* headers; only commerce / paid-API surfaces need it." That outcome counts as a pass. Unmet, which only a commerce surface can get: "Optional. x402 v2 (post-2026 launch) advertises via Accept: application/x402+json or Link: rel="payment-required". Commerce APIs that monetize per-request can implement via @x402/express, @x402/hono, @x402/next middleware. >100M payments processed by 2026."

Severity is info, so an unmet row renders with the ℹ icon, never red, and the agent-discovery fix prompt skips it. It does sit in the crawl-score denominator like every other row in that set, one unit of weight in the crawl score and three points in the SEO bucket, so a commerce site that leaves it unmet gives up a sliver. On the isitagentready parity card, the Commerce category (x402, MPP, UCP, ACP, AP2) only counts when the site is a commerce surface; otherwise the whole category drops out, which mirrors what Cloudflare's scorer does.

What does not trip it is the part to read twice:

- **A correct x402 deployment.** If `/api/report` answers 402 with a `PAYMENT-REQUIRED` header, the analyzer never learns it, because it never requests `/api/report`. It reads the homepage response and the aux files.
- **A `PAYMENT-REQUIRED` header on the homepage itself.** Different header name. The check reads `Link` and `Accept-Payment` only.
- **A `<link rel="payment-required">` element in the HTML head.** The check reads response headers, not link elements.
- **A Link header on the API response** rather than on the homepage.
- **A fetch that came through the alternate egress tier.** If the direct fetch was blocked and the retry did not return origin headers, the row is forced to pass with an "Unable to verify" note, so a pass in that state proves nothing.

The [Agent Ready Audit](/tools/agent-ready-audit/) probes the same protocol a different way: it requests `/api` and `/api/v1` and passes x402 if either returns status 402. A paid API mounted at `/v2/data` with no homepage Link header satisfies neither tool. That is a limit of scanning from outside, not a fault in the deployment, and it is why the fix below has an advertisement step.

## Why it matters

HTTP/1.1 reserved status 402 Payment Required in 1997 and never defined it. RFC 9110, the current HTTP semantics standard, still disposes of it in one line: the code "is reserved for future use." Cloudflare describes x402 as working "by reviving HTTP 402 Payment Required, a status code that has existed in the spec since 1997 but was never widely used." It is the first use of that code I know of with real volume behind it: Coinbase Developer Platform says it has processed more than 100 million x402 payments across Base and Solana.

The flow, per the v2 HTTP transport specification, is four messages. A client requests a paid resource. The server answers 402 with a `PAYMENT-REQUIRED` header whose value is base64-encoded JSON. Decoded, the spec's own example looks like this:

```json
{
  "x402Version": 2,
  "error": "PAYMENT-SIGNATURE header is required",
  "resource": {
    "url": "https://api.example.com/premium-data",
    "description": "Access to premium market data",
    "mimeType": "application/json"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:84532",
      "amount": "10000",
      "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
      "payTo": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
      "maxTimeoutSeconds": 60,
      "extra": { "name": "USDC", "version": "2" }
    }
  ]
}
```

Each entry in `accepts` names a scheme, a network in CAIP-2 form (`eip155:84532` is the Base Sepolia testnet, `eip155:8453` is Base mainnet), an amount in the asset's atomic units (10000 units of a six-decimal stablecoin is one cent), the asset contract, the address to pay, and a timeout. The client, usually an agent with a wallet, picks one entry, signs a payment, and retries the same request with a `PAYMENT-SIGNATURE` header. The server sends that payload to a facilitator's `/verify` endpoint, does the work, sends it to `/settle`, and returns 200 with a `PAYMENT-RESPONSE` header carrying the result (success, transaction hash, network, payer). The transport spec is explicit that "all x402 protocol information is communicated through headers." The body is yours.

Two things changed between v1 and v2 that affect anything you copy from an older tutorial. The v1 specification put the payment requirements in the 402 response body and named the client's header `X-PAYMENT` (its error string reads "X-PAYMENT header is required"); v2 moved the requirements into the `PAYMENT-REQUIRED` header and dropped the `X-` prefix, which is what RFC 6648 asked application protocols to do back in 2012. And network identifiers moved to CAIP-2, so `base-sepolia` in old examples is `eip155:84532` now. The v2 specification carries a December 9, 2025 date in its own version history, so the row's "post-2026 launch" wording is about when adoption picked up, not when the spec landed.

Neither the core v2 spec nor the HTTP transport spec defines a homepage advertisement, an `Accept-Payment` header, or the `application/x402+json` media type that the row's fail text names. The protocol's discovery model is "request the resource and get a 402." The Link header the analyzer looks for is a convention a scanner can check without knowing your paid paths, and `payment-required` is not in the IANA link relations registry. The registered relation is `payment`, defined as "a resource where payment is accepted," and RFC 8288 says an unregistered extension relation is supposed to be a URI. Because the analyzer matches the token anywhere in the header value, a URI-form relation that ends in `payment-required` passes too, so you can be strictly conformant and still trip the row.

Who this is for: anyone selling one request at a time to a machine. A paid API, metered data, a single report or article, an MCP tool call priced per invocation. The CDP facilitator verifies for free and charges nothing for the first 1,000 onchain facilitator transactions a month, then a tenth of a cent each, which is the cost structure that makes a one-cent API call possible. Governance moved to the Linux Foundation on July 14, 2026, when it announced the operational launch of the x402 Foundation with Coinbase's contribution complete and Amazon Web Services, American Express, Cloudflare, Google, Mastercard, Shopify, Stripe and Visa among the premier members. Cloudflare's Agent Readiness Score, published April 17, 2026, checks for x402, the Universal Commerce Protocol and the Agentic Commerce Protocol in its Commerce category and says plainly that "these do not currently count towards the score." The site's [Agent Ready Audit](/tools/agent-ready-audit/) runs four informational commerce probes: x402, MPP, UCP and ACP.

Who it is not for: a brochure site, a blog, a motel, a plumber. The row says not applicable on those and means it. Implementing a payment protocol to move an info row is the wrong trade in every case.

## How to fix it

Only if you sell per-request access to an API or to content. If you don't, skip to the next section.

**1. Pick one route and one price, on a testnet.** The seller quickstart at CDP prices `GET /report` at one cent on Base Sepolia, and that is the right size for a first deployment. Get one paid round trip working before you touch mainnet.

**2. Install the middleware for your framework and point it at a facilitator.** The x402 repository publishes `@x402/express`, `@x402/hono`, `@x402/next` and `@x402/fastify` adapters, plus `@x402/fetch` and `@x402/axios` for the client side. The CDP quickstart wires Express like this, with the route moved under `/api` to match the rest of this post (copy the current version from the quickstart rather than this page; the config keys changed between v1 and v2 and may change again):

```js
import express from "express";
import { createX402Server } from "@coinbase/cdp-sdk/x402";
import { paymentMiddlewareFromHTTPServer } from "@x402/express";

const server = await createX402Server({
  environment: "development",            // testnets and test funds
  payToConfig: { type: "address", evm: process.env.X402_PAY_TO },
  routes: {
    "GET /api/report": {
      price: "$0.01",
      networks: ["eip155:84532"],        // Base Sepolia; eip155:8453 is Base mainnet
      description: "One research report"
    }
  }
});

const app = express();
app.use(paymentMiddlewareFromHTTPServer(server));
app.get("/api/report", (req, res) => res.json({ report: "..." }));
app.listen(8402);
```

Every route listed in `routes` answers 402 with `PAYMENT-REQUIRED` until a valid `PAYMENT-SIGNATURE` arrives, and 200 plus `PAYMENT-RESPONSE` after settlement. Everything not listed stays free.

**3. Advertise it where a scanner looks.** Add a Link header to the homepage and to the API index. On Netlify that is two blocks in `_headers`:

```text
/
  Link: </api/report>; rel="payment-required"
/api/*
  Link: </api/report>; rel="payment-required"
```

On nginx it is `add_header Link '</api/report>; rel="payment-required"' always;` inside the relevant `location`. On Cloudflare it is a Transform Rule that sets a static response header. If the homepage already sends a Link header for llms.txt or an API catalog, put all the links in one header value separated by commas; RFC 8288 allows a list. If you want to stay inside the registry, use `rel="payment https://example.com/rel/payment-required"` instead: `payment` is registered, the URI form is what RFC 8288 asks of an extension relation, and the analyzer still matches.

**4. List the paid endpoint where an agent looks.** Publish `/.well-known/api-catalog` (RFC 9727) as `application/linkset+json`, pointing at the machine-readable description and the human page:

```json
{
  "linkset": [
    {
      "anchor": "https://example.com/api",
      "service-desc": [
        { "href": "https://example.com/api/openapi.json", "type": "application/json" }
      ],
      "service-doc": [
        { "href": "https://example.com/api/pricing", "type": "text/html" }
      ]
    }
  ]
}
```

In the OpenAPI document, give the paid operation a documented `402` response with the `PAYMENT-REQUIRED` header listed under `headers`, so an agent reading the spec knows the price negotiation is there before it makes the call.

**5. Publish a human page.** Accepted networks, the asset, the price per call, the pay-to address, what happens on a failed settlement, and your terms. It is what a buyer's operator reads when a charge shows up.

**6. Test from outside.** First the paid path:

```text
curl -i https://example.com/api/report
```

Expect `HTTP/1.1 402 Payment Required` and a `PAYMENT-REQUIRED` header. Base64-decode the value and check that `accepts` lists the network and amount you configured. Then the advertisement:

```text
curl -sI https://example.com/ | grep -i "^link"
```

Then run a full round trip with `@x402/fetch` and a funded testnet wallet, and confirm you get 200 with a `PAYMENT-RESPONSE` whose `success` is true. Re-run the [Mega Analyzer](/tools/mega-analyzer/) and the [Agent Ready Audit](/tools/agent-ready-audit/); the [Agent Ready Audit Reference](/tools/agent-ready-audit-reference/) documents each commerce probe and which ones are informational.

## When to leave it alone

- **The row says not applicable.** Then it is. A content site, a local-service site or a portfolio has nothing to sell per request, and nothing in this protocol helps its search or citation standing.
- **A store with a human cart.** Cloudflare describes UCP and ACP as the protocols for "products that humans would normally purchase via ecommerce storefronts and checkout flows." That is a shopping cart with shipping, not a priced HTTP resource. A Stripe script trips the commerce gate, so the row will read "Optional" on such a store, and Optional is the correct reading. The [agentic commerce audit](/blog/blog-tool-agentic-commerce-readiness/) covers the protocols that fit a storefront.
- **Books or products sold on a marketplace.** The gate already excludes a site whose Offers all point off-origin, and the answer would be no regardless: the marketplace owns the checkout.
- **A paid API whose customers are invoiced humans.** Settlement in x402 is a stablecoin on a blockchain, which means a wallet, a custody decision and a bookkeeping conversation before the first cent arrives. If your buyers are not agents, an unmet info row costs a sliver of crawl and SEO score and nothing else. Take it at its word.
- **Never add the Link header without a 402 behind it.** A `payment-required` link that resolves to 200 or 404 tells an agent to expect a price and then wastes its request. The row would pass, and you would have faked a signal on the one scanner category whose rows are honest about being optional.

If you are a solo builder who does want to charge for one endpoint without a billing stack, this is the rare case where the smallest paid thing you can ship has a protocol behind it. The $97 Launch is written for that builder.

## Fact-check notes and sources

- **Source**: https://www.rfc-editor.org/rfc/rfc9110.html#name-402-payment-required establishes that RFC 9110 section 15.5.3 reads, in full, "The 402 (Payment Required) status code is reserved for future use."
- **Source**: https://blog.cloudflare.com/agent-readiness/ establishes the Agent Readiness Score post (dated April 17, 2026), the wording that 402 "has existed in the spec since 1997 but was never widely used," the Commerce checks for x402, UCP and ACP, and that "these do not currently count towards the score."
- **Source**: https://github.com/coinbase/x402 establishes the middleware package list (@x402/express, @x402/fastify, @x402/hono, @x402/next, plus @x402/fetch and @x402/axios clients), the definition of a facilitator as "a server that facilitates verification and execution of payments for one or many networks," and EVM, SVM and Stellar support.
- **Source**: https://github.com/coinbase/x402/blob/main/specs/x402-specification-v2.md establishes the PaymentRequirements fields (scheme, network in CAIP-2, amount in atomic units, asset, payTo, maxTimeoutSeconds, extra), the facilitator /verify, /settle and /supported endpoints, the CAIP-2 identifiers eip155:84532 and eip155:8453, and the version history dating v2.0 to 2025-12-9.
- **Source**: https://github.com/coinbase/x402/blob/main/specs/transports-v2/http.md establishes the three v2 headers (PAYMENT-REQUIRED, PAYMENT-SIGNATURE, PAYMENT-RESPONSE), base64 JSON encoding, the decoded example reproduced above, the status mapping (402, 400, 500, 200), and the sentence "All x402 protocol information is communicated through headers."
- **Source**: https://github.com/coinbase/x402/blob/main/specs/x402-specification-v1.md establishes the v1 header name via its error string "X-PAYMENT header is required" and, in its section 5.1.1, that v1 returned the payment requirements in the response body.
- **Source**: https://docs.cdp.coinbase.com/x402/welcome establishes that CDP "has processed more than 100 million x402 payments across Base and Solana," and its facilitator and seller quickstart pages establish free verification, the first 1,000 onchain facilitator transactions per month free and $0.001 each after, USDC as the most common asset, and the createX402Server route configuration shape.
- **Source**: https://www.x402.org/ establishes the protocol's "zero protocol fees" positioning, the live 30-day transaction counters, and the link to the Foundation announcement.
- **Source**: https://x402.org/linux-foundation-announces-operational-launch-of-x402-foundation-to-standardize-internet-native-payments-for-ai-agents-and-applications/ establishes the July 14, 2026 announcement, Coinbase's completed contribution of the protocol, and the premier member list.
- **Source**: https://www.rfc-editor.org/rfc/rfc8288 establishes the Link header field syntax, that a rel value may list several relation types, and (section 2.1.2) that an extension relation type is a URI.
- **Source**: https://www.iana.org/assignments/link-relations/ establishes that `payment` is a registered relation ("Indicates a resource where payment is accepted") and that `payment-required` is not registered as of this writing.
- **Source**: https://www.rfc-editor.org/rfc/rfc6648 establishes the 2012 recommendation against "X-" prefixed parameters in application protocols.
- **Source**: https://www.rfc-editor.org/rfc/rfc9727.html establishes the /.well-known/api-catalog URI, the application/linkset+json format from RFC 9264, and the service-desc and service-doc relations from RFC 8631 used in the sample above.

## Related reading

- [Thirteen Probes For The Agent-Ready Web, And A Browser-Side Tool That Runs All Of Them On Any URL](/blog/blog-agent-ready-audit-tool/)
- [The agent web has four protocols now. Here is where each one fits.](/blog/blog-agent-protocol-stack/)
- [The Cloudflare Agent Readiness Score and What It Actually Checks](/blog/blog-cloudflare-agent-readiness-score/)
- [The agentic web is the new shopping surface: an audit for it](/blog/blog-tool-agentic-commerce-readiness/)
- [Agent readiness past llms.txt: eleven files, and the five that silently fail validation](/blog/agent-readiness-beyond-llms-txt/)

*This post is informational, not legal advice. Mentions of third parties are nominative fair use. No affiliation is implied.*


---

Canonical HTML: https://jwatte.com/blog/blog-mega-analyzer-x402-payment-advertisement/
RSS: https://jwatte.com/feed.xml
JSON Feed: https://jwatte.com/feed.json
Hero image: https://jwatte.com/images/blog-mega-analyzer-x402-payment-advertisement.webp
