Capture — Manual Entry API¶
Base path: /api/v1/capture/manual
Manual entry is the simplest knowledge-capture path in Knora. A user writes a title and body directly; the entry is created synchronously and returned immediately — no async processing, no file upload, no external integration required.
See API Reference for auth, errors, and pagination.
POST /api/v1/capture/manual/¶
Auth: JWT required · Plan: Any (all plans including Trial)
Creates a new KnowledgeEntry from user-written content. The entry is persisted synchronously and returned in the response body. source is automatically set to "manual", status defaults to "active", and confidence defaults to "high" (user-authored entries are considered high confidence).
After creation, a background task (on_entry_created) is enqueued to run embedding generation and graph linking asynchronously. The response is returned immediately and does not wait for that task.
Request body
| Field | Type | Required | Constraints | Default | Description |
|---|---|---|---|---|---|
title |
string | Yes | 1–500 characters | — | Entry title. Whitespace is stripped. |
content |
string | Yes | 1+ characters | — | Rich text or Markdown body. Whitespace is stripped. |
tag_ids |
array of UUID strings | No | Must reference existing tags in the org | [] |
Tags to attach to this entry. |
department_id |
UUID string | No | Must reference a valid department in the org | null |
Department this entry belongs to. |
language |
string | No | "en", "ar", "mixed" |
"en" |
Primary language of the content. |
visibility |
string | No | "all", "role", "specific_users" |
"all" |
Access scope for the entry. |
visible_user_ids |
array of UUID strings | Conditional | Required (non-empty) when visibility is "specific_users". All UUIDs must be members of the org. |
[] |
Users with explicit access. |
location |
string | No | Max 255 characters | null |
Geographic or physical location associated with the entry. |
Example — minimal
curl -X POST https://api.knora.io/api/v1/capture/manual/ \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"title": "How to reset the router in Bay 3",
"content": "Power-cycle the router by holding the reset button for 10 seconds."
}'
Example — full options
curl -X POST https://api.knora.io/api/v1/capture/manual/ \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"title": "Shift handover protocol — night to day",
"content": "## Steps\n1. Complete the end-of-shift checklist.\n2. Notify the incoming supervisor.",
"tag_ids": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"],
"department_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"language": "en",
"visibility": "specific_users",
"visible_user_ids": ["d4e5f6a7-b8c9-0123-defa-234567890123"],
"location": "Warehouse B, Bay 3"
}'
Response — 201 Created
Returns the full knowledge entry with relations expanded (tags, department, creator, verifier, related entries).
| Field | Type | Description |
|---|---|---|
id |
UUID string | Entry identifier |
org_id |
UUID string | Owning organisation |
title |
string | Entry title |
content |
string | Entry body |
source |
string | Always "manual" |
created_by |
UUID string or null | User who created the entry |
verified_by |
UUID string or null | null on creation |
verified_at |
ISO 8601 datetime or null | null on creation |
last_reviewed_at |
ISO 8601 datetime or null | null on creation |
department_id |
UUID string or null | Department UUID if assigned |
visibility |
string | "all", "role", or "specific_users" |
visible_user_ids |
array of UUID strings | Populated when visibility is "specific_users" |
status |
string | "active" on creation |
confidence |
string | "high" on creation |
language |
string | "en", "ar", or "mixed" |
location |
string or null | Location if provided |
version |
integer | 1 on creation |
created_at |
ISO 8601 datetime | Creation timestamp |
updated_at |
ISO 8601 datetime | Last update timestamp |
tags |
array of tag objects | Expanded tag objects |
department |
department object or null | Expanded department object |
creator |
user object or null | Expanded creator object |
verifier |
user object or null | null on creation |
related_entries |
array of objects | [] on creation |
{
"id": "f6a7b8c9-d0e1-2345-fabc-456789012345",
"org_id": "11223344-5566-7788-99aa-bbccddeeff00",
"title": "Shift handover protocol — night to day",
"content": "## Steps\n1. Complete the end-of-shift checklist in the ops portal.\n2. Notify the incoming supervisor via the radio channel.\n3. Log any open incidents in the shared tracker.",
"source": "manual",
"created_by": "d4e5f6a7-b8c9-0123-defa-234567890123",
"verified_by": null,
"verified_at": null,
"last_reviewed_at": null,
"department_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"visibility": "specific_users",
"visible_user_ids": [
"d4e5f6a7-b8c9-0123-defa-234567890123",
"e5f6a7b8-c9d0-1234-efab-345678901234"
],
"status": "active",
"confidence": "high",
"language": "en",
"location": "Warehouse B, Bay 3",
"version": 1,
"created_at": "2026-06-01T14:22:00+00:00",
"updated_at": "2026-06-01T14:22:00+00:00",
"tags": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "operations",
"color": "#FF5733",
"created_at": "2025-11-01T09:00:00+00:00",
"updated_at": "2025-11-01T09:00:00+00:00"
}
],
"department": {
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"name": "Logistics",
"description": "Manages warehouse and shipping operations",
"created_at": "2025-09-15T08:00:00+00:00",
"updated_at": "2025-09-15T08:00:00+00:00"
},
"creator": {
"id": "d4e5f6a7-b8c9-0123-defa-234567890123",
"name": "Baraa Al-Rashid",
"email": "baraa@example.com"
},
"verifier": null,
"related_entries": []
}
Errors
| HTTP | Code | Cause |
|---|---|---|
400 |
INVALID_DEPARTMENT |
department_id does not exist or does not belong to this org |
400 |
INVALID_TAGS |
One or more tag_ids not found in this org |
400 |
INVALID_USER_IDS |
One or more visible_user_ids are not members of this org |
400 |
INVALID_VISIBILITY_CONFIG |
visibility is "specific_users" but visible_user_ids is empty |
401 |
AUTHENTICATION_FAILED |
Missing, expired, or malformed JWT |
402 |
SUBSCRIPTION_REQUIRED |
Organisation's subscription is inactive or trial has expired |
403 |
ORG_NOT_FOUND |
The org_id claim in the JWT does not match any organisation |
403 |
MISSING_ORG_CLAIM |
JWT is valid but does not contain an org_id claim |
403 |
INVALID_ORG_CLAIM |
JWT org_id claim is not a valid UUID |
422 |
VALIDATION_ERROR |
Request body fails schema validation (see details array) |
500 |
INTERNAL_ERROR |
Unexpected server-side error |
Enum Reference¶
language¶
| Value | Description |
|---|---|
"en" |
English (default) |
"ar" |
Arabic |
"mixed" |
Bilingual / mixed-language content |
visibility¶
| Value | Description |
|---|---|
"all" |
Visible to every member of the organisation (default) |
"role" |
Visible to users with the matching role |
"specific_users" |
Visible only to users listed in visible_user_ids (at least one required) |
confidence (read-only, set by the API)¶
| Value | Description |
|---|---|
"high" |
User-authored entries (this endpoint) |
"medium" |
AI-extracted content |
"low" |
Low-certainty AI extraction |
status (read-only, set by the API)¶
| Value | Description |
|---|---|
"active" |
Live and searchable (default on creation) |
"archived" |
Archived |
"needs_review" |
Flagged for review |
"outdated" |
Marked outdated |
source (read-only, set by the API)¶
| Value | Set by |
|---|---|
"manual" |
This endpoint |
"voice_note" |
Voice capture module |
"document" |
Document upload module |
"interview" |
Interview flow module |
"shift_log" |
Shift log module |
"slack" |
Slack integration |
"email" |
Email integration |