API Overview

Documents

List, open, update, delete, restore, and publicly share vault 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

MethodPathDescription
GET/api/documentsList all documents
POST/api/documents/by-pathOpen a document by file path
PUT/api/documents/:idUpdate document metadata and content
DELETE/api/documents/:idDelete a document
POST/api/documents/:id/restoreRestore a deleted document
GET/api/documents/:id/publicGet 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:

ParameterTypeDescription
includeDeletedbooleanInclude soft-deleted documents. Default: false
projectIdstringFilter by project ID
fileTypestringFilter by type: markdown, text, or binary
searchstringSearch 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:

FieldTypeRequiredDescription
pathstringYesVault-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 Typebodymetadata
markdownMarkdown without frontmatterParsed frontmatter fields
textRaw file contentTitle and tags from DB
binaryEmpty stringTitle 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:

FieldTypeRequiredDescription
titlestringNoNew title
tagsstringNoReplace all tags
projectIdstring or nullNoNew project ID or null to unset
sharedbooleanNoEnable or disable sharing
shareTypestring or nullNopublic or private
bodystringNoNew 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
  }
}
StatusCondition
400Invalid UUID format
403Document exists but shared is false
404Document not found or soft-deleted