Skip to content

Ticket Escalation Rules

Ticket Escalation Rules

Ticket escalation rules enable automatic escalation of tickets that have been unresolved for too long. This ensures critical tickets receive timely attention and prevents important issues from being overlooked.

Overview

Escalation rules automatically:

  • Monitor ticket age against time thresholds
  • Evaluate conditions to determine if escalation is needed
  • Route tickets to appropriate escalation targets
  • Send notifications through multiple channels
  • Track escalation history on tickets

How Escalation Works

Basic Flow

  1. Rule Configuration - Define escalation rules per priority level
  2. Time Monitoring - System continuously monitors ticket age
  3. Condition Evaluation - When time threshold is reached, check if conditions are met
  4. Escalation Trigger - If conditions match, initiate escalation
  5. Target Assignment - Route ticket to escalation target (manager, team, specific user, or rotation)
  6. Notifications - Send alerts via configured channels (email, SMS, Slack, in-app)
  7. Audit Trail - Increment escalation counter and optionally add internal note

Rule Configuration

Creating an Escalation Rule

const response = await fetch("/api/tickets/escalation-rules", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
name: "Urgent Ticket Escalation",
description: "Escalate urgent tickets after 30 minutes",
enabled: true,
priority: "urgent",
conditions: [
{
field: "status",
operator: "not_equals",
value: "resolved",
},
{
field: "status",
operator: "not_equals",
value: "closed",
},
],
escalateAfterMinutes: 30,
escalateTo: "manager",
notificationChannels: ["email", "slack"],
addInternalNote: true,
internalNoteTemplate:
"Ticket escalated to manager after 30 minutes without resolution",
}),
});

Rule Properties

Basic Configuration

  • name (required) - Descriptive name for the rule
  • description (optional) - Detailed explanation of escalation purpose
  • enabled (required) - Whether the rule is actively monitoring tickets
  • priority (required) - Priority level to apply rule to: urgent, high, medium, low, or all

Time Threshold

  • escalateAfterMinutes (required) - How many minutes before escalation triggers

Common thresholds by priority:

  • Urgent: 30-60 minutes
  • High: 2-4 hours
  • Medium: 8-24 hours
  • Low: 24-48 hours

Conditions

Common escalation conditions:

[
// Don't escalate already resolved/closed tickets
{ "field": "status", "operator": "not_in", "value": ["resolved", "closed"] },
// Only escalate if not already assigned
{ "field": "assignedToUserId", "operator": "equals", "value": null },
// Only escalate specific categories
{ "field": "categoryId", "operator": "equals", "value": 5 }
]

Escalation Target

  • escalateTo (required) - Where to escalate the ticket
TargetDescriptionRequired Fields
managerAssigned user’s managerNone (uses org hierarchy)
teamSpecific teamescalateToTeamId
specific_userSpecific userescalateToUserId
rotationNext in rotationescalateToRotationId

Examples:

// Escalate to manager
{
"escalateTo": "manager"
}
// Escalate to specific team
{
"escalateTo": "team",
"escalateToTeamId": 5
}
// Escalate to specific user
{
"escalateTo": "specific_user",
"escalateToUserId": 123
}
// Escalate to rotation
{
"escalateTo": "rotation",
"escalateToRotationId": 7
}

Notifications

  • notificationChannels (required) - Array of channels to send alerts through

Available channels:

  • email - Email notification
  • sms - SMS text message
  • slack - Slack message
  • in_app - In-app notification
{
"notificationChannels": ["email", "slack", "in_app"]
}

Audit Trail

  • addInternalNote (optional) - Whether to add an internal note to the ticket
  • internalNoteTemplate (optional) - Template for the internal note
{
"addInternalNote": true,
"internalNoteTemplate": "Escalated to {escalation_target} after {minutes} minutes"
}

Template variables:

  • {escalation_target} - Name of escalation target
  • {minutes} - Time elapsed before escalation
  • {priority} - Ticket priority
  • {rule_name} - Name of escalation rule

Priority-Specific Rules

You can create different escalation rules for each priority level, or use priority: 'all' to apply the same rule to all priorities.

Example: Tiered Escalation by Priority

// Urgent tickets - 30 minutes
{
"name": "Urgent Escalation - Level 1",
"priority": "urgent",
"escalateAfterMinutes": 30,
"escalateTo": "team",
"escalateToTeamId": 1,
"notificationChannels": ["email", "sms", "slack"]
}
// High priority - 2 hours
{
"name": "High Priority Escalation",
"priority": "high",
"escalateAfterMinutes": 120,
"escalateTo": "manager",
"notificationChannels": ["email", "slack"]
}
// Medium priority - 24 hours
{
"name": "Medium Priority Escalation",
"priority": "medium",
"escalateAfterMinutes": 1440,
"escalateTo": "team",
"escalateToTeamId": 2,
"notificationChannels": ["email"]
}
// Low priority - 48 hours
{
"name": "Low Priority Escalation",
"priority": "low",
"escalateAfterMinutes": 2880,
"escalateTo": "team",
"escalateToTeamId": 2,
"notificationChannels": ["email"]
}

Multi-Level Escalation

You can create multiple rules for the same priority to implement multi-level escalation.

// Level 1: Escalate to team after 30 minutes
{
"name": "Urgent Escalation - Level 1",
"priority": "urgent",
"escalateAfterMinutes": 30,
"escalateTo": "team",
"escalateToTeamId": 5,
"conditions": [
{"field": "escalationLevel", "operator": "equals", "value": 0}
]
}
// Level 2: Escalate to manager after 60 minutes
{
"name": "Urgent Escalation - Level 2",
"priority": "urgent",
"escalateAfterMinutes": 60,
"escalateTo": "manager",
"conditions": [
{"field": "escalationLevel", "operator": "equals", "value": 1}
]
}
// Level 3: Escalate to director after 90 minutes
{
"name": "Urgent Escalation - Level 3",
"priority": "urgent",
"escalateAfterMinutes": 90,
"escalateTo": "specific_user",
"escalateToUserId": 1, // Director
"notificationChannels": ["email", "sms", "slack"],
"conditions": [
{"field": "escalationLevel", "operator": "equals", "value": 2}
]
}

Escalation Tracking

Each ticket tracks its escalation state:

Ticket Fields

  • escalationLevel - Current escalation level (increments with each escalation)
  • lastEscalatedAt - Timestamp of most recent escalation
  • escalationHistory - JSON array of all escalations

Escalation History Entry

{
"escalatedAt": "2025-11-01T15:30:00Z",
"ruleId": 123,
"ruleName": "Urgent Escalation - Level 1",
"escalatedFrom": 456, // User ID
"escalatedTo": 789, // User ID or Team ID
"escalationType": "team",
"reason": "Ticket unresolved after 30 minutes"
}

Notification Templates

Escalation notifications include comprehensive context about the ticket and escalation.

Email Notification

Subject: [ESCALATION] Urgent Ticket #1234 - Database Connection Issues

Body:

A ticket has been escalated to you.
Ticket #1234
Subject: Database Connection Issues
Priority: Urgent
Status: Open
Created: 2025-11-01 14:30:00
Age: 35 minutes
Escalation Reason: Unresolved after 30 minutes
Escalation Level: 1
Previous Assignee: John Doe
Description:
Production database is experiencing intermittent connection failures...
View Ticket: https://app.pulse.com/tickets/1234

Slack Notification

🚨 *Ticket Escalation*
*Ticket #1234*: Database Connection Issues
*Priority*: 🔴 Urgent
*Age*: 35 minutes
*Status*: Open
Escalated from John Doe after 30 minutes without resolution.
<https://app.pulse.com/tickets/1234|View Ticket>

SMS Notification

ESCALATION: Urgent ticket #1234 assigned to you.
Subject: Database Connection Issues
Age: 35 mins
View: https://app.pulse.com/t/1234

Integration with SLA

Escalation rules work in conjunction with SLA tracking:

  • Escalation thresholds should align with SLA targets
  • Escalate before SLA breach occurs
  • Use SLA “at risk” status to trigger earlier escalations

Example: SLA-Aligned Escalation

// Urgent SLA: 15 min first response, 4 hours resolution
{
"name": "Urgent - First Response SLA Escalation",
"priority": "urgent",
"escalateAfterMinutes": 12, // 80% of 15 min SLA
"conditions": [
{"field": "slaStatus", "operator": "equals", "value": "at_risk"},
{"field": "firstResponseTime", "operator": "equals", "value": null}
],
"escalateTo": "team",
"escalateToTeamId": 1
}

Business Hours Support

Escalation rules can respect business hours:

{
"name": "Business Hours Escalation",
"priority": "high",
"escalateAfterMinutes": 120,
"businessHoursOnly": true, // Only count time during business hours
"escalateTo": "manager"
}

When businessHoursOnly: true:

  • Escalation timer only advances during configured business hours
  • After-hours tickets resume counting when business hours begin
  • Useful for non-urgent tickets that don’t require 24/7 attention

Common Use Cases

1. Simple Priority-Based Escalation

Escalate all urgent tickets to a specific team after 30 minutes:

{
"name": "Urgent Team Escalation",
"priority": "urgent",
"escalateAfterMinutes": 30,
"escalateTo": "team",
"escalateToTeamId": 5,
"notificationChannels": ["email", "slack"]
}

2. Manager Escalation Path

Escalate to the assigned user’s manager:

{
"name": "Manager Escalation Path",
"priority": "high",
"escalateAfterMinutes": 120,
"escalateTo": "manager",
"conditions": [
{"field": "assignedToUserId", "operator": "not_equals", "value": null}
],
"notificationChannels": ["email"]
}

3. Category-Specific Escalation

Escalate security-related tickets more aggressively:

{
"name": "Security Ticket Escalation",
"priority": "all",
"escalateAfterMinutes": 15,
"conditions": [
{"field": "categoryId", "operator": "equals", "value": 7} // Security category
],
"escalateTo": "team",
"escalateToTeamId": 3, // Security team
"notificationChannels": ["email", "sms", "slack"]
}

4. Unassigned Ticket Escalation

Ensure unassigned tickets get attention:

{
"name": "Unassigned Ticket Alert",
"priority": "all",
"escalateAfterMinutes": 60,
"conditions": [
{"field": "assignedToUserId", "operator": "equals", "value": null},
{"field": "status", "operator": "equals", "value": "open"}
],
"escalateTo": "rotation",
"escalateToRotationId": 1,
"notificationChannels": ["slack"]
}

Best Practices

1. Align with SLA Targets

Set escalation thresholds at 70-80% of SLA targets to provide buffer time before breach.

2. Use Multi-Level Escalation

Implement 2-3 escalation levels for critical priorities to ensure issues receive attention.

3. Don’t Over-Escalate

Too many escalations create alert fatigue. Reserve aggressive escalation for truly urgent matters.

4. Test Notification Channels

Verify all notification channels work correctly before enabling rules in production.

5. Monitor Escalation Metrics

Track how often tickets are escalated to identify process bottlenecks.

6. Exclude Resolved Tickets

Always add conditions to prevent escalating already resolved or closed tickets:

"conditions": [
{"field": "status", "operator": "not_in", "value": ["resolved", "closed"]}
]

7. Document Escalation Paths

Clearly document who receives escalations at each level so team members know expectations.

8. Regular Review

Review escalation rules quarterly to ensure thresholds still match business needs.

Permissions

Escalation rules require:

  • Permission.readSupport - View escalation rules
  • Permission.writeSupport - Create, update, delete escalation rules
  • Permission.manageSettings - Modify escalation notification settings

API Endpoints

  • GET /api/tickets/escalation-rules - List all escalation rules
  • POST /api/tickets/escalation-rules - Create new escalation rule
  • GET /api/tickets/escalation-rules/:id - Get rule details
  • PUT /api/tickets/escalation-rules/:id - Update rule
  • DELETE /api/tickets/escalation-rules/:id - Delete rule

Database Schema

ticket_escalation_rules

  • id - Unique identifier
  • accountId - Account ownership
  • name - Rule name
  • description - Rule description
  • enabled - Active status
  • priority - Priority level to apply rule to
  • conditions - JSON array of conditions
  • escalateAfterMinutes - Time threshold
  • escalateTo - Escalation target type
  • escalateToUserId - User ID (if applicable)
  • escalateToTeamId - Team ID (if applicable)
  • escalateToRotationId - Rotation ID (if applicable)
  • notificationChannels - JSON array of channels
  • businessHoursOnly - Whether to count only business hours
  • addInternalNote - Whether to add internal note
  • internalNoteTemplate - Template for internal note
  • createdAt - Creation timestamp
  • updatedAt - Last update timestamp
  • createdBy - User who created the rule
  • updatedBy - User who last updated

Troubleshooting

Escalations not triggering

  1. Check rule is enabled - Verify enabled: true
  2. Verify time threshold - Ensure enough time has passed
  3. Test conditions - Ensure conditions match ticket state
  4. Check business hours - If businessHoursOnly: true, verify current time
  5. Review ticket status - Don’t escalate resolved/closed tickets

Notifications not received

  1. Verify channels configured - Check account notification settings
  2. Test channel integration - Ensure Slack/SMS integrations are working
  3. Check user preferences - Users may have opted out of certain notifications
  4. Review email deliverability - Check spam folders
  5. Verify permissions - Ensure recipient has permission to view ticket

Wrong escalation target

  1. Check target configuration - Verify escalateTo field is correct
  2. Verify IDs - Ensure userIds, teamIds exist and are valid
  3. Test manager hierarchy - Ensure org chart is properly configured
  4. Check rotation status - Verify rotation is active and has members