Eviworx
Docs

Response Templates API

The Response Templates API manages canned responses (text snippets) that agents insert in the ticket composer. Templates are multilingual (de/en/fr/es/it) and have a scope (PERSONAL / AGENT_GROUP / ORGANIZATION) that drives visibility and management rights. Mount: /api/response-templates.

💬
Features
✓ Three scopes (PERSONAL, AGENT_GROUP, ORGANIZATION)
✓ Multilingual (de/en/fr/es/it)
✓ Picker list (visible and active)
✓ Management list (GET /manage)
✓ Category grouping, sorted by name
✓ Body up to 5000 characters per language
✓ Activate and deactivate (isActive)
✓ Soft delete

🔐 Auth: Logged-in users only — API keys get 403, since personal templates are bound to a user. The rights required for a change depend on the template's scope (PERSONAL → manageOwn and owner, shared → manageShared). See RBAC →.

Endpoints

Method Endpoint Description Permission
GET/api/response-templatesPicker list (visible + active); query search/category → { data }use
GET/api/response-templates/manageManagement list → { data }manageOwnmanageShared
POST/api/response-templatesCreate (201)per scope
PATCH/api/response-templates/:idUpdateper scope
PATCH/api/response-templates/:id/activeActivate/deactivate { isActive } → 204per scope
DELETE/api/response-templates/:idSoft-delete → 204per scope

GET / returns templates insertable in the composer (visible by scope, only isActive). GET /manage returns manageable templates: manageShared sees all shared (ORGANIZATION + AGENT_GROUP) plus own PERSONAL; manageOwn-only sees just own PERSONAL. For changes, per scope: PERSONAL requires manageOwn AND ownership, ORGANIZATION/AGENT_GROUP require manageShared.

Response Shape

Both lists return the templates under data — without page numbers, because the set stays small per user and is delivered in full. The picker list sorts by category, then name; the management list puts the scope first. POST and PATCH :id return the object bare, the two remaining mutations answer 204 with no body.

{
  "data": [
    {
      "id": "clx-tpl-ack",
      "name": "Acknowledgement",
      "category": "General",
      "scope": "ORGANIZATION",
      "ownerId": null,
      "agentGroupId": null,
      "isActive": true,
      "translations": {
        "de": { "body": "Vielen Dank für Ihre Anfrage. Wir kümmern uns darum." },
        "en": { "body": "Thank you for your request. We are on it." }
      },
      "agentGroup": null
    }
  ]
}

ownerId is set only for PERSONAL — that is how the picker recognises your own templates. For scope AGENT_GROUP, agentGroup carries the target group with id, name and isArchived; templates of archived groups stay visible in management (with a note) and disappear from the picker.

Scopes

ScopeVisible toRequired field
PERSONALowner onlyownerId (set by the server: the logged-in user)
AGENT_GROUPactive members of the AgentGroupagentGroupId
ORGANIZATIONall agents with responseTemplates.use

Create Template

POST /api/response-templates
{
  "name": "Acknowledgement",
  "category": "General",
  "scope": "ORGANIZATION",
  "isActive": true,
  "translations": {
    "de": { "body": "Vielen Dank für Ihre Anfrage. Wir kümmern uns darum." },
    "en": { "body": "Thank you for your request. We are on it." }
  }
}
// scope AGENT_GROUP — agentGroupId required:{
  "name": "Network Standard Reply",
  "scope": "AGENT_GROUP",
  "agentGroupId": "clx-group-network",
  "translations": { "de": { "body": "Bitte starten Sie zunächst Ihren Router neu …" } }
}

Fields: name (1–120), category? (max 60, empty string → null), scope (default PERSONAL), agentGroupId (required only for AGENT_GROUP, forbidden otherwise), translations (record of de/en/fr/es/it → { body 1–5000 }, at least 1 language), isActive (default true). ownerId is always set by the server (the logged-in user). The body is validated strictly: an unknown field is a 400 — so a typo in a field name surfaces immediately instead of being silently ignored. The same applies to the query of GET / (only search, max 200 characters, and category).

Update Template

PATCH /api/response-templates/:id
{ "name": "Acknowledgement (short)", "translations": { "de": { "body": "…" } } }

⚠️ scope cannot be changed on update, because that would change the template's owner and visibility. A GROUP↔ORG move = delete + recreate. An agentGroupId change within AGENT_GROUP is allowed. A PATCH with empty translations is rejected (at least 1 language).

Use in the Ticket Composer

Templates are inserted into the ticket reply composer via the picker (GET /). Since the per-language body limit equals the ticket message limit (5000 chars), the picker checks the combined length (existing text + template) on insert; if it is too long, nothing is inserted and a notice is shown instead of truncating.

🎫 Ticket messages and reply flow: Tickets API →.

Error codes

StatuserrorCodeMeaning
400AGENT_GROUP_NOT_ACTIVETarget group missing, inactive or archived (details names agentGroupId)
400RESPONSE_TEMPLATE_SCOPE_MISMATCHagentGroupId on a template whose scope has no group
403FORBIDDENRight for the scope missing; also for API key calls
404RESPONSE_TEMPLATE_NOT_FOUNDTemplate does not exist or is not visible to the caller
410RESPONSE_TEMPLATE_DELETEDVisible template has been deleted

🔒 A personal template belonging to someone else answers every change with 404, not 403: a 403 would confirm that the template exists. Personal templates therefore stay invisible even to managers holding manageShared.

Permissions (responseTemplates)

PermissionDescription
responseTemplates.useUse the picker (read + insert visible templates)
responseTemplates.manageOwnCreate/edit/delete own PERSONAL templates
responseTemplates.manageSharedManage ORGANIZATION + AGENT_GROUP templates
Related Pages
Tickets API →

Composer inserts templates into ticket replies

Email Signatures API →

Signatures (separate from text snippets)

Users & Groups API →

AgentGroups for scope AGENT_GROUP

RBAC →

responseTemplates.* rights