Webhooks

Signed work events, delivered to you.

Register an HTTPS destination with webhook_register(url, events_json, secret?). ZenSched rejects private, loopback, link-local, and reserved destinations.

Available events

worker.invitedworker.activatedshift.checkinshift.checkoutshift.missedtimesheet.readybilling.low_balancewebhook.disabled

Use webhook_test to test delivery and webhook_deliveries to inspect attempts.

Verify every request

ZenSched sends X-ZenSched-Signature, X-ZenSched-Timestamp, and X-ZenSched-Event. The signature is a hexadecimal HMAC-SHA256 digest over exactly "{timestamp}.{raw_body}".

import hashlib, hmac

def valid_signature(secret, timestamp, raw_body, signature):
    signed = f"{timestamp}.{raw_body.decode()}".encode()
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

Payload envelope

{
  "event": "shift.checkin",
  "org_id": 123,
  "event_id": 456,
  "created_at": "2026-07-27T18:00:00Z",
  "data": { }
}

webhook_test uses a test payload with test: true and sent_at in place of the regular event identifiers.

Retries and disablement