Webhooks

View as Markdown

Subscribe to webhooks from your organisation’s settings to receive events at a URL you control, instead of polling. Each delivery is an HTTP POST with a JSON body, retried on failure.

Verifying a delivery

Every request carries two headers:

  • X-Webhook-Signature — an HMAC-SHA256 hex digest of the raw request body, keyed with your webhook’s signing secret.
  • X-Webhook-Timestamp — when the event occurred (ISO 8601).

Recompute the signature over the exact bytes you received and compare before trusting the payload:

1expected = OpenSSL::HMAC.hexdigest("SHA256", signing_secret, raw_request_body)
2# constant-time compare expected against the X-Webhook-Signature header

Events

report_export_completed

Fired when a report export finishes building (see the Create a report export endpoint). The payload carries a short-lived, signed download_url — fetch it promptly. The event covers every report export in your organisation; filter on report_export.exportable or creator if you only want some of them.

1{
2 "action": "report_export_completed",
3 "created_at": "2026-05-31T12:16:19Z",
4 "organisation": { "id": "01946a36-84da-..." },
5 "creator": { "id": "019469dc-ef01-...", "name": "Jane Smith" },
6 "report_export": {
7 "id": "019e7df6-ab7f-...",
8 "status": "completed",
9 "format": "pdf",
10 "exportable": { "type": "Form", "id": "01946a34-219e-..." },
11 "created_at": "2026-05-31T12:16:18Z",
12 "completed_at": "2026-05-31T12:16:19Z",
13 "download_url": "https://..."
14 }
15}