Skip to main content

Overview

BoxBilling sends webhook notifications when key events occur. Webhooks are delivered as HTTP POST requests with JSON payloads to your configured endpoints.

Setting up webhooks

Create a webhook endpoint

curl -X POST /v1/webhook_endpoints \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/webhooks/boxbilling",
    "signature_algo": "hmac"
  }'
You can create multiple endpoints — each will receive all webhook events.

List endpoints

curl /v1/webhook_endpoints \
  -H "Authorization: Bearer $API_KEY"

Webhook events

Invoice events

EventTrigger
invoice.createdNew invoice generated
invoice.finalizedInvoice finalized and ready for payment
invoice.paidInvoice fully paid
invoice.voidedInvoice voided

Payment events

EventTrigger
payment.createdPayment record created
payment.succeededPayment completed successfully
payment.failedPayment failed

Subscription events

EventTrigger
subscription.createdNew subscription created
subscription.startedSubscription activated
subscription.plan_changedPlan upgrade or downgrade applied
subscription.trial_endedTrial period expired
subscription.canceledSubscription canceled
subscription.terminatedSubscription terminated

Customer events

EventTrigger
customer.createdNew customer created
customer.updatedCustomer record updated

Credit note events

EventTrigger
credit_note.createdCredit note created
credit_note.finalizedCredit note finalized

Wallet events

EventTrigger
wallet.createdWallet created
wallet.terminatedWallet terminated
wallet.transaction.createdWallet transaction recorded

Usage events

EventTrigger
usage_threshold.crossedUsage threshold exceeded

Payment request events

EventTrigger
payment_request.createdDunning payment request created
payment_request.payment_succeededDunning payment succeeded
payment_request.payment_failedDunning payment failed

Payload format

{
  "webhook_type": "invoice.finalized",
  "object_type": "invoice",
  "object_id": "550e8400-e29b-41d4-a716-446655440000",
  "payload": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "invoice_number": "INV-20250115-0001",
    "status": "finalized",
    "total": 9900,
    "currency": "USD"
  }
}

Signature verification

Every webhook includes signature headers for verification:
HeaderDescription
X-Bxb-SignatureHMAC-SHA256 hex digest of the payload
X-Bxb-Signature-AlgorithmSignature algorithm (default: hmac)
X-Bxb-Webhook-IdUnique webhook delivery ID

Verifying signatures

import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

Retry logic

Failed webhook deliveries are automatically retried with exponential backoff:
RetryDelay
1st2 minutes
2nd4 minutes
3rd8 minutes
4th16 minutes
5th32 minutes
Formula: delay = 2^retries minutes The retry task runs every 5 minutes. After the maximum number of retries (default: 5), the webhook is marked as permanently failed.

Webhook statuses

StatusDescription
pendingQueued for delivery
succeededDelivered successfully (2xx response)
failedDelivery failed after all retries

Monitoring webhooks

List webhook deliveries

curl "/v1/webhook_endpoints/hooks/list?status=failed" \
  -H "Authorization: Bearer $API_KEY"

Retry a failed webhook

curl -X POST /v1/webhook_endpoints/hooks/{webhook_id}/retry \
  -H "Authorization: Bearer $API_KEY"

API endpoints

MethodPathDescription
POST/v1/webhook_endpointsCreate endpoint
GET/v1/webhook_endpointsList endpoints
GET/v1/webhook_endpoints/{id}Get endpoint
PUT/v1/webhook_endpoints/{id}Update endpoint
DELETE/v1/webhook_endpoints/{id}Delete endpoint
GET/v1/webhook_endpoints/hooks/listList deliveries
GET/v1/webhook_endpoints/hooks/{id}Get delivery details
POST/v1/webhook_endpoints/hooks/{id}/retryRetry a delivery