Tickets

Track, prioritize, and resolve customer issues with the ticket system.

Overview

Tickets provide a structured way to track customer issues that need follow-up beyond a single conversation. Unlike live chat conversations, tickets have a defined lifecycle with statuses, priorities, and assignees — making them ideal for issues that require investigation, collaboration, or async resolution.

Creating Tickets

Tickets can be created in three ways:

1. From the Tickets page

Click New Ticket in the tickets section to create a ticket manually. Fill in the subject, description, priority, and optionally assign it to an agent.

2. Converted from a conversation

While viewing a conversation in the inbox, click Convert to Ticket to create a ticket linked to that conversation. The conversation thread is preserved as context — agents can reference the original messages while working the ticket.

💡Converting a conversation to a ticket doesn't close the conversation. Both can remain active simultaneously. The ticket gains a link to the source conversation for context.

3. Offline visitor submissions

When visitors submit the offline form in the widget (no agents available), a ticket is automatically created with the visitor's subject, message, and contact info. These appear in the Unassigned filter.

Ticket Fields

FieldTypeDescription
referenceNumberstringAuto-generated (e.g., ZT-1042). Unique, sequential, human-readable.
subjectstringBrief summary of the issue (required)
descriptionstringDetailed explanation of the problem or request
statusenumCurrent lifecycle state (see Status Workflow below)
priorityenumlow, medium, high, urgent
assigneeIdstring | nullThe agent responsible for resolving this ticket
createdAtdatetimeWhen the ticket was created
resolved_atdatetime | nullWhen the ticket was moved to Resolved status. Null if still open.

Status Workflow

Tickets follow a linear status progression with the ability to reopen:

Status transitions
Open → In Progress → Resolved → Closed
  ↑         ↑                |
  └─────────┴── Reopen ──────┘
StatusMeaningAllowed Transitions
OpenNew ticket, not yet being worked on→ In Progress, → Resolved
In ProgressActively being investigated or worked on→ Resolved, → Open (back to queue)
ResolvedSolution delivered, awaiting confirmation→ Closed, → Open (reopen)
ClosedFully resolved and archived→ Open (reopen)

When a ticket transitions to Resolved, the resolved_at timestamp is recorded. If the ticket is later reopened, resolved_at is cleared. This field is useful for measuring resolution time in reporting.

Filtering and Search

The tickets list supports filtering by multiple dimensions. Filters can be combined and are preserved in the URL for bookmarking or sharing with teammates.

FilterOptions
StatusOpen, In Progress, Resolved, Closed (multi-select)
PriorityLow, Medium, High, Urgent (multi-select)
AssigneeAny agent, Unassigned, or a specific agent

Additionally, a text search searches across ticket subject, description, and reference number.

Ticket Detail View

Clicking a ticket opens its detail view with:

  • Header: Reference number, subject, status badge, priority badge
  • Description: Full description text
  • Activity feed: All status changes, assignment changes, and comments in chronological order
  • Comments: Agents can add comments to discuss the ticket internally
  • Linked conversation: If converted from a conversation, a link to the original thread
  • Actions: Change status, reassign, update priority

Ticket via API

Tickets can also be managed programmatically:

Create a ticket via API
curl -X POST https://api.zapticket.app/api/tickets \
  -H "Authorization: Bearer zt_sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Cannot reset password",
    "description": "User reports the reset email never arrives.",
    "priority": "high",
    "assigneeId": "agent_abc123"
  }'
Update ticket status
curl -X PATCH https://api.zapticket.app/api/tickets/tkt_8f3a2b1c \
  -H "Authorization: Bearer zt_sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "resolved" }'