Files
nvrl 9363a0024d navigation: the list by name outside the diary, Ctrl-P goes to anything by its name, new things land beside what they belong to
The list is folders first and then by name in every space but the diary,
which stays a journal by day; a document's row elsewhere shows when it
was last edited. Ctrl-P is a jump by name across every space, served by
GET /api/jump: the last word is looked for in the name, the ones before
along the path. / is the one full-text search, and Tab on its line takes
it to every space and back. A card's notes are made in the folder being
browsed when that is in the card's space, and a missing [[link]]'s
document beside the one linking to it. o in a space with templates opens
the line as :new with them listed.
2026-10-22 17:39:24 +02:00

67 lines
6.3 KiB
Markdown

<!-- Generated by scripts/wiki.ts from the API section of README.md. Edit that, then run `make wiki`. -->
# API
Everything except the login, the health check and the two share routes
requires the session cookie; `/api/capture` takes a token instead. Media answers `Range` requests, so a video seeks,
sealed or not.
| method | path | purpose |
| --- | --- | --- |
| `GET` | `/api/health` | public: up, and the database answers — for a supervisor |
| `POST` | `/api/login`, `/api/logout` | session; `/api/logout?everywhere=true` ends every one |
| `GET` | `/api/me` | current user |
| `GET` | `/api/sessions` | every signed-in browser, the one seen last first |
| `DELETE` | `/api/sessions/{id}` | sign another browser out, and lock the vault |
| `GET`/`POST` | `/api/spaces` | the spaces / create one |
| `GET`/`POST` | `/api/nodes` | children (`?parent=`) or search (`?q=`, `?space=`; a file matched by its text has `in_text` and the words around the match as `excerpt`, each matched word between U+0002 and U+0003) / create, from a template with `template_id` |
| `GET`/`PUT`/`DELETE` | `/api/nodes/{id}` | read / update only the fields sent — `name`, `body`, `created_at`, `has_board`; with `base_updated_at`, refused with `409` once it was saved since / delete into the trash, subtree and all — or for good, for something already in it |
| `GET`/`DELETE` | `/api/trash` | what was deleted, the last first / empty it |
| `DELETE` | `/api/trash/{id}` | delete one thing in the trash for good |
| `POST` | `/api/trash/{id}/restore` | back where it was deleted from, or to its space when that folder is gone |
| `GET` | `/api/spaces/{id}/board` | the lists and cards of one space |
| `GET` | `/api/agenda` | open cards due within a week or in hand, on every board, whether the diary has today, its entries `on_this_day` in earlier years, and `today` in `WORKSPACE_TIMEZONE`, with its bounds |
| `GET` | `/api/diary/days?month=2026-10` | the diary's entries in a month, each with its local `day` |
| `POST` | `/api/diary/day` | `{ day? }`: the entry of `2026-10-22`, or of today in `WORKSPACE_TIMEZONE`, started from `templates/day` when there is none; answers `{ id, created }` |
| `GET` | `/api/diary/around/{id}` | the entries before and after a diary entry, by date |
| `GET` | `/api/nodes/{id}/templates` | the templates of the space the node is in |
| `POST` | `/api/capture` | `{ text, to: "card" \| "diary" \| "note" \| "document", space?, document?, note? }`, with a session or `Authorization: Bearer` a token; `note` is a scratch note the text came from, dropped once it has landed |
| `GET`/`POST` | `/api/tokens` | the capture tokens / make one, `{ name }`, answered with the token this once |
| `DELETE` | `/api/tokens/{id}` | remove a capture token |
| `POST` | `/api/spaces/{id}/lists` | add a list |
| `PUT`/`DELETE` | `/api/lists/{id}` | rename / delete a list and its cards |
| `POST` | `/api/lists/{id}/cards` | add a card |
| `PUT`/`DELETE` | `/api/cards/{id}` | update (title, body, due, repeat, checklist, labels, done, link) / delete; finishing a repeating card answers its copy as `again` |
| `POST` | `/api/cards/{id}/move` | to another list and place in it; `again` as above |
| `GET` | `/api/cards?q=…` | cards whose title, summary or a checklist step matches, open ones first; `space` keeps it to one board |
| `GET`/`POST` | `/api/scratch` | the scratchpad's notes, the one touched last first, or with `?q=` those a search finds / a new note `{ body }` |
| `PUT`/`DELETE` | `/api/scratch/{id}` | rewrite a note `{ body }` / drop it |
| `POST` | `/api/nodes/{id}/move` | reparent, and place among the new siblings |
| `POST` | `/api/nodes/move` | `{ ids, parent_id }`: several into one folder, all or none |
| `POST` | `/api/nodes/{id}/import` | import a folder or zip (multipart) under this node |
| `POST` | `/api/import` | import an export at the root: directories become spaces |
| `GET` | `/api/resolve?path=` | the node behind a slug path, `work/notes/monday` |
| `GET` | `/api/jump?q=` | `Ctrl-P`: the nodes in every space whose name holds the last word and whose path holds the ones before, best first, each with its `location` |
| `GET` | `/api/nodes/{id}/revisions` | a document's earlier versions, the newest first |
| `GET` | `/api/nodes/{id}/revisions/{rev}` | one earlier version, with its text |
| `GET` | `/api/nodes/{id}/backlinks` | the documents that link to this one, with the line each does it on |
| `GET` | `/api/nodes/{id}/cards` | the cards about this document: its own (`node_id`) and the ones whose summary links here — also in the node itself as `cards` |
| `POST`/`DELETE` | `/api/nodes/{id}/share` | mint or rotate / revoke a share link |
| `GET` | `/api/export` | the whole workspace, boards and dates included, as a zip |
| `GET`/`POST` | `/api/backup` | Proton Drive mirror: status / run now |
| `POST`/`DELETE` | `/api/backup/login` | log the mirror in to Proton, body `{"username","password"}` / forget its session |
| `POST` | `/api/backup/login/totp`, `/api/backup/login/captcha` | the two-factor code `{"code"}`, or the solved human check `{"token"}`, a waiting login asked for |
| `GET` | `/api/media/{id}` | serve a file's bytes (with `Range`) |
| `POST` | `/api/typst` | `{source}` of a ` ```typst ` block → `{svg}`, or `{error}` as typst words it |
| `GET` | `/api/spaces/overview` | every space with what was last written in it |
| `POST` | `/api/nodes/{id}/files` | upload files (multipart) into a space or folder, or to a document as its own; `?encrypt=true` seals them, and a sealed folder always does |
| `POST` | `/api/nodes/{id}/inspect` | what a certificate, key or keystore file holds (`{password}` opens a protected one) |
| `POST` | `/api/nodes/{id}/encrypt`, `/decrypt` | seal a file, or a folder for good — what is in it and what lands later — or take it out |
| `GET`/`POST`/`PUT` | `/api/vault` | status / set the password once / change it |
| `POST` | `/api/vault/unlock`, `/api/vault/lock` | open / close the vault |
| `GET`/`POST` | `/api/ssh-keys` | the keys that may mount over SFTP / add one |
| `DELETE` | `/api/ssh-keys/{id}` | remove a key, which ends its mounts |
| `POST` | `/api/share/{token}` | public: read a shared document, body `{"key"}`; sets the share's media cookie |
| `GET` | `/api/share/{token}/media/{id}` | public: media inside a shared document, with that cookie |
| `POST` | `/api/share/{token}/typst` | public: a typst block the shared document holds, with that cookie |