Service desk
Everything that happens between a request landing and a ticket closing — inbound email, AI triage, statuses, SLAs, and the agent console.
Ticket types
Zentra unifies the four ITIL practices on a single underlying record-of-truth, distinguished by ticketType:
- Incident — unplanned interruption or degradation of a service. Restoration is the priority.
- Service request — standard, planned, low-risk work the user is entitled to (access, hardware, software).
- Problem — root cause behind a recurring or significant incident. See Change & problem.
- Change request — planned modification to a service. See Change & problem.
All four share the same lifecycle, SLA model, and agent console; they differ in the workflow and approvals they pull in.
Ticket lifecycle
The status field follows a defined sequence:
| Status | What it means |
|---|---|
new | Just arrived. Background jobs (classify, auto-resolve) haven’t run yet. Not visible in the agent UI. |
processing | AI is working. Not visible in the agent UI. |
open | Ready for an agent. The default state agents see when they open the queue. |
in_progress | An agent is actively working on it. |
escalated | Routed up to supervisor or another team for help. |
resolved | Agent believes the issue is fixed. Awaiting requester confirmation or auto-close. |
closed | Final. No further activity expected. |
The agent UI hides new and processing on purpose — they’re system-managed. Custom statuses (e.g. Awaiting customer, Awaiting vendor) can be configured and marked as on-hold, which pauses SLA timers automatically.
Priority
Tickets carry one of four priorities:
low— non-blocking, can wait.medium— default for most requests.high— affecting one or more users with no workaround.urgent— critical service interruption, major incident, or revenue-impacting issue.
Each priority has its own first-response and resolution SLA. Set defaults in Settings → SLAs.
Intake channels
Today, Zentra accepts new tickets from these channels:
| Channel | How it works |
|---|---|
Inbound email parsed via SendGrid Inbound Parse webhook to /api/webhooks/inbound-email. Replies thread automatically onto the existing ticket. | |
| Customer portal | End-users in role customer sign in and submit requests through the portal UI. Service catalog items create pre-filled requests. |
| Agent console | Agents file tickets on behalf of callers using the New ticket action. |
Slack and Teams are notification channels, not yet inbound channels. A general-purpose webhook intake and a Slack/Teams intake are on the roadmap.
AI classification
When an OpenAI key is configured, every new ticket is processed by the classify-ticket background job within seconds of arrival. The job calls the configured model (default gpt-4o-mini) and assigns one of your tenant’s ticketCategories. The job has retry-with-exponential-backoff (3 attempts, 30 s base) and is skipped silently when no API key is configured.
Auto-resolve
Right after classification, the auto-resolve-ticket job attempts to resolve the request itself. It feeds the request body and your knowledge base to the model and asks for either a customer-ready reply or the literal token ESCALATE.
- If the model returns a reply, it’s posted as an agent reply and the ticket transitions to
resolved. - If the model returns
ESCALATE, the ticket transitions toopenand a human picks it up.
Tune the source knowledge base in Settings → Knowledge base; published articles are surfaced to the model when generating responses.
Routing & assignment
Tickets are routed via the workflow engine. A typical first-pass routing rule:
- If
category = "Network"→ team Network. - If the requester’s
organizationIdmatches an MSP client → team MSP · <Client>. - Otherwise → team Service desk · Tier 1.
See Automation for the trigger / condition / action vocabulary.
SLAs
Every ticket gets two SLA targets calculated at creation: firstResponseDueAt and resolutionDueAt. They’re derived from priority and your configured matrix. The ticket also tracks:
firstRespondedAt— when the first agent reply was posted.resolvedAt— when the ticket transitioned toresolved.slaBreached— flag set when either SLA timer expires.slaPausedAt/slaPausedMinutes— pause window when an on-hold status is active.
Pausing on hold is the right behavior for the vast majority of teams. If you operate strict round-the-clock and don’t want pausing, mark zero of your custom statuses as on-hold.
Agent console
The console is built around speed. Common features:
- Inline reply — public reply or internal note; previous correspondence threaded above.
- Status, priority, category, team, assignee — single-field edits with optimistic UI.
- Knowledge suggestions — relevant published articles surfaced beside the ticket.
- Linked records — attach assets, problems, changes, or other tickets.
- Followers — additional stakeholders kept in the loop on every update.
Refer to the in-product Help overlay for the full and current feature set — it tracks ahead of these docs.
CSAT (customer satisfaction)
When a ticket is closed, an optional CSAT survey is sent to the requester. Each rating is captured on the CsatRating record (1–5 stars + optional comment). Aggregates show average rating, response rate, and positive/negative trend on the analytics dashboard.
Toggle CSAT under Settings → CSAT and customize the prompt and email template.
Customer portal
End-users in role customer see a portal with:
- Their open and recent tickets, with status and last update.
- The service catalog (request a laptop, request access, etc.).
- Public knowledge articles tailored to their group.
End-users sign in via Better Auth (email/password or Google, depending on what’s enabled).
Next
- Automation — auto-route, escalate, run multi-step workflows
- Change & problem — link incidents to root causes and changes
- Webhooks & API — fire outbound webhooks on ticket events