Webhooks
Receive real-time event notifications from Panacea in your own backend systems.
Webhooks let Panacea push real-time event notifications to your own server. Instead of polling the API, your backend receives an HTTP POST when something happens.
Opening Webhooks
Go to Settings -> Webhooks. Requires admin or trainer role.
Creating a webhook
- Click New webhook.
- Enter the endpoint URL — a publicly accessible HTTPS URL on your server.
- Select the events you want to subscribe to.
- Click Save.
Panacea sends a test event immediately. If your server returns a 200 OK, the webhook is active.
Available events
| Event | Triggered when |
|---|---|
entry.created |
A wiki entry is created |
entry.updated |
A wiki entry is edited |
entry.deleted |
A wiki entry is deleted |
review.requested |
A new review queue proposal is created |
review.approved |
A proposal is approved |
review.rejected |
A proposal is rejected |
ingest.completed |
An ingestion run completes successfully |
ingest.failed |
An ingestion run fails |
handover.requested |
A session is escalated to a human agent |
handover.claimed |
An agent claims an escalation |
handover.resolved |
An escalation is marked resolved |
session.closed |
A session is closed |
Webhook payload format
All events share the same envelope:
{
"event": "handover.requested",
"tenantId": "ten_xxxxxxxxxxxx",
"timestamp": "2026-06-25T18:43:09.703Z",
"data": {
"id": "esc_xxxxxxxxxxxx",
"sessionId": "sess_xxxxxxxxxxxx",
"trigger": "CUSTOMER_REQUESTED",
"status": "pending"
}
}
Verifying webhook signatures
Every webhook request includes an X-Panacea-Signature header with the format sha256=<HMAC-SHA256>, signed with your webhook secret.
import { createHmac } from 'crypto'
export async function POST(req: Request) {
const body = await req.text()
const signature = req.headers.get('X-Panacea-Signature')
const expected = 'sha256=' + createHmac('sha256', process.env.PANACEA_WEBHOOK_SECRET!)
.update(body)
.digest('hex')
if (signature !== expected) {
return new Response('Unauthorized', { status: 401 })
}
const event = JSON.parse(body)
// handle event...
return new Response('OK')
}
Retry behaviour
If your endpoint returns a non-2xx status or times out (>10 seconds), Panacea retries 3 times with increasing delays: 100 ms, 1 s, and 5 s. After all retries fail the event is marked failed. Each delivery attempt uses the same idempotency ID — safe to replay from the webhook detail view.
Testing webhooks locally
Use a tool like ngrok to expose your local development server:
ngrok http 3000
# Forwarding: https://abc123.ngrok.io -> http://localhost:3000
Use the ngrok URL as your webhook endpoint during development.