Documents
Documents represent files in your vault. They are synced between the filesystem and the database -- the file on disk is the source of truth, and the database stores metadata, content hashes, and sharing settings.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/documents | List all documents |
| POST | /api/documents/by-path | Open a document by file path |
| PUT | /api/documents/:id | Update document metadata and content |
| DELETE | /api/documents/:id | Delete a document |
| POST | /api/documents/:id/restore | Restore a deleted document |
| GET | /api/documents/:id/public | Get a shared document (public access) |
All endpoints except the public viewer require authentication.
List Documents
GET /api/documents
Return all documents (without body content), ordered by last modified date. Includes related project data.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| includeDeleted | boolean | Include soft-deleted documents. Default: false |
| projectId | string | Filter by project ID |
| fileType | string | Filter by type: markdown, text, or binary |
| search | string | Search title, content, and path (case-insensitive, partial match) |
The list endpoint excludes the content field to keep responses lightweight. Use the by-path endpoint to fetch full content.
Response: 200 OK
{
"data": [
{
"id": "doc-123",
"title": "Meeting Notes",
"path": "projects/backend/meeting-notes.md",
"fileType": "markdown",
"shared": false,
"tags": ["meetings"],
"project": { "id": "proj-1", "name": "Backend", "color": "#3b82f6" },
"modifiedAt": "2025-01-07T10:00:00.000Z"
}
]
}
Open Document by Path
POST /api/documents/by-path
Open a document by its vault-relative file path. This endpoint reads the file from disk, parses frontmatter (for markdown files), syncs metadata to the database, and returns the full content.
If the document does not exist in the database, it is created. If the file has changed since the last sync (based on content hash), the database is updated.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| path | string | Yes | Vault-relative file path |
Response: 200 OK
{
"data": {
"document": {
"id": "doc-123",
"title": "Meeting Notes",
"path": "projects/backend/meeting-notes.md",
"fileType": "markdown",
"tags": ["meetings"],
"shared": false
},
"metadata": {
"title": "Meeting Notes",
"tags": ["meetings"],
"shared": false
},
"body": "# Meeting Notes\n\nDiscussed API design..."
}
}
The response shape varies by file type:
| File Type | body | metadata |
|---|---|---|
markdown | Markdown without frontmatter | Parsed frontmatter fields |
text | Raw file content | Title and tags from DB |
binary | Empty string | Title from filename |
Returns 404 if the file does not exist on disk.
Update Document
PUT /api/documents/:id
Update a document's metadata, content, or both. Writes changes to the file on disk and updates the database.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| title | string | No | New title |
| tags | string | No | Replace all tags |
| projectId | string or null | No | New project ID or null to unset |
| shared | boolean | No | Enable or disable sharing |
| shareType | string or null | No | public or private |
| body | string | No | New markdown/text content |
Binary files cannot be edited through this endpoint. Attempting to update a binary document returns 400.
Response: 200 OK
{
"data": {
"document": {
"id": "doc-123",
"title": "Meeting Notes",
"shared": true,
"shareType": "public"
},
"metadata": {
"title": "Meeting Notes",
"tags": ["meetings"],
"shared": true,
"shareType": "public"
},
"body": "# Meeting Notes\n\nUpdated content..."
}
}
Delete Document
DELETE /api/documents/:id
Delete a document. The file is removed from disk and the database record is soft-deleted.
Response: 200 OK
{
"data": {
"id": "doc-123",
"deleted": true
}
}
Restore Document
POST /api/documents/:id/restore
Restore a soft-deleted document. For markdown files with stored content, the file is recreated on disk with its original frontmatter and body.
Returns 400 if the document is not currently deleted.
Response: 200 OK
{
"data": {
"id": "doc-123",
"title": "Meeting Notes",
"deletedAt": null
}
}
Get Public Document
GET /api/documents/:id/public
Retrieve a shared document. This endpoint is publicly accessible -- no authentication required. However, the document must have shared: true to be viewable.
Authentication: Not required (but authenticated users get isOwner: true for their own documents)
Response: 200 OK
{
"data": {
"document": {
"id": "doc-123",
"title": "Meeting Notes",
"path": "projects/backend/meeting-notes.md",
"fileType": "markdown",
"shared": true,
"shareType": "public",
"tags": ["meetings"],
"createdAt": "2025-01-05T08:00:00.000Z",
"modifiedAt": "2025-01-07T10:00:00.000Z",
"creatorName": "Tony"
},
"content": "# Meeting Notes\n\nDiscussed API design...",
"isOwner": false
}
}
| Status | Condition |
|---|---|
400 | Invalid UUID format |
403 | Document exists but shared is false |
404 | Document not found or soft-deleted |