Reference
Webhook Events
Every event the engine emits, with field-by-field payload documentation. All webhooks are HMAC-signed, delivered with exponential-backoff retry, and audit-logged in webhook_deliveries so you can replay or diagnose any delivery.
Subscribe
Create a webhook subscription:
curl -X POST http://localhost:8000/api/webhooks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"label": "Clinician alerts",
"url": "https://yourapp.example/webhook",
"events": "proactive.*,safety.blocked"
}'signing_secret (awhsec_…string) — store it now. You'll use it to verify the X-Humane-Signature header on every incoming delivery.Event filters
The events field takes a comma-separated list. Supported patterns:
*— everythingproactive.*— prefix wildcardsafety.blocked,safety.hold— explicit list
Verifying signatures
Every delivery carries X-Humane-Signature: t=<unix>,v1=<hex>. Compute HMAC-SHA256(secret, "{t}.{raw_body}") and compare constant-time. Reject timestamps older than 5 minutes (replay protection).
# Python — using the SDK's helper
from humane_ai import verify_webhook_signature
@app.post("/webhook")
async def receive(request: Request):
raw = await request.body()
sig = request.headers.get("X-Humane-Signature")
if not verify_webhook_signature(MY_SIGNING_SECRET, raw, sig):
raise HTTPException(401, "invalid signature")
event = json.loads(raw)
...Core events
interaction.processedEvery successful SDK /process call.
{
"event": "interaction.processed",
"timestamp": "2026-04-17T14:22:10Z",
"data": {
"user_id": "patient_42",
"safety_action": "PROCEED",
"mood": 0.48,
"energy": 0.51,
"interaction_count": 7
}
}user.createdFirst time an end_user appears for this tenant.
{
"event": "user.created",
"timestamp": "2026-04-17T14:22:10Z",
"data": {
"user_id": "patient_42",
"channel": "ios_app",
"timestamp": "2026-04-17T14:22:10Z"
}
}user.sentiment_shiftSentiment changes by more than 0.2 in a single interaction.
{
"event": "user.sentiment_shift",
"timestamp": "2026-04-17T14:22:10Z",
"data": {
"user_id": "patient_42",
"old_sentiment": 0.62,
"new_sentiment": 0.31,
"delta": 0.31,
"direction": "negative"
}
}Safety events
safety.blockedPre-LLM safety gate returns BLOCK. The LLM is never called.
{
"event": "safety.blocked",
"timestamp": "2026-04-17T14:22:10Z",
"data": {
"user_id": "patient_42",
"risk_score": 0.92,
"flags": ["self_harm"],
"message_preview": "I don't want to..."
}
}safety.holdAmbiguous message — flagged for human review but not blocked.
{
"event": "safety.hold",
"timestamp": "2026-04-17T14:22:10Z",
"data": {
"user_id": "patient_42",
"risk_score": 0.58,
"flags": ["medication_advice"]
}
}Proactive events
proactive.mood_dropEnd-user mood drops below 0.3.
{
"event": "proactive.mood_drop",
"timestamp": "2026-04-17T14:22:10Z",
"data": {
"trigger": "mood_drop",
"description": "User mood dropped below critical threshold",
"suggested_action": "Send empathetic check-in message",
"end_user_id": "patient_42",
"user_state": {
"mood": 0.18, "energy": 0.42, "trust": 0.55,
"interaction_count": 7,
"last_seen": "2026-04-17T14:19:40Z"
},
"timestamp": "2026-04-17T14:22:10Z"
}
}proactive.energy_lowEnd-user energy drops below 0.25.
{
"event": "proactive.energy_low",
"timestamp": "...",
"data": { "trigger": "energy_low", "end_user_id": "...", "user_state": { ... } }
}proactive.trust_milestoneEnd-user crosses trust > 0.7 with more than 10 interactions.
{
"event": "proactive.trust_milestone",
"timestamp": "...",
"data": { "trigger": "trust_milestone", "end_user_id": "...", "user_state": { ... } }
}proactive.user_inactiveEnd-user has not interacted in more than 48 hours.
{
"event": "proactive.user_inactive",
"timestamp": "...",
"data": { "trigger": "user_inactive", "end_user_id": "...", "user_state": { ... } }
}proactive.policy_{rule_name}Any policy with a fire_event action matched.
{
"event": "proactive.policy_sustained_distress",
"timestamp": "...",
"data": {
"user_id": "patient_42",
"policy_rule": "sustained_distress",
"mood": 0.22, "energy": 0.4, "trust": 0.55
}
}Audit trail
Every fired event is persisted in webhook_deliverieswhether or not a receiver was subscribed. Query them via:
curl -H "X-API-Key: hx_..." \
"http://localhost:8000/api/webhook-events?since_hours=168&limit=100"Returns each event with delivery status and the full payload. Useful for the Signals UI, incident forensics, or a "re-deliver failed webhook" flow.