HTTP-native payments.
Understand how an HTTP request becomes a signed payment, an on-chain settlement, and a response.
Based on Loxley documentation · Reviewed October 1, 2026 · Upstream reference
Unaudited · Testnet only
Use test tokens, never real funds. This is a documentation reference, not an activated Apiary integration. Apiary’s current gateway uses x402 v2; LX-402 uses different headers and SDKs.
Calling marketplace services? Use the agent quickstart.How it works
LX-402 is Loxley’s HTTP payment protocol. A caller signs an intent describing the purchase; a facilitator submits settlement. The merchant supplies a payout address, not a customer’s private key.
- 01
Request
An unpaid request receives a 402 challenge with the asset, recipient, amount, and expiry.
- 02
Authorize
The caller checks its spending policy, signs, then retries with the payment header.
- 03
Settle
For the default fixed-price flow, settlement precedes the handler. The response includes a receipt.
Developer quickstart
SDK distribution needs confirmation
The upstream guide names @loxley/server and @loxley/client. Both returned HTTP 404 from public npm on October 1, 2026. Request package or repository access from the maintainer before following these examples.
Upstream specifies Node.js 20+. Prepare a dedicated test wallet, supported test tokens, and verified network and contract settings. The snippets below show the documented SDK interfaces; they are not standalone, verified installation instructions.
1. Inspect the facilitator
# Read-only checks. These do not sign or transfer anything.
curl https://loxley-facilitator-production.up.railway.app/health
curl https://loxley-facilitator-production.up.railway.app/supported2. Protect an endpoint
// Illustrative middleware configuration, not a deployed Apiary route.
import { loxley } from '@loxley/server';
// app: your Express application.
// treasuryAddress and testAsset: verified TESTNET addresses.
// tokenName and tokenVersion: the test token's EIP-712 domain values.
app.get('/v1/report/:symbol', loxley({
price: 10_000n, // 0.01 tokens only when the asset has 6 decimals
payTo: treasuryAddress,
asset: testAsset,
assetName: tokenName,
assetVersion: tokenVersion,
network: 'eip155:46630',
settlement: '0x54A49180CFb0f1573f8d6227eA36aDE583Cf0743',
facilitator: 'https://loxley-facilitator-production.up.railway.app',
}), (req, res) => {
res.json({ paidBy: req.loxley!.payer });
});3. Give the caller a spending policy
// Illustrative SDK usage; package access is required first.
import { createLoxleyFetch } from '@loxley/client';
// account: a local signer for a dedicated TEST wallet.
// chain: the Robinhood Chain Testnet definition (46630).
// testAsset: a supported test-token address, verified independently.
const paidFetch = createLoxleyFetch({
account,
chain,
policy: {
maxAmountPerRequest: 50_000n,
maxTotalPerSession: 1_000_000n,
allowedAssets: [testAsset],
allowedNetworks: ['eip155:46630'],
},
});
// Use an endpoint that explicitly supports LX-402, not Apiary's gateway.
const response = await paidFetch('https://api.example.com/v1/report/AAPL');
console.log(response.headers.get('X-Loxley-Receipt'));Limits are token base units, not dollar amounts. Keep signing keys local, use a dedicated wallet, and restrict assets and networks. Do not send LX-402 payment headers to Apiary’s existing x402 gateway.
Protocol reference
| Message | Format |
|---|---|
| Unpaid response | HTTP 402 with a JSON challenge: lx402, resource, resourceHash, expiresAt, and accepts. |
| Signed retry | X-Loxley-Payment: base64url-encoded JSON containing lx402, scheme, network, source, settlement, intent, and signature. |
| Settlement receipt | X-Loxley-Receipt: base64url-encoded JSON. The source describes transaction hash, block, and fee information. |
Each accepted requirement defines the scheme, network, settlement contract, token, amount, recipient, salt, validity window, and available sources. Token-domain signing also needs the asset’s EIP-712 name and version.
The intent must match the selected requirement. Validate the recipient, token, amount, network, contract, expiry, and resource hash before accepting it. A fresh 32-byte salt distinguishes each challenge; upstream recommends a short 30–120 second validity window.
Settlement sources
| Source | Payer setup | Metered |
|---|---|---|
| authorization | EIP-3009 token signature; no prior approval. Uses a token-domain signature bound to the intent digest. | No |
| permit2 | An initial token approval to Permit2, followed by witnessed payment signatures. | Yes |
| balance | Test tokens deposited into the settlement contract; payments debit that balance. Withdrawals have a cooldown. | Yes |
| allowance | Token approval to the settlement contract, followed by a signature for each payment. | Yes |
Only use sources advertised by the selected facilitator. Initial approvals and deposits are separate on-chain actions and can require gas. The documented browser paywall uses Permit2, not the authorization source.
Usage-based billing
The exact scheme authorizes a fixed charge. The upto scheme authorizes a ceiling, with the merchant reporting actual usage through req.loxleyMeter.charge().
Metered authorization is checked before work begins; settlement happens after the response. Spending limits must cover the full ceiling. The documented contract rejects charges above it, applies the fee to actual usage, and makes no charge if usage is not reported.
Settlement is not guaranteed before delivery
Deferred settlement adds collection risk. The source describes after-response settlement as fire-and-forget: a process failure can leave completed work unpaid. Do not treat it as a durable billing queue.
Resource binding
canonical = "<METHOD> <scheme>://<host><path>"
resourceHash = keccak256(utf8(canonical))
// Query parameters and fragments are excluded.Recompute the resource hash when validating a request. Behind a reverse proxy, configure the middleware’s public origin so the client and merchant agree on the URL.
The documented hash does not bind the query string or request body. For prices that depend on parameters, issue distinct challenges and validate the application-level request terms; do not assume the path hash protects every input.
Upstream also documents Express middleware, a withLoxley Web Request/Response guard, and loxleyHono. Keep real SDK identifiers unchanged when integrating; Apiary branding does not rename these packages.
Facilitator & discovery
The read-only checks on October 1, 2026 returned a healthy facilitator advertising Robinhood Chain Testnet (eip155:46630), both schemes, all four sources, and feeBps: 30 (0.30%). This is a dated observation, not an uptime or future pricing guarantee.
- Public facilitator
- https://loxley-facilitator-production.up.railway.app
- Advertised testnet settlement contract
- 0x54A49180CFb0f1573f8d6227eA36aDE583Cf0743
| Endpoint | Purpose |
|---|---|
| GET /health | RPC connectivity and the facilitator’s gas funding. |
| GET /supported | Current networks, schemes, sources, contract addresses, and fee. |
| POST /verify | Signature and simulation checks; not a settlement receipt. |
| POST /settle | Broadcasts settlement; documented as idempotent per intent hash. |
| GET /discovery/resources | Search the facilitator’s paid-endpoint index. |
| POST /discovery/register | Submit a resource URL for independent challenge verification and indexing. |
Discovery results can become stale; check a fresh challenge before paying. Registration in this index does not publish a service in Apiary’s marketplace. Request and response schemas beyond this overview remain in the upstream reference.
Status & safety
Loxley marks this implementation as unaudited and for testnet use. We checked public HTTP responses and package availability, not contract security, end-to-end SDK execution, or mainnet deployments.
- Use test funds only. Verify contracts, token domains, approvals, and spending limits independently.
- Signature binding and on-chain replay protection are the upstream design; they are not an independent security audit.
- A facilitator can fail or refuse service. A successful verification is not proof that a payment settled.
- Self-hosting requires gas on each configured chain. The source requires Postgres coordination before running multiple replicas; rate limits remain per process.
- Solana support is described as a design, not an implemented payment path. Do not infer live support from a network list.
Before an Apiary integration can be considered, confirm SDK access, review the contracts and commercial terms, and test payment, replay, failure, and recovery paths. This documentation does not activate LX-402 billing or replace existing marketplace payments.
Read upstream status and limitations