# Webhooks

For long-running renders or batch jobs you can register a webhook URL
that Audome calls when each generation completes. Webhooks save you
from holding open HTTP connections and let you build async pipelines.

## Configuring a webhook

1. Go to `https://audome.io/render/api-tokens`.
2. Click **Webhooks** next to a token.
3. Add a destination URL (must be HTTPS) and a secret.

You can register up to 5 webhook destinations per account.

## Payload

Every webhook delivery is a `POST` with body:

```json
{
  "id": "evt_01HX9Y...",
  "type": "render.completed",
  "createdAt": "2026-05-07T12:34:56.000Z",
  "data": {
    "generationId": "gen_01HX9Y...",
    "projectId": "8fce2c7e-...",
    "imageUrl": "https://cdn.audome.io/renders/2026/05/abc.png",
    "width": 1080,
    "height": 1080,
    "format": "png",
    "creditsUsed": 1,
    "metadata": { /* whatever you passed at request time */ }
  }
}
```

Other event types:

- `render.completed` — render succeeded.
- `render.failed` — render permanently failed.
- `token.created` — a new API token was minted on the account.
- `token.revoked` — a token was deleted.

## Verifying signatures

Each delivery includes:

```http
Audome-Signature: t=1715098496,v1=<hex hmac sha256>
Audome-Event: render.completed
```

Compute the HMAC of `<timestamp>.<raw_body>` with your webhook secret:

```js
import crypto from 'node:crypto';

function verify(rawBody, header, secret) {
  const [tPart, sigPart] = header.split(',');
  const t = tPart.split('=')[1];
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${t}.${rawBody}`)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(sigPart.split('=')[1])
  );
}
```

Reject any request older than 5 minutes to prevent replay attacks.

## Retries

Audome retries non-2xx responses with exponential backoff for up to 24
hours: 1 min, 5 min, 30 min, 2 h, 6 h, 24 h. After that the event is
marked `failed` and visible in the dashboard's webhook log.

## Local testing

Use any tunnel (ngrok, cloudflared, tailscale funnel) to expose your
local server, then send a test event from
`https://audome.io/render/api-tokens` -> **Webhooks** -> **Send test**.
