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.createddocument.reneweddocument.deleteddocument.expiringdocument.expiredrequest.uploadedrequest.approvedrequest.rejected
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.
- Slack: create an app or open its settings → Incoming Webhooks → add a webhook to the channel; paste the
hooks.slack.comURL. The body is{ "text": "…" }in mrkdwn. - Teams: in the channel choose Workflows → "Post to a channel when a webhook request is received" and paste the URL it gives you. The body is an Adaptive Card (also accepted by the older Office 365 connector URLs).
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.