Statuses & Workflows
Configure ticket statuses to match your support workflow. Start with the built-in system statuses and add custom ones as your process evolves.
System Statuses
Every brand starts with four system statuses that cannot be deleted. They represent the fundamental stages of a ticket's lifecycle:
| Status | Key | Color | Meaning |
|---|---|---|---|
| Open | open | Blue (#3b82f6) | New ticket awaiting attention |
| Pending | pending | Amber (#f59e0b) | Waiting on customer or external input |
| Resolved | resolved | Green (#22c55e) | Issue addressed, awaiting confirmation |
| Closed | closed | Green (#22c55e) | Ticket finalized, no further action |
System statuses can be renamed and recolored but not deleted. Their keys (open, pending, resolved, closed) remain constant for API compatibility.
Custom Statuses
Add custom statuses to model workflows beyond the basics. Custom statuses slot between the system statuses and can be reordered freely.
Examples
- In Progress - Agent is actively working on the ticket
- Waiting on Engineering - Escalated to the dev team
- Scheduled - Issue will be addressed in a future release
- On Hold - Paused, waiting for external dependency
- Needs Review - Requires manager or QA approval
const status = await dispatch.statuses.create('br_abc123', {
name: 'In Progress',
key: 'in_progress', // Unique identifier, lowercase with underscores
color: '#8b5cf6', // Purple
description: 'Agent is actively working on this ticket',
});
console.log(status.id); // 'sts_xyz789'Status Properties
| Field | Required | Description |
|---|---|---|
| name | Yes | Display name shown in the UI |
| key | Yes | Unique identifier (lowercase, underscores). Immutable after creation. |
| color | No | Hex color for badges and indicators (default: #6b7280) |
| description | No | Internal description for your team |
Status Lifecycle
There are no enforced transition rules. A ticket can move from any status to any other status. This keeps the system flexible for different workflows.
Typical Flow
Open ──→ In Progress ──→ Resolved ──→ Closed
│ │ │
│ ▼ │
│ Waiting on Eng │
│ │ │
└────────── ─┴───── Pending ─┘
│
▼
(customer replies → reopens to Open)When a ticket moves to a new status, the change is recorded in the ticket's activity log and watchers are notified. If the ticket has a webhook configured, a ticket.updated event is fired with the status change in the changes field.
await dispatch.tickets.update('br_abc123', 'tkt_def456', {
statusId: 'sts_xyz789', // Use status ID
});
// Or use the status key for system statuses
await dispatch.tickets.update('br_abc123', 'tkt_def456', {
status: 'resolved',
});Active vs. Inactive Statuses
Statuses are grouped into two categories for filtering:
- Active - Tickets that need attention (open, pending, and custom statuses)
- Inactive - Tickets that are done (resolved, closed)
The dashboard's default view shows active tickets. Use the status filter to include resolved or closed tickets.
Managing Statuses
Via the Dashboard
Go to Settings → Brand → Statuses to view, create, edit, and reorder statuses. Drag-and-drop to set the order they appear in dropdowns and filters.
Via the API
const statuses = await dispatch.statuses.list('br_abc123');
// Returns system + custom statuses in display order
statuses.forEach(s => {
console.log(`${s.name} (${s.key}) - ${s.isSystem ? 'system' : 'custom'}`);
});// Set display order for all statuses
await dispatch.statuses.reorder('br_abc123', {
statusIds: [
'sts_open',
'sts_in_progress',
'sts_pending',
'sts_waiting_eng',
'sts_resolved',
'sts_closed',
],
});const stats = await dispatch.statuses.stats('br_abc123');
// Returns: [{ statusId, statusName, count }, ...]
stats.forEach(s => {
console.log(`${s.statusName}: ${s.count} tickets`);
});Deleting Custom Statuses
When you delete a custom status, you must specify a replacement status for any tickets that currently have it. System statuses cannot be deleted.
Deleting a status is permanent. All tickets with that status will be moved to the replacement status you choose.
Automations
Dispatch Tickets includes built-in automations that update ticket status based on activity:
Auto-Reopen on Customer Reply
When a customer replies to a resolved or closed ticket (via email or portal), the ticket automatically reopens to open. This ensures customer follow-ups don't get missed.
Webhook-Based Workflows
For more complex automations, use webhooks to listen for status changes and trigger custom logic:
// Example: Auto-assign tickets based on category
app.post('/webhooks/dispatch', (req, res) => {
const event = req.body;
if (event.type === 'ticket.created') {
const { ticket } = event.data;
// Route billing tickets to the billing team
if (ticket.category?.key === 'billing') {
dispatch.tickets.update(ticket.brandId, ticket.id, {
assigneeEmail: '[email protected]',
status: 'in_progress',
});
}
}
res.status(200).send('OK');
});Integration Triggers
Combine status changes with external integrations:
- Notify Slack when a ticket moves to "Waiting on Engineering"
- Create a Jira issue when priority is set to "urgent"
- Send a satisfaction survey when a ticket is resolved
- Update your CRM when a ticket is closed