Two protocols are racing to let software pay software with no human in the loop, and both are revivals of the same neglected HTTP status code: 402 Payment Required. x402 is the stablecoin version, promoted by Coinbase, where the client signs a USDC transfer on Base or another EVM chain and retries the request with a payment header. L402 is the Bitcoin version, from Lightning Labs (originally called LSAT), where the client pays a Lightning invoice and presents the payment preimage as proof. Same status code, same shape of handshake, completely different settlement rail.
The short answer, if that is all you came for: L402 is what you want when the payments are tiny, constant, and Bitcoin denominated, because a Lightning payment of 5 sats costs effectively nothing to send and settles in about a second with no chain gas and no account. x402 is what you want when your agent's treasury already lives in USDC on an EVM chain and you want a dollar denominated unit. Neither one requires an API key, a signup form, or a subscription, which is the whole point of both.
We are not a neutral observer here, and we are also not guessing about x402. Lightning Faucet runs a fleet of live L402 protected endpoints, a public registry of other people's L402 endpoints, and an npm package called lightning-wallet-mcp that gives an AI agent an actual Bitcoin wallet. That same package pays x402 endpoints too, because we wrote the fallback client. So the comparison below comes from having shipped both halves of the 402 handshake in production, not from reading two specs side by side.
x402 vs L402: the definitions
L402 is an HTTP authentication scheme where a server answers an unpaid request with 402 Payment Required plus a WWW-Authenticate header containing two things: a macaroon (a bearer credential describing what you bought) and a BOLT11 Lightning invoice. The client pays the invoice, gets the preimage back from the Lightning Network, and retries with Authorization: L402 <macaroon>:<preimage>. The server checks that the preimage hashes to the invoice's payment hash and that the macaroon's caveats permit the request. Payment and authorization are the same object.
x402 is an HTTP payment scheme where the server answers with 402 Payment Required and a payment requirements header describing an amount, an asset (typically USDC), a chain (typically Base), and a destination address. The client signs a transfer authorization for that amount and retries with a payment header carrying the signed payload. A facilitator settles it on chain. The credential is the signature over the transfer, not a macaroon.
Both are trying to solve the same failure: an autonomous agent hits a paywall, and there is no human present to enter a card number or complete an OAuth consent screen.
The wire flow, side by side
Here is a real L402 challenge from our gateway, trimmed:
HTTP/1.1 402 Payment Required
WWW-Authenticate: L402 version="0", token="AgEEbGF...", invoice="lnbc300n1p..."
And the paid retry:
Authorization: L402 AgEEbGF...:8f3c1a...preimage_hex
Our server also still accepts the legacy LSAT <macaroon>:<preimage> form, and it accepts the older macaroon= header key alongside the current token= key, because clients in the wild are split across both. That backward compatibility is not in any spec. It is what you learn after you watch real clients fail.
The x402 flow our client implements looks like this instead: read the base64 JSON payment requirements off the 402 response, convert the quoted USDC amount into sats so the agent's budget accounting stays in one unit, sign an EIP-712 typed payload with the agent's EVM key, and retry the original request with the signed payment header attached. Then record the payment with payment_protocol='x402' in the same ledger table that holds the L402 payments, so a single agent has one spending history across both rails.
What actually differs once you run both
Specs make these look like siblings. Operating them does not.
Settlement and cost floor
A Lightning payment for 5 sats is a routine thing. Our cheapest live endpoints are priced at 5 and 10 sats precisely because Lightning has no per transaction floor that makes that absurd: routing fees on a payment that small are typically zero or one sat, and settlement is roughly a second. This is what makes per request pricing honest rather than theatrical. You can charge a tenth of a cent for a UUID and the payment is not larger than the product.
An on chain settlement layer has a different cost structure. Whatever the current gas environment, the economics push you toward larger amounts per call or toward batching, which changes what kinds of products you can price. That is a real design constraint, not a knock on x402. It is why the two protocols will probably end up serving different price bands rather than one killing the other.
Unit of account
This is the honest tradeoff and it cuts against Lightning for some builders. x402 quotes in dollars. If you are selling an API to a business that budgets in dollars, a USDC price is simpler to reason about and does not move under you. L402 quotes in sats, so a sat denominated price is a fixed amount of Bitcoin and a floating amount of fiat.
We chose sats and we do not pretend it is free of tradeoffs. It is the right unit if you believe the agent economy settles in Bitcoin, and the wrong unit if your accounting department wants a stable invoice line. Our client bridges this by converting x402's USDC quote into sats at payment time, so an operator watching one agent's budget sees a single number regardless of which rail the agent used.
Identity and custody
L402's macaroon is a capability, not an account. It says what you bought, for how long, and under what constraints. Our challenges carry a service name, a capability list, and an expiry, and the macaroon is verified against those caveats on every retry. Nobody registers. Nobody is identified. The credential expires and that is the end of the relationship.
An EVM based scheme ties the payment to an address, which is durable and publicly linkable by design. That is a feature if you want on chain reputation for your agent and a drawback if you wanted the request to be as anonymous as dropping a coin in a slot.
Failure modes we actually hit
The L402 failure we see most is not a payment failure, it is a header handling failure. Clients re-encode the macaroon, strip whitespace, or truncate it, and then the signature check fails on retry. Our verifier returns an explicit hint telling the caller the macaroon must be the exact base64 string from the 402 response, because the generic "unauthorized" answer sent people hunting for the wrong bug for hours.
The second most common one is the client that pays the invoice and then never retries, so it is out the sats and has nothing to show for it. If you write an L402 client, treat pay-and-retry as one atomic operation with the preimage persisted between the two steps.
Giving an agent a wallet: the part most comparisons skip
Choosing a protocol is the easy half. The hard half is that an AI agent needs somewhere to keep money, a way to be funded, and a limit on what it can spend before it does something expensive at three in the morning.
That is what lightning-wallet-mcp is. It is an npm package that runs as an MCP server for Claude Code, Cursor, and other MCP native clients, and as a plain CLI (lw) for any agent framework with shell access. The agent gets tools, not documentation: check_balance, pay_l402_api, pay_invoice, create_invoice, get_transactions, withdraw.
Install is one line:
npm install -g lightning-wallet-mcp
The operator and agent split
The design decision that matters most here is the hierarchy. You, the human, register as an operator. You hold the API key and the recovery code, and you deposit sats by paying a Lightning invoice. Then you create agents underneath yourself, and each agent gets its own API key, its own isolated balance, and its own budget cap.
Think corporate cards. The agent can spend what it has been given and nothing more. create_agent, fund_agent, set_budget, and get_budget_status are all exposed as tools, so the agent can even be told to check its own remaining budget before it commits to an expensive call. sweep_agent pulls unspent funds back to the operator, deactivate_agent freezes one immediately, and rotate_api_key and recover_account exist for the day something leaks.
There is also a per request payment ceiling enforced on our side, independent of the agent's balance, so a malformed 402 quoting an absurd price cannot drain an agent in one call. Budget caps protect you from a chatty agent. The per request ceiling protects you from a hostile server.
One tool call, either protocol
The tool an agent actually reaches for is pay_l402_api, and despite the name it is protocol agnostic. It issues the request, reads the 402, and decides: if there is an L402 WWW-Authenticate header, it pays a Lightning invoice; if instead there is an x402 style payment requirements header, it falls back to the USDC path. The agent never has to know which rail it used. That is the design we would recommend to anyone building agent payments right now. Pick Lightning as the default because of the cost floor, and keep a stablecoin fallback so a paywalled endpoint is never a dead end.
The endpoints we charge for
Positioning is cheap. Here is the actual price list from our live L402 gateway, which is also what our .well-known/l402.json discovery document publishes:
| Endpoint | Price | What it returns |
|---|---|---|
/time | 10 sats | High precision time with current Bitcoin block height |
/uuid | 5 sats per id | Time ordered UUID v7 identifiers, 1 to 10 per request |
/entropy | 5 to 10 sats | Cryptographic random bytes, 32 to 256, hex or base64 |
/headers | 5 sats | Echoes your headers, IP, and user agent for debugging |
/onchain-fee | 50 sats | Bitcoin fee estimates, fastest through economy |
/mempool-heatmap | 30 sats | Fee distribution across upcoming blocks |
/invoice-decode | 30 sats | BOLT11 amount, description, destination, expiry |
/lnurl-metadata | 30 sats | Resolve an LNURL or Lightning address |
/node-info | 30 sats | Lightning node alias, channels, peers, sync status |
/price-oracle | 200 sats | Aggregated BTC price in USD, EUR, GBP, JPY |
/lightning-stats | 200 sats | Network capacity, channels, nodes, averages |
/sentiment | 50 sats | Sentiment classification with confidence scores |
/keywords | 50 sats | Keyword extraction with relevance scores |
/summarize-title | 100 sats | Ultra short summarization, 5 to 20 words |
/profanity-filter | 10 sats | Detection or filtering with severity scores |
/memory | 5 to 50 sats | Persistent key value storage for agents |
/ask-human | 500 sats | A binary question answered by a human judge panel |
/timestamp | dynamic | Anchor a SHA-256 hash to Bitcoin via OP_RETURN |
Two of those deserve a note.
/ask-human is the one people do not expect. An agent posts a binary question with two options and a language, and a panel of human native speakers votes with written rationales. Three vote consensus. Reading the result back is free once the question is paid for. The judges are paid a flat per judgment rate in sats through Boltwork, our human judgment layer, which is an open beta. It exists because there are questions no model should answer alone, and 500 sats is a rational price for a second opinion from a person.
/timestamp prices dynamically rather than at a fixed rate, because it broadcasts a real Bitcoin transaction and the cost of that transaction is set by the mempool, not by us. Static pricing on an endpoint whose cost floats is a good way to lose money quietly.
Discovery: how an agent finds paid endpoints at all
A payment protocol without discovery leaves your agent needing a human to paste in a URL, which defeats the purpose.
Our answer has two halves. The first is the L402 discovery document at .well-known/l402.json, which any agent can fetch for free. It lists every endpoint, its method, its parameters, its category, and its price in sats. An agent reads that once and knows what it can buy and what it will cost, before spending anything.
The second half is the registry, and it works in a way that we think is the interesting part. Anyone can submit their own L402 endpoint through the /registry-submit endpoint. Submission costs a platform fee plus the actual cost of a probe payment, because we do not take your word for it: we send a real L402 payment to the endpoint you submitted and check that the handshake completes. Pass and you are auto approved. Fail and you are auto rejected. There is no manual review queue and no human to lobby, which means the registry lists endpoints that provably worked at least once.
On top of that, the gateway keeps a crowd sourced directory. Every time an agent pays an external L402 endpoint through our infrastructure, we record the target URL and build stats on it. Once an endpoint has been paid successfully at least five times by at least two distinct agents, it is auto promoted into the curated registry. Payment history is a much harder signal to fake than a submission form. The same table records x402 payments with a protocol column, so the directory can answer "which rail does this endpoint speak" as well as "does it work".
So which one should you build on
Honest version, no cheerleading:
Build on L402 if your prices are under a few cents, if your calls are frequent, if you want no accounts and no user identity, or if you are Bitcoin denominated already. The cost floor is the argument. Nothing else lets you charge 5 sats and keep almost all of it.
Build on x402 if your treasury and your customers are already USDC on an EVM chain, if you need dollar stable pricing on the invoice, or if the on chain address as durable identity is something you want rather than something you tolerate.
Build on both if you are writing the client rather than the server, because a client that only speaks one protocol will hit paywalls it cannot cross. That is exactly why our own client falls back rather than failing.
Try it against something real
The fastest way to understand the handshake is to make an agent do it once. Fetch our discovery document, point an agent at the 10 sat /time endpoint, and watch it hit a 402, pay, and retry.
- Start at the builder hub for the gateway docs, the endpoint list, and operator registration.
- Fund an operator account without spending anything first by working through the earn surfaces, which pay out in sats to the same Lightning wallet.
- If you want a live example of sat denominated settlement in a product rather than an API, the prediction markets settle in sats on real world outcomes, and the games run on the same provably fair server seed, client seed, and nonce scheme you can verify yourself.
Deposits and withdrawals on all of it are LNURL based. You scan a QR code or tap a link and your wallet fetches the invoice itself, which is the same instinct L402 is built on: the machine handles the payment plumbing, and the human just approves the intent.
The part both protocols get right
It is worth stepping back from the rivalry. The interesting thing is not Lightning versus USDC. It is that after roughly three decades of 402 Payment Required sitting unused in the HTTP spec, two independent groups reached for it at the same moment, for the same reason: software agents finally needed to buy things.
Every existing payment path assumes a human at a keyboard. Card forms assume typing. OAuth assumes consent screens. API keys assume a signup, a billing relationship, and a monthly minimum, which is nonsense when an agent wants to make one call for a tenth of a cent and never come back. 402 assumes none of that. The server quotes a price in a header, the client pays it, the request goes through. It is the only part of HTTP that was designed for exactly this and never got used.
Whichever rail wins the volume, that pattern is the durable idea, and it is the reason we built our endpoints, our registry, and our wallet package around it rather than around another API key scheme.