Agent-native L402 lands on bolthub
L402 already let an agent pay for an API call with no account and no card. That is the hard part, and it works. But running real agent workloads surfaced the next layer of problems: paying a Lightning invoice on every single call adds latency when an agent hits a provider many times, a parent agent has no clean way to hand a budget to a worker, when an origin fails after you have paid you want your money back without arguing about it, and you want a verifiable record of every call you paid for.
We shipped four features that close those gaps. All of them are opt-in, and none of them change how a normal single-payment call works.
Pay once, call a provider a hundred times
Prepaid credit lets an agent pay a single Lightning invoice for a sats budget, then spend it across any of one provider's endpoints with zero further payments. When an agent knows it will hit several of a provider's endpoints, it buys that much credit once and just keeps calling.
// One payment for a budget usable across the provider's endpoints.await client.buyCredit("https://acme.gw.bolthub.ai/v1/data", 10_000);
// Any of acme's endpoints now draw the budget. No payInvoice happens.await client.get("https://acme.gw.bolthub.ai/v1/data");await client.get("https://acme.gw.bolthub.ai/v1/reports");An NWC wallet payment takes one to three seconds, and in a workload that touches a provider's endpoints many times that latency dominates every call. Credit collapses it to one upfront settle. It is face-value: you prepay N sats and spend N sats, no discount and no arithmetic. And it is non-custodial by construction, because a single Lightning payment settles to one provider's wallet. Credit is scoped to that one provider and never becomes a pooled balance. Calling across several providers is several payments, one per provider, which is exactly what batchFetch does when you hand it a mixed list of URLs.
Hand your sub-agents a budget, not your wallet
A parent agent that bought credit for a provider can now mint a scoped, capped, revocable child credential from it and hand it to a sub-agent, entirely offline, without re-paying.
mint_scoped_token({ slug: "acme", path: "/v1/data", n_uses: 20, spend_cap_sats: 300, path_prefix: "/v1/data/reports" })The child can make at most 20 requests, spend at most 300 sats, and only under /v1/data/reports. Attenuation is tighten-only: a child can never widen its scope or exceed its parent's remaining budget, and the gateway enforces every cap server-side. The spend cap is reserved from the parent's budget the moment you mint, so a parent and all its children can never jointly overspend. When you are done, one revoke_token call kills the whole delegation tree at once.
The worker never holds your keys or an open-ended balance. It holds exactly the slice you gave it.
If the origin gives you nothing, you pay nothing
Payment settles before the gateway forwards your request, so every way an origin can fail now has a defined, automatic outcome. The rule: if the origin gave you nothing, the attempt costs nothing.
- •Origin unreachable, 5xx, 408, or 429: your paid proof stays spendable, so re-sending the identical request is free.
- •A real 4xx (400, 404, 422): the call stays paid, because the API gave a genuine answer about your request.
To be clear about what "free retry" means under the hood: a Lightning payment is final, and nothing is clawed back over Lightning. The sats settled once and stay with the seller. What the gateway restores is your *claim to a delivery* — it marks your already-paid proof spendable again (or credits your session balance), so the retry needs no new payment. It is an at-least-once delivery guarantee funded by a single payment, not a reversal of money.
The gateway signals the outcome with an X-Bolthub-Payment status header, and the official SDKs act on it automatically, retrying the free-retryable failures with jittered backoff. You do not have to write the retry logic. For sub-cent per-call prices, a free retry is the refund.
A verifiable receipt for every sat
Every paid call now produces a receipt built on the Lightning preimage, which is cryptographic proof the invoice was paid. Buyers can keep a local ledger, export it as JSON or CSV, and verify each entry offline with no service in the loop. Sellers get their own export for reconciliation. Point a receipt store at your client and it just accumulates:
const client = new L402Client({ wallet, receiptStore: new FileReceiptStore() });// ... paid calls happen ...const csv = client.exportReceipts({ format: "csv", redact: true });Redacted exports keep the expense record but strip the preimage, so you can share a spend report without handing over anything credential-shaped.
Where these live
Two things are in play, and it helps to know which is which:
- •The hosted bolthub Gateway is what makes most of this real on the server side. When a seller lists an API on bolthub, they get a hosted gateway that mints the paywall, meters prepaid credit and grants for delegation, reverts a charge when the origin fails, and captures seller-side receipts.
- •The free
@bolthub/paySDK and the MCP server are how an agent *consumes* it: buying credit, paying, minting scoped child credentials, and keeping receipts. Both are MIT-licensed and free.
So prepaid credit, capped delegation, and automatic reverts are hosted-Gateway features you reach through the free client. A couple of pieces stand on their own: buyer-side receipts and offline attenuate() work against any L402 endpoint, hosted or self-hosted, and the SDK's seller API lets you self-host a basic paywall too. But the grant-backed features here assume a bolthub-hosted endpoint on the other end.
All of it is opt-in
None of this changes a normal single-payment call. Prepaid credit is bought only when you ask for it, delegation only narrows a credential you already hold, the retry behavior can be switched off, and receipts only exist if you ask for a receipt store. It is the same L402, with the sharp edges an agent economy actually hits filed down.