Workspace API
REST endpoints for notes, kanban boards, and calendar events. All require Authorization: Bearer <token>.
Notes
Mounted at /api/notes. Notes are stored as markdown in SQLite and use delta-based (incremental) updates rather than full overwrites.
| Method | Path | Description |
|---|---|---|
GET | /api/notes | List all notes. Optional ?q= for full-text search across titles and content. |
POST | /api/notes | Create a note. Body: { title, content } |
GET | /api/notes/:id | Get a note by ID. |
POST | /api/notes/:id/delta | Apply incremental delta changes to a note. Used by the rich-text editor for collaborative-style updates. Body: ProseMirror changeset. |
DELETE | /api/notes/:id | Delete a note permanently. |
POST | /api/notes/link-preview | Fetch Open Graph metadata for a URL. Body: { url }. Used by the editor to embed link previews. |
POST | /api/notes/:id/export/docx | Export a note as a .docx file. Returns the file as an attachment download. |
POST | /api/notes/:id/export/pdf | Export a note as a PDF. Returns the file as an attachment download. |
Note: There is no PUT /api/notes/:id endpoint. All updates go through POST /:id/delta which applies incremental changes rather than replacing the full content.
Kanban columns
Mounted at /api/columns. Columns belong to a project (board). Reordering columns uses a dedicated /order endpoint.
Method Path Description GET /api/columns Get all columns (scoped to authenticated user's workspace). POST /api/columns Create a column. Body: { title, projectId } PUT /api/columns/order Update the sort order of columns. Body: { columnIds: ["id1", "id2", ...] } PUT /api/columns/:id Update a column. Body: { title } DELETE /api/columns/:id Delete a column and all its cards.
Kanban cards
Mounted at /api/cards. Cards live inside columns and support checklists and file attachments. Attachment uploads use multipart/form-data.
Method Path Description GET /api/cards/column/:columnId Get all cards in a column, ordered by position. GET /api/cards/:id Get a single card with its checklist and attachments. POST /api/cards Create a card. Accepts multipart/form-data with optional file attachments. Fields: title, columnId, description?, priority?, dueDate? PUT /api/cards/:id Update a card. Body: any subset of card fields (title, description, priority, dueDate, progress). DELETE /api/cards/:id Delete a card and its attachments. POST /api/cards/:id/move Move a card to a different column and/or position. Body: { columnId, position? } PUT /api/cards/:id/checklist Replace the full checklist. Body: { checklist: [{ text, completed }] } POST /api/cards/:id/attachments Upload file attachment(s). multipart/form-data, field name file. Max 10 files, 10 MB each. DELETE /api/cards/:id/attachments/:attachmentId Remove a specific attachment from a card.
Allowed attachment MIME types
Images (PNG, JPEG, GIF, WebP, SVG, BMP), documents (PDF, Word, Excel, PowerPoint), text/code (plain text, HTML, CSS, JS, JSON, XML, CSV), archives (ZIP, RAR, 7z, tar, gzip).
Calendar events
Mounted at /api/events. Events are scoped to the authenticated user. Time fields are ISO 8601 strings. The API accepts several flexible date/time input formats.
Method Path Description GET /api/events List events. Optional ?startDate=ISO&endDate=ISO range filter, ?limit=500&offset=0 pagination. GET /api/events/combined-data Same as list but returns events wrapped in { data: { events } } with totals. Useful for dashboard views. POST /api/events Create an event. See event body below. GET /api/events/:id Get an event by ID. PUT /api/events/:id Update an event. Body: any subset of event fields. DELETE /api/events/:id Delete an event.
Event body
The API accepts flexible date/time formats. Use whichever form is most convenient:
Field Type Required Description titlestring Yes Event title. startTimeISO string Yes* Full ISO datetime. If provided with endTime, used directly. endTimeISO string Yes* Must be after startTime. startDate + startTimestrings Alt Date YYYY-MM-DD + time HH:MM combined on the server. date + start + endstrings Alt Single date with start/end times. descriptionstring No Event notes or agenda. locationstring No Physical or virtual location. colorstring No Color name (e.g. purple, blue). Default: purple. isAllDayboolean No Mark as an all-day event. Default: false.
Example
# Create an event using full ISO datetimes
curl -X POST http://localhost:8716/api/events \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Team sync",
"startTime": "2026-06-01T10:00:00.000Z",
"endTime": "2026-06-01T11:00:00.000Z",
"color": "blue",
"location": "Zoom"
}'