---
summary: "When and how the bot hands off \u2014 triggers (keyword, intent, sentiment,\
  \ confidence, explicit), actions (email, webhook, Slack, queue)."
title: Escalation
path: concepts/escalation
status: published
---

# Escalation

Some questions a bot shouldn't try to answer. Escalation rules let you detect those moments and route the conversation to a human, a system, or both.

## The model

An **escalation rule** has three parts:

- **Trigger** — when the rule fires. One of five types.
- **Action** — what happens when it fires. One of four types.
- **Message** — what the bot says to the visitor at that point.

Rules are evaluated in priority order. Higher priority wins; ties are stable in creation order.

## Trigger types

### `keyword`

Substring or regex match against the visitor's message.

```json
{
  "trigger_type": "keyword",
  "trigger_config": {
    "keywords": ["refund", "chargeback", "billing error"],
    "match_mode": "substring"
  }
}
```

Cheapest trigger (runs before any model call), so good for high-confidence triggers like billing terms.

### `explicit`

Matches when the visitor explicitly asks for a human.

```json
{ "trigger_type": "explicit" }
```

Detects phrasings like "talk to a person", "real human", "agent please". Multi-language; tuned per locale.

### `intent`

Classifies the visitor's message against intent labels you provide.

```json
{
  "trigger_type": "intent",
  "trigger_config": {
    "intents": ["buying-intent", "cancellation-intent"],
    "threshold": 0.7
  }
}
```

Runs a small classifier model — fires before the main chat completion. Costs ~50 tokens per check.

### `sentiment`

Fires when the visitor's recent messages show sustained negative sentiment.

```json
{
  "trigger_type": "sentiment",
  "trigger_config": {
    "threshold": -0.6,
    "window_messages": 3
  }
}
```

Useful as a safety net — if the visitor is getting frustrated, hand off before the experience deteriorates further.

### `confidence`

Fires when the bot's own response carries low confidence — typically because retrieved knowledge was thin or unrelated.

```json
{
  "trigger_type": "confidence",
  "trigger_config": {
    "threshold": 0.5,
    "consecutive_low_turns": 2
  }
}
```

Evaluated *after* generation. The bot says its escalation message instead of the low-confidence response. Helps prevent confident-sounding hallucinations.

## Action types

### `email`

Sends a transcript and a "needs human attention" link to a fixed inbox.

```json
{
  "action_type": "email",
  "action_config": {
    "to": "support@example.com",
    "subject_template": "[ScaiBot escalation] {bot_name} – {trigger_name}"
  }
}
```

### `webhook`

POSTs a JSON payload to your URL. Useful for piping into a CRM, helpdesk, or your own backend.

```json
{
  "action_type": "webhook",
  "action_config": {
    "url": "https://your-crm.example.com/escalations",
    "headers": {"X-Source": "scaibot"},
    "signing_secret": "wh_secret_..."
  }
}
```

The webhook is signed (HMAC-SHA256 over the body, in `X-ScaiBot-Signature`). Verify it the same way you'd verify any ScaiGrid outbound webhook.

### `slack`

Posts a message into a Slack channel via an incoming webhook.

```json
{
  "action_type": "slack",
  "action_config": {
    "webhook_url": "https://hooks.slack.com/services/...",
    "channel_override": "#support-escalations"
  }
}
```

### `scaiqueue`

Enqueues the conversation into a ScaiQueue topic for human-review workflows.

```json
{
  "action_type": "scaiqueue",
  "action_config": {
    "topic": "human-review",
    "priority": 5
  }
}
```

ScaiQueue's typed message channels are the right fit when you want a UI for human reviewers to pick up escalations in order.

## What the visitor sees

The bot replies with the rule's `message`. The widget shows it as a regular assistant message but adds a subtle "escalated to support" badge underneath. Subsequent visitor messages on the same conversation still arrive — you decide on the human side whether to take over the chat (via a separate UI) or close it.

## Patterns

**Cheap-first ordering.** Put keyword and explicit rules at high priority; intent and sentiment at lower priority. You skip the expensive classifier and the model call entirely when the cheap rules match.

**Confidence as a safety net.** Add one `confidence` rule with a moderate threshold and a generic escalation message ("I'm not sure I have a good answer for this — let me get someone who can help.") at the lowest priority. It catches edge cases the other rules miss.

**Sentiment with care.** Sentiment classifiers misfire on irony, frustration *about something else*, and curt-but-not-hostile messages. Use a window of at least 2-3 messages and a strict threshold.

**Webhook actions for everything else.** When in doubt, use a webhook — it's the most flexible. Email and Slack are convenient defaults; ScaiQueue is for serious workflows.
