Helpdesk & Knowledge Base
The helpdesk has two parts: a knowledge base managed with the helpdeskKb tRPC router,
and tickets built on unified-inbox conversations. Both are available in the console at
/manage/helpdesk.
The helpdeskKb router
Knowledge-base articles and their categories are managed with the helpdeskKb router on the
Platform API, called at /api/trpc/helpdeskKb.<procedure> using
the tRPC conventions:
| Procedure | Type | Input | Permission |
|---|---|---|---|
getArticles |
query | filters (optional) | helpdesk:read |
getArticleById |
query | { id } |
helpdesk:read |
createArticle |
mutation | article fields | helpdesk:write |
updateArticle |
mutation | { id, ...fields } |
helpdesk:write |
deleteArticle |
mutation | { id } |
helpdesk:write |
getCategories |
query | none | helpdesk:read |
getCategoryById |
query | { id } |
helpdesk:read |
createCategory |
mutation | category fields | helpdesk:write |
updateCategory |
mutation | { id, ...fields } |
helpdesk:write |
deleteCategory |
mutation | { id } |
helpdesk:write |
Every procedure works on the authenticated user's workspace data. IDs are UUIDs.
Articles
Fields accepted by createArticle (only title is required):
| Field | Type | Default |
|---|---|---|
title |
string, non-empty | |
slug |
string | derived from the title |
excerpt |
string | null |
body |
string | null |
status |
string: draft or published |
draft |
visibility |
string: internal or public |
internal |
categoryId |
string or null |
null |
tags |
string[] | [] |
seoTitle |
string | null |
seoDescription |
string | null |
order |
integer | 0 |
The slug is normalized (lowercased, accents stripped, non-alphanumeric characters replaced
with -, at most 120 characters), whether you pass it or it is derived from the title. It
must be unique within the site.
updateArticle takes a flat object: id plus the fields to change, all optional, and
archived (boolean) to archive or unarchive an article.
getArticles accepts these filters, all optional:
| Filter | Type | Effect |
|---|---|---|
search |
string | Case-insensitive search in the title, excerpt and body. |
status |
string | Filter on status. |
visibility |
string | Filter on visibility. |
categoryId |
string | Filter on category. |
includeArchived |
boolean | Include archived articles (default false). |
The list is sorted by order ascending, then by last update descending. Each item has
id, title, slug, excerpt, status, visibility, categoryId, tags, order,
updatedAt and category ({ id, name }). getArticleById, the create and update
mutations, and deleteArticle return the full article: those fields plus body,
seoTitle, seoDescription, archived, createdAt and the helpfulYes / helpfulNo
vote counters.
Publish a draft:
curl -X POST "https://manage.inklura.fr/api/trpc/helpdeskKb.updateArticle" \
-H "Authorization: Bearer $INKLURA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"json":{"id":"<article-id>","status":"published","visibility":"public"}}'
List the published articles of a category:
curl -G "https://manage.inklura.fr/api/trpc/helpdeskKb.getArticles" \
-H "Authorization: Bearer $INKLURA_TOKEN" \
--data-urlencode 'input={"json":{"status":"published","categoryId":"<category-id>"}}'
Categories
Fields accepted by createCategory (only name is required):
| Field | Type | Default |
|---|---|---|
name |
string, non-empty | |
slug |
string | derived from the name |
description |
string | null |
icon |
string | null |
parentId |
string or null |
null (top-level category) |
order |
integer | 0 |
The slug follows the same rules as for articles. updateCategory also takes a flat object
(id plus the fields to change, and archived).
getCategories returns the non-archived categories, sorted by order, with id, name,
slug, description, icon, parentId and order. getCategoryById adds archived,
createdAt and updatedAt.
Deleting a category does not delete its content: its articles get categoryId: null and
its subcategories get parentId: null.
Errors
| Code | When |
|---|---|
UNAUTHORIZED |
No valid session. |
FORBIDDEN |
The session lacks the helpdesk:read or helpdesk:write permission. |
BAD_REQUEST |
Invalid input (for example an empty title or name, a missing id). |
NOT_FOUND |
getArticleById or getCategoryById with an ID unknown in the workspace. |
INTERNAL_SERVER_ERROR |
Write failure, including a slug already taken in the site, or an update or delete on an unknown ID. |
To model your own relational domain (articles and categories, for example) in an app built on the framework, see Entities.
Tickets
A ticket is a unified-inbox conversation with helpdesk fields added:
- priority (
low,normal,high,urgent;normalby default) - tags
- SLA (first-response and resolution due dates)
- resolution (
solvedorclosed) - customer satisfaction (CSAT: a score and a comment)
The console shows them at /manage/helpdesk/tickets (where /manage/helpdesk lands), next
to the knowledge base (/manage/helpdesk/knowledge-base). A ticket's messages flow through
the inbox like any other conversation; the helpdesk adds the tracking information. These
fields are edited in the console: the helpdeskKb router only covers the knowledge base.
Related
- Entities
- tRPC Procedures: how to call
helpdeskKb.* - Integrations Overview