L402 for humans
L402 is an informal pattern (popularized around Lightning + HTTP) where:
-
A client calls your API without a prior payment proof.
-
The server responds with
402 Payment Requiredand aWWW-Authenticatechallenge containing a BOLT11 invoice and a macaroon the client will present after paying. -
The client pays the invoice out-of-band with a Lightning wallet.
-
The client retries the same request with an
Authorizationheader:Authorization: L402 <macaroon-base64>:<preimage-hex> -
The gateway verifies the macaroon + preimage, confirms the invoice settled, and forwards the request to your upstream.
Why not 401?
401 Unauthorized usually means “bad credentials.” 402 signals “payment needed” — a distinct axis so clients can branch: pay → retry, instead of assuming a broken API key.
Macaroons
Macaroons are short-lived credentials minted by the proxy. They can encode caveats like expiry or max uses. Cache them per route until they expire so you do not pay twice within the same window.
Error surface
| Status | Meaning |
|---|---|
| 402 | Pay the attached invoice, then retry with Authorization: L402 <macaroon>:<preimage> |
| 401 | Bad/expired macaroon or preimage, or the HTLC hasn’t settled yet |
| 429 | Back off — discovery APIs send Retry-After |
ZapAds’ role
ZapAds does not replace your upstream HTTP server. It provides:
- Discovery —
/api/v1/servicesfor agents and humans. - Billing hooks —
log-invocationrecords settled calls for reputation and fees. - A reference proxy (
zapads-proxy) that speaks L402 in front of your backend.
For machine-oriented field names and error semantics, see For agents or /.well-known/zapads.md.