Sign in

Webhooks

Be told, instead of asking again.

Webhooks tell a server what happens as it happens. An organisation's admins add HTTPS endpoints in Control › Webhooks and pick the events. Each delivery is a JSON POST, signed, retried for about 1.5 hours.

A delivery
{
  "id": "cm31…",
  "event": "approval.decided",
  "createdAt": "2026-10-17T09:41:12.000Z",
  "data": {
    "approval": {
      "id": "cm2x…",
      "status": "approved",
      "module": "salesInvoices",
      "action": "create",
      "recordId": "cm2w…"
    }
  }
}

Check the signature#

ZiloMail-Signature: t=1760693472,v1=5257a8…: an HMAC-SHA256 of <t>.<body> with the endpoint's secret (shown when it was added). Compare in constant time and refuse old timestamps (5 minutes). ZiloMail-Event and ZiloMail-Delivery carry the event and the delivery's id (the same delivery retried keeps its id: use it to ignore repeats).

import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
  const mac = createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
  return timingSafeEqual(Buffer.from(mac), Buffer.from(parts.v1 ?? ""));
}

Events#

EventWhen
message.receivedNew mail stored in a mailbox (Inbox, a filter's folder or Junk).
message.sentSomeone sent mail from webmail, a mail app or the API.
delivery.succeededAnother server accepted a message sent from here.
delivery.failedA message couldn't be delivered (bounced) and won't be retried.
drive.file.uploadedA file was uploaded to ZiloDrive (from Drive, ZiloPDF or the API) and passed the virus scan.
drive.item.trashedA file, folder, document, spreadsheet or presentation was moved to Trash.
drive.item.sharedSomething was shared with a colleague, or a public link was made.
document.createdA new document, spreadsheet or presentation (kind: doc, sheet, slide).
user.createdA person was added to the organisation (in Control or the API).
user.disabledA person's mailbox was turned off.
user.enabledA person's mailbox was turned back on.
security.threat_blockedZiloSecur found a virus in mail or a ZiloDrive file and stopped it.
security.password_attackMany wrong passwords for one account in a short time (someone may be guessing).
security.new_deviceSomeone signed in from a browser or device the account hasn't used before.
app.signed_inSomeone signed in to one of your Sign in with ZiloOne apps.
approval.requestedA change (from a page or the API) is waiting for an approver: invoices, customers, leave and every module with approval levels.
approval.decidedA change waiting for approval was approved (and made) or rejected.

Answer quickly#

Answer 2xx within 10 seconds and do the work afterwards. An endpoint that fails 20 deliveries in a row is switched off (the admin is told).