Skip to content

Webhooks

Webhook best practices

On this page

Answer fast, work later#

Answer 2xx as soon as the signature checks out, and queue the work. Ten seconds is the limit; a slow receiver gets retries and, in the end, turned off (Retries).

Verify every request#

Check the signature against the raw body and refuse old timestamps. Keep the signing secret in a secret manager, never in code.

Skip duplicates#

Delivery is at least once. Store the webhook-id of each message you processed and skip one you've seen. Retries come within about a day, but a delivery can be resent from the log for 30 days, so keep ids that long.

Don't rely on order#

Retries can reorder events. Use timestamp to order changes about the same record, or better, treat an event as "this record changed" and fetch its current state:

JavaScript
async function onEvent(event) {
  if (event.type.startsWith('person.') && event.type !== 'person.erased') {
    const res = await bizisy('org/people.get', { person_id: event.data.person_id });
    await upsertPerson(res.data); // the current state, whatever order events arrived in
  }
  if (event.type === 'person.erased') await deletePerson(event.data.person_id);
}

Fetch what the payload doesn't carry#

Snapshots carry public and job details only. If your system needs more, read it with an API key whose role allows it: and remember that keys never get other people's private or pay data (What machines can see).

Honour erasure#

person.erased and document.deleted mean the data is gone from Bizisy. Delete your copy too: it's what the person asked for.

Reconcile now and then#

Webhooks can be turned off, endpoints can fail for a day. Run a full read now and then (nightly, or after an endpoint was off) to catch anything you missed. The sync guide shows both halves.

Subscribe to what you use#

Choose only the event types you handle: less traffic, and less data leaving Bizisy.

Something missing or wrong on this page? Write to hello@bizisy.com.

Developer docs