Webhooks

Real-time event notifications for your integration.

Available Events

Event Description
order.createdA new order was created
order.updatedAn order's status or details changed
invoice.createdA Lightning invoice was generated
invoice.paidAn invoice was paid
invoice.expiredAn invoice expired without payment
payment.receivedA payment was received
payment.confirmedA payment was confirmed

Webhook Setup

  1. Go to your merchant dashboard → Webhooks
  2. Click Add Endpoint
  3. Enter your URL (must be HTTPS in production)
  4. Select which events to subscribe to

A unique secret key is auto-generated for each webhook endpoint. You'll use this to verify signatures.

Webhook Headers

Every webhook request includes these headers:

Header Description
X-Webhook-SignatureHMAC-SHA256 hex digest of the raw JSON body
X-Webhook-EventEvent type (e.g. payment.confirmed)
X-Webhook-Delivery-IDUnique delivery identifier
X-Idempotency-KeyUse this to deduplicate deliveries
X-Webhook-TimestampUnix timestamp of when the webhook was sent
User-AgentSatsRail-Webhook/1.0

Signature Verification

Compute an HMAC-SHA256 of the raw JSON request body using your webhook's secret key. Compare the result to the X-Webhook-Signature header.

Node.js
const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body, 'utf8')
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}
Python
import hmac, hashlib

def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)
Ruby
def verify_webhook(body, signature, secret)
  expected = OpenSSL::HMAC.hexdigest("SHA256", secret, body)
  ActiveSupport::SecurityUtils.secure_compare(signature, expected)
end

Retry Logic

SatsRail retries failed webhook deliveries (non-2xx responses) up to 3 times:

Attempt Delay
1st retry30 seconds
2nd retry5 minutes
3rd retry30 minutes
⚠️ Auto-disable: After 10 consecutive failures, the webhook endpoint is automatically disabled. Re-enable it from your dashboard.

For additional webhook reference, see the Webhooks documentation page.

Set up your first webhook

Follow the quickstart to get up and running in minutes.

Quickstart Guide →