Skip to content

Webhooks ​

Webhooks notify an HTTPS endpoint when subscription and invoice activity occurs. They let another system react to billing events without polling this application.

Before you begin ​

Prepare a publicly reachable endpoint that:

  • Accepts POST requests over HTTPS.
  • Reads a JSON request body.
  • Verifies the request signature before acting on the data.
  • Returns a 2xx response promptly—requests time out after 10 seconds.
  • Handles duplicate deliveries safely. Delivery is at-least-once, so use the webhook event ID as your idempotency key.

Keep the endpoint secret in a secure server-side configuration store; do not expose it in browser code or source control.

Create an endpoint ​

  1. In the admin application, open Settings → Webhook endpoints and select Add new.
  2. Enter the full receiver URL, for example https://billing.example.com/webhooks/subtreo.
  3. Enter a long, random Secret shared only with your receiver.
  4. Leave Active selected.
  5. Choose the event types your receiver needs and save.

The current event types are:

EventSent when
subscription.createdA subscription is created.
subscription.updatedA subscription is changed.
subscription.immediate_cancellationA subscription is cancelled immediately.
invoice.createdAn invoice is generated.
invoice.paidAn invoice is marked paid.

Each endpoint receives only the event types it subscribes to. Endpoint configuration and deliveries are tenant-specific.

Request format and verification ​

The service sends a JSON POST with these headers:

HeaderValue
Content-Typeapplication/json
User-AgentSubTreo-webhooks
X-Webhook-Event-IdThe persisted webhook event ID.
X-Webhook-SignatureHex-encoded HMAC-SHA-256 of the exact raw request body, using the endpoint secret.

The body has this envelope:

json
{
  "id": "123",
  "type": "invoice.paid",
  "createdAt": "2026-09-30T10:15:00+00:00",
  "data": {
    "id": 42,
    "customerId": 9,
    "status": "paid"
  }
}

data contains the event snapshot. Invoice events include invoice totals, due and paid dates, and line items. Subscription events include the subscription status, term dates, recurring charges, physical assets, one-time charge IDs, and collection settings.

Verify the signature against the unmodified raw bytes before parsing or processing the payload. In pseudocode:

text
expected = HMAC_SHA256_HEX(rawRequestBody, webhookSecret)
accept only when timingSafeEqual(expected, X-Webhook-Signature)

After verification, record X-Webhook-Event-Id as processed before performing side effects. Return a 2xx response for successfully accepted events, including events already processed.

Retries and delivery history ​

A delivery succeeds only on an HTTP 2xx response. Network errors, timeouts, and non-2xx responses are retried up to seven attempts, with delays of 1 minute, 5 minutes, 30 minutes, 2 hours, 12 hours, and 24 hours between retries. After the final unsuccessful attempt, the delivery becomes failed.

Test safely ​

To pause deliveries, clear Active on the endpoint. Existing queued deliveries to a disabled endpoint are marked failed when the worker encounters them; reactivate the endpoint and manually retry any delivery you still need.