Agent Quick Start
Machine-readable guide for AI agents integrating with the Subscriptions Manager API.
TL;DR
# List available plans (read-only)
curl -X GET "https://your-lnbits.com/subscriptions_manager/api/v1/plans" \
-H "X-Api-Key: YOUR_INVOICE_KEY"
# Create a subscription for a user (no auth needed)
curl -X POST "https://your-lnbits.com/subscriptions_manager/api/v1/public/subscribe" \
-H "Content-Type: application/json" \
-d '{
"plan_id": "PLAN_ID",
"payment_method": "lightning",
"email": "user@example.com"
}'Authentication
LNbits uses API keys passed in the X-Api-Key header.
| Key | Header | Use For |
|---|---|---|
| Admin Key | X-Api-Key: {key} | Create/update/delete plans, manage subscriptions |
| Invoice Key | X-Api-Key: {key} | Read-only: list plans, subscriptions, payments |
| Subscriber Token | X-Subscriber-Token: {token} | Subscriber self-service (cancel, manage wallets) |
Find your keys: LNbits dashboard → Wallet → API Info (key icon).
All endpoints are under the base path /subscriptions_manager appended to your LNbits URL.
Core Operations
1. List Plans
GET /api/v1/plans
Header: X-Api-Key: {invoice_key}
Query: ?limit=50&offset=0Returns a paginated list of active plans with items, total, limit, offset.
2. Create a Plan
POST /api/v1/plans
Header: X-Api-Key: {admin_key}
Content-Type: application/json
{
"name": "Pro Plan",
"amount_sats": 10000,
"interval": "monthly",
"description": "Premium access",
"trial_days": 7,
"grace_period_days": 3,
"allow_lightning": true,
"allow_onchain": false,
"allow_stripe": false,
"allow_paypal": false
}| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Plan display name |
amount_sats | integer | Yes | Price in satoshis |
interval | string | Yes | weekly, monthly, or yearly |
description | string | No | Shown on checkout |
trial_days | integer | No | Free trial period (default: 0) |
grace_period_days | integer | No | Days after failed payment (default: 0) |
allow_lightning | boolean | No | Enable Lightning (default: true) |
allow_onchain | boolean | No | Enable on-chain Bitcoin |
allow_stripe | boolean | No | Enable Stripe cards |
allow_paypal | boolean | No | Enable PayPal |
3. Create a Subscription (Public)
POST /public/subscribe
Content-Type: application/json
# No auth required
{
"plan_id": "plan_abc123",
"payment_method": "lightning",
"email": "user@example.com",
"name": "John Doe"
}Returns a payment invoice (Lightning) or redirect URL (Stripe/PayPal). For trial plans, returns an immediately active subscription.
4. Check Payment Status (Public)
GET /public/payment/{payment_id}/status
# No auth requiredReturns: { "payment_id": "...", "status": "pending|paid|expired", "paid_at": ..., "subscription_id": "..." }
5. Manage Subscriptions
# Pause
POST /api/v1/subscriptions/{id}/pause
Header: X-Api-Key: {admin_key}
# Resume
POST /api/v1/subscriptions/{id}/resume
Header: X-Api-Key: {admin_key}
# Cancel
POST /api/v1/subscriptions/{id}/cancel
Header: X-Api-Key: {admin_key}
Body (optional): { "reason": "...", "immediate": false }
# Extend (add free days)
POST /api/v1/subscriptions/{id}/extend?days=7
Header: X-Api-Key: {admin_key}NWC Autopay Flow
NWC (Nostr Wallet Connect) enables automatic recurring payments. No manual invoice payment needed.
# Step 1: Validate the NWC connection string
POST /public/nwc/validate
Content-Type: application/json
{ "nwc_string": "nostr+walletconnect://pubkey?relay=wss://relay.example.com&secret=..." }
# Step 2: Create NWC subscription
POST /public/subscribe/nwc
Content-Type: application/json
{
"plan_id": "plan_abc123",
"email": "user@example.com",
"nwc_connection_string": "nostr+walletconnect://...",
"contact_preference": "email"
}If the wallet has sufficient balance, the first payment is completed immediately and the subscription becomes active.
Public Endpoints (No Auth)
These endpoints power the checkout flow and require no API key:
| Method | Endpoint | Description |
|---|---|---|
GET | /public/plan/{id} | Get plan info for checkout display |
POST | /public/subscribe | Create subscription (returns invoice) |
GET | /public/payment/{id}/status | Poll payment status |
POST | /public/nwc/validate | Validate NWC connection |
POST | /public/subscribe/nwc | Create NWC autopay subscription |
Subscription Statuses
| Status | Meaning |
|---|---|
pending | Waiting for first payment |
active | Paid and current |
paused | Temporarily suspended by admin |
past_due | Payment failed, in grace period |
payment_failed | Grace period ended, payment still failed |
cancelled | Manually cancelled |
expired | Billing period ended |
Pagination
All list endpoints support pagination:
?limit=50&offset=0limit: 1–200 (default 50)offset: 0+ (default 0)- Response:
{ "items": [...], "total": N, "limit": 50, "offset": 0 }
Complete Python Example
import requests
BASE = "https://your-lnbits.com/subscriptions_manager"
ADMIN_KEY = "your_admin_key"
INVOICE_KEY = "your_invoice_key"
# Create a plan
plan = requests.post(
f"{BASE}/api/v1/plans",
headers={"X-Api-Key": ADMIN_KEY},
json={
"name": "Pro Monthly",
"amount_sats": 10000,
"interval": "monthly",
"allow_lightning": True,
}
).json()
print(f"Plan created: {plan['id']}")
# List plans
plans = requests.get(
f"{BASE}/api/v1/plans",
headers={"X-Api-Key": INVOICE_KEY}
).json()
print(f"Total plans: {plans['total']}")
# Subscribe a user (public, no auth)
checkout = requests.post(
f"{BASE}/api/v1/public/subscribe",
json={
"plan_id": plan["id"],
"payment_method": "lightning",
"email": "user@example.com",
}
).json()
print(f"Invoice: {checkout['payment_request']}")
# Poll for payment
import time
while True:
status = requests.get(
f"{BASE}/api/v1/public/payment/{checkout['payment_id']}/status"
).json()
if status["status"] == "paid":
print(f"Paid! Subscription: {status['subscription_id']}")
break
time.sleep(3)
# Check subscription
sub = requests.get(
f"{BASE}/api/v1/subscriptions/{status['subscription_id']}",
headers={"X-Api-Key": INVOICE_KEY}
).json()
print(f"Status: {sub['status']}")Complete JavaScript Example
const BASE = 'https://your-lnbits.com/subscriptions_manager'
const ADMIN_KEY = 'your_admin_key'
const INVOICE_KEY = 'your_invoice_key'
// Create a plan
const plan = await fetch(`${BASE}/api/v1/plans`, {
method: 'POST',
headers: {
'X-Api-Key': ADMIN_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Pro Monthly',
amount_sats: 10000,
interval: 'monthly',
allow_lightning: true,
}),
}).then(r => r.json())
// Subscribe a user (public, no auth)
const checkout = await fetch(`${BASE}/api/v1/public/subscribe`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
plan_id: plan.id,
payment_method: 'lightning',
email: 'user@example.com',
}),
}).then(r => r.json())
console.log('Invoice:', checkout.payment_request)
// Poll for payment
const poll = setInterval(async () => {
const status = await fetch(
`${BASE}/api/v1/public/payment/${checkout.payment_id}/status`
).then(r => r.json())
if (status.status === 'paid') {
clearInterval(poll)
console.log('Paid! Subscription:', status.subscription_id)
}
}, 3000)Error Codes
| HTTP Status | Meaning |
|---|---|
200 | Success |
201 | Created |
400 | Bad request (missing/invalid fields) |
401 | Unauthorized (missing or invalid API key) |
403 | Forbidden (wrong key type, e.g. Invoice Key for admin action) |
404 | Not found |
422 | Validation error |
500 | Server error |
Decision Tree
Need to READ data (list plans, subscriptions, payments)?
→ Use Invoice Key with GET endpoints
Need to WRITE data (create plan, cancel subscription)?
→ Use Admin Key with POST/PUT/DELETE endpoints
Building a checkout for end users?
→ Use public endpoints (no auth needed)
→ POST /public/subscribe → returns invoice
→ GET /public/payment/{id}/status → poll until "paid"
Want automatic recurring payments?
→ Use NWC flow
→ POST /public/nwc/validate → then POST /public/subscribe/nwc
Subscriber wants self-service?
→ Use Subscriber Token with /public/manage/* endpoints