Integration Prompt
Copy-paste system prompt and templates for configuring an AI agent to work with the Subscriptions Manager API.
System Prompt
Copy this into your agent's system prompt or instructions:
text
You are an integration assistant for the Subscriptions Manager API — a self-hosted
LNbits extension for recurring Bitcoin payments.
## API Base
All endpoints are at: {LNBITS_URL}/subscriptions_manager
## Authentication
- Admin Key (create/update/delete): X-Api-Key: {ADMIN_KEY}
- Invoice Key (read-only): X-Api-Key: {INVOICE_KEY}
- Public endpoints (checkout): No auth needed
## Key Endpoints
### Plans (requires API key)
- GET /api/v1/plans — List plans (paginated: ?limit=50&offset=0)
- POST /api/v1/plans — Create plan (Admin Key)
- GET /api/v1/plans/{id} — Get plan
- PUT /api/v1/plans/{id} — Update plan (Admin Key)
- DELETE /api/v1/plans/{id} — Archive plan (Admin Key)
### Subscriptions (requires API key)
- GET /api/v1/subscriptions — List subscriptions (?status=active)
- GET /api/v1/subscriptions/{id} — Get subscription
- POST /api/v1/subscriptions/{id}/pause — Pause (Admin Key)
- POST /api/v1/subscriptions/{id}/resume — Resume (Admin Key)
- POST /api/v1/subscriptions/{id}/cancel — Cancel (Admin Key)
- POST /api/v1/subscriptions/{id}/extend?days=N — Add free days (Admin Key)
### Public (no auth)
- GET /public/plan/{id} — Plan info for checkout
- POST /public/subscribe — Create subscription (returns invoice)
- GET /public/payment/{id}/status — Check payment status
- POST /public/nwc/validate — Validate NWC connection
- POST /public/subscribe/nwc — Create NWC autopay subscription
## Payment Methods
lightning, onchain, nwc, stripe, paypal
## Subscription Statuses
pending → active → paused | past_due | payment_failed | cancelled | expired
## Rules
1. Use Invoice Key for reading, Admin Key for writing
2. Never expose Admin Key in client-side code
3. Public endpoints need no authentication
4. All list responses are paginated: { items, total, limit, offset }
5. All timestamps are Unix seconds
6. Prices are in satoshis (1 BTC = 100,000,000 sats)Quick Start Templates
cURL — List Plans
bash
curl -X GET "https://your-lnbits.com/subscriptions_manager/api/v1/plans" \
-H "X-Api-Key: YOUR_INVOICE_KEY"cURL — Create Plan
bash
curl -X POST "https://your-lnbits.com/subscriptions_manager/api/v1/plans" \
-H "X-Api-Key: YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Pro Plan",
"amount_sats": 10000,
"interval": "monthly",
"allow_lightning": true
}'cURL — Subscribe a User
bash
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"
}'Python — Full Flow
python
import requests
import time
BASE = "https://your-lnbits.com/subscriptions_manager"
ADMIN_KEY = "your_admin_key"
INVOICE_KEY = "your_invoice_key"
def create_plan(name, amount_sats, interval="monthly"):
return requests.post(
f"{BASE}/api/v1/plans",
headers={"X-Api-Key": ADMIN_KEY},
json={
"name": name,
"amount_sats": amount_sats,
"interval": interval,
"allow_lightning": True,
}
).json()
def subscribe_user(plan_id, email, method="lightning"):
return requests.post(
f"{BASE}/api/v1/public/subscribe",
json={
"plan_id": plan_id,
"payment_method": method,
"email": email,
}
).json()
def wait_for_payment(payment_id, timeout=300):
start = time.time()
while time.time() - start < timeout:
status = requests.get(
f"{BASE}/api/v1/public/payment/{payment_id}/status"
).json()
if status["status"] == "paid":
return status
if status["status"] == "expired":
return None
time.sleep(3)
return None
def check_subscription(sub_id):
return requests.get(
f"{BASE}/api/v1/subscriptions/{sub_id}",
headers={"X-Api-Key": INVOICE_KEY}
).json()JavaScript — Full Flow
javascript
const BASE = 'https://your-lnbits.com/subscriptions_manager'
const ADMIN_KEY = 'your_admin_key'
const INVOICE_KEY = 'your_invoice_key'
async function createPlan(name, amountSats, interval = 'monthly') {
return fetch(`${BASE}/api/v1/plans`, {
method: 'POST',
headers: { 'X-Api-Key': ADMIN_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
name,
amount_sats: amountSats,
interval,
allow_lightning: true,
}),
}).then(r => r.json())
}
async function subscribeUser(planId, email, method = 'lightning') {
return fetch(`${BASE}/api/v1/public/subscribe`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
plan_id: planId,
payment_method: method,
email,
}),
}).then(r => r.json())
}
async function waitForPayment(paymentId, timeoutMs = 300000) {
const start = Date.now()
while (Date.now() - start < timeoutMs) {
const status = await fetch(
`${BASE}/api/v1/public/payment/${paymentId}/status`
).then(r => r.json())
if (status.status === 'paid') return status
if (status.status === 'expired') return null
await new Promise(r => setTimeout(r, 3000))
}
return null
}
async function checkSubscription(subId) {
return fetch(`${BASE}/api/v1/subscriptions/${subId}`, {
headers: { 'X-Api-Key': INVOICE_KEY },
}).then(r => r.json())
}MCP Server Configuration
Add this to your IDE's MCP configuration to give your AI assistant access to the Subscriptions Manager docs:
json
{
"mcpServers": {
"subscriptions-manager-docs": {
"command": "npx",
"args": [
"-y",
"@anthropic-ai/claude-code-mcp",
"--url",
"https://docs-subscriptions.netlify.app/llms.txt"
]
}
}
}For Cursor: Settings → MCP → Add the config above.
For VS Code: Settings → MCP → Add the config above.
For Claude Code: Add to your .claude/settings.json or project .mcp.json.
Validation Checklist
Use this to verify your integration is working:
- [ ] Can list plans with Invoice Key (
GET /api/v1/plans) - [ ] Can create a plan with Admin Key (
POST /api/v1/plans) - [ ] Can create a subscription via public endpoint (
POST /public/subscribe) - [ ] Can poll payment status (
GET /public/payment/{id}/status) - [ ] Receives correct response format (
{ items, total, limit, offset }for lists) - [ ] Handles 401 errors (wrong/missing API key)
- [ ] Handles 404 errors (plan/subscription not found)
- [ ] Payment polling stops on
paidorexpiredstatus - [ ] Admin Key is never exposed in client-side code
