Tickets
TICKETING — PAID PLUGINBuilt-in ITIL-style incident and request tracking. Every ticket has a state machine, a priority, an audit trail, and an optional SLA timer. Workflows are GitOps-declared in Helm values — there is no in-app editor.
What is a ticket
A ticket is the unit of work in ITOps. It can be opened by a user from the UI, automatically created when a monitored service flips to DOWN, or pushed in via the GraphQL API. Each ticket carries a title, description, priority, assignee, status, optional SLA target, and a chronological audit log of every state change.
Tickets are scoped to the Ticketing plugin: the plugin is enabled per-installation by the license, and can be toggled at runtime via the togglePlugin GraphQL mutation. When disabled, ticket-related menus disappear from the sidebar; when enabled, the existing data is preserved.
Lifecycle — the state machine
Every ticket moves through a fixed set of states:
OPEN -> IN_PROGRESS -> RESOLVED -> CLOSED
^_________________|
(re-open if the fix did not stick)
OPEN— just created. No one is actively working on it yet.IN_PROGRESS— an assignee has picked it up. The SLA response timer stops here.RESOLVED— the assignee believes the issue is fixed and is waiting for the requester to confirm. The SLA resolution timer stops here.CLOSED— the requester (or the system, after a grace period) confirms. The ticket becomes immutable except for comments.
Allowed transitions are restricted by the configured workflow (see Default Workflows). Anything outside the allowed transitions is rejected with a 403 forbidden_transition error and never silently accepted.
Priority
Four levels, mapped to colours in the UI and to default SLA targets when the ticket is opened from a catalog item:
| Priority | Default response | Default resolution | Typical use |
|---|---|---|---|
CRITICAL | 5 min | 2 h | Production outage, payment system down |
HIGH | 30 min | 8 h | Major degradation, big customer impact |
MEDIUM | 2 h | 1 day | Standard request, single-user impact |
LOW | 1 day | 5 days | Nice-to-have, cosmetic, internal |
The defaults above are baked into the plugin and overridable per catalog item (see Service Catalog).
Workflow — GitOps declared
There is no graphical workflow editor in the UI. Workflows live in Helm values, get applied on chart upgrade, and are versioned in Git like everything else. This is intentional: workflows are infrastructure, not user data, so they belong with the rest of your configuration.
ticketing:
enabled: true
workflows:
- name: incident_response
displayName: "Incident Response"
transitions:
- {from: OPEN, to: IN_PROGRESS, role: assignee}
- {from: IN_PROGRESS, to: RESOLVED, role: assignee}
- {from: RESOLVED, to: CLOSED, role: requester}
- {from: RESOLVED, to: IN_PROGRESS, role: any}
Each transition declares who is allowed to perform it (assignee, requester, or any). On chart upgrade the platform reconciles the declared workflows against the database: new workflows are added, existing ones updated in place, and tickets that reference a removed workflow keep their last known transitions but cannot transition further until a matching workflow is re-declared.
For the full set of 5 default workflows shipped with the plugin see Default Workflows.
How tickets are created
Three entry points, all funnelled through the same backend creation path:
- From a catalog item — user picks a card on the “New ticket” page, optionally edits one or two fields (title, description), and submits. Priority, group, workflow, SLA target are pre-filled from the catalog item. This is the recommended path. See Service Catalog.
- From an empty form — for ad-hoc tickets that do not map to a known category. The user fills every field manually.
- Auto-created on outage — when a service with
autoTicket: trueflips toDOWN, the operator creates aCRITICALticket assigned to the service’s SLA group. The ticket is auto-closed when the service recovers, unless an operator has interacted with it in the meantime.
Audit trail
Every state change, assignee change, and comment is recorded in ticket_status_history with a timestamp, the actor (user ID or system for auto-events), the old value, and the new value. The history is rendered as a timeline on the ticket detail page, and is exported to YAML by /api/v1/templates/export for backup.
The history table is append-only — rows cannot be edited or deleted via the API, only via direct database access (which is itself logged at the platform level).
Example — ticket payload
A typical ticket fetched via GraphQL:
{
"data": {
"ticket": {
"id": "tk_4f8e29",
"title": "Payment API returning 503",
"description": "Stripe webhook timing out, /v1/charge 503 since 14:02 CET.",
"status": "IN_PROGRESS",
"priority": "CRITICAL",
"workflow": "incident_response",
"requester": {"id": "u_b1", "name": "Anna K."},
"assignee": {"id": "u_c4", "name": "Marton P."},
"assigneeGroup": "payment-team",
"sla": {
"responseDueAt": "2026-04-28T14:07:00Z",
"resolutionDueAt": "2026-04-28T16:02:00Z",
"responseBreached": false,
"resolutionBreached": false
},
"createdAt": "2026-04-28T14:03:00Z",
"updatedAt": "2026-04-28T14:05:21Z",
"history": [
{"at": "2026-04-28T14:03:00Z", "actor": "system", "from": null, "to": "OPEN"},
{"at": "2026-04-28T14:05:21Z", "actor": "u_c4", "from": "OPEN", "to": "IN_PROGRESS"}
]
}
}
}
See also
- Default Workflows — the 5 built-in state-machine variants and when to use each.
- GitOps Setup — how to declare workflows + catalog as Helm values.
- Service Catalog — pre-filled ticket templates declared in YAML.
- SLA Portal PAID — how the public status page surfaces incident tickets.
- API reference — full GraphQL schema for ticket queries and mutations.