Basalt docs
GitHub

Collaboration

Comments, page history, activity, notifications, attachments and the workspace symbol library.

26 operations. Every path is relative to the instance origin; every response body is JSON unless stated. See API for authentication, errors and pagination.

POST /api/v1/workspaces/{workspaceId}/attachments

Upload an image attachment (multipart/form-data, one file field; image/* only, 10 MiB max). Send a pageId field naming the page the image goes on: it requires edit there and decides who may read the bytes afterwards. Omit it only for an icon — that uploads workspace-scoped (member+), readable by every member. Returns the attachment DTO whose url is a relative same-origin serve path.

uploadAttachment · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required

Response 200application/json

  • id · string (uuid) — required
  • url · string — required
  • filename · string — required
  • mime · string — required
  • sizeBytes · integer — required, 0–9007199254740991

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

GET /api/v1/workspaces/{workspaceId}/attachments/{attachmentId}

Stream an attachment's bytes with its stored Content-Type and a long immutable Cache-Control (ids are stable). Workspace-scoped; auth + membership guarded. Served as an image, not JSON — use as an <img src>.

getAttachment · token scope: content:read

Path parameters

  • workspaceId · string (uuid) — required
  • attachmentId · string (uuid) — required

Response 200application/json

  • string

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

GET /api/v1/workspaces/{workspaceId}/symbols

The workspace's named symbols, newest first. Readable by every member — an entry only names bytes that are already workspace-scoped.

listSymbols · token scope: session only

Path parameters

  • workspaceId · string (uuid) — required

Response 200application/json

  • items · object[] — required
    • id · string (uuid) — required
    • name · string — required
    • attachmentId · string (uuid) — required
    • url · string — required
    • mime · string — required
    • createdAt · string (date-time) — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

POST /api/v1/workspaces/{workspaceId}/symbols

Name a workspace-scoped attachment so it appears in the symbol library. Upload the image first with uploadAttachment and omit its pageId; a page-scoped attachment is refused, because naming it would widen who may read the bytes. Requires member.

createSymbol · token scope: session only

Path parameters

  • workspaceId · string (uuid) — required

Request bodyapplication/json, required

  • attachmentId · string (uuid) — required
  • name · string — required, length 1–80

Response 200application/json

  • id · string (uuid) — required
  • name · string — required
  • attachmentId · string (uuid) — required
  • url · string — required
  • mime · string — required
  • createdAt · string (date-time) — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

PATCH /api/v1/workspaces/{workspaceId}/symbols/{symbolId}

Rename a symbol. Requires member.

updateSymbol · token scope: session only

Path parameters

  • workspaceId · string (uuid) — required
  • symbolId · string (uuid) — required

Request bodyapplication/json, required

  • name · string — required, length 1–80

Response 200application/json

  • id · string (uuid) — required
  • name · string — required
  • attachmentId · string (uuid) — required
  • url · string — required
  • mime · string — required
  • createdAt · string (date-time) — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

DELETE /api/v1/workspaces/{workspaceId}/symbols/{symbolId}

Remove a symbol from the library. The underlying attachment and its bytes are kept on purpose: icons are stored by URL, so deleting them would break every page already wearing this one. Requires member.

deleteSymbol · token scope: session only

Path parameters

  • workspaceId · string (uuid) — required
  • symbolId · string (uuid) — required

Response 200application/json

  • ok · true — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

GET /api/v1/workspaces/{workspaceId}/pages/{pageId}/comments

Every comment thread on a page, with its replies, oldest thread first. Needs read on the page (ADR-0016 D4); a trashed page resolves to no capability and answers 404 (D9c). Each thread's anchor is resolved against the server's copy of the document, so state and currentText say whether it still points at text.

listPageComments · token scope: content:read

Path parameters

  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required

Query parameters

  • status · "open" | "resolved" | "all"

Response 200application/json

  • items · object[] — required
    • id · string (uuid) — required
    • workspaceId · string (uuid) — required
    • pageId · string (uuid) — required
    • pageTitle · string — required
    • anchor · object — required
      • kind · "block" | "text" — required
      • blockId · string (uuid) — required
      • quote · string — required
      • start · string (byte) | null — required
      • end · string (byte) | null — required
      • state · "anchored" | "orphaned" | "unknown" — required
      • currentText · string | null — required
    • resolved · boolean — required
    • resolvedAt · string (date-time) | null — required
    • resolvedBy · string (uuid) | null — required
    • createdBy · string (uuid) — required
    • createdAt · string (date-time) — required
    • updatedAt · string (date-time) — required
    • comments · object[] — required
      • id · string (uuid) — required
      • threadId · string (uuid) — required
      • body · string — required
      • author · object — required
        • id · string (uuid) — required
        • email · string (email) | null — required
        • name · string | null — required
        • image · string | null — required
      • createdAt · string (date-time) — required
      • editedAt · string (date-time) | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

POST /api/v1/workspaces/{workspaceId}/pages/{pageId}/comments

Open a thread on a page — anchored to a block or to a text range — with its first comment. Needs comment on the page, the level D4 defines for exactly this.

createCommentThread · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required

Request bodyapplication/json, required

  • body · string — required, length 1–10000
  • anchor · object — required
    • kind · "block" | "text" — required
    • blockId · string (uuid) — required
    • quote · string — length 0–2000
    • start · string (byte) — length 0–2048
    • end · string (byte) — length 0–2048

Response 200application/json

  • id · string (uuid) — required
  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required
  • pageTitle · string — required
  • anchor · object — required
    • kind · "block" | "text" — required
    • blockId · string (uuid) — required
    • quote · string — required
    • start · string (byte) | null — required
    • end · string (byte) | null — required
    • state · "anchored" | "orphaned" | "unknown" — required
    • currentText · string | null — required
  • resolved · boolean — required
  • resolvedAt · string (date-time) | null — required
  • resolvedBy · string (uuid) | null — required
  • createdBy · string (uuid) — required
  • createdAt · string (date-time) — required
  • updatedAt · string (date-time) — required
  • comments · object[] — required
    • id · string (uuid) — required
    • threadId · string (uuid) — required
    • body · string — required
    • author · object — required
      • id · string (uuid) — required
      • email · string (email) | null — required
      • name · string | null — required
      • image · string | null — required
    • createdAt · string (date-time) — required
    • editedAt · string (date-time) | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

GET /api/v1/workspaces/{workspaceId}/comments

Comment threads across the workspace, most recent first — the review queue. Keyset-paginated and permission-filtered inside the SQL, before the LIMIT (D9): threads on pages the caller cannot read, and on trashed pages, are gone before the page is cut. Anchors are NOT resolved here (state is unknown) — this listing loads no documents.

listWorkspaceComments · token scope: content:read

Path parameters

  • workspaceId · string (uuid) — required

Query parameters

  • cursor · string — length 1–∞
  • limit · integer — 1–100
  • status · "open" | "resolved" | "all"

Response 200application/json

  • items · object[] — required
    • id · string (uuid) — required
    • workspaceId · string (uuid) — required
    • pageId · string (uuid) — required
    • pageTitle · string — required
    • anchor · object — required
      • kind · "block" | "text" — required
      • blockId · string (uuid) — required
      • quote · string — required
      • start · string (byte) | null — required
      • end · string (byte) | null — required
      • state · "anchored" | "orphaned" | "unknown" — required
      • currentText · string | null — required
    • resolved · boolean — required
    • resolvedAt · string (date-time) | null — required
    • resolvedBy · string (uuid) | null — required
    • createdBy · string (uuid) — required
    • createdAt · string (date-time) — required
    • updatedAt · string (date-time) — required
    • comments · object[] — required
      • id · string (uuid) — required
      • threadId · string (uuid) — required
      • body · string — required
      • author · object — required
        • id · string (uuid) — required
        • email · string (email) | null — required
        • name · string | null — required
        • image · string | null — required
      • createdAt · string (date-time) — required
      • editedAt · string (date-time) | null — required
  • nextCursor · string | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

GET /api/v1/workspaces/{workspaceId}/comment-threads/{threadId}

One thread with its replies. Needs read on the page it is anchored to.

getCommentThread · token scope: content:read

Path parameters

  • workspaceId · string (uuid) — required
  • threadId · string (uuid) — required

Response 200application/json

  • id · string (uuid) — required
  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required
  • pageTitle · string — required
  • anchor · object — required
    • kind · "block" | "text" — required
    • blockId · string (uuid) — required
    • quote · string — required
    • start · string (byte) | null — required
    • end · string (byte) | null — required
    • state · "anchored" | "orphaned" | "unknown" — required
    • currentText · string | null — required
  • resolved · boolean — required
  • resolvedAt · string (date-time) | null — required
  • resolvedBy · string (uuid) | null — required
  • createdBy · string (uuid) — required
  • createdAt · string (date-time) — required
  • updatedAt · string (date-time) — required
  • comments · object[] — required
    • id · string (uuid) — required
    • threadId · string (uuid) — required
    • body · string — required
    • author · object — required
      • id · string (uuid) — required
      • email · string (email) | null — required
      • name · string | null — required
      • image · string | null — required
    • createdAt · string (date-time) — required
    • editedAt · string (date-time) | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

POST /api/v1/workspaces/{workspaceId}/comment-threads/{threadId}/comments

Append a reply to a thread. Needs comment on the page.

replyToCommentThread · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required
  • threadId · string (uuid) — required

Request bodyapplication/json, required

  • body · string — required, length 1–10000

Response 200application/json

  • id · string (uuid) — required
  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required
  • pageTitle · string — required
  • anchor · object — required
    • kind · "block" | "text" — required
    • blockId · string (uuid) — required
    • quote · string — required
    • start · string (byte) | null — required
    • end · string (byte) | null — required
    • state · "anchored" | "orphaned" | "unknown" — required
    • currentText · string | null — required
  • resolved · boolean — required
  • resolvedAt · string (date-time) | null — required
  • resolvedBy · string (uuid) | null — required
  • createdBy · string (uuid) — required
  • createdAt · string (date-time) — required
  • updatedAt · string (date-time) — required
  • comments · object[] — required
    • id · string (uuid) — required
    • threadId · string (uuid) — required
    • body · string — required
    • author · object — required
      • id · string (uuid) — required
      • email · string (email) | null — required
      • name · string | null — required
      • image · string | null — required
    • createdAt · string (date-time) — required
    • editedAt · string (date-time) | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

POST /api/v1/workspaces/{workspaceId}/comment-threads/{threadId}/resolve

Resolve or un-resolve a thread. Needs comment on the page: settling a discussion is part of taking part in it, and a reviewer who may reply but never tidy up leaves every page permanently marked.

resolveCommentThread · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required
  • threadId · string (uuid) — required

Request bodyapplication/json, required

  • resolved · boolean — required

Response 200application/json

  • id · string (uuid) — required
  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required
  • pageTitle · string — required
  • anchor · object — required
    • kind · "block" | "text" — required
    • blockId · string (uuid) — required
    • quote · string — required
    • start · string (byte) | null — required
    • end · string (byte) | null — required
    • state · "anchored" | "orphaned" | "unknown" — required
    • currentText · string | null — required
  • resolved · boolean — required
  • resolvedAt · string (date-time) | null — required
  • resolvedBy · string (uuid) | null — required
  • createdBy · string (uuid) — required
  • createdAt · string (date-time) — required
  • updatedAt · string (date-time) — required
  • comments · object[] — required
    • id · string (uuid) — required
    • threadId · string (uuid) — required
    • body · string — required
    • author · object — required
      • id · string (uuid) — required
      • email · string (email) | null — required
      • name · string | null — required
      • image · string | null — required
    • createdAt · string (date-time) — required
    • editedAt · string (date-time) | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

PATCH /api/v1/workspaces/{workspaceId}/comment-threads/{threadId}/comments/{commentId}

Edit a comment's body. Authors only — edit on the page does not include putting words in someone else's mouth.

updateComment · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required
  • threadId · string (uuid) — required
  • commentId · string (uuid) — required

Request bodyapplication/json, required

  • body · string — required, length 1–10000

Response 200application/json

  • id · string (uuid) — required
  • threadId · string (uuid) — required
  • body · string — required
  • author · object — required
    • id · string (uuid) — required
    • email · string (email) | null — required
    • name · string | null — required
    • image · string | null — required
  • createdAt · string (date-time) — required
  • editedAt · string (date-time) | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

DELETE /api/v1/workspaces/{workspaceId}/comment-threads/{threadId}/comments/{commentId}

Delete a comment. Its author may always delete it; so may anyone with edit on the page, since moderating a page is part of maintaining it. Deleting the last comment deletes the thread.

deleteComment · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required
  • threadId · string (uuid) — required
  • commentId · string (uuid) — required

Response 200application/json

  • commentId · string (uuid) — required
  • threadDeleted · boolean — required
  • thread · object | null — required
    • id · string (uuid) — required
    • workspaceId · string (uuid) — required
    • pageId · string (uuid) — required
    • pageTitle · string — required
    • anchor · object — required
      • kind · "block" | "text" — required
      • blockId · string (uuid) — required
      • quote · string — required
      • start · string (byte) | null — required
      • end · string (byte) | null — required
      • state · "anchored" | "orphaned" | "unknown" — required
      • currentText · string | null — required
    • resolved · boolean — required
    • resolvedAt · string (date-time) | null — required
    • resolvedBy · string (uuid) | null — required
    • createdBy · string (uuid) — required
    • createdAt · string (date-time) — required
    • updatedAt · string (date-time) — required
    • comments · object[] — required
      • id · string (uuid) — required
      • threadId · string (uuid) — required
      • body · string — required
      • author · object — required
        • id · string (uuid) — required
        • email · string (email) | null — required
        • name · string | null — required
        • image · string | null — required
      • createdAt · string (date-time) — required
      • editedAt · string (date-time) | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

GET /api/v1/workspaces/{workspaceId}/pages/{pageId}/history

Browse a page's versions, newest first, keyset-paginated. History is content, so it is gated like content (ADR-0016 D4): read on the page. A trashed page resolves to no capability and answers 404 (D9c) — the same answer an unknown page id gets. Metadata only; use getPageVersion for a version's body.

listPageVersions · token scope: content:read

Path parameters

  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required

Query parameters

  • cursor · string — length 1–∞
  • limit · integer — 1–100

Response 200application/json

  • items · object[] — required
    • id · string (uuid) — required
    • pageId · string (uuid) — required
    • kind · "auto" | "manual" | "pre_restore" | "restore" — required
    • label · string | null — required
    • title · string — required
    • excerpt · string — required
    • blockCount · integer — required, 0–9007199254740991
    • sizeBytes · integer — required, 0–9007199254740991
    • createdBy · string (uuid) | null — required
    • createdAt · string (date-time) — required
    • restoredFrom · string (uuid) | null — required
  • nextCursor · string | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

POST /api/v1/workspaces/{workspaceId}/pages/{pageId}/history

Capture the page's current body as a named version. Requires edit — a version is a write to the page's history. Unlike the automatic capture this is never deduplicated against the previous version and is never pruned by retention: it exists because a person asked for it.

savePageVersion · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required

Request bodyapplication/json, required

  • label · string — length 0–200

Response 200application/json

  • id · string (uuid) — required
  • pageId · string (uuid) — required
  • kind · "auto" | "manual" | "pre_restore" | "restore" — required
  • label · string | null — required
  • title · string — required
  • excerpt · string — required
  • blockCount · integer — required, 0–9007199254740991
  • sizeBytes · integer — required, 0–9007199254740991
  • createdBy · string (uuid) | null — required
  • createdAt · string (date-time) — required
  • restoredFrom · string (uuid) | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

GET /api/v1/workspaces/{workspaceId}/pages/{pageId}/history/{versionId}

Read one version, including its body as canonical Markdown (ADR-0012). Requires read on the page.

getPageVersion · token scope: content:read

Path parameters

  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required
  • versionId · string (uuid) — required

Response 200application/json

  • id · string (uuid) — required
  • pageId · string (uuid) — required
  • kind · "auto" | "manual" | "pre_restore" | "restore" — required
  • label · string | null — required
  • title · string — required
  • excerpt · string — required
  • blockCount · integer — required, 0–9007199254740991
  • sizeBytes · integer — required, 0–9007199254740991
  • createdBy · string (uuid) | null — required
  • createdAt · string (date-time) — required
  • restoredFrom · string (uuid) | null — required
  • markdown · string — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

DELETE /api/v1/workspaces/{workspaceId}/pages/{pageId}/history/{versionId}

Delete one version. Requires edit on the page. Exists because retention deliberately never prunes a version a person created or a restore recorded — removing one has to be a decision, not a background job. Returns the deleted row.

deletePageVersion · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required
  • versionId · string (uuid) — required

Response 200application/json

  • id · string (uuid) — required
  • pageId · string (uuid) — required
  • kind · "auto" | "manual" | "pre_restore" | "restore" — required
  • label · string | null — required
  • title · string — required
  • excerpt · string — required
  • blockCount · integer — required, 0–9007199254740991
  • sizeBytes · integer — required, 0–9007199254740991
  • createdBy · string (uuid) | null — required
  • createdAt · string (date-time) — required
  • restoredFrom · string (uuid) | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

POST /api/v1/workspaces/{workspaceId}/pages/{pageId}/history/{versionId}/restore

Put a version's body back. Requires edit on the page (the matrix prices editing a body at edit — D4). The write goes through the doc mutator as one Yjs transaction, so the CRDT is never bypassed and connected editors see it live. Two versions are recorded: the state being overwritten (undo) and the restored state (restored) — nothing after the restored point is deleted, so a restore is itself undoable.

restorePageVersion · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required
  • versionId · string (uuid) — required

Response 200application/json

  • undo · object — required
    • id · string (uuid) — required
    • pageId · string (uuid) — required
    • kind · "auto" | "manual" | "pre_restore" | "restore" — required
    • label · string | null — required
    • title · string — required
    • excerpt · string — required
    • blockCount · integer — required, 0–9007199254740991
    • sizeBytes · integer — required, 0–9007199254740991
    • createdBy · string (uuid) | null — required
    • createdAt · string (date-time) — required
    • restoredFrom · string (uuid) | null — required
  • restored · object — required
    • id · string (uuid) — required
    • pageId · string (uuid) — required
    • kind · "auto" | "manual" | "pre_restore" | "restore" — required
    • label · string | null — required
    • title · string — required
    • excerpt · string — required
    • blockCount · integer — required, 0–9007199254740991
    • sizeBytes · integer — required, 0–9007199254740991
    • createdBy · string (uuid) | null — required
    • createdAt · string (date-time) — required
    • restoredFrom · string (uuid) | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

GET /api/v1/workspaces/{workspaceId}/pages/{pageId}/activity

One page's activity, most recent first. Requires read access to the page; entries are coalesced per actor, verb and time window.

listPageActivity · token scope: content:read

Path parameters

  • workspaceId · string (uuid) — required
  • pageId · string (uuid) — required

Query parameters

  • cursor · string — length 1–∞
  • limit · integer — 1–100

Response 200application/json

  • items · object[] — required
    • id · string (uuid) — required
    • blockId · string (uuid) — required
    • resourceType · "page" | "database" — required
    • title · string — required
    • verb · "created" | "edited" | "renamed" | "moved" | "trashed" | "restored" — required
    • actorId · string (uuid) | null — required
    • occurredAt · string (date-time) — required
    • count · integer — required, −∞–9007199254740991
    • movedUnderTitle · string | null — required
  • nextCursor · string | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

GET /api/v1/workspaces/{workspaceId}/activity

Recent activity across the workspace, most recent first, filtered to the pages and databases the caller may read (filtered in SQL before the LIMIT).

listWorkspaceActivity · token scope: content:read

Path parameters

  • workspaceId · string (uuid) — required

Query parameters

  • cursor · string — length 1–∞
  • limit · integer — 1–100

Response 200application/json

  • items · object[] — required
    • id · string (uuid) — required
    • blockId · string (uuid) — required
    • resourceType · "page" | "database" — required
    • title · string — required
    • verb · "created" | "edited" | "renamed" | "moved" | "trashed" | "restored" — required
    • actorId · string (uuid) | null — required
    • occurredAt · string (date-time) — required
    • count · integer — required, −∞–9007199254740991
    • movedUnderTitle · string | null — required
  • nextCursor · string | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

GET /api/v1/workspaces/{workspaceId}/notifications

The caller's inbox for this workspace, newest first. Entries about content the caller can no longer read are omitted.

listNotifications · token scope: content:read

Path parameters

  • workspaceId · string (uuid) — required

Query parameters

  • cursor · string — length 1–∞
  • limit · integer — 1–100
  • status · "unread" | "all"

Response 200application/json

  • items · object[] — required
    • id · string (uuid) — required
    • kind · "mention" — required
    • blockId · string (uuid) — required
    • title · string — required
    • sourceType · "block" | "comment" — required
    • sourceId · string (uuid) — required
    • actorId · string (uuid) | null — required
    • createdAt · string (date-time) — required
    • readAt · string (date-time) | null — required
  • nextCursor · string | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

GET /api/v1/workspaces/{workspaceId}/notifications/summary

How many unread notifications the caller has here — the shell's badge. Counted over the same permission filter as the listing.

getInboxSummary · token scope: content:read

Path parameters

  • workspaceId · string (uuid) — required

Response 200application/json

  • unread · integer — required, 0–9007199254740991

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

POST /api/v1/workspaces/{workspaceId}/notifications/{notificationId}/read

Mark one of your own notifications read (or unread again).

markNotificationRead · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required
  • notificationId · string (uuid) — required

Request bodyapplication/json, required

  • read · boolean — required

Response 200application/json

  • id · string (uuid) — required
  • kind · "mention" — required
  • blockId · string (uuid) — required
  • title · string — required
  • sourceType · "block" | "comment" — required
  • sourceId · string (uuid) — required
  • actorId · string (uuid) | null — required
  • createdAt · string (date-time) — required
  • readAt · string (date-time) | null — required

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

POST /api/v1/workspaces/{workspaceId}/notifications/read

Mark every notification the caller can currently see as read.

markAllNotificationsRead · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required

Response 200application/json

  • updated · integer — required, 0–9007199254740991

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required

DELETE /api/v1/workspaces/{workspaceId}/notifications/{notificationId}

Clear one of your own notifications — it leaves the inbox for good.

clearNotification · token scope: content:write

Path parameters

  • workspaceId · string (uuid) — required
  • notificationId · string (uuid) — required

Response 200application/json

  • updated · integer — required, 0–9007199254740991

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required