Skip to content

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