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

# Webhooks

> Listen for render completion events

Webhooks let your server react to render lifecycle events without polling.

## Event types

| Event                  | Fired when                            |
| ---------------------- | ------------------------------------- |
| `image.completed`      | Image render reaches `completed`      |
| `image.failed`         | Image render reaches `failed`         |
| `video.completed`      | Video render reaches `completed`      |
| `video.failed`         | Video render reaches `failed`         |
| `collection.completed` | All children of a collection finished |

## Per-render webhooks

Pass `webhook_url` in the render payload:

```json theme={null}
{
  "template_id": "tpl_abc",
  "modifications": [...],
  "webhook_url": "https://your.app/hooks/imtegrate"
}
```

Imtegrate POSTs to that URL once the render is `completed` or `failed`.

## Org-level webhooks

In **Settings → Webhooks**, register an endpoint that receives **all** events for the organization. Useful when you don't control the request (e.g., dashboard-triggered renders).

## Payload

```json theme={null}
{
  "type": "image.completed",
  "created_at": "2026-05-04T10:01:23Z",
  "data": {
    "id": "img_xyz",
    "status": "completed",
    "result_url": "https://storage.imtegrate.com/...",
    "template_id": "tpl_abc",
    "duration_ms": 3210
  }
}
```

## Signature verification

Each request includes an `X-Imtegrate-Signature` header — HMAC-SHA256 of the raw body, keyed by the webhook secret shown at creation time.

```typescript theme={null}
import crypto from "node:crypto";

function verify(rawBody: string, signature: string, secret: string) {
  const mac = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(signature));
}
```

<Warning>
  Always verify the signature before trusting the payload. Reject any request whose signature doesn't match.
</Warning>

## Retries

Failed deliveries (non-2xx response or timeout) are retried with exponential backoff: 1 min, 5 min, 30 min, 2 h, 12 h. After 5 failed attempts the event is dropped and surfaced in the dashboard.

## Idempotency

Each delivery includes `X-Imtegrate-Delivery-Id`. Treat it as an idempotency key on your side — the same event may be delivered more than once.
