HTTP has reserved the 402 Payment Required status since 1991.
open402 makes it real — a simple, open protocol and TypeScript SDK that lets
any server charge per-request and any client pay transparently.
No subscriptions. No API keys. No intermediaries.
/.well-known/402/pay to create an invoiceGET /.well-known/402/pay/:id until receipt is readyPayment-Receipt: <jwt>, server respondsimport express from 'express'
import { Open402Server, createWellKnownRouter, paywall } from '@open402/server'
const app = express()
app.use(express.json())
const pay402 = new Open402Server()
await pay402.init()
pay402.registerAdapter(myLightningAdapter)
app.use('/.well-known/402', createWellKnownRouter(pay402))
app.get(
'/api/data',
paywall(pay402, { path: '/api/data', amount: 1000, currency: 'BTC' }),
(req, res) => res.json({ secret: 'the data' }),
)
import { Open402Client } from '@open402/client'
import { WebLNWallet } from '@open402/lightning'
const client = new Open402Client({ wallet: new WebLNWallet() })
// automatically handles 402, pays, and retries
const res = await client.fetch('https://api.example.com/api/data')
const data = await res.json()
/.well-known/402 routes, paywall()
The protocol defines headers and a receipt format. Payment adapters are plug-in. Lightning ships first; any payment rail can implement the interface.
Receipts are ES256 JWTs signed by the server's own keypair, published at GET /.well-known/402. No central authority. No third-party verification service.
The protocol spec is language-agnostic. Any HTTP server can issue 402s. Any HTTP client can pay them.