All endpoints require a valid JWT Bearer token unless otherwise noted.
Authorization: Bearer <access_token>
Returns the hierarchical document tree structure.
Auth Required: Yes (Bearer token)
Response (200):
[
{
"type": "directory",
"name": "security",
"path": "security",
"children": [
{
"type": "document",
"name": "auth-guide.md",
"path": "security/auth-guide.md",
"metadata": { "size": 2048, "modified": "2026-02-20T10:00:00Z", "word_count": 350 }
}
]
}
]Returns aggregate document statistics.
Response (200):
{ "total_directories": 2, "total_documents": 10, "total_subdirectories": 3, "total_words": 5430 }Fetch a single document by path.
Response (200):
{ "path": "security/auth-guide.md", "content": "# Auth Guide\n...", "metadata": { "size": 2048, "modified": "...", "word_count": 350 } }Create a new document.
Request:
{ "path": "guides/new-guide.md", "content": "# New Guide\n\nContent here." }Response (201): Created document object
Update an existing document.
Request:
{ "content": "# Updated content" }Response (200): Updated document object
Delete a document.
Response (200):
{ "message": "Deleted", "path": "guides/old-guide.md" }Search documents by content or filename.
Request:
{ "query": "authentication" }Response (200):
[{ "path": "security/auth-guide.md", "name": "auth-guide.md", "matches": [{ "type": "content", "snippet": "...authentication flow...", "position": 42 }], "metadata": { "size": 2048, "modified": "...", "word_count": 350 } }]Create a new directory.
Request: { "path": "new-category" }
Response (201): {}
Delete an empty directory.
Response (200): {}
Error (400): Directory not empty
List all directories.
Response (200): ["security", "operations"]
Delete multiple documents.
Request: { "paths": ["doc1.md", "doc2.md"] }
Response (200): { "successful": ["doc1.md"], "failed": [] }
Move multiple documents to a target directory.
Request: { "paths": ["doc1.md"], "target_directory": "archive" }
Response (200): { "successful": ["doc1.md"], "failed": [] }
Get category tree with document counts.
Response (200): CategoryNode array
Get per-category statistics with chunk level distribution.
Response (200): CategoryStats array
Route a search query to relevant document categories using LLM.
Request: { "query": "how do I authenticate?" }
Response (200): { "categories": ["security"], "reasoning": "...", "confidence": 0.95 }
Get sync status for all tracked documents (filesystem vs database).
Response (200):
[
{
"file_path": "security/auth-guide.md",
"sync_status": "in_sync",
"filesystem_mtime": "2026-02-20T10:00:00Z",
"database_mtime": "2026-02-20T10:00:00Z",
"chunk_count": 5,
"error_message": null,
"source": "filesystem",
"last_checked": "2026-02-28T12:00:00Z"
}
]Sync Status Values: in_sync, out_of_sync, processing, error, orphaned_chunks, pending_indexing
Get sync status for a single document.
Response (200): Single DocumentSyncInfo object (same shape as array items above)
Manually trigger re-indexing for a single document. Rate limited.
Response (200): Updated DocumentSyncInfo object
Trigger re-indexing for all documents in a directory. Rate limited.
Response (200): Array of DocumentSyncInfo objects
Trigger re-indexing for all documents. Rate limited. Concurrency controlled by SYNC_REINDEX_CONCURRENCY (default 3).
Response (200): Array of DocumentSyncInfo objects
Resolve a conflict between filesystem and database versions of a document. Rate limited.
Request:
{ "strategy": "keep_filesystem" }Strategies: keep_filesystem, keep_database, manual_merge
For manual_merge, include the merged content:
{ "strategy": "manual_merge", "merged_content": "# Merged content\n..." }Response (200): Resolved Document object
Real-time document update notifications via WebSocket.
Auth: Pass JWT token as query parameter: /api/documents/ws?token=<access_token>
Server-sent message types:
sync_status_update— A document's sync status changeddocument_created— A new document was createddocument_updated— A document was modifieddocument_deleted— A document was deletedreindex_complete— A re-indexing operation finished
Message format:
{ "type": "sync_status_update", "data": { "file_path": "docs/guide.md", "sync_status": "in_sync" }, "timestamp": "2026-02-28T12:00:00Z" }- 400 — Validation error (invalid filename, empty content)
- 401 — Unauthorized (missing/expired JWT)
- 404 — Document or directory not found
- 409 — Conflict (filename already exists)
- 429 — Rate limited (100 req/60s per user for mutations)
- 500 — Internal server error