This document describes the integration between a bank's internal Complaint Management System (CMS) and the Saudi Central Bank's (SAMA) complaint platform. It covers the escalation workflow, actors, states, the Complaint Triage Agent (AI agent for detection/routing), and integration touchpoints required to implement the system.
| Actor | Description |
|---|---|
| Customer | Raises the complaint/inquiry/suggestion via bank channels |
| Complaint Triage Agent | AI agent that classifies, detects escalation triggers, and drafts handoff summaries (see Section 6) |
| Bank L1 | First-line agent/team handling the complaint |
| Bank L2 | Second-level / specialized team for unresolved or complex cases |
| SAMA (Ministry) | Central bank platform acting as regulator / final escalation point |
Only Complaints follow the full escalation lifecycle described below. Inquiries and Suggestions are typically closed at L1 without escalation unless the customer explicitly disputes the response.
| # | Rule | Trigger | Result |
|---|---|---|---|
| 1 | Direct closure | Simple inquiry/suggestion resolved by Bank L1 | Case Closed |
| 2 | Customer dissatisfaction | Customer rejects L1's response | Case Escalated (reopened) to L1 supervisor / re-review, or directly to L2 depending on bank policy |
| 3 | SLA breach at L1 | L1 does not resolve within configured SLA (e.g., X business days) | Auto-escalate to Bank L2 |
| 4 | L2 unable to resolve | L2 cannot resolve within its SLA, or determines it is outside its authority | Escalate to SAMA (Ministry) |
| 5 | Direct-to-SAMA categories | Case type is pre-flagged as "direct escalation eligible" (defined by SAMA category list) | L1 can escalate directly to SAMA, bypassing L2 |
[New]
→ (Inquiry/Suggestion, resolved) → [Closed]
→ (Complaint, resolved by L1) → [Pending Customer Confirmation]
→ (Customer satisfied) → [Closed]
→ (Customer dissatisfied) → [Escalated - L2]
→ (Complaint, L1 SLA breach) → [Escalated - L2] (auto)
→ (Complaint, direct-escalation category) → [Escalated - SAMA] (auto/manual by L1)
[Escalated - L2]
→ (Resolved by L2, customer satisfied) → [Closed]
→ (L2 SLA breach / unresolved) → [Escalated - SAMA]
[Escalated - SAMA]
→ (SAMA resolves / instructs bank) → [Closed] or [Reopened at Bank]
SLA timers should be configurable per case category/severity, e.g.:
| Level | Default SLA | Escalation Trigger |
|---|---|---|
| L1 | 3–5 business days (configurable) | Timer expiry without closure |
| L2 | 5–10 business days (configurable) | Timer expiry without closure |
| SAMA direct-eligible types | Immediate (no SLA wait) | Category match |
Customer
│
▼
Bank Channels (branch, app, call center, email)
│
▼
Bank CMS (case creation, SLA engine, workflow) ───► Bank L1 / L2 queues
│ ▲
│ │
▼ │
Complaint Triage Agent (classification, dissatisfaction/SLA/rule-5 detection,
escalation summaries — see Section 6)
│
│ (escalation event / status sync)
▼
SAMA Integration Layer (API Gateway / Adapter)
│
▼
SAMA Complaint Platform
The Integration Layer is responsible for:
Rather than a single classification call, this is framed as an agent ("Complaint Triage Agent") that observes case events, reasons over them, and takes actions within defined tools/permissions — with humans approving anything that affects customer-facing outcomes.
Customer submits case (text/voice-transcript/email/chat)
│
▼
Complaint Triage Agent ◄── monitors: new case, customer reply, SLA timer events
│
│ reasons using: SAMA category taxonomy, escalation rules, case history,
│ similar past cases
│
│ acts via tools:
│ - classify_case() → type/category/subcategory/severity
│ - flag_direct_escalation() → rule 5 (direct L1→SAMA eligible)
│ - detect_dissatisfaction() → rule 2 (customer rejected response)
│ - check_sla_breach() → rule 3/4 triggers
│ - suggest_response() → draft for agent review
│ - summarize_case() → handoff summary for L2/SAMA escalation
│ - request_human_review() → fallback on low confidence
▼
Bank CMS (case created/updated/routed/escalated based on agent's action + human approval where required)
| Rule | Agent behavior |
|---|---|
| 1 | Classifies inquiry/suggestion, confirms no dispute signal → routes for straightforward L1 closure |
| 2 | Monitors customer's reply after L1 response; on dissatisfaction/rejection signal, triggers escalation event |
| 3 | Watches SLA timer per case; on breach, auto-triggers escalation to L2 |
| 4 | On L2 SLA breach or explicit "unresolved" marker, triggers escalation to SAMA |
| 5 | Checks case content/category against direct-escalation list at intake; flags for immediate L1→SAMA path |
request_human_review() instead of acting, so ambiguous cases don't get silently misrouted.| Operation | Direction | Description |
|---|---|---|
POST /cases |
Bank → SAMA | Create a new case record at SAMA when escalated (L1-direct or L2-failure) |
PUT /cases/{id}/status |
Bank → SAMA | Update SAMA on case status changes (e.g., closed at bank before SAMA involvement, if applicable) |
POST /cases/{id}/escalate |
Bank → SAMA | Formal escalation submission with case history and evidence |
GET /cases/{id} |
Bank ← SAMA | Poll/webhook for SAMA's resolution or status update |
POST /webhooks/sama-status |
SAMA → Bank | Push notification when SAMA updates the case (recommended over polling) |
Each payload should include:
Case
Escalation Log
SAMA Sync Record