Tecto docs
tectoapp.io

Collections

The top level of the page tree, and who may see each one.

9 operations. Every path is relative to the instance origin; every response body is JSON unless stated. The endpoint descriptions below come straight from the server’s own route table. See API for authentication, errors and pagination.

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 200application/json

  • items · object[] — required
    • id · string (uuid) — required
    • workspaceId · string (uuid) — required
    • name · string — required
    • icon · string | null — required
    • description · string | null — required
    • visibility · "open" | "closed" | "private" — required
    • accessLevel · "read" | "comment" | "edit" | "full" | null — required
    • createdAt · string (date-time) — 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
    • reason · 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 bodyapplication/json, required

  • name · string — required, length 1–200
  • icon · string — length 0–2048
  • description · string — length 0–280
  • visibility · "open" | "closed" | "private" — required

Response 200application/json

  • id · string (uuid) — required
  • workspaceId · string (uuid) — required
  • name · string — required
  • icon · string | null — required
  • description · string | null — required
  • visibility · "open" | "closed" | "private" — required
  • accessLevel · "read" | "comment" | "edit" | "full" | null — 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
    • reason · 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) — required
  • collectionId · string (uuid) — required

Request bodyapplication/json, required

  • name · string — length 1–200
  • icon · string | null
  • description · string | null
  • visibility · "open" | "closed" | "private"

Response 200application/json

  • id · string (uuid) — required
  • workspaceId · string (uuid) — required
  • name · string — required
  • icon · string | null — required
  • description · string | null — required
  • visibility · "open" | "closed" | "private" — required
  • accessLevel · "read" | "comment" | "edit" | "full" | null — 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
    • reason · 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) — required
  • collectionId · string (uuid) — required

Query parameters

  • withContents · string

Response 200application/json

  • id · string (uuid) — required
  • workspaceId · string (uuid) — required
  • name · string — required
  • icon · string | null — required
  • description · string | null — required
  • visibility · "open" | "closed" | "private" — required
  • accessLevel · "read" | "comment" | "edit" | "full" | null — 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
    • reason · 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) — required
  • collectionId · string (uuid) — required

Response 200application/json

  • total · integer — required, -9007199254740991–9007199254740991
  • byProduct · object — required
    • basalt · integer — required, -9007199254740991–9007199254740991
    • lithic · integer — required, -9007199254740991–9007199254740991
    • tecto · integer — required, -9007199254740991–9007199254740991
  • outOfReach · integer — required, -9007199254740991–9007199254740991

Response defaultapplication/json

  • error · object — required
    • code · "bad_request" | "validation_failed" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "rate_limited" | "internal" — required
    • message · string — required
    • reason · 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) — required
  • collectionId · string (uuid) — required

Query parameters

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

Response 200application/json

  • items · object[] — required
    • workspaceId · string (uuid) — required
    • scopeType · "workspace" | "collection" | "database" — required
    • scopeId · string (uuid) — required
    • fieldId · string (uuid) — required
    • position · string — required
    • required · boolean — required
    • defaultValue · object | 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
    • reason · 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) — required
  • collectionId · string (uuid) — required

Request bodyapplication/json, required

  • fieldId · string (uuid) — required
  • required · boolean
  • defaultValue · object | null
  • beforeId · string (uuid)
  • afterId · string (uuid)

Response 200application/json

  • workspaceId · string (uuid) — required
  • scopeType · "workspace" | "collection" | "database" — required
  • scopeId · string (uuid) — required
  • fieldId · string (uuid) — required
  • position · string — required
  • required · boolean — required
  • defaultValue · object | 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
    • reason · 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) — required
  • collectionId · string (uuid) — required
  • fieldId · string (uuid) — required

Request bodyapplication/json, required

  • required · boolean
  • defaultValue · object | null
  • beforeId · string (uuid)
  • afterId · string (uuid)

Response 200application/json

  • workspaceId · string (uuid) — required
  • scopeType · "workspace" | "collection" | "database" — required
  • scopeId · string (uuid) — required
  • fieldId · string (uuid) — required
  • position · string — required
  • required · boolean — required
  • defaultValue · object | 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
    • reason · 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) — required
  • collectionId · string (uuid) — required
  • fieldId · string (uuid) — required

Response 200application/json

  • workspaceId · string (uuid) — required
  • scopeType · "workspace" | "collection" | "database" — required
  • scopeId · string (uuid) — required
  • fieldId · string (uuid) — required
  • position · string — required
  • required · boolean — required
  • defaultValue · object | 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
    • reason · string — length 1–64