OpenTree DashboardSign in

$ HTTP 402

Why there is no payment wall for agents here

An autonomous client cannot fill in a checkout form, so hosted services grew a payment rail for agents: a challenge, a signed authorization, an on-chain settlement, then access. This deployment has none of it — and the reason is worth writing down.

The problem the rail solves

A human buying hosting opens a browser, types a card number and gets an account. An agent holding a wallet has no way through that flow. So a service returns 402 Payment Required with a challenge; the client signs an authorization; a facilitator settles the amount on chain; the request is retried and succeeds. No human, no account, no session.

Why it is absent here

Nothing here is metered. Publishing is free, the storage bill lands with the Cloudflare account running the deployment, and there is no operator margin to collect. A payment rail with a price of zero on every call is not a feature, it is dead code with a wallet attached.

What the machinery would look like

StepWho acts
Request an unprovisioned capabilityThe client
402 plus a challenge: amount, method, recipientThe service
The client signs a payment authorizationThe client's wallet
A facilitator settles it on mainnetThe facilitator
The original request is retried and provisionedThe client

What an agent gets here instead

curl -X POST https://read.botook.ai/v1/publish -F file=@index.html

The one piece that survived

link_wallet is still here. It attaches a wallet identity to the account that owns a page, so an autonomous client has something durable to be recognised by. It moves no money and settles nothing — identity was the useful half of that design.

link_wallet({ address: "0x…", label: "publisher-bot" })

Balance, and why there is none to check

No balance, no credits, no per-publish charge to draw down. The only balance in the system is your infrastructure account's, and Cloudflare bills that in the ordinary way.

Would a self-hosted deployment ever want this?

If you ran this for other people and wanted agents to buy their own keys, then yes — a challenge on key issuance, a facilitator to settle it, done. That is a hosting business, and this repository is not one.

One-time unlocks

Hosted products often price single capabilities: make this link permanent, attach a custom domain for a month. Here both are settings. expires_in_hours: "never" is free and so are domains.

Stripe, and other human rails

Also absent, for the same reason. There is no billing code in the deployment at all — no checkout, no invoices, no subscription state.

The machine-payment protocol family

x402 is one of several designs for the same handshake — challenge, signature, settlement. A comparison of the family, and what an implementation here would have to decide, is on the machine payment protocol page.

What a paywalled request would look like on the wire

The shape is worth knowing even when you are not going to implement it, because it explains why the absence costs an agent nothing here. A paid endpoint answers the first, unpaid call with a challenge; the client settles it and retries with proof attached:

$ curl -i https://read.botook.ai/sites -X POST -F file=@index.html
HTTP/2 402
# ...a challenge describing amount, asset and where to settle

$ curl -i https://read.botook.ai/sites -X POST -F file=@index.html \
    -H "X-Payment: <proof of settlement>"
HTTP/2 201

Here the first call is the only call. There is no 402 in this deployment's vocabulary — a publish either succeeds, or fails for a reason about the content or the key.

What replaces the meter

A payment rail is one way to stop an open endpoint becoming somebody else's file host. It is not the only way, and for a deployment with no marginal cost to recover it is a heavy one. The limits that do the same job here are ordinary and free:

ConcernHandled by
An open publish endpoint being abusedA fixed-window rate limit per address on anonymous publishes
Anonymous pages accumulating foreverA 24-hour default life, and expiry that deletes rather than hides
Telling apart callersAn API key per client, revocable one at a time
Runaway usage in generalThe ceilings in your own configuration — see pricing

What persistent identity is still for

Strip out settlement and one useful idea survives: an autonomous agent benefits from a durable identity that is not a human's login. link_wallet attaches one to the account that owns a page, so a long-running agent has something persistent to be recognised by across sessions — without any of it implying a balance, a charge or a chain to settle on.

link_wallet({ address: "0x…" })

What agents actually need from a host

  1. A publish call that does not require a browser.
  2. A stable link across revisions.
  3. Gates it can set by itself.
  4. A way to read back what viewers did.

All four are here. None of them needed a payment.

If you disagree

The code is yours to extend. A 402 challenge on key issuance is a small patch, and the account model already has room for a wallet — see self-host.

Questions

Can an agent get a key without a human?

Not today. It can publish anonymously without one, and claim the page later.

Is any of this on-chain?

No. link_wallet stores an identifier; it signs nothing and settles nothing.

Does it cost anything to run?

Your Cloudflare bill — pricing.

Keep reading