Webhooks
Stop polling. Register a webhook and BIE will POST completed intelligence to your endpoint the moment analysis finishes, signed with HMAC-SHA256 so you can trust the sender.
Registering a webhook
Add an endpoint under Settings → Webhooks in the app. Paste your HTTPS URL, choose which events to subscribe to, and BIE generates a signing secret shown exactly once, copy it immediately. The secret is stored encrypted and used to sign every delivery.
Event types
Subscribe to any combination of four events per endpoint:
layer_z_threshold_crossed, a scored human turn pushed a Layer Z dimension (trust calibration, frustration buildup, or dependency drift) into the broken band (above 0.55) on a deployment.anomaly_detected, a rated behavioral anomaly fired on a deployment.uhr_generated, a weekly User Health Report finished generating.outcome_shift_detected, a deploy event meaningfully moved the conversation resolved-rate before vs after (at least 3 points, at least 30 conversations each side, statistically significant), measured once the post-deploy window settles.
Payload shape
BIE sends a POST request with a stable envelope (id, event_type, version, created_at, org_id, deployment_id, and an event-specific data object) plus three headers: X-BIE-Event identifies the event type, X-BIE-Signature carries an HMAC-SHA256 of the raw request body using your webhook secret, and X-BIE-Delivery is a stable id you can use to deduplicate retries.
POST /webhooks/bie HTTP/1.1
Content-Type: application/json
X-BIE-Event: layer_z_threshold_crossed
X-BIE-Signature: sha256=a1b2c3...
X-BIE-Delivery: wh-7f3c...-lzx:9a2e...:frustration_buildup
{
"id": "lzx:9a2e...:frustration_buildup",
"event_type": "layer_z_threshold_crossed",
"version": "webhooks-v1.0",
"created_at": "2026-05-28T17:04:11.000Z",
"org_id": "8b1d...",
"deployment_id": "b25f7018-...",
"data": {
"dimension": "frustration_buildup",
"score": 0.72,
"threshold": 0.55,
"band": "broken",
"conversation_id": "c3f0...",
"conversation_external_id": "conv_0000080",
"signal_id": "a17c...",
"occurred_at": "2026-05-28T17:04:10.000Z"
}
}Verifying the signature
Always verify the signature before trusting a payload. Compute HMAC-SHA256 of the raw request body using your webhook secret and compare against X-BIE-Signature using a constant-time comparison.
import { createHmac, timingSafeEqual } from 'node:crypto'
function verifySignature(rawBody: string, header: string, secret: string): boolean {
const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex')
const a = Buffer.from(expected)
const b = Buffer.from(header)
return a.length === b.length && timingSafeEqual(a, b)
}Retries and delivery status
A delivery succeeds when your endpoint returns a 2xx status within 10 seconds. Failed deliveries (non-2xx, timeout, or connection error) retry with exponential backoff up to 5 attempts; after the fifth failure the delivery is marked failed and stops. Every attempt is recorded under Settings → Webhooks, where you can see the status, response code, attempt count, and error for recent deliveries, and fire a test event at any endpoint.
Idempotency
Each event carries a stable id and X-BIE-Delivery header. The same event is never re-queued for the same endpoint, but retries reuse the same delivery id, key on it if you need exactly-once processing.