Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.zenoo.com/llms.txt

Use this file to discover all available pages before exploring further.

Webhook Events

Zenoo sends webhook events to your configured endpoint when significant actions occur in the CLM platform. Use webhooks to build real-time integrations, trigger workflows, and keep external systems in sync.

Event delivery

PropertyValue
MethodPOST
Content-Typeapplication/json
Signature headerX-Zenoo-Signature (HMAC-SHA256)
Retry schedule1 min, 5 min, 30 min, 2 hr, 24 hr
IdempotencyEach event has a unique event_id
Timeout30 seconds (your endpoint must respond)
Always verify the X-Zenoo-Signature header before processing webhook payloads. See the signature verification section below.

Event types

Case events

EventTrigger
case.createdNew case created
case.status_changedCase status transition
case.closedCase closed with resolution
case.escalatedCase escalated to a manager

Alert events

EventTrigger
alert.createdNew alert generated from check result
alert.resolvedAlert resolved by analyst or auto-disposition
alert.escalatedAlert escalated to manager
alert.ai_research_completedAI research completed for alert

Check events

EventTrigger
check.completedCheck execution completed with result
check.failedCheck execution failed

Risk events

EventTrigger
risk_assessment.completedRisk assessment scoring completed
risk_assessment.approvedRisk assessment approved by reviewer

SLA events

EventTrigger
sla.warningCase approaching SLA deadline (warning threshold)
sla.breachedCase has passed its SLA deadline

Common envelope

Every webhook event uses this envelope structure:
{
  "event_id": "evt_abc123xyz",
  "event_type": "case.created",
  "created_at": "2026-02-16T10:01:00Z",
  "data": {
    // Event-specific payload
  }
}
FieldTypeDescription
event_idstringUnique event identifier for idempotency
event_typestringEvent type string
created_atstringISO 8601 timestamp of event creation
dataobjectEvent-specific payload (varies by type)

Event payloads

case.created

{
  "event_id": "evt_001",
  "event_type": "case.created",
  "created_at": "2026-02-16T10:01:00Z",
  "data": {
    "case_token": "cas_xyz789",
    "type": "Onboarding",
    "status": "New",
    "priority": "Medium",
    "entity_token": "ent_abc123",
    "entity_name": "Acme Holdings Ltd",
    "due_date": "2026-03-02T10:00:00Z"
  }
}

case.status_changed

{
  "event_id": "evt_002",
  "event_type": "case.status_changed",
  "created_at": "2026-02-16T10:30:00Z",
  "data": {
    "case_token": "cas_xyz789",
    "old_status": "New",
    "new_status": "In Progress",
    "changed_by": { "id": "user_analyst01", "name": "Sarah Johnson" }
  }
}

case.closed

{
  "event_id": "evt_003",
  "event_type": "case.closed",
  "created_at": "2026-02-16T11:35:00Z",
  "data": {
    "case_token": "cas_xyz789",
    "risk_tier": "Medium",
    "risk_score": 45,
    "resolution_notes": "All checks passed. PEP match reviewed and cleared.",
    "closed_by": { "id": "user_analyst01", "name": "Sarah Johnson" }
  }
}

case.escalated

{
  "event_id": "evt_004",
  "event_type": "case.escalated",
  "created_at": "2026-02-16T12:00:00Z",
  "data": {
    "case_token": "cas_xyz789",
    "escalated_by": { "id": "user_analyst01", "name": "Sarah Johnson" },
    "escalated_to": { "id": "user_manager01", "name": "Mike Chen" },
    "reason": "Complex corporate structure requires senior review."
  }
}

alert.created

{
  "event_id": "evt_005",
  "event_type": "alert.created",
  "created_at": "2026-02-16T10:15:00Z",
  "data": {
    "alert_token": "alt_001",
    "case_token": "cas_xyz789",
    "type": "Screening",
    "category": "PEP Match",
    "title": "PEP Match: John Doe",
    "priority": "High",
    "priority_score": 78,
    "entity_name": "John Doe"
  }
}

alert.resolved

{
  "event_id": "evt_006",
  "event_type": "alert.resolved",
  "created_at": "2026-02-16T11:30:00Z",
  "data": {
    "alert_token": "alt_001",
    "case_token": "cas_xyz789",
    "status": "Resolved",
    "resolution_action": "Approve",
    "resolution_notes": "Former local councillor. Low risk.",
    "resolved_by": { "id": "user_analyst01", "name": "Sarah Johnson" }
  }
}

alert.escalated

{
  "event_id": "evt_007",
  "event_type": "alert.escalated",
  "created_at": "2026-02-16T12:00:00Z",
  "data": {
    "alert_token": "alt_002",
    "case_token": "cas_xyz789",
    "escalated_by": { "id": "user_analyst01", "name": "Sarah Johnson" },
    "escalated_to": { "id": "user_manager01", "name": "Mike Chen" },
    "reason": "Potential sanctions match requires senior review."
  }
}

alert.ai_research_completed

{
  "event_id": "evt_008",
  "event_type": "alert.ai_research_completed",
  "created_at": "2026-02-16T10:05:30Z",
  "data": {
    "alert_token": "alt_001",
    "confidence": 85,
    "false_positive_probability": 82,
    "recommended_action": "Approve"
  }
}

check.completed

{
  "event_id": "evt_009",
  "event_type": "check.completed",
  "created_at": "2026-02-16T10:10:12Z",
  "data": {
    "check_token": "chk_001",
    "case_token": "cas_xyz789",
    "type": "PEP Screening",
    "category": "Screening",
    "result": "Refer",
    "provider": "WorldCheck",
    "entity_name": "John Doe",
    "alert_generated": true,
    "alert_token": "alt_001"
  }
}

check.failed

{
  "event_id": "evt_010",
  "event_type": "check.failed",
  "created_at": "2026-02-16T10:12:00Z",
  "data": {
    "check_token": "chk_003",
    "case_token": "cas_xyz789",
    "type": "Company Registry",
    "category": "Company",
    "error": "Provider timeout after 30 seconds",
    "retry_scheduled": true,
    "retry_count": 1
  }
}

risk_assessment.completed

{
  "event_id": "evt_011",
  "event_type": "risk_assessment.completed",
  "created_at": "2026-02-16T11:00:00Z",
  "data": {
    "assessment_token": "rsk_001",
    "case_token": "cas_xyz789",
    "overall_tier": "Medium",
    "overall_score": 45,
    "customer_risk": { "score": 40, "tier": "Medium" },
    "geographic_risk": { "score": 30, "tier": "Low" },
    "product_risk": { "score": 55, "tier": "Medium" },
    "channel_risk": { "score": 25, "tier": "Low" },
    "edd_required": false
  }
}

risk_assessment.approved

{
  "event_id": "evt_012",
  "event_type": "risk_assessment.approved",
  "created_at": "2026-02-16T11:15:00Z",
  "data": {
    "assessment_token": "rsk_001",
    "case_token": "cas_xyz789",
    "approved_by": { "id": "user_manager01", "name": "Mike Chen" },
    "overall_tier": "Medium"
  }
}

sla.warning

{
  "event_id": "evt_013",
  "event_type": "sla.warning",
  "created_at": "2026-02-28T01:00:00Z",
  "data": {
    "case_token": "cas_xyz789",
    "due_date": "2026-03-02T10:00:00Z",
    "days_remaining": 2,
    "assigned_to": { "id": "user_analyst01", "name": "Sarah Johnson" }
  }
}

sla.breached

{
  "event_id": "evt_014",
  "event_type": "sla.breached",
  "created_at": "2026-03-03T01:00:00Z",
  "data": {
    "case_token": "cas_xyz789",
    "due_date": "2026-03-02T10:00:00Z",
    "days_overdue": 1,
    "auto_escalated": true,
    "escalated_to": { "id": "user_manager01", "name": "Mike Chen" }
  }
}

Signature verification

Verify the webhook signature to ensure the payload is authentic:
import hmac
import hashlib

def verify_signature(payload_bytes, signature, secret):
    expected = hmac.new(
        secret.encode("utf-8"),
        payload_bytes,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

# In your webhook handler:
signature = request.headers.get("X-Zenoo-Signature")
is_valid = verify_signature(request.body, signature, WEBHOOK_SECRET)

Next steps