Skip to content

Agent Quick Start ​

Machine-readable guide for AI agents integrating with the Subscriptions Manager API.

TL;DR ​

bash
# 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.

KeyHeaderUse For
Admin KeyX-Api-Key: {key}Create/update/delete plans, manage subscriptions
Invoice KeyX-Api-Key: {key}Read-only: list plans, subscriptions, payments
Subscriber TokenX-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 ​

bash
GET /api/v1/plans
Header: X-Api-Key: {invoice_key}
Query: ?limit=50&offset=0

Returns a paginated list of active plans with items, total, limit, offset.

2. Create a Plan ​

bash
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
}
FieldTypeRequiredDescription
namestringYesPlan display name
amount_satsintegerYesPrice in satoshis
intervalstringYesweekly, monthly, or yearly
descriptionstringNoShown on checkout
trial_daysintegerNoFree trial period (default: 0)
grace_period_daysintegerNoDays after failed payment (default: 0)
allow_lightningbooleanNoEnable Lightning (default: true)
allow_onchainbooleanNoEnable on-chain Bitcoin
allow_stripebooleanNoEnable Stripe cards
allow_paypalbooleanNoEnable PayPal

3. Create a Subscription (Public) ​

bash
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) ​

bash
GET /public/payment/{payment_id}/status
# No auth required

Returns: { "payment_id": "...", "status": "pending|paid|expired", "paid_at": ..., "subscription_id": "..." }

5. Manage Subscriptions ​

bash
# 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.

bash
# 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:

MethodEndpointDescription
GET/public/plan/{id}Get plan info for checkout display
POST/public/subscribeCreate subscription (returns invoice)
GET/public/payment/{id}/statusPoll payment status
POST/public/nwc/validateValidate NWC connection
POST/public/subscribe/nwcCreate NWC autopay subscription

Subscription Statuses ​

StatusMeaning
pendingWaiting for first payment
activePaid and current
pausedTemporarily suspended by admin
past_duePayment failed, in grace period
payment_failedGrace period ended, payment still failed
cancelledManually cancelled
expiredBilling period ended

Pagination ​

All list endpoints support pagination:

?limit=50&offset=0
  • limit: 1–200 (default 50)
  • offset: 0+ (default 0)
  • Response: { "items": [...], "total": N, "limit": 50, "offset": 0 }

Complete Python Example ​

python
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 ​

javascript
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 StatusMeaning
200Success
201Created
400Bad request (missing/invalid fields)
401Unauthorized (missing or invalid API key)
403Forbidden (wrong key type, e.g. Invoice Key for admin action)
404Not found
422Validation error
500Server 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

Further Reading ​