Skip to content
Searchbillingmart.com

Webhooks

Register an endpoint, see which events BillingMart sends today, verify the signature, and understand retries, rotation, and what switches an endpoint off.

Last updated Web

A webhook is a signed message that BillingMart sends to a web address of yours when something happens, such as an invoice being sent or paid. An owner or admin registers the address on the Webhooks page. Webhooks are a feature of the plans that include them.

Register an endpoint

  1. Open Webhooks in the sidebar and press New endpoint.
  2. Enter the URL. It must start with https://. An address on a private network is refused, now and again at every delivery.
  3. Tick the Events you want. You must pick at least one.
  4. Press Register. A banner says Copy this signing secret now — it is shown once.

We keep the secret sealed and cannot show it again. If you lose it, rotate it (below). The form has no description field. You can add one through the REST API with a key that holds Webhooks · manage: see API keys and the REST API.

Events sent today

Event When it is sent
invoice.sent An invoice is sent.
invoice.paid, invoice.partiallyPaid A card payment leaves the invoice paid in full, or part-paid.
payment.succeeded A card payment is approved, on an invoice or through a payment link.
payment.refunded A refund goes through.
client.created A client is created.
agentAction.proposed, .approved, .rejected, .executed, .failed, .expired, .withdrawn An assistant's or the Agent's request moves through its steps.

The event list on the form is longer than this. These events are offered but nothing sends them today: invoice.viewed, invoice.overdue, invoice.voided, estimate.sent, estimate.accepted, estimate.declined, payment.declined and payment.returned. Do not build on them. A payment you record by hand, such as cash or a check, does not send a payment event today.

What a delivery contains

A delivery is a POST with a JSON body: id, event, occurredAt, tenantId and data, the record as it is when sent. The id is the same on every retry, so make your handler safe to run twice. An event never holds up the invoice or payment that caused it.

Check the signature

Every delivery has the header X-BillingMart-Signature. It holds t= followed by a Unix time in seconds, then v1= followed by a hex signature. The v1 value is an HMAC-SHA256 of t, a full stop and the raw body, with your signing secret as the key.

  1. Read t. Refuse it if it is more than five minutes from your clock.
  2. Compute the HMAC over the raw bytes you received, exactly as sent.
  3. Compare in constant time. Accept if any v1 in the header matches. During a rotation the header can hold two.

When a delivery fails

Any answer outside the 2xx range, a timeout or a redirect counts as a failure. The Deliveries button on an endpoint lists each delivery as Sending, Delivered, Retrying, Gave up or Paused — plan, with Attempt shown like "3 of 8". BillingMart tries up to 8 times, waiting longer each time. After that the delivery is Gave up. Send again on a retrying or given-up delivery starts a fresh set of attempts. It rebuilds the body from the record as it is now, so it can differ from the original.

After 50 failures in a row the endpoint is switched off and shows Switched off after 50 failures. Press Switch on to turn it back on and clear the count. You can also Switch off or Delete an endpoint. Deleting keeps its delivery history readable.

Rotate the secret

  1. Press Rotate secret on the endpoint and confirm.
  2. Copy the new secret from the banner.
  3. Update your receiver within 24 hours. For that time the old secret also keeps working, and each delivery is signed with both.

If your plan lacks webhooks

The page shows Deliveries paused — your plan does not include webhooks. Your endpoints and history are kept, but events in that time are not queued, so nothing is sent later for them.

Related articles