KI BMS

Webhooks

Subscribe an HTTPS endpoint to KI BMS events.

Webhooks let your own service react to changes in KI BMS the moment they happen - no polling. Each subscription picks the events it cares about and ships a signed JSON payload to your URL. Failed deliveries retry with exponential backoff (up to 12 attempts); a subscription that fails consistently is auto-paused so it can't tail-spin your receiver. Manage your subscriptions from the Webhooks menu in the user dropdown.

How it works

  1. Create a subscription from the Webhooks menu in the top-right. Pick an endpoint URL and the events you care about.
  2. Copy the secret. The whsec_… value is shown exactly once on create (and on rotate).
  3. Verify each delivery using the secret + the X-Webhook-Signature header. Your endpoint replies 2xx within 10 seconds.
  4. Failures retry automatically with exponential backoff up to 12 attempts; after that the subscription is auto-paused.

What's in the contract?

Sign every payload

Each delivery carries X-Webhook-Signature: v1=<hex>,t=<unix>. Verify with hmac_sha256(secret, "v1." + t + "." + body). Reject any request whose t is more than 300 seconds away from your server clock to block replays. The signing secret is shown exactly once on create + on rotate.

Idempotent receivers

Retries fire with the same id (and the same data) but a new X-Webhook-Delivery header per attempt. Dedupe on id so a retried success doesn't reapply the side-effect.

Reply within 10 seconds

Return any 2xx response within 10 seconds to confirm receipt. Anything else (timeout, 4xx, 5xx) counts as a failure and schedules the next retry.

Test before you ship

Use the Send test button on the Webhooks page to fire a synthetic webhook.test delivery. Lets you verify your signature check + payload parser without waiting for a real event to happen.

Examples

{
"id": "<delivery uuid>",
"event": "<type>.<after_create|after_update|after_delete>",
"type": "<type>",
"app": "ats",
"timestamp": 1714501234,
"attempt": 1,
"actor_id": "<user id or null>",
"object": { "id": "…", "data": { } }
}

Event names

Event names use the <type>.<after_create|after_update|after_delete> shape. A subscription can also wildcard a single type (<type>.*) or every event in the deployment (*). The synthetic webhook.test value is fired only by the Send-test button.

Rotate secrets without dropping events

The 'Rotate secret' button opens a one-week grace window by default. During the window each delivery carries two signatures - one for the new secret and one for the previous one:

X-Webhook-Signature: v1=<hex new>,v1=<hex previous>,t=<unix>

Iterate every v1= token in the header and accept the delivery as soon as any matches your configured secret. Roll the new value out at your own pace - no events are lost during the cutover. After the window closes only the new secret signs. If the previous secret is leaked, end the grace immediately with the 'Revoke previous secret now' button.