Developers

Outgoing webhooks

ExpirySuite can POST a JSON message to a URL you choose whenever something happens to a document in your workspace. Use it with Zapier ("Webhooks by Zapier" → Catch Hook), Make, n8n or your own backend.

Available on the Pro and Business plans in business workspaces. Owners and admins add webhooks under Settings → Integrations, up to 5 per workspace. To pull data on demand instead, see the read-only API. This page is in English only.

Events

document.expiring fires at each reminder threshold before the expiry date (60, 30, 14, 7 and 1 day; data.offsetDays); document.expired on the expiry day and at 3, 7 and 14 days after (negative offsetDays). The request events follow the document request flow.

Request

POST to your URL with Content-Type: application/json, User-Agent: ExpirySuite-Webhooks/1.0, X-ExpirySuite-Event and X-ExpirySuite-Signature headers. Only HTTPS URLs are accepted; redirects are not followed. Respond with any 2xx status within 8 seconds. The body never contains files, email addresses or links with access tokens.

{
  "id": "3f1c9c9e-5d5b-4b7e-9c1a-2b3d4e5f6a7b",
  "event": "document.expiring",
  "createdAt": "2026-10-01T05:00:12.000Z",
  "workspaceId": "da9f137b-0084-493b-b1c6-df8cdddde223",
  "documentId": "8a2b6d10-7c7e-4f4a-9d3c-1e2f3a4b5c6d",
  "data": {
    "title": "Health certificate",
    "subjectName": "Ayşe Yılmaz",
    "offsetDays": 14,
    "escalation": 0
  }
}

Signature

Each webhook has its own secret (shown once when you create it). The header is t=<unix seconds>,v1=<hex> where v1 is HMAC-SHA256 over the string <t>.<raw body> with the secret. Verify against the raw request body and reject timestamps older than five minutes:

import crypto from "node:crypto";

export function verify(secret, header, rawBody, toleranceSec = 300) {
  const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header);
  if (!m) return false;
  const t = Number(m[1]);
  if (Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
  const expected = crypto.createHmac("sha256", secret).update(t + "." + rawBody).digest();
  const given = Buffer.from(m[2], "hex");
  return expected.length === given.length && crypto.timingSafeEqual(expected, given);
}

Slack and Microsoft Teams

Choose the Slack or Microsoft Teams destination when adding a webhook and ExpirySuite posts a readable message in the language of your interface instead of the JSON above: the event, the record and document, the expiry date and a link to the workspace. The same events, retries and pause rules apply.

Retries

Delivery is attempted immediately. If your endpoint fails or times out, the message is retried 5 more times after 1 min, 5 min, 30 min, 2 h, 12 h. Use the message id to ignore duplicates. After 20 consecutive failures the webhook is paused; resume it from Settings once your endpoint is healthy. The "Send test" button posts a document.expiring sample with data.test = 1.