Resolution Codes API
Resolution codes are configurable closing/resolution codes per entity type (ticket, incident, problem) — e.g. FIXED, WORKAROUND, DUPLICATE. They govern closing (RESOLVED/CLOSED): if codes are configured for an entity type, a code is mandatory on the terminal status change. Each code also drives SLA behavior and can be propagated across linked entities during cascading.
Authentication & Permissions
Reading is open to any logged-in user (active codes are needed in the closing dialogs). Listing inactive codes and all write operations require settings.editGeneral. See Permissions & RBAC.
| Action | Permission |
|---|---|
| Read active codes / list | any auth (login) |
| Include inactive codes (?includeInactive) | settings.editGeneral |
| Create / update / deactivate | settings.editGeneral |
User context required (no API key): Create, update and deactivate require a logged-in user. An X-API-Key is rejected with 403 here. GET routes work without settings.editGeneral (login is enough) — except ?includeInactive=true.
Endpoints Overview
| Method | Endpoint | Description | Permission |
|---|---|---|---|
GET | /api/resolution-codes | List (grouped by type or filtered via ?entityType) | any auth |
GET | /api/resolution-codes?entityType=TICKET | Active codes of this type only (array) | any auth |
GET | /api/resolution-codes?includeInactive=true | Incl. inactive codes (settings UI). Revoking the permission takes effect here immediately. | settings.editGeneral |
POST | /api/resolution-codes | Create code (201). An existing code returns 409 RESOLUTION_CODE_EXISTS. | settings.editGeneral |
PATCH | /api/resolution-codes/:id | Update code | settings.editGeneral |
DELETE | /api/resolution-codes/:id | Deactivate (soft delete, isActive=false) → 204. The last active code of a type cannot be deactivated (409 RESOLUTION_CODE_LAST_ACTIVE). | settings.editGeneral |
Without ?entityType, GET / returns an object grouped by type { "TICKET": [...], "INCIDENT": [...], "PROBLEM": [...] }; with ?entityType a flat array. All lists are sorted by sortOrder (ascending).
Fields
| Field | Type | Description |
|---|---|---|
entityType | enum | TICKET, INCIDENT, PROBLEM (required on create, cannot be changed afterwards) |
code | String (1–50) | UPPER_SNAKE_CASE (regex ^[A-Z][A-Z0-9_]*$), unique per entityType. Input is normalized (hyphens/spaces → _). |
label | JSON (i18n) | Localized labels — de and en REQUIRED, fr/es/it optional |
description | JSON? (i18n) | Optional localized description |
isDefault | Boolean | Pre-selected code — only ONE per entityType (setting it unsets the others automatically) |
isActive | Boolean | Active. Soft delete sets false; the last active code cannot be deactivated (409) |
sortOrder | Int | Order in the UI (default 99 on create) |
requiresNote | Boolean | Forces an additional mandatory text field on selection |
requiresLink | Boolean | Forces selecting a master entity (e.g. DUPLICATE → link the original) |
slaBehavior | enum | RESOLVE, CANCEL, EXCLUDE_FROM_REPORTING (default RESOLVE) |
color | String? (≤20) | Badge color in the UI (e.g. green, amber, red) |
Create Code
POST /api/resolution-codes
{
"entityType": "TICKET",
"code": "DUPLICATE",
"label": { "de": "Duplikat", "en": "Duplicate" },
"description": { "de": "Bereits in einem anderen Vorgang erfasst", "en": "Already tracked in another item" },
"isDefault": false,
"sortOrder": 30,
"requiresLink": true,
"slaBehavior": "CANCEL",
"color": "amber"
}
Response (201 Created)
{
"id": "clx...",
"entityType": "TICKET",
"code": "DUPLICATE",
"label": { "de": "Duplikat", "en": "Duplicate" },
"isDefault": false,
"isActive": true,
"sortOrder": 30,
"requiresNote": false,
"requiresLink": true,
"slaBehavior": "CANCEL",
"color": "amber"
}
code is normalized server-side (uppercase, hyphens/spaces → underscore). An already existing code for the same entityType returns 409 Conflict.
Validation & Application (on closing)
On the change to RESOLVED or CLOSED the system checks the code uniformly for tickets, incidents and problems:
- If NO codes are configured for the entity type → the code is optional.
- If codes are configured and the transition is terminal but no code is provided →
400 RESOLUTION_CODE_REQUIRED. - Unknown or deactivated code →
400 INVALID_RESOLUTION_CODE. Both errors carry details with entityType, code and reason. - Valid code → normalized and applied; slaBehavior drives SLA handling, requiresNote/requiresLink make the UI additionally ask for a note or link.
SLA Behavior
slaBehavior |
Effect |
|---|---|
RESOLVE | Normal resolution — SLA counts as met (default) |
CANCEL | SLA is cancelled (e.g. DUPLICATE, not a real resolution) |
EXCLUDE_FROM_REPORTING | Item is excluded from SLA reporting |
Cascading Mapping (problem→incident→ticket)
During cascading and batch resolve, the source entity's resolution code is carried over to the target entity as follows:
- If the same code exists active on the target type → it is reused directly.
- Otherwise → the target type's default code (fallback FIXED if no default).
- The original source code is preserved in the activity for transparency.
See Cascading System and Entity Linking API (batch-resolve, DUPLICATE).
Audit & UI
- Audit: Changes are logged as ADMIN / RESOLUTION_CODE (RESOLUTION_CODE_CREATED / _UPDATED).
- UI: Admin Center → Service Configuration → Resolution Codes (
/admin/resolution-codes)