Take a customer issue from open to resolution
The Inbox tickets surface is where a customer issue becomes tracked work: an inbound channel (a phone call disposition, a chat, a help-center form, an operator’s own note) opens a ticket, the operator links it to the contact and thread it came from, drafts a reply with AI assistance, resolves it, and the timestamps land in SLA and resolution reporting. This guide walks one ticket through every state it can hold —open → pending → resolved / wont_fix, plus the reopen path — over the same routes the dashboard buttons post to.
Everything shown here is tenant-owned configuration: your API key, your SLA policies, your knowledge bases, your escalation rules. Reading the queue works with a inbox:read scope; mutating tickets requires an owner, admin, or developer role on the workspace, matching the dashboard’s role gate.
1. The open-to-resolution lifecycle
A ticket is a row with a subject, a status, a priority (low / normal / high / urgent), a type (question / incident / problem / task), an optional contact and conversation linkage, SLA clocks, and an audit-trailed history. Statuses are deliberately small — four values that mirror the helpdesk state machine the API enforces:
open— work has started or is queued. A new ticket arrivesopen.pending— waiting on the customer or a third party; the operator answered and the ball is with the requester.resolved— the issue is answered; the resolution timestamps stamp the SLA clocks. Resolving the ticket closes the work item.wont_fix— deliberately closed without resolution (spam, duplicate, out of scope). Distinct fromresolvedso reports don’t count dropped work as answered.
callback, escalate, unresolved, or customer_request disposition, which fires ticket creation; an operator escalates a chat conversation into a ticket; or an unauthenticated visitor submits the help-center form) and manual (the operator clicks Create ticket on the Inbox → Tickets page, or a partner system POSTs to the internal endpoint). Both land on the same queue with the same shape. The queue-operations guide covers the filters, assignment modes, and SLA attachment mechanics in depth — this page covers the lifecycle path one ticket travels.
The audit trail is part of the lifecycle, not a sidecar. Every status transition, assignment change, and reopen writes a history row that GET /api/v1/inbox/tickets/:id/history returns timeline-ordered, and the same events drive the reopen-rate metric supervisors report against. The dedicated reopen action (POST /tickets/:id/reopen) exists so “reopened from resolved” is measurable separately from a bare status flip back to open — counting reopen rate against first resolution is how you know whether the answer actually held.
2. Worked example A: customer complaint to AI-drafted resolution
A retail customer, Priya, calls to complain that order #58-2214 never arrived. The agent who takes the call can’t resolve it in one pass — it needs a warehouse lookup. This is the canonical lifecycle. Open. The agent dispositions the callescalate on hangup, and the auto-create path opens a ticket with the call’s call_id and the resolved contact already attached. The equivalent explicit create, when the agent files it by hand from the call screen:
tkt_...) in open status. If the inbound channel was a chat instead of a call, the same create accepts conversation_id instead of call_id — one ticket, whichever channel started it.
Link. Two tickets and four conversations about the same order shouldn’t live as separate cases. If a duplicate ticket exists — say the customer also submitted the help-center form — merge it so one thread owns the resolution:
problem ticket — attach a parent edge instead:
send / escalate / end), and source citations when the knowledge base was consulted. Post the operator-approved reply onto the ticket:
open with a reopen timestamp, and the billing question works the same lifecycle a second time.
3. The auto-answer loop: deflection with kb-auto-draft integration
Before a ticket ever needs an operator, high-confidence FAQs can answer themselves. Two autonomous stages run ahead of the operator queue, and both are opt-in tenant settings. Inbound deflection. When an inbound chat or form submission matches a knowledge-base answer above the tenant’s confidence threshold, the auto-deflect loop posts the answer immediately. The negative-sentiment guard keeps the conversation open when the caller is angry — an automatable FAQ with an unhappy customer still gets a human — and a monthly resolution cap and budget pre-check bound how much the loop can spend. The tenant flips the loop on and sets its thresholds through the ticket-deflection configuration; the published stats (GET /api/v1/inbox/deflection/stats) report how many inbound questions the loop resolved without queue time.
Interactive deflect card. On an existing ticket, the operator asks the deflection endpoints (POST /api/v1/inbox/tickets/:id/deflect) for a candidate answer based on the ticket’s question, then accepts the draft as the public reply or escalates it when the candidate is wrong. Accepting stamps the ticket resolved via the same endpoints above; escalating keeps it in the queue with a note on why the automatable answer missed.
Closing the loop with kb-auto-draft. Deflection is only as good as the knowledge base behind it. The kb-auto-draft miner reads unresolved, repetitive question clusters — the ones where deflection attempted and lost — and drafts a new help article from the real conversation excerpts. The article lands in a dedicated pending-approval knowledge base for human review. Operators enable it and bound it per run:
POST /api/v1/knowledge-bases/:id/documents/:docId/approve), and once published the same answer is available to both the deflection loop and the AI draft assistant on the next similar question. That is the loop: unanswered questions become articles, articles become automatic answers, and the operator queue only holds the work that genuinely needs a person.
4. Escalation: when a ticket moves into an escalation runbook
Stay in the tickets queue when the issue is a customer question a support answer resolves — even a long one. Move into an escalation runbook when the issue has crossed into incident territory: the inbox ticket is the how a customer reported it, but the fix belongs to an on-call responder with an SLA of its own. The triggers operators use:- An
incident-type ticket withurgentpriority that is breaching its response SLA, and the breach notify action already reassigned it once — the queue is telling you the queue can’t clear it. - A cluster of tickets linked to one
problemparent (the parent-edge shape from worked example A) — the pattern is a service degradation, not individual complaints. Promote the parent problem ticket to an incident and run the on-call policy on it; the linked incidents stay in the queue as customer-facing status reports. - A ticket that names a platform outage (delivery failures, webhook backlog, provider degradation) — that is never an inbox-resolution shape.
GET/POST /api/v1/inbox/sla/policies), and the on-call runbook that receives the promoted incident is drafted by the on-call roster and escalation policy runbook. Tickets do not migrate themselves — the escalation decision is the operator’s or the breach action’s, and the ticket keeps its own audit trail through it. The SLA escalation policies guide covers the policy-side knobs; the escalation-stack guide covers the responder side.
5. Worked example B: escalation for a breach-prone incident
A workspace reports that WhatsApp deliveries are stalling. Within an hour, six tickets arrive with the same symptom across different channels — help-center form, chat, two phone dispositions. Promote the pattern, link the cases. The first ticket becomes the incident-of-record; the rest merge in as duplicates, then oneproblem ticket parents the incident for the root-cause investigation:
problem ticket stays open until the root cause lands; the customer-facing incidents close as the fix rolls out.
6. Measurement: SLA attainment and resolution-time reporting
Two overlapping measurements cover “did we resolve it in time”: the conversation-side breach report the supervisors run on the Inbox SLA report page, and per-ticket resolution evidence you pull over the tickets API. Per-ticket attainment. Query resolved tickets in a window and compare each ticket’s opened and resolved timestamps against your policy targets. The list endpoint’s filters take the burden:GET /api/v1/inbox/sla/policies) supplies the target it gets judged against. The bulk-export variant delivers the same rows as CSV or JSON with full comments when the review runs offline:
7. Export and handoff: the full thread leaves together
Export. The export endpoint above —GET /api/v1/inbox/tickets/export with format=csv|json and optional include_comments=true — downloads the same filtered queue the operator was looking at, with the full comment thread when requested. That is the handoff payload for a partner helpdesk migration, an audit request, or an offline review. The operation is recorded in the workspace audit log, and the role gates (admin, developer, owner) apply to the mutation-adjacent surfaces — everything on this surface is tenant-owned configuration, not a platform-side lock.
Handoff to Devotel Orbit’s own support. When the ticket is about your Orbit workspace itself — an API 5xx, a deliverability anomaly, a billing question — the receiving side is the workspace’s own support-history surface: Support → Timeline in the dashboard. Opening it from your own organization creates the same kind of tracked work this guide operates on, from the other side of the relationship. The support-timeline guide covers the rows, the search, and the export; the support-timeline-vs-archive guide disambiguates it from your customers’ archived conversation history. The handoff discipline that matters either way: quote the ticket reference from your queue when you open the support request so the threads stay linked — a support response is much faster when the receiving agent can see the exact case rather than a re-described one.
Troubleshooting
- 422 on create or patch. The schemas reject an enum miss (
status: "solved",priority: "critical") or missing required fields. Match the four statuses, four priorities, and four types exactly. - Ticket not linked to the conversation. Create it with
conversation_id(orcall_id) in the body; the auto-create path and the dashboard’s create-from-thread button fill it automatically, the bare API call only if you pass it. - SLA clocks not counting. Attach a policy (
POST /api/v1/inbox/sla/policies) at open time — the platform defaults (4h first response, 24h resolution, business hours) apply only when no policy matches, andbusiness_hours_onlypauses clocks outside your posted hours. See the SLA timers guide. - Re-open metric looks inflated. Switch bare
PATCH status:"open"back-openers to the explicitPOST /tickets/:id/reopen— only the dedicated action stamps the reopen marker that analytics count.
See also
- Operate the Inbox Tickets queue — queue operations, filters, assignment, SLA attachment mechanics.
- Inbox setup — the queue configuration this lifecycle runs on.
- Inbox SLA timers and SLA escalation policies — the clocks behind the measurement.
- Inbox ticket automation — rule-based auto-actions on ticket events.
- On-call roster and escalation runbook — the runbook a breaching incident moves into.
- Support timeline — the receiving surface for handoff to Devotel Orbit support.
- Ticket deflection configuration — the auto-answer loop’s budget and thresholds.