Skip to main content
A webhook is a request Saasybill sends to a URL you choose when something changes. Use webhooks to learn that an invoice was paid or a subscription ended, instead of polling the API.

Events

Every event and what its payload holds.

Verify signatures

Check each request came from Saasybill.

Delivery and retries

What happens when your server is down.

Set up an endpoint

Endpoints are managed in the app. The API doesn’t manage them yet. Only an owner or admin can add one.
1

Open Webhooks

Go to Organisation Settings, then Developer Settings, then Webhooks.
2

Add the endpoint

Click Add Endpoint and fill in the fields.
3

Copy the signing secret

Click Add Endpoint. The Your Signing Secret dialog shows a secret beginning whsec_. Copy it now and store it as an environment variable. It can’t be shown again.
4

Send a test event

Open the endpoint’s menu and click Send Test Event. Confirm your server receives it and passes signature verification.

Endpoint rules

The address is checked when you save the URL and again on every delivery.
To receive webhooks while developing on your own machine, use a tunnelling tool that gives you a public https:// address.

Manage an endpoint

Each endpoint has a menu.

What a webhook looks like

Saasybill sends a POST with a JSON body.

The event object

Events are thin on purpose. They carry the fields that changed and no more. To get the full object, fetch it with its id, for example GET /v1/invoices/{id}.

Respond quickly

Reply with any 2xx status within 10 seconds. Acknowledge the event first and do the slow work afterwards, on a queue or a background job. Anything else is a failure and is retried.

Things to know

Saasybill finds changes about once a minute by comparing each object with how it looked last time. An event arrives up to a minute after the change.
An invoice that is approved and paid within the same minute arrives as one invoice.paid event, and previous_attributes.status is draft. You won’t see an approved step. Write your handler to depend on the current state, not on seeing every step.
Delivery is at-least-once. Store each Saasybill-Event-Id you have processed and skip repeats.
Order is not guaranteed, and a retry can arrive after a newer event. If order matters, fetch the object from the API and act on its current state.
When an organisation gets its first endpoint, Saasybill records the current state silently. You’ll hear about changes from then on, not about every existing invoice.
A Xero contact that hasn’t been imported as a customer produces no events until it is imported.