--- title: "Webhooks" description: "Get a signed POST when brand research, audience research or a weekly report finishes, and verify each delivery with HMAC-SHA256." canonical: https://tryadlicio.com/docs/api/webhooks --- # Webhooks Get a signed POST when brand research, audience research or a weekly report finishes, and verify each delivery with HMAC-SHA256. Add an https endpoint from [your account](https://tryadlicio.com/app/account) and pick the events to receive. We POST a JSON payload when each event fires. ## Events | Event | When it fires | |---|---| | `brand_research.completed` | A brand research run finished. `data` includes `brand_id` and `brief_id`. | | `audience_research.completed` | An audience research run finished. `data` includes `audience_id` and `brief_id`. | | `brand_digest.completed` | A weekly report finished. `data` includes `brand_id`, `digest_id`, `headline`, `new_comment_count`, `period_start` and `period_end`. | ## Payload ```json { "id": "b2f8c1e0-...", "event": "brand_research.completed", "created_at": "2026-07-11T02:14:00.000Z", "data": { "brand_id": "…", "brand_name": "Acme", "brief_id": "…" } } ``` ## Verify the signature Every delivery is signed. The `X-Adlicio-Signature` header is `sha256=` followed by the HMAC-SHA256 of the raw request body, keyed by your endpoint secret. Compare it against your own computation before you trust the payload. Retries reuse the same `id`, so dedupe on it. ```js import crypto from "node:crypto"; // body is the RAW request bytes, secret is your "whsec_..." endpoint secret. function verify(body, header, secret) { const expected = "sha256=" + crypto.createHmac("sha256", secret).update(body).digest("hex"); return header === expected; } ```