> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sila.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Receive signed events as a crawl progresses.

Pass `webhook` when you [create a crawl](https://docs.sila.sh/api-reference/crawls-create.md). Sila sends no events for crawls without it. Find your signing secret (`whsec_…`) on the **Webhooks** page.

## Event types

`crawl.started`, `crawl.discovered`, `crawl.page_batch`, `crawl.completed`, `crawl.failed`, `crawl.canceled`.

## Body

```json theme={null}
{
  "id": "evt_…",
  "type": "crawl.page_batch",
  "createdAt": "2026-11-04T00:00:00.000Z",
  "data": { "crawlId": "…", "status": "running", "phase": "crawling", "pagesStored": 50, "cursor": 1 },
  "metadata": {}
}
```

`metadata` echoes what you sent in `webhook.metadata`. `data.cursor` is the number of page batches stored so far: when it is higher than the last `nextCursor` you read, call [crawl pages](https://docs.sila.sh/api-reference/crawls-pages.md) with your `nextCursor` to fetch the new batches.

## Signature

Each request has the header:

```
Sila-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256>
```

The HMAC key is your signing secret. The signed message is `<t>.<raw body>`. Reject requests more than 300 seconds old.

```js theme={null}
import { createHmac, timingSafeEqual } from "node:crypto";

export function verifySilaSignature(rawBody, header, secret, nowSec = Math.floor(Date.now() / 1000)) {
  const parts = Object.fromEntries((header ?? "").split(",").map((p) => p.split("=")));
  const t = Number(parts.t);
  if (!parts.v1 || !Number.isFinite(t) || Math.abs(nowSec - t) > 300) return false;
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1);
  return a.length === b.length && timingSafeEqual(a, b);
}
```

Verify against the raw body, not re-serialized JSON.

## Delivery

Return any `2xx` quickly. Sila retries failed deliveries with growing delays, up to 8 attempts. Events can arrive more than once; dedupe on `id`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.