Collections
Die oberste Ebene des Seitenbaums — und wer sie jeweils zu sehen bekommt.
9 Operationen. Jeder Pfad ist relativ zum Ursprung der Instanz; jeder Antwortkörper ist JSON, sofern nicht anders vermerkt. Die Endpunktbeschreibungen unten stammen unverändert aus der Routentabelle des Servers und bleiben englisch. Authentifizierung, Fehler und seitenweise Abfrage stehen unter API.
GET /api/v1/workspaces/{workspaceId}/collections
List the collections of a workspace, filtered by visibility (ADR-0016 D2): open and closed collections are listed for every member, private ones only for their explicit members. Each entry carries the caller's effective accessLevel — null means "listed by name only" (a closed collection a member may see but not open).
listCollections · token scope: content:read
Path parameters
workspaceId· string (uuid) — required
Query parameters
cursor· string — length 1–∞limit· integer — 1–100
Response 200 — application/json
items· object[] — requiredid· string (uuid) — requiredworkspaceId· string (uuid) — requiredname· string — requiredicon· string | null — requireddescription· string | null — requiredvisibility·"open"|"closed"|"private"— requiredaccessLevel·"read"|"comment"|"edit"|"full"| null — requiredcreatedAt· string (date-time) — required
nextCursor· string | null — required
Response default — application/json
error· object — requiredcode·"bad_request"|"validation_failed"|"unauthorized"|"forbidden"|"not_found"|"conflict"|"rate_limited"|"internal"— requiredmessage· string — requiredreason· string — length 1–64
POST /api/v1/workspaces/{workspaceId}/collections
Create a collection in a workspace.
createCollection · token scope: content:write
Path parameters
workspaceId· string (uuid) — required
Request body — application/json, required
name· string — required, length 1–200icon· string — length 0–2048description· string — length 0–280visibility·"open"|"closed"|"private"— required
Response 200 — application/json
id· string (uuid) — requiredworkspaceId· string (uuid) — requiredname· string — requiredicon· string | null — requireddescription· string | null — requiredvisibility·"open"|"closed"|"private"— requiredaccessLevel·"read"|"comment"|"edit"|"full"| null — requiredcreatedAt· string (date-time) — required
Response default — application/json
error· object — requiredcode·"bad_request"|"validation_failed"|"unauthorized"|"forbidden"|"not_found"|"conflict"|"rate_limited"|"internal"— requiredmessage· string — requiredreason· string — length 1–64
PATCH /api/v1/workspaces/{workspaceId}/collections/{collectionId}
Update a collection name, icon, description and/or visibility. Changing visibility requires full on the collection and bumps the workspace access generation; explicit collection_member rows survive it.
updateCollection · token scope: content:write
Path parameters
workspaceId· string (uuid) — requiredcollectionId· string (uuid) — required
Request body — application/json, required
name· string — length 1–200icon· string | nulldescription· string | nullvisibility·"open"|"closed"|"private"
Response 200 — application/json
id· string (uuid) — requiredworkspaceId· string (uuid) — requiredname· string — requiredicon· string | null — requireddescription· string | null — requiredvisibility·"open"|"closed"|"private"— requiredaccessLevel·"read"|"comment"|"edit"|"full"| null — requiredcreatedAt· string (date-time) — required
Response default — application/json
error· object — requiredcode·"bad_request"|"validation_failed"|"unauthorized"|"forbidden"|"not_found"|"conflict"|"rate_limited"|"internal"— requiredmessage· string — requiredreason· string — length 1–64
DELETE /api/v1/workspaces/{workspaceId}/collections/{collectionId}
Delete a collection. Requires the collections.delete capability (admin/owner) AND full on the collection (ADR-0016 D1: no role grants implicit access). Refuses (409) while the collection holds anything — including trashed items and content the asking app does not list — unless withContents=true, which destroys the whole thing: every document in it, of every kind, irreversibly and WITHOUT the trash. That is still refused (409) while the collection holds a single block the caller lacks full on: no role crosses a restriction boundary, so a delete may never destroy what its actor could not read. Its collection_member rows and field bindings go with it either way. Returns the deleted collection.
deleteCollection · token scope: content:write
Path parameters
workspaceId· string (uuid) — requiredcollectionId· string (uuid) — required
Query parameters
withContents· string
Response 200 — application/json
id· string (uuid) — requiredworkspaceId· string (uuid) — requiredname· string — requiredicon· string | null — requireddescription· string | null — requiredvisibility·"open"|"closed"|"private"— requiredaccessLevel·"read"|"comment"|"edit"|"full"| null — requiredcreatedAt· string (date-time) — required
Response default — application/json
error· object — requiredcode·"bad_request"|"validation_failed"|"unauthorized"|"forbidden"|"not_found"|"conflict"|"rate_limited"|"internal"— requiredmessage· string — requiredreason· string — length 1–64
GET /api/v1/workspaces/{workspaceId}/collections/{collectionId}/contents
What a collection holds, counted per app (ADR-0030 D2) — the inventory a delete confirmation shows. Counted UNSCOPED on purpose: the point is to name what the asking app does not list, which is what makes deleting a shared collection a decision rather than a surprise. The counts OVERLAP and do not sum to total: a page attached to a board belongs to two apps at once and is counted in both. outOfReach counts the blocks the caller does not hold full on — the ones that make withContents refuse. Requires full on the collection.
getCollectionContents · token scope: content:read
Path parameters
workspaceId· string (uuid) — requiredcollectionId· string (uuid) — required
Response 200 — application/json
total· integer — required, -9007199254740991–9007199254740991byProduct· object — requiredbasalt· integer — required, -9007199254740991–9007199254740991lithic· integer — required, -9007199254740991–9007199254740991tecto· integer — required, -9007199254740991–9007199254740991
outOfReach· integer — required, -9007199254740991–9007199254740991
Response default — application/json
error· object — requiredcode·"bad_request"|"validation_failed"|"unauthorized"|"forbidden"|"not_found"|"conflict"|"rate_limited"|"internal"— requiredmessage· string — requiredreason· string — length 1–64
GET /api/v1/workspaces/{workspaceId}/collections/{collectionId}/fields
List the fields offered on every page of a collection.
listCollectionFields · token scope: content:read
Path parameters
workspaceId· string (uuid) — requiredcollectionId· string (uuid) — required
Query parameters
cursor· string — length 1–∞limit· integer — 1–100
Response 200 — application/json
items· object[] — requiredworkspaceId· string (uuid) — requiredscopeType·"workspace"|"collection"|"database"— requiredscopeId· string (uuid) — requiredfieldId· string (uuid) — requiredposition· string — requiredrequired· boolean — requireddefaultValue· object | null — required
nextCursor· string | null — required
Response default — application/json
error· object — requiredcode·"bad_request"|"validation_failed"|"unauthorized"|"forbidden"|"not_found"|"conflict"|"rate_limited"|"internal"— requiredmessage· string — requiredreason· string — length 1–64
POST /api/v1/workspaces/{workspaceId}/collections/{collectionId}/fields
Offer a registry field on every page of a collection.
bindCollectionField · token scope: content:write
Path parameters
workspaceId· string (uuid) — requiredcollectionId· string (uuid) — required
Request body — application/json, required
fieldId· string (uuid) — requiredrequired· booleandefaultValue· object | nullbeforeId· string (uuid)afterId· string (uuid)
Response 200 — application/json
workspaceId· string (uuid) — requiredscopeType·"workspace"|"collection"|"database"— requiredscopeId· string (uuid) — requiredfieldId· string (uuid) — requiredposition· string — requiredrequired· boolean — requireddefaultValue· object | null — required
Response default — application/json
error· object — requiredcode·"bad_request"|"validation_failed"|"unauthorized"|"forbidden"|"not_found"|"conflict"|"rate_limited"|"internal"— requiredmessage· string — requiredreason· string — length 1–64
PATCH /api/v1/workspaces/{workspaceId}/collections/{collectionId}/fields/{fieldId}
Reorder a collection binding among the collection's fields.
updateCollectionBinding · token scope: content:write
Path parameters
workspaceId· string (uuid) — requiredcollectionId· string (uuid) — requiredfieldId· string (uuid) — required
Request body — application/json, required
required· booleandefaultValue· object | nullbeforeId· string (uuid)afterId· string (uuid)
Response 200 — application/json
workspaceId· string (uuid) — requiredscopeType·"workspace"|"collection"|"database"— requiredscopeId· string (uuid) — requiredfieldId· string (uuid) — requiredposition· string — requiredrequired· boolean — requireddefaultValue· object | null — required
Response default — application/json
error· object — requiredcode·"bad_request"|"validation_failed"|"unauthorized"|"forbidden"|"not_found"|"conflict"|"rate_limited"|"internal"— requiredmessage· string — requiredreason· string — length 1–64
DELETE /api/v1/workspaces/{workspaceId}/collections/{collectionId}/fields/{fieldId}
Stop offering a field in a collection (values already on pages are kept).
unbindCollectionField · token scope: content:write
Path parameters
workspaceId· string (uuid) — requiredcollectionId· string (uuid) — requiredfieldId· string (uuid) — required
Response 200 — application/json
workspaceId· string (uuid) — requiredscopeType·"workspace"|"collection"|"database"— requiredscopeId· string (uuid) — requiredfieldId· string (uuid) — requiredposition· string — requiredrequired· boolean — requireddefaultValue· object | null — required
Response default — application/json
error· object — requiredcode·"bad_request"|"validation_failed"|"unauthorized"|"forbidden"|"not_found"|"conflict"|"rate_limited"|"internal"— requiredmessage· string — requiredreason· string — length 1–64