Skip to content

Build1 publisher3 min readPublished

A one-cent company lookup swaps the signup flow for an HTTP 402 bill

The mechanism works over 4,008,800 ASIC records with no human in the loop. But the first version would have let a caller verify a payment against their own price, and two spec versions still fight inside one response.

The Engineer · Build desk

Illustration accompanying A one-cent company lookup swaps the signup flow for an HTTP 402 bill

What happened

  • The Australian company lookup APIs the builder found each wanted an email address, a confirmation click, a dashboard visit, a plan chosen and a key pasted into an environment variable, all of which needs a person.
  • His replacement has no account, no key, no dashboard and no free tier, and sells lookups over the ASIC register of 4,008,800 companies at one cent each.
  • An unpaid request returns a machine-readable bill, the client signs an EIP-3009 authorisation into a PAYMENT-SIGNATURE header and repeats the request, and a facilitator verifies and settles it on Base.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • exposure Any 402 server that hands the caller's copy of the payment terms to its facilitator has invited the payer to set both the price and the payee, and that version shipped before it was caught.
  • constraint Because the facilitator only accepts the older envelope, the version a server publishes to clients is now decoupled from the version it speaks inward, so each side has to be upgraded and tested separately.
  • cost Four HTTP requests and two facilitator round trips stand behind one cent of revenue, so the settlement path rather than the database query sets the per-call cost floor for anyone copying this.
  • capability An agent holding USDC on Base and a signing key can buy a record unattended, and the seller can support that without ever holding a key, signing a transaction or paying gas.

The defect worth copying out of this build sits at the trust boundary. An x402 payment envelope carries a copy of the requirements it claims to satisfy, and that copy arrives from the caller [14]. The author's first version forwarded it to the facilitator, so the facilitator was asked whether a payment satisfied terms the payer had written: their receiving address, their price [15]. It would have answered yes. The fix is to check the envelope's copy for internal consistency, discard it, and verify against the server's own published terms [16]. The same hole exists in any 402 implementation that lets the incoming request supply the figure it is checked against.

The version split costs about as much. The JSON body is an x402 v1 challenge with network `base`. The base64 `payment-required` header is a v2 challenge with network `eip155:8453` and a top-level `resource` object. Neither is a superset of the other, so a single merged document validates as neither [11]. A v1 client reads the body and never learns the header exists; a v2 client does the reverse [12]. The price lives in `maxAmountRequired` under v1 and `amount` under v2, and both documents carry both keys at the same value, so a client that is vague about which version it speaks still reads a price instead of finding nothing [13].

Inward, the shape flips. The first genuine paid call returned HTTP 400 from `/verify` with a correctly signed client on the other end [17]. The facilitator's own `openapi.json` requires two `PaymentPayload` fields to be objects under the v2 shape, and it rejects the envelope a correct v2 client actually sends; the v1 request shape validated and came back with a real verdict [18]. The server now addresses the facilitator in v1 whatever the caller speaks, on the grounds that the thing being verified is the EIP-3009 authorisation, which is byte-identical either way, with only the network naming differing [19]. A facilitator whose published schema rejects its own newer envelope cannot serve as a working reference implementation of that envelope.

Four HTTP requests move one record: two from the client, two from the server to the facilitator, and no human in any of them [9]. The bill quotes 10000 atomic units of USDC, which is USD 0.01 [6]. Buying the register outright is 4,008,800 records at one cent, so USD 40,088 [1]. With no account and no key issued, there is nothing to revoke [4], which makes the price the only rate limit, and USD 40,088 is a low fence around a public register.

The part I would keep regardless of where the standard lands: the server holds no private key, signs nothing, pays no gas, and can do nothing except check that money arrived [10]. Whoever takes the API host gets the data and the receiving address, not the balance. That is a smaller blast radius than most billing integrations manage.

Demand is the piece left unestablished here. The post names neither the competing ABN providers nor the facilitator, and reports no traffic or revenue [21]. The finding that signup rather than price is the blocker is one builder's account of one attempt [1][2]. The mechanism works; whether some other developer's agent will spend a cent on an Australian company record is a separate, untested question.

What to watch

  • Whether x402 v1 and v2 converge, or facilitators keep accepting only one envelope shape while clients send the other.
  • Whether a third-party agent, not the author's own, ever completes a paid call; the post reports no usage figures.
  • Whether price alone holds as the rate limit once someone tries to pull the register in bulk with no key to revoke.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories