Pay Per Call (L402)
Monetize any HTTP route with Lightning payments using the L402 challenge and proof flow.
Gate any API route behind a Lightning payment. Clients request a resource, receive a 402 challenge, pay the invoice, then retry with an Authorization proof.
This section documents the Axo implementation using:
@axobot/pay(server-side route protection)@axobot/fetch(client-side challenge payment and retry)@axobot/cli(axo fetchfor CLI-based paid requests)
Info
The canonical scheme is L402. Legacy LSAT is still accepted for backwards compatibility.
How It Works
sequenceDiagram
participant C as Client
participant S as Protected API
participant L as Lightning
C->>S: GET /premium
S-->>C: 402 + invoice + macaroon
C->>L: pay invoice
L-->>C: preimage
C->>S: GET /premium Authorization: L402 macaroon:preimage
S->>S: verify token, path, amount, expiry, settlement
S-->>C: 200 OK + dataClient calls a protected endpoint without credentials
Server returns 402 with WWW-Authenticate and challenge JSON
Client pays invoice and receives a payment preimage
Client retries with Authorization: L402 <macaroon>:<preimage>
Server verifies proof and forwards request to your handler
Wire Format
Axo Pay returns a challenge header like:
WWW-Authenticate: L402 macaroon="<token>", invoice="<bolt11>"And a JSON body with these fields:
{
"error": {
"code": "payment_required",
"message": "Payment required"
},
"macaroon": "<token>",
"invoice": "<bolt11>",
"paymentHash": "<hash>",
"amountSats": 21,
"expiresAt": 1735766400
}What To Read Next
Setup
Install packages, configure environment variables, and run a local paid-route demo.
Protect Routes
Add payment gates to Express, Hono, and Next.js with @axobot/pay.
Call Paid APIs
Use Axo Fetch or axo fetch to solve 402 challenges automatically.
Error Reference
Understand every L402-related error code returned by the middleware.