checkout402_
Get started

Concepts#

checkout402 has one object. Understanding it is most of understanding the product.

The Checkout#

A checkout is { price, payTo, what-you-get } — a URL with two faces.

Checkout  =  Offer  +  Payment  +  Fulfilment
Part What it means
Offer What's for sale, described well enough that an agent can decide before paying
Payment The price, the fee, and which rails you accept
Fulfilment What the buyer actually receives once money moves

There is no separate "product", "listing", or "catalogue" object. Deliberately: creating a checkout should not feel like creating a marketplace listing.

Two faces, one URL#

GET /c/chk_abc123 content-negotiates:

Accept You get
text/html A pay page — price, description, a wallet button
anything else HTTP 402 with accepts[], the fee split, and the offer card

Same object, same price, same ID. The buyer's client decides which face makes sense.

The offer card#

The optional metadata that makes an unpaid 402 genuinely useful. All fields are optional — creating a checkout stays fast — but each one raises the chance an agent completes the purchase.

Field Answers
title, description What is this? (required)
input_schema What do I provide?
output_schema What will I get back?
example_input, example_output Can I see it before paying?
freshness, coverage, source Is it suitable for my task?
constraints What are the limits?

These are commercial claims

freshness, coverage and source are assertions a buyer will rely on. If an agent fills them in on your behalf, it should propose them for your approval — not publish them as fact.

Fulfilment modes#

What happens after settlement. Money moves first, always.

Mode Behaviour Use when
inline Returns payload verbatim You're selling a key, a file, a fixed answer
relay Calls your origin_url, forwards the response You're putting an existing API behind a paywall
webhook Receipt only; you're notified async Fulfilment happens in your own system

Settle-before-deliver is not configurable

The ordering — verify, settle, then release — isn't a setting. The opposite ordering isn't representable in the code.

Payments and receipts#

Every payment attempt writes a CheckoutPayment row with its own pay_… id, addressable at /r/pay_….

A receipt carries the payer, the seller, the exact split, the network, the transaction hash, and the delivery outcome. Two faces again: JSON for agents, HTML for humans.

The X-PAYMENT-RECEIPT header returns it inline on the paying request, so an agent gets its receipt in the same round trip as the goods.

Retrying is safe

Re-presenting the same X-PAYMENT redelivers the goods and never charges twice. A dropped connection after settlement is the worst failure in payments — the buyer has paid and has nothing — so the same signed authorization is idempotent by design.

Single-shot vs reusable#

Behaviour
Default One payment, then status: paid. An invoice.
reusable: true Many payments, stays open. A payment link or a metered endpoint.

Test mode#

A test_mode checkout settles without touching a chain — synthetic 0xtest_… hash, test_mode: true stamped on the payment and the receipt.

It's gated by the checkout row, which only its seller controls, and a c402_live_ key cannot create one. So it's never silently reachable from a live checkout.

The fee#

0.5% of the price, plus $0.01. Visible in the 402 before anyone pays, and split out on-chain in the same transaction that pays you.

Your price     $0.10
Fee            $0.0105     (0.5% of $0.10 = $0.0005, plus the $0.01 fixed part)
Buyer pays     $0.1105
You receive    $0.10       — always your full price

On Base the split runs through an immutable splitter contract. On Solana there's no contract at all — the split is two SPL transfers inside the buyer's own transaction. Either way, checkout402 never holds the money.

Identity#

Who How Why
Buyers Nothing. The payment is the login. No signup is the entire point
Sellers (human) Magic link → session cookie No password to leak
Sellers (agent) Wallet signature → automation key Agents have keys, not inboxes

A signed wallet challenge is a verified identity here — bring-your-own-wallet is the product thesis, and the signature proves control of the payout address.

The fixed $0.01 is one on-chain settlement, not margin — it costs real money to land a transaction, and it costs the same whether the sale is $0.01 or $1,000. That is also why packages exist: a package settles once and serves many calls, so a $1 package of 1,000 calls pays the fixed part once instead of a thousand times. Selling calls for less than a cent each is a package, not a cheaper single call.

Single calls have no minimum price, deliberately. A cheap one is how a buyer tries your API before committing — $0.015 to find out, rather than $1.01.