Knowledge API¶
Base path: /api/v1/knowledge
See API Reference for auth, errors, and pagination.
The Knowledge module manages the core institutional memory graph: entries, tags, departments, categories, version history, and entry relationships.
Enumerations¶
source¶
| Value | Description |
|---|---|
manual |
Manually authored (default) |
voice_note |
Captured from a voice note |
slack |
Imported from Slack |
email |
Imported from email |
document |
Imported from a document |
interview |
Captured during an interview |
shift_log |
Captured from a shift log |
status¶
| Value | Description |
|---|---|
active |
Live and discoverable (default) |
archived |
Soft-deleted / hidden |
needs_review |
Flagged for editorial review |
outdated |
Superseded; kept for reference |
confidence¶
| Value | Description |
|---|---|
high |
Highly reliable |
medium |
Moderately reliable (default) |
low |
Uncertain or unverified |
language¶
| Value | Description |
|---|---|
en |
English (default) |
ar |
Arabic |
mixed |
Bilingual content |
visibility¶
| Value | Description |
|---|---|
all |
Visible to everyone in the org (default) |
role |
Restricted to managers and admins |
specific_users |
Visible only to users in visible_user_ids |
When visibility is specific_users, visible_user_ids must be non-empty or the request fails with INVALID_VISIBILITY_CONFIG.
Response Shapes¶
KnowledgeEntryResponse¶
Returned by create, get, update, verify, needs-review, and relate endpoints.
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"title": "How to handle a refund request",
"content": "Full markdown content...",
"source": "manual",
"status": "active",
"confidence": "high",
"language": "en",
"visibility": "all",
"visible_user_ids": [],
"location": "Dubai HQ",
"version": 3,
"department_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"category_id": "c1d2e3f4-a5b6-7890-abcd-ef1234567890",
"created_by": "c0ffee00-dead-beef-cafe-000000000001",
"verified_by": "c0ffee00-dead-beef-cafe-000000000002",
"verified_at": "2026-05-01T10:30:00Z",
"last_reviewed_at": "2026-05-20T08:00:00Z",
"created_at": "2026-04-01T09:00:00Z",
"updated_at": "2026-05-20T08:00:00Z",
"tags": [{ "id": "tag-uuid", "name": "Refunds", "color": "#FF5733", "created_at": "...", "updated_at": "..." }],
"department": { "id": "...", "name": "Customer Support", "description": "...", "created_at": "...", "updated_at": "..." },
"category": { "id": "...", "org_id": "...", "name": "Policies", "description": null, "color": null, "icon": null, "parent_id": null, "sort_order": 0, "is_active": true, "created_at": "...", "updated_at": "..." },
"creator": { "id": "...", "name": "Ali Hassan", "email": "ali@example.com" },
"verifier": { "id": "...", "name": "Sara Ahmed", "email": "sara@example.com" },
"related_entries": [{ "id": "some-uuid", "title": "Refund policy overview" }]
}
KnowledgeEntryListItem¶
Lighter shape for list views — omits content, creator, verifier, related_entries.
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"title": "How to handle a refund request",
"source": "manual",
"status": "active",
"confidence": "high",
"language": "en",
"visibility": "all",
"department_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"category_id": null,
"created_by": "c0ffee00-dead-beef-cafe-000000000001",
"verified_by": null,
"version": 1,
"created_at": "2026-04-01T09:00:00Z",
"updated_at": "2026-04-01T09:00:00Z",
"tags": [],
"department": null,
"category": null
}
VersionResponse¶
{
"id": "ver-uuid",
"entry_id": "entry-uuid",
"version_number": 2,
"title": "Old title before update",
"content": "Old content before update...",
"changed_by": "user-uuid",
"changed_by_name": "Ali Hassan",
"changed_at": "2026-05-10T14:00:00Z",
"change_summary": "Corrected refund window from 14 to 30 days.",
"created_at": "2026-05-10T14:00:00Z"
}
CategoryResponse¶
{
"id": "cat-uuid",
"org_id": "org-uuid",
"name": "Policies",
"description": "Internal policy documents",
"color": "#3B82F6",
"icon": "document",
"parent_id": null,
"sort_order": 0,
"is_active": true,
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
}
Knowledge Entries¶
GET /knowledge/¶
Auth: JWT · Any role · Any plan
Returns a paginated list of knowledge entries scoped to the caller's org. Members only see entries their visibility settings grant access to; managers and above see all entries.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 |
Page number (min 1) |
per_page |
integer | 20 |
Items per page (1–100, clamped) |
department_id |
UUID | — | Filter by department |
tag_ids |
UUID[] | — | Filter by tags — supports repeated params (?tag_ids=x&tag_ids=y) and comma-separated (?tag_ids=x,y) |
status |
string | — | Filter by status enum |
visibility |
string | — | Filter by visibility enum |
language |
string | — | Filter by language enum |
confidence |
string | — | Filter by confidence enum |
search |
string | — | Full-text search across title and content |
Response 200 OK
{
"items": [ /* KnowledgeEntryListItem[] */ ],
"pagination": { "page": 1, "per_page": 20, "total": 150, "total_pages": 8, "has_next": true, "has_prev": false }
}
Errors: 400 VALIDATION_ERROR (invalid UUID params), 401, 402, 403 KNOWLEDGE_ACCESS_DENIED (members filtering by role visibility)
curl -G "https://api.knora.io/api/v1/knowledge/" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "search=refund" \
--data-urlencode "status=active" \
--data-urlencode "tag_ids=tag-uuid-1,tag-uuid-2"
POST /knowledge/¶
Auth: JWT · Any role · Any plan
Creates a new knowledge entry. After creation, on_entry_created is dispatched asynchronously (embeddings, notifications).
Request body
| Field | Type | Required | Constraints |
|---|---|---|---|
title |
string | Yes | 1–500 characters |
content |
string | Yes | Min 1 character |
source |
string | No | source enum; default manual |
department_id |
UUID | No | Must exist in the org |
category_id |
UUID | No | Must exist in the org |
tag_ids |
UUID[] | No | Each must exist in the org; default [] |
visibility |
string | No | visibility enum; default all |
visible_user_ids |
UUID[] | No | Required and non-empty when visibility is specific_users |
status |
string | No | status enum; default active |
confidence |
string | No | confidence enum; default medium |
language |
string | No | language enum; default en |
location |
string | No | Max 255 characters |
Response 201 Created — KnowledgeEntryResponse
Errors: 400 VALIDATION_ERROR, 400 INVALID_VISIBILITY_CONFIG, 401, 402, 404 DEPARTMENT_NOT_FOUND, 404 CATEGORY_NOT_FOUND, 404 TAG_NOT_FOUND
curl -X POST "https://api.knora.io/api/v1/knowledge/" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "How to process a refund", "content": "Open the order, click Refund, confirm amount.", "confidence": "high", "language": "en"}'
GET /knowledge/:entry_id¶
Auth: JWT · Any role · Any plan
Fetches a single entry with all relationships loaded. Visibility rules are enforced for members.
Response 200 OK — KnowledgeEntryResponse
Errors: 401, 402, 403 KNOWLEDGE_ACCESS_DENIED, 404 KNOWLEDGE_ENTRY_NOT_FOUND
curl "https://api.knora.io/api/v1/knowledge/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
-H "Authorization: Bearer $TOKEN"
PUT /knowledge/:entry_id¶
Auth: JWT · Any role (creator, manager, or admin only) · Any plan
Updates one or more fields. Only provided fields are changed. Each call:
- Creates an immutable KnowledgeVersion snapshot of the pre-update state.
- Increments version on the entry.
- Dispatches on_entry_updated asynchronously.
Request body (all fields optional)
| Field | Type | Constraints |
|---|---|---|
title |
string | 1–500 characters |
content |
string | Min 1 character |
source |
string | source enum |
department_id |
UUID | Must exist in org; send null to unset |
category_id |
UUID | Must exist in org; send null to unset |
tag_ids |
UUID[] | Replaces all existing tags |
visibility |
string | visibility enum |
visible_user_ids |
UUID[] | Required when changing to specific_users |
status |
string | status enum |
confidence |
string | confidence enum |
language |
string | language enum |
location |
string | Max 255 characters |
change_summary |
string | Max 1000 characters; stored in the version record |
Response 200 OK — KnowledgeEntryResponse
Errors: 400 VALIDATION_ERROR, 400 INVALID_VISIBILITY_CONFIG, 401, 402, 403 KNOWLEDGE_ACCESS_DENIED, 404 KNOWLEDGE_ENTRY_NOT_FOUND, 404 CATEGORY_NOT_FOUND, 404 TAG_NOT_FOUND
curl -X PUT "https://api.knora.io/api/v1/knowledge/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"confidence": "high", "change_summary": "Verified after Q2 policy review."}'
DELETE /knowledge/:entry_id¶
Auth: JWT · Any role (creator, manager, or admin only) · Any plan
Soft-deletes the entry by setting status to archived. The record and version history are preserved.
Response 200 OK
Errors: 401, 402, 403 KNOWLEDGE_ACCESS_DENIED, 404 KNOWLEDGE_ENTRY_NOT_FOUND
curl -X DELETE "https://api.knora.io/api/v1/knowledge/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
-H "Authorization: Bearer $TOKEN"
POST /knowledge/:entry_id/verify¶
Auth: JWT · manager+ · Any plan
Marks an entry as verified. Records the verifying user and timestamp. Also restores status to active if it was outdated or needs_review. Entries already verified return 409.
Request body (optional)
| Field | Type | Constraints |
|---|---|---|
notes |
string | Max 1000 characters; accepted but not persisted (reserved) |
Response 200 OK — KnowledgeEntryResponse (with verified_by and verified_at populated)
Errors: 401, 402, 403 INSUFFICIENT_ROLE, 404 KNOWLEDGE_ENTRY_NOT_FOUND, 409 KNOWLEDGE_ENTRY_ALREADY_VERIFIED
curl -X POST "https://api.knora.io/api/v1/knowledge/3fa85f64-5717-4562-b3fc-2c963f66afa6/verify" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"notes": "Reviewed in May 2026 policy sync."}'
POST /knowledge/:entry_id/needs-review¶
Auth: JWT · Any role · Any plan
Flags an entry with status: needs_review. Any authenticated user with visibility access can flag.
Request body (optional)
| Field | Type | Constraints |
|---|---|---|
reason |
string | Max 1000 characters; accepted but not persisted (reserved) |
Response 200 OK — KnowledgeEntryResponse (with status: "needs_review")
Errors: 401, 402, 403 KNOWLEDGE_ACCESS_DENIED, 404 KNOWLEDGE_ENTRY_NOT_FOUND
curl -X POST "https://api.knora.io/api/v1/knowledge/3fa85f64-5717-4562-b3fc-2c963f66afa6/needs-review" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"reason": "Policy changed."}'
GET /knowledge/:entry_id/versions¶
Auth: JWT · Any role (visibility-gated) · Any plan
Returns the full version history ordered newest-first. Each version is an immutable snapshot of title and content captured before the update was applied.
Response 200 OK — Array of VersionResponse
Errors: 401, 402, 403 KNOWLEDGE_ACCESS_DENIED, 404 KNOWLEDGE_ENTRY_NOT_FOUND
curl "https://api.knora.io/api/v1/knowledge/3fa85f64-5717-4562-b3fc-2c963f66afa6/versions" \
-H "Authorization: Bearer $TOKEN"
POST /knowledge/:entry_id/relate¶
Auth: JWT · Any role · Any plan
Links two entries. Both must belong to the same org. Self-relation is rejected.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
related_entry_id |
UUID | Yes | Target entry to link |
Response 200 OK — KnowledgeEntryResponse (source entry with updated related_entries)
Errors: 400 VALIDATION_ERROR, 400 SELF_RELATION_NOT_ALLOWED, 401, 402, 403 KNOWLEDGE_ACCESS_DENIED, 404 KNOWLEDGE_ENTRY_NOT_FOUND, 404 RELATED_ENTRY_NOT_FOUND
curl -X POST "https://api.knora.io/api/v1/knowledge/3fa85f64-5717-4562-b3fc-2c963f66afa6/relate" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"related_entry_id": "other-entry-uuid"}'
DELETE /knowledge/:entry_id/relate/:related_id¶
Auth: JWT · Any role · Any plan
Removes the link between two entries.
Response 200 OK — KnowledgeEntryResponse (source entry with updated related_entries)
Errors: 401, 402, 403 KNOWLEDGE_ACCESS_DENIED, 404 KNOWLEDGE_ENTRY_NOT_FOUND, 404 RELATED_ENTRY_NOT_FOUND
curl -X DELETE \
"https://api.knora.io/api/v1/knowledge/3fa85f64-5717-4562-b3fc-2c963f66afa6/relate/other-entry-uuid" \
-H "Authorization: Bearer $TOKEN"
Bulk Operations¶
Both bulk endpoints require the Growth plan (feature flag: knowledge_graph).
POST /knowledge/bulk-import¶
Auth: JWT · Any role · Growth+ (knowledge_graph feature)
Imports an array of entries. Departments and tags are resolved by name — they are created automatically if they do not exist. Per-item failures are skipped and reported in errors; the rest are saved.
Request body
{
"entries": [
{
"title": "Opening procedure for Dubai store",
"content": "1. Unlock the shutters...",
"source": "document",
"department_name": "Operations",
"tag_names": ["Procedures", "Dubai"],
"visibility": "all",
"status": "active",
"confidence": "high",
"language": "en",
"location": "Dubai Mall"
}
]
}
BulkImportItem fields
| Field | Type | Required | Constraints |
|---|---|---|---|
title |
string | Yes | 1–500 characters |
content |
string | Yes | Min 1 character |
source |
string | No | source enum; default manual |
department_name |
string | No | Resolved or created by name |
tag_names |
string[] | No | Each resolved or created by name |
visibility |
string | No | visibility enum; default all |
status |
string | No | status enum; default active |
confidence |
string | No | confidence enum; default medium |
language |
string | No | language enum; default en |
location |
string | No | Free-form location string |
The entries array must contain at least one item.
Response 200 OK
{
"created": 47,
"failed": 2,
"errors": [
{ "index": 3, "title": "Some bad entry", "message": "title: String should have at most 500 characters" }
]
}
Errors: 400 VALIDATION_ERROR (malformed envelope), 401, 402, 403 PLAN_UPGRADE_REQUIRED
curl -X POST "https://api.knora.io/api/v1/knowledge/bulk-import" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"entries": [{"title": "Opening procedure", "content": "Unlock shutters, disable alarm.", "department_name": "Operations", "tag_names": ["Procedures"], "confidence": "high"}]}'
GET /knowledge/export¶
Auth: JWT · Any role · Growth+ (knowledge_graph feature)
Exports all matching entries as a flat JSON array. Same visibility rules as list. Hard-capped at 5000 entries; use the paginated list endpoint for larger datasets.
Query parameters
| Parameter | Type | Description |
|---|---|---|
department_id |
UUID | Filter by department |
tag_ids |
UUID[] | Filter by tags — supports repeated params and comma-separated |
status |
string | Filter by status enum |
language |
string | Filter by language enum |
Response 200 OK
Errors: 400 VALIDATION_ERROR (invalid UUID params), 401, 402, 403 PLAN_UPGRADE_REQUIRED
curl -G "https://api.knora.io/api/v1/knowledge/export" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "status=active" \
--data-urlencode "language=en"
Tags¶
Tags are flat, org-scoped labels applied to entries for categorization and filtering.
GET /knowledge/tags¶
Auth: JWT · Any role · Any plan
Returns all tags for the caller's org.
Response 200 OK — Array of tag objects
[{ "id": "tag-uuid", "name": "Refunds", "color": "#FF5733", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z" }]
Errors: 401, 402
POST /knowledge/tags¶
Auth: JWT · manager+ · Any plan
Creates a tag. Names are unique within an org (case-sensitive).
Request body
| Field | Type | Required | Constraints |
|---|---|---|---|
name |
string | Yes | 1–100 characters; unique within org |
color |
string | No | Hex color #RRGGBB |
Response 201 Created — Tag object
Errors: 400 VALIDATION_ERROR, 401, 402, 403 INSUFFICIENT_ROLE, 409 TAG_ALREADY_EXISTS
curl -X POST "https://api.knora.io/api/v1/knowledge/tags" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Refunds", "color": "#FF5733"}'
DELETE /knowledge/tags/:tag_id¶
Auth: JWT · manager+ · Any plan
Deletes a tag and removes it from all entries (cascade via join table).
Response 200 OK
Errors: 401, 402, 403 INSUFFICIENT_ROLE, 404 TAG_NOT_FOUND
curl -X DELETE "https://api.knora.io/api/v1/knowledge/tags/tag-uuid" \
-H "Authorization: Bearer $TOKEN"
Departments¶
Departments are org-scoped organizational units for grouping and filtering entries.
GET /knowledge/departments¶
Auth: JWT · Any role · Any plan
Returns all departments for the caller's org.
Response 200 OK — Array of department objects
[{ "id": "dept-uuid", "name": "Customer Support", "description": "Handles customer queries", "created_at": "...", "updated_at": "..." }]
Errors: 401, 402
POST /knowledge/departments¶
Auth: JWT · manager+ · Any plan
Creates a department. Names are unique within an org.
Request body
| Field | Type | Required | Constraints |
|---|---|---|---|
name |
string | Yes | 1–255 characters; unique within org |
description |
string | No | Max 2000 characters |
Response 201 Created — Department object
Errors: 400 VALIDATION_ERROR, 401, 402, 403 INSUFFICIENT_ROLE, 409 DEPARTMENT_ALREADY_EXISTS
curl -X POST "https://api.knora.io/api/v1/knowledge/departments" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Customer Support", "description": "Front-line support team."}'
PUT /knowledge/departments/:dept_id¶
Auth: JWT · manager+ · Any plan
Updates a department's name and/or description. Only provided fields are changed.
Request body (all optional)
| Field | Type | Constraints |
|---|---|---|
name |
string | 1–255 characters; unique within org |
description |
string | Max 2000 characters |
Response 200 OK — Department object
Errors: 400 VALIDATION_ERROR, 401, 402, 403 INSUFFICIENT_ROLE, 404 DEPARTMENT_NOT_FOUND, 409 DEPARTMENT_ALREADY_EXISTS
curl -X PUT "https://api.knora.io/api/v1/knowledge/departments/dept-uuid" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Customer Success"}'
POST /knowledge/departments/classify¶
Auth: JWT · manager+ · Any plan
Auto-classifies knowledge entries into departments using AI. When dry_run=true the classification runs synchronously and returns a preview without making any changes. Without dry_run, the task is enqueued and returns 202 Accepted.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
dry_run |
boolean | false |
Run synchronously and preview results without persisting |
Response 200 OK (dry run) — Classification preview object returned by the task
Response 202 Accepted (live run)
Errors: 401, 402, 403 INSUFFICIENT_ROLE
# Preview without changes
curl -X POST "https://api.knora.io/api/v1/knowledge/departments/classify?dry_run=true" \
-H "Authorization: Bearer $TOKEN"
# Enqueue classification
curl -X POST "https://api.knora.io/api/v1/knowledge/departments/classify" \
-H "Authorization: Bearer $TOKEN"
Categories¶
Categories provide a hierarchical (tree) taxonomy for entries. All category endpoints require the Growth plan and the custom_categories feature. Categories support nested structures via parent_id.
GET /knowledge/categories¶
Auth: JWT · Any role · Growth+ (custom_categories feature)
Lists org categories.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
format |
string | flat |
flat — flat array; tree — root nodes with recursive children |
active |
boolean | false |
When true, returns only active categories |
Response 200 OK
format=flat— Array ofCategoryResponseformat=tree— Array ofCategoryTree(each node haschildren: CategoryTree[])
Errors: 401, 402, 403 PLAN_UPGRADE_REQUIRED
curl "https://api.knora.io/api/v1/knowledge/categories?format=tree&active=true" \
-H "Authorization: Bearer $TOKEN"
POST /knowledge/categories¶
Auth: JWT · manager+ · Growth+ (custom_categories feature)
Creates a custom category. Names are unique within the same parent scope.
Request body
| Field | Type | Required | Constraints |
|---|---|---|---|
name |
string | Yes | 1–255 characters; unique under the same parent |
description |
string | No | Max 2000 characters |
color |
string | No | Hex color #RRGGBB |
icon |
string | No | Max 100 characters |
parent_id |
UUID | No | Parent category; must belong to the same org |
sort_order |
integer | No | Non-negative integer; default 0 |
Response 201 Created — CategoryResponse
Errors: 400 VALIDATION_ERROR, 401, 402, 403 INSUFFICIENT_ROLE, 403 PLAN_UPGRADE_REQUIRED, 404 CATEGORY_NOT_FOUND (invalid parent), 409 CATEGORY_ALREADY_EXISTS
curl -X POST "https://api.knora.io/api/v1/knowledge/categories" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Policies", "color": "#3B82F6", "sort_order": 1}'
PUT /knowledge/categories/:id¶
Auth: JWT · manager+ · Growth+ (custom_categories feature)
Updates a category. Reparenting is supported via parent_id; circular references are rejected. Only provided fields are changed.
Request body (all optional)
| Field | Type | Constraints |
|---|---|---|
name |
string | 1–255 characters |
description |
string | Max 2000 characters |
color |
string | Hex color #RRGGBB |
icon |
string | Max 100 characters |
parent_id |
UUID | New parent; must belong to same org; cannot be a descendant of this category |
sort_order |
integer | Non-negative integer |
is_active |
boolean | Activate or deactivate |
Response 200 OK — CategoryResponse
Errors: 400 VALIDATION_ERROR, 400 CATEGORY_CIRCULAR_REFERENCE, 401, 402, 403 INSUFFICIENT_ROLE, 403 PLAN_UPGRADE_REQUIRED, 404 CATEGORY_NOT_FOUND, 409 CATEGORY_ALREADY_EXISTS
curl -X PUT "https://api.knora.io/api/v1/knowledge/categories/cat-uuid" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "HR Policies", "color": "#10B981"}'
DELETE /knowledge/categories/:id¶
Auth: JWT · manager+ · Growth+ (custom_categories feature)
Soft-deactivates a category and all its descendants. Records are preserved.
Response 200 OK
Errors: 401, 402, 403 INSUFFICIENT_ROLE, 403 PLAN_UPGRADE_REQUIRED, 404 CATEGORY_NOT_FOUND
curl -X DELETE "https://api.knora.io/api/v1/knowledge/categories/cat-uuid" \
-H "Authorization: Bearer $TOKEN"
GET /knowledge/categories/:id/path¶
Auth: JWT · Any role · Growth+ (custom_categories feature)
Returns the full ancestor path from the root category down to (and including) the requested category.
Response 200 OK — Ordered array of CategoryResponse (root first)
[
{ "id": "root-uuid", "name": "Company Knowledge", "parent_id": null, ... },
{ "id": "mid-uuid", "name": "HR", "parent_id": "root-uuid", ... },
{ "id": "cat-uuid", "name": "HR Policies", "parent_id": "mid-uuid", ... }
]
Errors: 401, 402, 403 PLAN_UPGRADE_REQUIRED, 404 CATEGORY_NOT_FOUND
curl "https://api.knora.io/api/v1/knowledge/categories/cat-uuid/path" \
-H "Authorization: Bearer $TOKEN"
Notes¶
Versioning — Every PUT /knowledge/:id call creates an immutable version snapshot of the previous state. The optional change_summary field is stored with the record for a human-readable audit trail. Version numbers increment from 1. Retrieve history via GET /knowledge/:id/versions.
Visibility and access — Members only see entries where visibility is all or specific_users with their ID included. role visibility is restricted to managers and above.
Background tasks — on_entry_created and on_entry_updated are Celery tasks dispatched asynchronously. HTTP responses return immediately without waiting for task completion.
Multi-tenancy — All resources (entries, tags, departments, categories, versions) are strictly scoped to the caller's org via the org_id JWT claim. Cross-org access is impossible through these endpoints.
Tag filtering format — tag_ids supports both repeated params (?tag_ids=x&tag_ids=y) and comma-separated values (?tag_ids=x,y). Both formats can be mixed in the same request.