

Register webhook endpoints to get real-time notifications when jobs or exports complete.

## Register a Webhook [#register-a-webhook]

```bash title="Terminal"
curl -X POST https://blitzreels.com/api/v1/webhooks \
  -H "Authorization: Bearer $BLITZREELS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url":"https://example.com/webhooks/blitzreels",
    "events":["job.complete","job.failed","export.ready"]
  }'
```

## Events [#events]

* `project.created`
* `media.uploaded`
* `transcription.complete`
* `transcription.failed`
* `faceless.complete`
* `faceless.failed`
* `export.ready`
* `export.failed`
* `job.complete`
* `job.failed`

## Payload Shape [#payload-shape]

```json title="Webhook Payload"
{
  "id": "evt_xyz789",
  "type": "export.ready",
  "created_at": "2026-02-04T10:05:00Z",
  "data": {
    "project_id": "proj_abc123",
    "export_id": "exp_def456",
    "download_url": "https://cdn.blitzreels.com/exports/xxx.mp4",
    "expires_at": "2026-02-05T10:05:00Z"
  }
}
```

## Verify Signatures [#verify-signatures]

Each request includes:

* `x-blitzreels-signature`
* `x-blitzreels-timestamp`

Use `HMAC-SHA256` on `${timestamp}.${payload}` with your webhook secret to verify.

```ts title="Signature Verification (Node)"
import crypto from "crypto";

export async function POST(req: Request) {
  const signature = req.headers.get("x-blitzreels-signature") ?? "";
  const timestamp = req.headers.get("x-blitzreels-timestamp") ?? "";
  const body = await req.text();

  const expected = crypto
    .createHmac("sha256", process.env.WEBHOOK_SECRET ?? "")
    .update(`${timestamp}.${body}`)
    .digest("hex");

  if (signature !== expected) {
    return new Response("Invalid signature", { status: 401 });
  }

  return new Response("ok", { status: 200 });
}
```
