> ## Documentation Index
> Fetch the complete documentation index at: https://api-tools.memories.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> How completion callbacks are delivered, signed, and retried.

An operation submitted with a `callback_url` (HTTPS) receives a POST when it completes — **success or failure**.

## Payload

The body is the operation snapshot. On a successful ingest that detected safety events, an `events` array is appended:

```json theme={null}
{ "operation": "op_xxx", "kind": "ingest", "done": true,
  "progress": {"preprocess":"done","index":"done","derive":"done","percent":100},
  "resource": "vid_xxx", "error": null, "cancelled": false,
  "created_at": "…", "updated_at": "…",
  "events": [ { "event_id": "evt_5", "event_type": "safety", "start": 812.0, "end": 816.0,
                "score": 0.86, "description": "…", "detector_id": "safety-detector",
                "detector_version": "1.0.0" } ] }
```

<Info>
  When no detector is enabled or nothing is detected, the `events` key is **omitted** — the body shape is otherwise unchanged. A safe video is silent.
</Info>

## Signature

Each delivery carries:

```
X-Signature: sha256=<hex(hmac_sha256(secret, raw_body))>
```

The `secret` is the callback key the platform issues to you; the signature covers the full raw body.

```python theme={null}
import hmac, hashlib
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
assert hmac.compare_digest(expected, headers["X-Signature"])
```

## Retries

* Non-`2xx` / timeout retries with `1s / 5s / 30s / 5m / 30m` backoff — **5 attempts** total.
* Exhausted attempts are marked dead (`status: dead` via [List Deliveries](/datalake/operations/list-deliveries)).
* A completion caused by `:cancel` does **not** fire a callback.
