Public Endpoints
No-authentication endpoints for subscriber-facing integrations.
These endpoints are designed for checkout flows. They don't require API keys.
Endpoints
GET
/public/plan/{id}Get plan information for checkout
Response:
json
{
"id": "plan_abc123",
"name": "Pro Plan",
"amount_sats": 10000,
"interval": "monthly",
"description": "Access to premium features",
"payment_methods": ["lightning", "onchain"],
"available_contact_methods": ["email", "telegram"]
}POST
/public/subscribeCreate a new subscription
Request:
json
{
"plan_id": "plan_abc123",
"contact_method": "email",
"contact_value": "user@example.com",
"name": "John Doe",
"payment_method": "lightning"
}Response:
json
{
"subscription_id": "sub_xyz789",
"payment_id": "pay_123",
"payment_request": "lnbc10000n1...",
"payment_hash": "abc123...",
"amount_sats": 10000,
"expires_at": 1704070800
}Payment Methods:
| Method | Returns |
|---|---|
lightning | payment_request (BOLT11) |
onchain | onchain_address, bip21_uri |
nwc | Use /public/subscribe/nwc instead |
NWC Endpoints
Endpoints for NWC (Nostr Wallet Connect) automatic payment subscriptions.
POST
/public/nwc/validateValidate NWC connection string
Request:
json
{
"nwc_string": "nostr+walletconnect://pubkey?relay=wss://relay.example.com&secret=..."
}Response (valid):
json
{
"valid": true,
"error": null
}Response (invalid):
json
{
"valid": false,
"error": "Connection timed out. Please ensure your wallet is online and try again."
}POST
/public/subscribe/nwcCreate subscription with NWC automatic payment
Request:
json
{
"plan_id": "plan_abc123",
"email": "user@example.com",
"name": "John Doe",
"nwc_connection_string": "nostr+walletconnect://...",
"contact_preference": "email"
}Response (success):
json
{
"subscription_id": "sub_xyz789",
"status": "active",
"message": "Subscription created and first payment completed"
}Response (payment failed):
json
{
"subscription_id": "sub_xyz789",
"status": "pending",
"message": "Your wallet doesn't have enough sats for this payment.",
"error_code": "INSUFFICIENT_BALANCE"
}See Status Codes for all NWC error codes.
GET
/public/payment/{id}/statusCheck payment status
Response:
json
{
"status": "paid",
"subscription_id": "sub_xyz789"
}Statuses:
| Status | Meaning |
|---|---|
pending | Waiting for payment |
paid | Payment received |
expired | Invoice expired |
GET
/public/manage/subscriptionsGet subscriber's subscriptions (requires token)
Query Parameters:
| Param | Type | Required |
|---|---|---|
token | string | Yes |
POST
/public/manage/subscription/{id}/cancelSubscriber cancels their own subscription
Query Parameters:
| Param | Type | Required |
|---|---|---|
token | string | Yes |
Custom Checkout Flow
Build your own checkout instead of using the default subscribe page:
javascript
// 1. Get plan info
const plan = await fetch(`/subscriptions_manager/api/v1/public/plan/${planId}`)
.then(r => r.json())
// 2. Create subscription
const checkout = await fetch('/subscriptions_manager/api/v1/public/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
plan_id: planId,
contact_method: 'email',
contact_value: userEmail,
payment_method: 'lightning'
})
}).then(r => r.json())
// 3. Show QR code with checkout.payment_request
// 4. Poll for payment
const interval = setInterval(async () => {
const status = await fetch(`/subscriptions_manager/api/v1/public/payment/${checkout.payment_id}/status`)
.then(r => r.json())
if (status.status === 'paid') {
clearInterval(interval)
// Redirect to success page
}
}, 2000)NWC Checkout Flow
For NWC subscriptions with automatic payments:
javascript
// 1. Validate NWC connection
const validation = await fetch('/subscriptions_manager/api/v1/public/nwc/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ nwc_string: userNwcString })
}).then(r => r.json())
if (!validation.valid) {
showError(validation.error)
return
}
// 2. Create subscription with NWC
const result = await fetch('/subscriptions_manager/api/v1/public/subscribe/nwc', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
plan_id: planId,
email: userEmail,
name: userName,
nwc_connection_string: userNwcString,
contact_preference: 'email'
})
}).then(r => r.json())
// 3. Check result
if (result.status === 'active') {
// Success! First payment completed
redirectToSuccess(result.subscription_id)
} else {
// Payment failed - show error message
showError(result.message)
}