Skip to content

Docs

Knobs Docs are collaborative rich-text documents. REST covers metadata, sharing, content reads, trash, image assets, and import/export. Live editing does not flow through REST — the apps push CRDT frames over the realtime connection after joining via the open call; a REST client reads materialized content instead.

All routes are workspace-scoped and accept a session JWT or API key. Docs are private by default with per-doc ACLs: a doc you can’t view reads as 404.

Endpoint Description
GET /v1/workspaces/{wid}/docs List docs you can read (?limit=)
POST /v1/workspaces/{wid}/docs Create {title}201 — private to you by default
GET /v1/workspaces/{wid}/docs/{did} Doc metadata + latest snapshot ref (view access)
PATCH /v1/workspaces/{wid}/docs/{did} Exactly one of {title} (rename, edit access), {trash: true}, or {restore: true} (owner/admin)
DELETE /v1/workspaces/{wid}/docs/{did} Permanently purge a trashed doc → 202 {purging: true} (async)
POST /v1/workspaces/{wid}/docs/{did}/open Join for live editing: verifies access, returns metadata + a signed snapshot URL. Used by collaborative clients; plain REST readers don’t need it
GET /v1/workspaces/{wid}/docs/trash List trashed docs
POST /v1/workspaces/{wid}/docs/trash:empty Purge everything in the trash → 202 {purging: n}
Endpoint Description
GET /v1/workspaces/{wid}/docs/{did}/content Materialized document bytes; ?format=html (default) or ?format=md. Serves a strong ETag and honors If-None-Match
Terminal window
curl -H "Authorization: Bearer knak_..." \
"https://api.knobs.io/v1/workspaces/{wid}/docs/{did}/content?format=md"

The response body is the document itself (text/html or text/markdown), not JSON. Heavier formats (DOCX, PDF, …) go through the async export flow below.

The access model is ownerUid + workspaceAccess (none/view/comment/edit, what any workspace member gets) + grants (per-principal levels; principals are user uids or group ids grp_…). Workspace admins/owners implicitly have owner-level access.

Endpoint Description
GET /v1/workspaces/{wid}/docs/{did}/access The sharing panel: {ownerUid, workspaceAccess, grants} (owner or workspace admin)
PUT /v1/workspaces/{wid}/docs/{did}/access Wholesale replace {workspaceAccess, grants} — the owner’s grant is server-maintained and must not appear
Terminal window
curl -X PUT https://api.knobs.io/v1/workspaces/{wid}/docs/{did}/access \
-H "Authorization: Bearer knak_..." \
-H "Content-Type: application/json" \
-d '{"workspaceAccess": "view", "grants": {"u_5ac2…": "edit", "grp_design…": "comment"}}'

Editor images upload directly to storage via a signed URL; the doc references the stable asset id.

Endpoint Description
POST /v1/workspaces/{wid}/docs/{did}/assets Start an upload {mime, size}{assetId, url, headers} — PUT the bytes to url with headers (edit access)
GET /v1/workspaces/{wid}/docs/{did}/assets/{aid} Resolve an asset → {url} (short-lived signed download URL; view access)

Both directions are async jobs. Supported formats include TXT, Markdown, HTML, DOCX, ODT, RTF, and (export-only) PDF.

Endpoint Description
POST /v1/workspaces/{wid}/docs/import Multipart upload (file + optional title) → 202 {job} — the new doc is private to you
GET /v1/workspaces/{wid}/doc-imports/{jid} Import job status → {job} (includes the doc id when done)
POST /v1/workspaces/{wid}/docs/{did}/export Start an export {format}202 {job}
GET /v1/workspaces/{wid}/docs/{did}/exports/{jid} Export job status → {job, url}url is a fresh signed download link once ready
Terminal window
curl -X POST https://api.knobs.io/v1/workspaces/{wid}/docs/import \
-H "Authorization: Bearer knak_..." \
-F "file=@spec.docx" -F "title=Product spec"

Import files are capped at 20 MiB (413 too_large); unsupported types return 400 unsupported_format.

  • Sheets — the same sharing model on workbooks.
  • Taskstasks:create-from-doc source-links a task to a doc.