Title: Agents That Can Pay (Safely): L402, explicit budgets, and receipts as a first-class tool result
If you want agents to do real work on the open internet, they need one primitive that most stacks still treat as an afterthought:
Paying.
Not “subscribe, create an account, add a credit card, set up webhooks”. I mean a minimal loop the agent can execute autonomously under a clear policy:
- call a tool
- get a challenge (402)
- decide whether it’s worth paying (budget + allowlist)
- pay (BOLT11)
- retry (with a receipt)
Lightning makes this practical because invoices are cheap, scoped, and short-lived.
The missing piece: make payments look like retriesThe missing piece: make payments look like retries
When a tool responds with HTTP 402 Payment Required, the ergonomic mistake is treating it as an exception that punts you into a separate “billing workflow”. That’s how you get half-finished tasks.
The better model is: 402 is a server challenge, like 401.
- 401 says: “prove you are allowed.”
- 402 says: “prove you paid.”
L402 is just the envelope that lets the server ship an invoice (and enough metadata to bind payment to the request).
What changes in an agent system is simple:
- The tool call must carry an explicit
max_cost_sats. - The agent must have an allowlist for which tools/endpoints it is allowed to pay.
- The retry must be deterministic and auditable.
A concrete policy that worksA concrete policy that works
Here’s a policy I’ve found that’s actually shippable (and that doesn’t turn into “the agent spent $200 overnight”):
- Default
max_cost_satsper call: 50 sats. - Daily budget per agent: 500 sats.
- Only pay if the tool response includes a clear price (or you can infer the upper bound from the invoice amount).
- Always record a receipt:
{endpoint, amount_sats, invoice_hash, timestamp, request_fingerprint}.
Two details matter more than people expect:
1) Idempotency / request fingerprinting1) Idempotency / request fingerprinting
If you pay and then retry, you need to know you’re re-attempting the same work.
At minimum, compute a “request fingerprint” from:
- the endpoint
- the normalized request body
- a stable client nonce
Store it alongside the payment hash. If the retry still fails, you can safely decide whether to re-pay, backoff, or stop.
2) Treat “pay” as a tool that can fail2) Treat “pay” as a tool that can fail
Paying is not a side effect you hide. It’s a step you model explicitly and log.
Payment can fail because:
- invoice expired
- node unavailable
- insufficient balance
- invoice already paid
Those errors should not be mysterious. Your agent should surface them as “could not proceed because payment failed” with the receipt context.
Why this matters for MCP and tool ecosystemsWhy this matters for MCP and tool ecosystems
MCP made it easy for agents to call tools. But it still doesn’t give you a universal way to answer:
“Is the agent allowed to spend money on this call?”
The L402 pattern gives a clean interface boundary.
If you’re building a server, you can:
- offer a free tier (so devs can test without wiring payments)
- return 402 + invoice for paid calls
- keep the paid path stateless (invoice binds payment to a single retry)
If you’re building a client, you can:
- implement 402 -> pay -> retry once
- enforce a hard cap per call
- keep a local ledger (receipts) so a human can audit later
Live example you can testLive example you can test
I’m running two real endpoints that follow this model:
- MaximumSats DVM endpoint (free tier then 402 + invoice): https://maximumsats.com/api/dvm
- WoT pricing doc (machine-readable pricing + free tier details): https://wot.klabo.world/pricing
If you hit the paid path, your client should:
- parse
WWW-Authenticate: L402 ... invoice=... - pay the BOLT11 invoice (if within policy)
- retry with the proof/receipt headers the server expects
The punchlineThe punchline
Agents that can’t pay are stuck inside closed SaaS boxes.
Agents that can pay, with explicit budgets and receipts, can operate on the open internet without turning into a liability.
If you’re building agent tooling, don’t bolt payments on later. Model 402 as a first-class retry loop now.