> ## 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

> CLM webhook event types with payload structures for real-time case, alert, check, and risk assessment notifications.

# 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

| Property         | Value                                   |
| ---------------- | --------------------------------------- |
| Method           | `POST`                                  |
| Content-Type     | `application/json`                      |
| Signature header | `X-Zenoo-Signature` (HMAC-SHA256)       |
| Retry schedule   | 1 min, 5 min, 30 min, 2 hr, 24 hr       |
| Idempotency      | Each event has a unique `event_id`      |
| Timeout          | 30 seconds (your endpoint must respond) |

<Warning>
  Always verify the `X-Zenoo-Signature` header before processing webhook payloads. See the signature verification section below.
</Warning>

## Event types

### Case events

| Event                 | Trigger                     |
| --------------------- | --------------------------- |
| `case.created`        | New case created            |
| `case.status_changed` | Case status transition      |
| `case.closed`         | Case closed with resolution |
| `case.escalated`      | Case escalated to a manager |

### Alert events

| Event                         | Trigger                                       |
| ----------------------------- | --------------------------------------------- |
| `alert.created`               | New alert generated from check result         |
| `alert.resolved`              | Alert resolved by analyst or auto-disposition |
| `alert.escalated`             | Alert escalated to manager                    |
| `alert.ai_research_completed` | AI research completed for alert               |

### Check events

| Event             | Trigger                               |
| ----------------- | ------------------------------------- |
| `check.completed` | Check execution completed with result |
| `check.failed`    | Check execution failed                |

### Risk events

| Event                       | Trigger                              |
| --------------------------- | ------------------------------------ |
| `risk_assessment.completed` | Risk assessment scoring completed    |
| `risk_assessment.approved`  | Risk assessment approved by reviewer |

### SLA events

| Event          | Trigger                                           |
| -------------- | ------------------------------------------------- |
| `sla.warning`  | Case approaching SLA deadline (warning threshold) |
| `sla.breached` | Case has passed its SLA deadline                  |

## Common envelope

Every webhook event uses this envelope structure:

```json theme={null}
{
  "event_id": "evt_abc123xyz",
  "event_type": "case.created",
  "created_at": "2026-02-16T10:01:00Z",
  "data": {
    // Event-specific payload
  }
}
```

| Field        | Type   | Description                             |
| ------------ | ------ | --------------------------------------- |
| `event_id`   | string | Unique event identifier for idempotency |
| `event_type` | string | Event type string                       |
| `created_at` | string | ISO 8601 timestamp of event creation    |
| `data`       | object | Event-specific payload (varies by type) |

## Event payloads

### case.created

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

```json theme={null}
{
  "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:

<CodeGroup>
  ```python Python theme={null}
  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)
  ```

  ```javascript Node.js theme={null}
  const crypto = require("crypto");

  function verifySignature(payload, signature, secret) {
    const expected = crypto
      .createHmac("sha256", secret)
      .update(payload)
      .digest("hex");
    return crypto.timingSafeEqual(
      Buffer.from(`sha256=${expected}`),
      Buffer.from(signature)
    );
  }

  // In your webhook handler:
  const signature = req.headers["x-zenoo-signature"];
  const isValid = verifySignature(req.rawBody, signature, WEBHOOK_SECRET);
  ```
</CodeGroup>

## Next steps

* [Audit Trail Guide](/guides/audit-trail). Query historical events.
* [Onboarding Quickstart](/use-cases/onboarding). See webhooks in action during onboarding.
