Files
stack/KNOWLEDGE_API.md
Jason Woltje 955bed91ed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
docs: add knowledge module documentation (closes #80)
- Created KNOWLEDGE_USER_GUIDE.md with comprehensive user documentation
  - Getting started, creating entries, wiki-links
  - Tags and organization, search capabilities
  - Import/export, version history, graph visualization
  - Tips, best practices, and permissions

- Created KNOWLEDGE_API.md with complete REST API reference
  - All endpoints with request/response formats
  - Authentication and permissions
  - Detailed examples with curl and JavaScript
  - Error responses and validation

- Created KNOWLEDGE_DEV.md with developer documentation
  - Architecture overview and module structure
  - Database schema with all models
  - Service layer implementation details
  - Caching strategy and performance
  - Wiki-link parsing and resolution system
  - Testing guide and contribution guidelines

- Updated README.md with Knowledge Module section
  - Feature overview and quick examples
  - Links to detailed documentation
  - Performance metrics
  - Added knowledge management to overview

All documentation includes:
- Real examples from codebase
- Code snippets and API calls
- Best practices and workflows
- Cross-references between docs
2026-01-30 15:18:35 -06:00

31 KiB

Knowledge Module - API Documentation

Complete REST API reference for the Knowledge Module endpoints.

Table of Contents

  1. Authentication
  2. Entry Endpoints
  3. Search Endpoints
  4. Tag Endpoints
  5. Import/Export Endpoints
  6. Stats Endpoints
  7. Cache Endpoints
  8. Error Responses

Authentication

All Knowledge Module endpoints require authentication via Bearer token and workspace context.

Headers

Authorization: Bearer {session_token}
x-workspace-id: {workspace_uuid}

Permission Levels

  • WORKSPACE_ANY: Any workspace member (including GUEST)
  • WORKSPACE_MEMBER: MEMBER role or higher
  • WORKSPACE_ADMIN: ADMIN or OWNER role

Entry Endpoints

List Entries

Get a paginated list of knowledge entries.

GET /api/knowledge/entries

Query Parameters:

Parameter Type Default Description
page integer 1 Page number
limit integer 20 Results per page (max: 100)
status string - Filter by status (DRAFT, PUBLISHED, ARCHIVED)

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/entries?page=1&limit=20&status=PUBLISHED' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "slug": "react-hooks-guide",
      "title": "React Hooks Guide",
      "content": "# React Hooks Guide\n\nComprehensive guide...",
      "contentHtml": "<h1>React Hooks Guide</h1><p>Comprehensive guide...</p>",
      "summary": "Learn about React Hooks",
      "status": "PUBLISHED",
      "visibility": "WORKSPACE",
      "createdAt": "2024-01-29T10:00:00Z",
      "updatedAt": "2024-01-30T15:30:00Z",
      "createdBy": "user-uuid",
      "updatedBy": "user-uuid",
      "tags": [
        {
          "id": "tag-uuid",
          "name": "React",
          "slug": "react",
          "color": "#61dafb"
        }
      ]
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 45,
    "totalPages": 3
  }
}

Get Entry

Retrieve a single knowledge entry by slug.

GET /api/knowledge/entries/:slug

Path Parameters:

Parameter Type Description
slug string Entry slug (e.g., "react-hooks-guide")

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/entries/react-hooks-guide' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "slug": "react-hooks-guide",
  "title": "React Hooks Guide",
  "content": "# React Hooks Guide\n\nUse [[useState]] and [[useEffect]]...",
  "contentHtml": "<h1>React Hooks Guide</h1><p>Use <a>useState</a>...</p>",
  "summary": "Learn about React Hooks",
  "status": "PUBLISHED",
  "visibility": "WORKSPACE",
  "createdAt": "2024-01-29T10:00:00Z",
  "updatedAt": "2024-01-30T15:30:00Z",
  "createdBy": "user-uuid",
  "updatedBy": "user-uuid",
  "tags": [
    {
      "id": "tag-uuid",
      "name": "React",
      "slug": "react",
      "color": "#61dafb"
    }
  ]
}

Create Entry

Create a new knowledge entry.

POST /api/knowledge/entries

Permissions: WORKSPACE_MEMBER

Request Body:

{
  "title": "React Hooks Guide",
  "content": "# React Hooks Guide\n\nContent here...",
  "summary": "Learn about React Hooks",
  "status": "DRAFT",
  "visibility": "WORKSPACE",
  "tags": ["react", "frontend"],
  "changeNote": "Initial draft"
}

Body Schema:

Field Type Required Constraints
title string Yes 1-500 characters
content string Yes Min 1 character
summary string No Max 1000 characters
status enum No DRAFT, PUBLISHED, ARCHIVED (default: DRAFT)
visibility enum No PRIVATE, WORKSPACE, PUBLIC (default: PRIVATE)
tags string[] No Array of tag slugs
changeNote string No Max 500 characters

Example Request:

curl -X POST 'http://localhost:3001/api/knowledge/entries' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "React Hooks Guide",
    "content": "# React Hooks Guide\n\nUse [[useState]] for state...",
    "summary": "Learn about React Hooks",
    "status": "DRAFT",
    "tags": ["react", "frontend"],
    "changeNote": "Initial draft"
  }'

Response:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "slug": "react-hooks-guide",
  "title": "React Hooks Guide",
  "content": "# React Hooks Guide\n\nUse [[useState]] for state...",
  "contentHtml": "<h1>React Hooks Guide</h1><p>Use <a>useState</a>...</p>",
  "summary": "Learn about React Hooks",
  "status": "DRAFT",
  "visibility": "WORKSPACE",
  "createdAt": "2024-01-30T10:00:00Z",
  "updatedAt": "2024-01-30T10:00:00Z",
  "createdBy": "user-uuid",
  "updatedBy": "user-uuid",
  "tags": [
    {
      "id": "tag-uuid",
      "name": "React",
      "slug": "react",
      "color": "#61dafb"
    }
  ]
}

Notes:

  • Slug is auto-generated from title
  • If tags don't exist, they are created automatically
  • Wiki-links in content are automatically parsed and stored
  • First version (version 1) is created automatically

Update Entry

Update an existing knowledge entry.

PUT /api/knowledge/entries/:slug

Path Parameters:

Parameter Type Description
slug string Entry slug

Permissions: WORKSPACE_MEMBER

Request Body:

{
  "title": "React Hooks Guide (Updated)",
  "content": "# React Hooks Guide\n\nUpdated content...",
  "summary": "Updated summary",
  "status": "PUBLISHED",
  "visibility": "WORKSPACE",
  "tags": ["react", "frontend", "tutorial"],
  "changeNote": "Added examples and updated title"
}

All fields are optional. Only provided fields are updated.

Example Request:

curl -X PUT 'http://localhost:3001/api/knowledge/entries/react-hooks-guide' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "PUBLISHED",
    "changeNote": "Ready for publication"
  }'

Response:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "slug": "react-hooks-guide",
  "title": "React Hooks Guide (Updated)",
  "content": "# React Hooks Guide\n\nUpdated content...",
  "contentHtml": "<h1>React Hooks Guide</h1><p>Updated...</p>",
  "summary": "Updated summary",
  "status": "PUBLISHED",
  "visibility": "WORKSPACE",
  "createdAt": "2024-01-30T10:00:00Z",
  "updatedAt": "2024-01-30T12:00:00Z",
  "createdBy": "user-uuid",
  "updatedBy": "user-uuid",
  "tags": [...]
}

Notes:

  • A new version is created on every update
  • Wiki-links are re-parsed and synchronized
  • Cache is invalidated automatically

Delete Entry

Soft-delete (archive) a knowledge entry.

DELETE /api/knowledge/entries/:slug

Path Parameters:

Parameter Type Description
slug string Entry slug

Permissions: WORKSPACE_ADMIN

Example Request:

curl -X DELETE 'http://localhost:3001/api/knowledge/entries/react-hooks-guide' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "message": "Entry archived successfully"
}

Notes:

  • This is a soft delete (sets status to ARCHIVED)
  • Entry remains in database with all versions
  • Links to this entry become unresolved
  • Can be restored by updating status back to DRAFT or PUBLISHED

Get all entries that link to this entry.

GET /api/knowledge/entries/:slug/backlinks

Path Parameters:

Parameter Type Description
slug string Entry slug

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/entries/react-hooks/backlinks' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "entry": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "slug": "react-hooks",
    "title": "React Hooks"
  },
  "backlinks": [
    {
      "id": "link-uuid-1",
      "sourceId": "entry-uuid-1",
      "source": {
        "id": "entry-uuid-1",
        "slug": "frontend-guide",
        "title": "Frontend Development Guide",
        "summary": "Complete frontend guide"
      },
      "linkText": "React Hooks",
      "context": "Learn about [[React Hooks]] for state management.",
      "createdAt": "2024-01-29T10:00:00Z"
    },
    {
      "id": "link-uuid-2",
      "sourceId": "entry-uuid-2",
      "source": {
        "id": "entry-uuid-2",
        "slug": "component-patterns",
        "title": "React Component Patterns",
        "summary": null
      },
      "linkText": "hooks",
      "context": "Modern [[hooks|React hooks]] make state simple.",
      "createdAt": "2024-01-30T08:00:00Z"
    }
  ],
  "count": 2
}

Notes:

  • Only resolved links are included
  • Context shows surrounding text (future feature)
  • Sorted by creation date (newest first)

List Versions

Get version history for an entry.

GET /api/knowledge/entries/:slug/versions

Path Parameters:

Parameter Type Description
slug string Entry slug

Query Parameters:

Parameter Type Default Description
page integer 1 Page number
limit integer 20 Results per page (max: 100)

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/entries/react-hooks-guide/versions?page=1&limit=10' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "data": [
    {
      "id": "version-uuid-3",
      "version": 3,
      "title": "React Hooks Guide",
      "summary": "Learn about React Hooks",
      "changeNote": "Added examples",
      "createdAt": "2024-01-30T15:00:00Z",
      "createdBy": "user-uuid",
      "author": {
        "id": "user-uuid",
        "name": "John Doe",
        "email": "john@example.com"
      }
    },
    {
      "id": "version-uuid-2",
      "version": 2,
      "title": "React Hooks Guide",
      "summary": "Learn about React Hooks",
      "changeNote": "Fixed typos",
      "createdAt": "2024-01-30T12:00:00Z",
      "createdBy": "user-uuid",
      "author": { ... }
    },
    {
      "id": "version-uuid-1",
      "version": 1,
      "title": "React Hooks Guide",
      "summary": null,
      "changeNote": "Initial draft",
      "createdAt": "2024-01-30T10:00:00Z",
      "createdBy": "user-uuid",
      "author": { ... }
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 3,
    "totalPages": 1
  }
}

Notes:

  • Versions sorted newest first
  • Content is NOT included (use Get Version endpoint for full content)
  • First version has changeNote from creation

Get Version

Get complete content for a specific version.

GET /api/knowledge/entries/:slug/versions/:version

Path Parameters:

Parameter Type Description
slug string Entry slug
version integer Version number

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/entries/react-hooks-guide/versions/2' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "id": "version-uuid-2",
  "entryId": "entry-uuid",
  "version": 2,
  "title": "React Hooks Guide",
  "content": "# React Hooks Guide\n\nOld content...",
  "summary": "Learn about React Hooks",
  "changeNote": "Fixed typos",
  "createdAt": "2024-01-30T12:00:00Z",
  "createdBy": "user-uuid",
  "author": {
    "id": "user-uuid",
    "name": "John Doe",
    "email": "john@example.com"
  }
}

Notes:

  • Includes full content as it existed in that version
  • Use this to preview before restoring

Restore Version

Restore an entry to a previous version.

POST /api/knowledge/entries/:slug/restore/:version

Path Parameters:

Parameter Type Description
slug string Entry slug
version integer Version number to restore

Permissions: WORKSPACE_MEMBER

Request Body:

{
  "changeNote": "Restored version 2 - reverted bad changes"
}
Field Type Required Constraints
changeNote string Yes Max 500 characters

Example Request:

curl -X POST 'http://localhost:3001/api/knowledge/entries/react-hooks-guide/restore/2' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "changeNote": "Restored version 2 - reverted bad changes"
  }'

Response:

{
  "id": "entry-uuid",
  "slug": "react-hooks-guide",
  "title": "React Hooks Guide",
  "content": "# React Hooks Guide\n\nRestored content...",
  "summary": "Learn about React Hooks",
  "status": "PUBLISHED",
  "visibility": "WORKSPACE",
  "createdAt": "2024-01-30T10:00:00Z",
  "updatedAt": "2024-01-30T16:00:00Z",
  "createdBy": "user-uuid",
  "updatedBy": "current-user-uuid",
  "tags": [...]
}

Notes:

  • Creates a new version (e.g., version 4) with content from the specified version
  • Original versions remain untouched (no history rewriting)
  • Change note is required to document why you restored
  • Wiki-links are re-parsed from the restored content

Search Endpoints

Search across entry titles and content.

GET /api/knowledge/search

Query Parameters:

Parameter Type Required Default Description
q string Yes - Search query
status enum No - DRAFT, PUBLISHED, ARCHIVED
page integer No 1 Page number
limit integer No 20 Results per page (max: 100)

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/search?q=react+hooks&page=1&limit=10' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "data": [
    {
      "id": "entry-uuid",
      "slug": "react-hooks-guide",
      "title": "React Hooks Guide",
      "content": "# React Hooks Guide\n\nContent...",
      "summary": "Learn about React Hooks",
      "status": "PUBLISHED",
      "visibility": "WORKSPACE",
      "createdAt": "2024-01-30T10:00:00Z",
      "updatedAt": "2024-01-30T12:00:00Z",
      "createdBy": "user-uuid",
      "updatedBy": "user-uuid",
      "tags": [...]
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 5,
    "totalPages": 1
  }
}

Search behavior:

  • Searches both title and content fields
  • Case-insensitive
  • Partial word matching
  • Relevance-ranked results

Search by Tags

Find entries with specific tags.

GET /api/knowledge/search/by-tags

Query Parameters:

Parameter Type Required Default Description
tags string Yes - Comma-separated tag slugs
status enum No - DRAFT, PUBLISHED, ARCHIVED
page integer No 1 Page number
limit integer No 20 Results per page (max: 100)

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/search/by-tags?tags=react,frontend&status=PUBLISHED' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

Same format as Full-Text Search response.

Notes:

  • Finds entries with ALL specified tags (AND logic)
  • For OR logic, make separate requests

Recent Entries

Get recently modified entries.

GET /api/knowledge/search/recent

Query Parameters:

Parameter Type Default Description
limit integer 10 Number of entries (max: 50)
status enum - DRAFT, PUBLISHED, ARCHIVED

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/search/recent?limit=5&status=PUBLISHED' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "data": [
    {
      "id": "entry-uuid",
      "slug": "react-hooks-guide",
      "title": "React Hooks Guide",
      "summary": "Learn about React Hooks",
      "status": "PUBLISHED",
      "updatedAt": "2024-01-30T16:00:00Z",
      "tags": [...]
    }
  ],
  "count": 5
}

Notes:

  • Sorted by updatedAt descending (newest first)
  • Does not include full content (use Get Entry for details)

Tag Endpoints

List Tags

Get all tags in the workspace.

GET /api/knowledge/tags

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/tags' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

[
  {
    "id": "tag-uuid-1",
    "name": "React",
    "slug": "react",
    "color": "#61dafb",
    "description": "React library and ecosystem"
  },
  {
    "id": "tag-uuid-2",
    "name": "Frontend",
    "slug": "frontend",
    "color": "#3b82f6",
    "description": null
  }
]

Get Tag

Get a single tag by slug.

GET /api/knowledge/tags/:slug

Path Parameters:

Parameter Type Description
slug string Tag slug

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/tags/react' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "id": "tag-uuid",
  "name": "React",
  "slug": "react",
  "color": "#61dafb",
  "description": "React library and ecosystem"
}

Create Tag

Create a new tag.

POST /api/knowledge/tags

Permissions: WORKSPACE_MEMBER

Request Body:

{
  "name": "TypeScript",
  "color": "#3178c6",
  "description": "TypeScript language and tooling"
}
Field Type Required Constraints
name string Yes Unique per workspace
color string No Hex color (e.g., "#3178c6")
description string No -

Example Request:

curl -X POST 'http://localhost:3001/api/knowledge/tags' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "TypeScript",
    "color": "#3178c6"
  }'

Response:

{
  "id": "new-tag-uuid",
  "name": "TypeScript",
  "slug": "typescript",
  "color": "#3178c6",
  "description": null
}

Notes:

  • Slug is auto-generated from name
  • Tags are workspace-scoped (same slug can exist in different workspaces)

Update Tag

Update an existing tag.

PUT /api/knowledge/tags/:slug

Path Parameters:

Parameter Type Description
slug string Tag slug

Permissions: WORKSPACE_MEMBER

Request Body:

All fields are optional. Only provided fields are updated.

{
  "name": "TypeScript (Updated)",
  "color": "#2f74c0",
  "description": "TypeScript programming language"
}

Example Request:

curl -X PUT 'http://localhost:3001/api/knowledge/tags/typescript' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "color": "#2f74c0"
  }'

Response:

{
  "id": "tag-uuid",
  "name": "TypeScript (Updated)",
  "slug": "typescript",
  "color": "#2f74c0",
  "description": "TypeScript programming language"
}

Delete Tag

Delete a tag (removes from all entries).

DELETE /api/knowledge/tags/:slug

Path Parameters:

Parameter Type Description
slug string Tag slug

Permissions: WORKSPACE_ADMIN

Example Request:

curl -X DELETE 'http://localhost:3001/api/knowledge/tags/typescript' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

204 No Content

Notes:

  • Tag is removed from all entries that used it
  • Entries themselves are NOT deleted

Get Tag Entries

Get all entries with a specific tag.

GET /api/knowledge/tags/:slug/entries

Path Parameters:

Parameter Type Description
slug string Tag slug

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/tags/react/entries' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

[
  {
    "id": "entry-uuid-1",
    "slug": "react-hooks-guide",
    "title": "React Hooks Guide",
    "summary": "Learn about React Hooks",
    "status": "PUBLISHED",
    "createdAt": "2024-01-30T10:00:00Z",
    "updatedAt": "2024-01-30T12:00:00Z"
  },
  {
    "id": "entry-uuid-2",
    "slug": "component-patterns",
    "title": "React Component Patterns",
    "summary": null,
    "status": "PUBLISHED",
    "createdAt": "2024-01-29T08:00:00Z",
    "updatedAt": "2024-01-29T09:00:00Z"
  }
]

Import/Export Endpoints

Export Entries

Export knowledge entries as a downloadable archive.

GET /api/knowledge/export

Query Parameters:

Parameter Type Default Description
format enum markdown Export format: markdown or json
entryIds string[] - Optional array of entry IDs to export

Permissions: WORKSPACE_ANY

Example Requests:

Export all entries as Markdown:

curl -X GET 'http://localhost:3001/api/knowledge/export?format=markdown' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID" \
  -o knowledge-export.zip

Export specific entries as JSON:

curl -X GET 'http://localhost:3001/api/knowledge/export?format=json&entryIds[]=uuid1&entryIds[]=uuid2' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID" \
  -o knowledge-export.zip

Response:

Binary .zip file with headers:

Content-Type: application/zip
Content-Disposition: attachment; filename="knowledge-export-YYYYMMDD-HHMMSS.zip"

Markdown format structure:

knowledge-export.zip
├── react-hooks-guide.md
├── component-patterns.md
└── state-management.md

Each .md file:

---
slug: react-hooks-guide
title: React Hooks Guide
status: PUBLISHED
visibility: WORKSPACE
tags: react, frontend
createdAt: 2024-01-30T10:00:00Z
updatedAt: 2024-01-30T12:00:00Z
---

# React Hooks Guide

Content with [[wiki-links]]...

JSON format structure:

knowledge-export.zip
└── entries.json

entries.json:

[
  {
    "slug": "react-hooks-guide",
    "title": "React Hooks Guide",
    "content": "# React Hooks Guide\n\nContent...",
    "summary": "Learn about React Hooks",
    "status": "PUBLISHED",
    "visibility": "WORKSPACE",
    "tags": ["react", "frontend"],
    "createdAt": "2024-01-30T10:00:00Z",
    "updatedAt": "2024-01-30T12:00:00Z"
  }
]

Import Entries

Import knowledge entries from uploaded file.

POST /api/knowledge/import

Permissions: WORKSPACE_MEMBER

Request:

Multipart form data with file upload.

curl -X POST 'http://localhost:3001/api/knowledge/import' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID" \
  -F "file=@knowledge-export.zip"

Supported file types:

  • .md (single Markdown file)
  • .zip (archive of Markdown files)

File size limit: 50MB

Response:

{
  "success": true,
  "totalFiles": 10,
  "imported": 8,
  "failed": 2,
  "results": [
    {
      "filename": "react-hooks.md",
      "success": true,
      "entryId": "new-entry-uuid",
      "slug": "react-hooks"
    },
    {
      "filename": "invalid-entry.md",
      "success": false,
      "error": "Title is required"
    }
  ]
}

Import behavior:

  • New entries created with status DRAFT
  • Existing entries (matching slug) are skipped
  • Tags created automatically if they don't exist
  • Wiki-links preserved (will resolve if targets exist)

Front matter parsing:

The importer reads YAML front matter:

---
slug: custom-slug
title: Entry Title
summary: Optional summary
status: PUBLISHED
visibility: WORKSPACE
tags: tag1, tag2
---

Content starts here...

If no front matter, slug is generated from filename.


Stats Endpoints

Get Statistics

Get knowledge base statistics for the workspace.

GET /api/knowledge/stats

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/stats' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "totalEntries": 42,
  "entriesByStatus": {
    "DRAFT": 5,
    "PUBLISHED": 35,
    "ARCHIVED": 2
  },
  "totalTags": 12,
  "totalLinks": 87,
  "totalVersions": 215,
  "averageVersionsPerEntry": 5.1,
  "topTags": [
    {
      "id": "tag-uuid",
      "name": "React",
      "slug": "react",
      "count": 15
    },
    {
      "id": "tag-uuid",
      "name": "Frontend",
      "slug": "frontend",
      "count": 12
    }
  ],
  "mostLinkedEntries": [
    {
      "id": "entry-uuid",
      "slug": "react-hooks",
      "title": "React Hooks",
      "incomingLinkCount": 8
    }
  ],
  "recentActivity": {
    "last24h": 5,
    "last7days": 18,
    "last30days": 42
  }
}

Cache Endpoints

Get Cache Stats

Get cache performance statistics.

GET /api/knowledge/cache/stats

Permissions: WORKSPACE_ANY

Example Request:

curl -X GET 'http://localhost:3001/api/knowledge/cache/stats' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "enabled": true,
  "stats": {
    "hits": 1250,
    "misses": 180,
    "sets": 195,
    "deletes": 15,
    "hitRate": 0.874
  }
}

Stats explanation:

  • hits: Cache hits (data found in cache)
  • misses: Cache misses (data not in cache, fetched from DB)
  • sets: Cache writes
  • deletes: Cache invalidations
  • hitRate: Percentage of requests served from cache (hits / (hits + misses))

Clear Cache

Clear all cached data for the workspace.

POST /api/knowledge/cache/clear

Permissions: WORKSPACE_ADMIN

Example Request:

curl -X POST 'http://localhost:3001/api/knowledge/cache/clear' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "message": "Cache cleared successfully"
}

Notes:

  • Clears ALL knowledge caches for the workspace
  • Includes entry caches, search caches, and graph caches
  • Does not affect other workspaces

Reset Cache Stats

Reset cache statistics counters to zero.

POST /api/knowledge/cache/stats/reset

Permissions: WORKSPACE_ADMIN

Example Request:

curl -X POST 'http://localhost:3001/api/knowledge/cache/stats/reset' \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "x-workspace-id: WORKSPACE_ID"

Response:

{
  "message": "Cache statistics reset successfully"
}

Error Responses

All endpoints follow standard HTTP error codes and return JSON error objects.

Error Format

{
  "statusCode": 404,
  "message": "Entry not found",
  "error": "Not Found"
}

Common Status Codes

Code Meaning Example
400 Bad Request Invalid request body, missing required field
401 Unauthorized Missing or invalid auth token
403 Forbidden Insufficient permissions for action
404 Not Found Entry, tag, or version doesn't exist
409 Conflict Slug already exists, duplicate entry
413 Payload Too Large Import file exceeds 50MB limit
422 Unprocessable Entity Validation failed (e.g., invalid enum value)
500 Internal Server Error Unexpected server error

Validation Errors

When validation fails, you get detailed error information:

{
  "statusCode": 422,
  "message": [
    "title must not be empty",
    "title must not exceed 500 characters",
    "status must be a valid EntryStatus"
  ],
  "error": "Unprocessable Entity"
}

JavaScript Examples

Using Fetch API

const API_URL = 'http://localhost:3001/api';
const token = 'YOUR_SESSION_TOKEN';
const workspaceId = 'YOUR_WORKSPACE_ID';

const headers = {
  'Authorization': `Bearer ${token}`,
  'x-workspace-id': workspaceId,
  'Content-Type': 'application/json'
};

// Create entry
async function createEntry() {
  const response = await fetch(`${API_URL}/knowledge/entries`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      title: 'My New Entry',
      content: '# Hello World\n\nThis is my first [[wiki-link]]!',
      tags: ['tutorial'],
      status: 'DRAFT'
    })
  });
  
  if (!response.ok) {
    throw new Error(`Failed: ${response.status}`);
  }
  
  return await response.json();
}

// Search entries
async function searchEntries(query) {
  const params = new URLSearchParams({ q: query, limit: 10 });
  const response = await fetch(`${API_URL}/knowledge/search?${params}`, {
    headers
  });
  
  return await response.json();
}

// Export entries
async function exportEntries() {
  const response = await fetch(`${API_URL}/knowledge/export?format=markdown`, {
    headers
  });
  
  const blob = await response.blob();
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'knowledge-export.zip';
  a.click();
}

Using Axios

import axios from 'axios';

const api = axios.create({
  baseURL: 'http://localhost:3001/api',
  headers: {
    'Authorization': `Bearer ${token}`,
    'x-workspace-id': workspaceId
  }
});

// Get entry
const entry = await api.get('/knowledge/entries/react-hooks');
console.log(entry.data);

// Update entry
const updated = await api.put('/knowledge/entries/react-hooks', {
  status: 'PUBLISHED',
  changeNote: 'Ready for publication'
});

// Import file
const formData = new FormData();
formData.append('file', fileInput.files[0]);
const result = await api.post('/knowledge/import', formData, {
  headers: { 'Content-Type': 'multipart/form-data' }
});

Next Steps


Happy building! 🚀