> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://api-docs.hindsiteind.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://api-docs.hindsiteind.com/_mcp/server.

# Webhooks

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:

```ruby
expected = OpenSSL::HMAC.hexdigest("SHA256", signing_secret, raw_request_body)
# 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.

```json
{
  "action": "report_export_completed",
  "created_at": "2026-05-31T12:16:19Z",
  "organisation": { "id": "01946a36-84da-..." },
  "creator": { "id": "019469dc-ef01-...", "name": "Jane Smith" },
  "report_export": {
    "id": "019e7df6-ab7f-...",
    "status": "completed",
    "format": "pdf",
    "exportable": { "type": "Form", "id": "01946a34-219e-..." },
    "created_at": "2026-05-31T12:16:18Z",
    "completed_at": "2026-05-31T12:16:19Z",
    "download_url": "https://..."
  }
}
```