↗LoxleyLX-402

● Live on Robinhood Chain testnet

Your API can charge for itself.

Answer 402 Payment Required with a price. The caller signs. It settles on-chain before your handler runs — no account, no API key, no checkout page.

1
Address, all chains
4
Ways to pay
7
Chains
0
Gas for the payer

Two requests.
The second one pays.

That is the entire protocol. Everything else is detail about how the signature is made and who broadcasts it.

$ curl https://api.example.com/v1/report/AAPL

HTTP/1.1 402 Payment Required
{
  "amount": "10000",          // 0.01 USDC
  "payTo":  "0xb3CF79a5…",
  "asset":  "0xB3633542…",
  "salt":   "0x50617cd8…",     // single-use
  "sources": ["authorization", "permit2", …]
}

$ curl … -H "X-Loxley-Payment: <signed intent>"

HTTP/1.1 200 OK
X-Loxley-Receipt: <txHash, block, fee>

The signature commits to the merchant, the amount and the resource. A payload captured for a cheap endpoint cannot be presented at an expensive one, and replay is refused on-chain rather than in a database.

The payer picks how they pay.

Not the merchant. You advertise what your facilitator can settle; the caller chooses whichever suits their wallet.

SourceCost to payerSetup
authorizationGasless — signature onlyNone
permit2Gasless after first approvalOnce, ever
balanceCheapest per paymentDeposit once
allowanceSignature + approvalPer spender

An agent on authorization pays while holding zero native token. The facilitator covers gas; one EIP-3009 signature carries everything else. Not a local-chain trick — every payment on the public testnet was made that way.

Charge for what was used.

Quote a ceiling, do the work, settle the truth. Per-token and per-byte pricing, which no other 402 scheme does today.

app.post('/v1/complete', loxleyMetered({ maxPrice: 20_000n }),
  async (req, res) => {
    const { tokens } = await runModel(req.body)

    req.loxleyMeter.charge(tokens * PRICE_PER_TOKEN)   // ← the truth

    res.json({ tokens })
  })

The ceiling is enforced on-chain and the fee is taken on what is charged, not on the ceiling. Metered intents carry a distinct signature, so a fixed quote can never be settled for a different figure. Report nothing and the payer is charged nothing.

One address, everywhere.

Deployed through the canonical CREATE2 deployer, so identical arguments land at an identical address on every chain. Hardcode one constant, not a lookup table.

Settlement 0x54A49180CFb0f1573f8d6227eA36aDE583Cf0743
ChainIDGaslessPermit2
Robinhood Chain4663—yes
Robinhood Testnet46630—yes
Base8453yesyes
Base Sepolia84532yesyes
Arbitrum One42161yesyes
Optimism10yesyes
Polygon137yesyes

What else is in the box.

Everything below is running, not planned.

01

Three clients

TypeScript, Python, Go. The latter two were written from the spec rather than ported — independent implementations of the same document.

02

Any framework

Express middleware, plus one guard over standard Request/Response covering Hono, Next, Bun, Deno and Workers. None of them a dependency.

03

Discovery

Facilitators index paid endpoints so agents can find what to buy. Registration self-verifies: the index records what an endpoint actually charges, not what its owner claims.

04

Browser paywall

Humans pay too. Send Accept: text/html and get a payment page instead of JSON — self-contained, no bundler, no crypto library.

05

Nothing to trust

The facilitator pays gas and can refuse to settle. It can never redirect funds, change an amount, or settle twice — those live inside the payer's signature.

Take payments today.

A public facilitator is already running. Point a merchant at it and you host nothing.

app.get('/v1/report/:symbol', loxley({
  price:       10_000n,
  payTo:       MERCHANT,
  asset:       USDC,
  network:     'eip155:46630',
  settlement:  '0x54A49180CFb0f1573f8d6227eA36aDE583Cf0743',
  facilitator: 'https://loxley-facilitator-production.up.railway.app',
}), handler)
Unaudited. Testnet only. Everything here is verified against real contracts on a public chain — but that is not adversarial review. Don't move real money through it until someone who didn't write it has tried to break it.