Skip to content

Webhooks ​

Receive real-time notifications when subscription events occur.

Setup ​

  1. Go to Settings (gear icon)
  2. Enable Webhook notifications
  3. Enter your webhook URL
  4. Save

Your endpoint will receive POST requests for subscription events.

Payload Format ​

json
{
  "event": "subscription.created",
  "timestamp": 1704067200,
  "data": {
    "subscription_id": "sub_abc123",
    "plan_id": "plan_xyz",
    "plan_name": "Pro Plan",
    "subscriber_email": "user@example.com",
    "subscriber_name": "John Doe",
    "status": "pending",
    "amount_sats": 10000
  }
}

Events ​

EventTriggered When
subscription.createdNew subscription created
subscription.activatedFirst payment received
subscription.renewedRenewal payment received
subscription.payment_failedPayment attempt failed
subscription.cancelledSubscription cancelled
subscription.expiredSubscription period ended

Event Details ​

subscription.created ​

Fired when someone starts the checkout process.

json
{
  "event": "subscription.created",
  "data": {
    "subscription_id": "sub_abc123",
    "plan_id": "plan_xyz",
    "subscriber_email": "user@example.com",
    "status": "pending"
  }
}

subscription.activated ​

Fired when the first payment is received.

json
{
  "event": "subscription.activated",
  "data": {
    "subscription_id": "sub_abc123",
    "plan_id": "plan_xyz",
    "subscriber_email": "user@example.com",
    "status": "active",
    "current_period_end": 1706745600
  }
}

subscription.cancelled ​

Fired when a subscription is cancelled.

json
{
  "event": "subscription.cancelled",
  "data": {
    "subscription_id": "sub_abc123",
    "subscriber_email": "user@example.com",
    "cancelled_by": "subscriber",
    "reason": "User requested cancellation"
  }
}

Handling Webhooks ​

python
from flask import Flask, request

app = Flask(__name__)

@app.post("/webhook/subscriptions")
def handle_webhook():
    event = request.json

    if event["event"] == "subscription.activated":
        # Grant access
        user_email = event["data"]["subscriber_email"]
        grant_premium_access(user_email)

    elif event["event"] == "subscription.cancelled":
        # Revoke access
        user_email = event["data"]["subscriber_email"]
        revoke_premium_access(user_email)

    return {"ok": True}
💡

Always respond with a 200 status code quickly. Do heavy processing asynchronously.

Security ​

Webhooks don't include a signature by default. To verify requests:

  1. Use a secret URL path (e.g., /webhook/abc123secret)
  2. Check the IP address matches your LNbits server
  3. Verify the subscription exists via API call

Retry Policy ​

Failed webhook deliveries (non-2xx response) are not automatically retried. Use the API to poll for missed events if needed.