Skip to main content

Monetize Your API in 10 Minutes

Lightning Enable turns any HTTP API into a paid API. Every request either includes a valid payment token or gets back a 402 with a Lightning invoice. You pick how it sits in the request path.

Two integration modes — pick one

Lightning Enable supports two ways to put L402 in front of your API:

Native mode (recommended for production APIs)Proxy mode (no code changes)
Where traffic livesOn your domain, your serversRouted through api.lightningenable.com
Code changesOne install + one line of middlewareNone
Existing auth, rate limiting, observabilityPreserved — chain your own middleware around itLE consumes Authorization, harder to pass through
Custom logic per routeFull controlLimited to what the proxy supports
Best forCommercial APIs, anything with sensitive infrastructurePublic APIs, experiments, demos

If your API is something you already run in production — and especially if it has its own auth — Native mode is the right answer. That's the path this Quick Start walks. If you want zero code changes and you're fine with traffic going through Lightning Enable, jump to Alternative: hosted proxy mode below.

Prerequisites

  • A Lightning Enable account on Agentic Commerce — Individual ($99/mo) or Agentic Commerce — Business ($299/mo). Both include a 30-day free trial; card required, no charge until trial ends.
  • A payment provider — Strike (recommended) or OpenNode. Strike supports preimage return for full L402 compatibility.
  • An existing HTTP API on a supported stack (Node + Express or .NET + ASP.NET Core today; FastAPI and Go on the roadmap — see the Producer API Reference for raw HTTP integration in any language).

Check your setup state at any time

If you want to know exactly where you are in the 10-minute setup — what's done, what's still required, what example payload comes next — hit the quick-start endpoint:

curl https://api.lightningenable.com/api/merchant/quickstart \
-H "X-API-Key: YOUR_LE_API_KEY"

You get back a state machine with completedSteps, requiredStepsCompleted, isReadyForProduction, and a per-step breakdown. Useful both as a "did I miss something" sanity check and as a programmatic readiness probe.

Step 1: Configure your payment provider (minutes 1-3)

Lightning Enable supports Strike (recommended) and OpenNode. Strike is the default — it supports preimage return for full L402 compatibility and requires no additional environment setup.

  1. Create an account at strike.me and get your API key from dashboard.strike.me
  2. Add it to Lightning Enable:
curl -X PUT https://api.lightningenable.com/api/merchant/strike-key \
-H "X-API-Key: YOUR_LE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"strikeApiKey": "your-strike-api-key"}'

Response:

{
"success": true,
"message": "Strike API key updated successfully. Webhook will re-register on the next L402 challenge."
}

Option B: OpenNode (alternative)

For testing (no KYB required): create a dev account at dev.opennode.com, generate an API key, and add it:

curl -X PUT https://api.lightningenable.com/api/merchant/opennode-key \
-H "X-API-Key: YOUR_LE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"openNodeApiKey": "your-opennode-dev-key"}'

For production: same flow at opennode.com. KYB verification takes 2-4 business days; use testnet in the meantime.

OpenNode environment (dev vs production) is set platform-wide in your Lightning Enable instance, not per-merchant. Hosted Lightning Enable runs against OpenNode production by default. If you need to switch your hosted account to dev, contact support.

Step 2: Install the middleware (minutes 4-5)

Pick your stack:

Node.js + Express

npm install l402-express l402-server

l402-server is the underlying SDK that l402-express calls; both are MIT-licensed and the middleware re-exports the SDK's types.

.NET + ASP.NET Core

dotnet add package L402Server.AspNetCore

The underlying L402Server SDK is pulled in transitively. Both are MIT-licensed.

Another stack?

The producer API is HTTP — you can integrate from any language. See the Producer API Reference for the two endpoints you'll call (POST /api/l402/challenges to mint, POST /api/l402/challenges/verify to validate).

Step 3: Add the middleware + set prices (minutes 6-7)

One line in your app. Anything mounted under it costs the configured number of sats per request.

Express

import express from "express";
import { l402 } from "l402-express";

const app = express();

// Anything below this costs 100 sats per request
app.use("/api/premium", l402({
apiKey: process.env.LIGHTNING_ENABLE_API_KEY,
priceSats: 100,
}));

app.get("/api/premium/weather", (_req, res) => {
res.json({ temp: 72 });
});

app.listen(3000);

Endpoints not mounted under l402(...) pass through untouched — mix paid and free routes freely.

For variable per-request pricing, pass a function instead of a number: priceSats: (req) => req.query.model === "premium" ? 500 : 100.

ASP.NET Core

using L402Server.AspNetCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddL402AspNetCore(opts =>
{
opts.ApiKey = builder.Configuration["LightningEnable:ApiKey"]!;
});

var app = builder.Build();

app.UseRouting();
app.UseL402();
app.MapControllers();
app.Run();

Then mark any action with [L402(PriceSats = N)]:

[ApiController]
[Route("api/premium")]
public class PremiumController : ControllerBase
{
[HttpGet("weather")]
[L402(PriceSats = 100)]
public IActionResult Weather() => Ok(new { temp = 72 });
}

That's the whole integration. For both stacks, the middleware:

  1. Reads Authorization: L402 <macaroon>:<preimage> from each request
  2. If absent → mints a fresh challenge and returns 402 Payment Required with the invoice
  3. If present → verifies it via Lightning Enable. Valid → call your handler; invalid → respond 401

Step 4: Test it (minutes 8-9)

Try an unpaid request

curl -i https://your-api.example/api/premium/weather

You'll get:

HTTP/1.1 402 Payment Required
Content-Type: application/json
WWW-Authenticate: L402 macaroon="AgEL...", invoice="lnbc..."

{
"error": "Payment Required",
"l402": {
"macaroon": "AgEL...",
"invoice": "lnbc1u1p3...",
"amount_sats": 100,
"payment_hash": "abc123...",
"expires_at": "<ISO-8601 timestamp, typically invoice-creation + 10 minutes>",
"resource": "/api/premium/weather"
}
}

Pay and access

# After paying the invoice and extracting the preimage:
curl https://your-api.example/api/premium/weather \
-H "Authorization: L402 AgEL...:deadbeef..."

# 200 OK — your API's response

Step 5: Ship it (minute 10)

Deploy your app. Your existing API is now a paid API. Give your callers (or their agents) the URL — they hit it, pay 402 invoices, get access.

How L402 interacts with your existing auth

The most common question: does L402 replace my auth, or sit next to it?

Two cases — both work:

  • L402 is your only auth. The macaroon's caveats (path, amount, merchant ID, expiry) plus preimage verification are the authorization. Anyone who pays for that resource gets in. This is the right model for the ~90% case — paid APIs where "they paid" is the only fact you need to enforce. L402 is anonymous-payment by design, so this is what you get out of the box.
  • L402 + your existing customer auth, side by side. They coexist because they live in different request fields. L402 owns Authorization: L402 <macaroon>:<preimage>. Your existing auth uses a cookie, X-API-Key, a JWT in a separate header, an IP allowlist, mTLS — whatever you're already doing. Chain your own auth middleware around l402(...) (Express) or before/after app.UseL402() (ASP.NET Core); they don't fight.

After successful verification, the middleware exposes the verified credential to your handler:

  • Express: res.locals.l402{ resource, amountSats, paymentHash }
  • ASP.NET Core: HttpContext items — same fields

Useful for usage logging, per-endpoint analytics, fraud detection. The payment hash gives you a stable per-payment identifier without revealing buyer identity.

Optional: list your API in the registry

If you want AI agents to discover your paid API (not just successfully call it once they know the URL), publish a manifest in the L402 registry. This step is independent of the middleware and uses the existing proxy management endpoints — see Setting Up Your Proxy for the manifest and registry portion (skip the upstream URL bits; in Native mode your manifest points at your own host).

Alternative: hosted proxy mode (no code changes)

If you'd rather not touch your application code, Lightning Enable can sit in front of your API as a hosted proxy. You give us your API URL, we give you a https://api.lightningenable.com/l402/proxy/{your-slug}/ URL that handles the 402 challenge dance and forwards paid requests to your origin.

  • Pros: zero code changes, no deploy required, fastest path to a working paywall
  • Cons: traffic flows through Lightning Enable, your existing Authorization-header auth is hard to preserve, customer domain changes

Full walkthrough: Setting Up Your Proxy.

What Lightning Enable handles (both modes)

ConcernHandled
Invoice creationVia your configured payment provider (Strike or OpenNode)
Payment verificationPreimage validated against payment hash cryptographically
Token managementMacaroon mint with caveats (path, amount, merchant ID, expiry)
Tenant isolationA token for Merchant A can never verify against Merchant B
Token reuse within validity windowSame payment hash re-verifiable for same resource until expiry (feature, not bug; see producer API reference)
SSRF protection (proxy mode)Private IPs blocked, target URLs validated
AnalyticsTracks requests, revenue, endpoint usage

Next steps