Skip to content
Cloudtifact docs

Spaces API

Publishing files as versions, reading them, comments and the space database.

All paths are relative to the API origin. Send Authorization: Bearer <token> unless a route says otherwise; see the API overview for tokens and errors.

GET /v1/spaces

?workspace=<slug>: that workspace's spaces you can see (unknown slug: empty); else all you can push to

Query

FieldTypeRequiredNotes
workspacestringno

Response

FieldTypeRequiredNotes
spacesobject[]yes

POST /v1/spaces

Body

FieldTypeRequiredNotes
workspacestringyes
namestringyes
visibility"public" | "members"no (default "public")

Response

FieldTypeRequiredNotes
idstringyes
namestringyes
workspaceobjectyes
visibility"public" | "members"yes
guestCommentsbooleanyes
guestWritesbooleanyes
viewersobjectyes
passwordProtectedbooleanyes (default false)
latestVersionintegeryes
pathstringyes
urlstringyes
shareUrlstring | nullyes
kind"repo" | "room" | "app"yes (default "repo")
permissionsobjectyes
createdAtnumberyes

GET /v1/spaces/:id

Response

FieldTypeRequiredNotes
idstringyes
namestringyes
workspaceobjectyes
visibility"public" | "members"yes
guestCommentsbooleanyes
guestWritesbooleanyes
viewersobjectyes
passwordProtectedbooleanyes (default false)
latestVersionintegeryes
pathstringyes
urlstringyes
shareUrlstring | nullyes
kind"repo" | "room" | "app"yes (default "repo")
permissionsobjectyes
createdAtnumberyes

PATCH /v1/spaces/:id

Body

FieldTypeRequiredNotes
namestringno
visibility"public" | "members"no
guestCommentsbooleanno
guestWritesbooleanno
viewersobjectno
passwordstring | nullno

Response

FieldTypeRequiredNotes
idstringyes
namestringyes
workspaceobjectyes
visibility"public" | "members"yes
guestCommentsbooleanyes
guestWritesbooleanyes
viewersobjectyes
passwordProtectedbooleanyes (default false)
latestVersionintegeryes
pathstringyes
urlstringyes
shareUrlstring | nullyes
kind"repo" | "room" | "app"yes (default "repo")
permissionsobjectyes
createdAtnumberyes

GET /v1/spaces/:id/head

  • liveUrl

Response

FieldTypeRequiredNotes
latestVersionintegeryes
commentsUpdatedAtnumberyes
uploadsintegeryes (default 0)
uploadsUpdatedAtnumberyes (default 0)
liveUrlstringno

POST /v1/spaces/:id/unlock

Public space with a password; 401 wrong, 429 too many tries (PRD 013)

Body

FieldTypeRequiredNotes
passwordstringyes

Response

FieldTypeRequiredNotes
tokenstringyes
expintegeryes

POST /v1/spaces/:id/views

View; the app's beacon; not counted for people who can push

Body

FieldTypeRequiredNotes
pathstringyes
versioninteger | nullno
referrerstring | nullno

Response: 204, no body

GET /v1/spaces/:id/visitors

Push; views, visitors, people, last 90 days max

Query

FieldTypeRequiredNotes
daysintegerno (default 30)

Response

FieldTypeRequiredNotes
daysintegeryes
viewsintegeryes
visitorsintegeryes
signedInintegeryes
dailyobject[]yes
countriesobject[]yes
referrersobject[]yes
pagesobject[]yes
peopleobject[]yes
recentobject[]yes

POST /v1/spaces/:id/push/plan

Body

FieldTypeRequiredNotes
filesobject[]yes

Response

FieldTypeRequiredNotes
baseVersionintegeryes
missingstring[]yes
diffobjectyes

PUT /v1/spaces/:id/blobs/:sha256

Server verifies the hash

Request: raw file bytes

Response: 204, no body

POST /v1/spaces/:id/versions

409 if a listed blob is missing

Body

FieldTypeRequiredNotes
filesobject[]yes
messagestringno

Response

FieldTypeRequiredNotes
versionobject | nullyes
diffobjectyes
urlstringyes

GET /v1/spaces/:id/versions

Newest first

Response

FieldTypeRequiredNotes
versionsobject[]yes

GET /v1/spaces/:id/versions/:n

N = number or "latest"

Response

FieldTypeRequiredNotes
versionobjectyes
filesobject[]yes
diffobjectyes

GET /v1/spaces/:id/files/*path

Request: ?v=<n>

Response

FieldTypeRequiredNotes
versionNumberintegeryes
fileobjectyes
contentstringyes
rawUrlstring | nullyes

GET /v1/spaces/:id/history/*path

Response

FieldTypeRequiredNotes
entriesobject[]yes

GET /v1/spaces/:id/download/*path

View; attachment (PRD 012)

Request: ?v=<n>

Response: file bytes

GET /v1/spaces/:id/download-link/*path

View; 5-minute /dl/<ticket> link for browsers

Request: ?v=<n>

Response

FieldTypeRequiredNotes
urlstringyes
expiresAtnumberyes

GET /v1/spaces/:id/uploads

CanSeeFiles; newest first (PRD 012)

Response

FieldTypeRequiredNotes
uploadsobject[]yes

POST /v1/spaces/:id/uploads

Push; Content-Length required, MAX_UPLOAD_BYTES; streamed to R2

Request: raw bytes, ?name=

Response

FieldTypeRequiredNotes
idstringyes
namestringyes
sizeintegeryes
sha256stringyes
contentTypestringyes
uploadedByobject | nullyes
createdAtnumberyes

GET /v1/spaces/:id/uploads/:uploadId/raw

CanSeeFiles; attachment, nosniff, sandbox CSP, x-content-sha256

Response: file bytes

CanSeeFiles; 5-minute /dl/<ticket> link for browsers

Response

FieldTypeRequiredNotes
urlstringyes
expiresAtnumberyes

DELETE /v1/spaces/:id/uploads/:uploadId

Push

Response: 204, no body

GET /v1/spaces/:id/comments

Query

FieldTypeRequiredNotes
pathstringno
status"open" | "resolved" | "all"no (default "open")

Response

FieldTypeRequiredNotes
threadsobject[]yes

POST /v1/spaces/:id/comments

Signed in + canComment, or a guest when the space allows guest comments (20 per ip per 10 min)

Body

FieldTypeRequiredNotes
pathstringyes
bodystringyes
quotestringno
anchorobjectno
parentIdstringno
versionNumberintegerno
guestobjectno

Response

FieldTypeRequiredNotes
idstringyes
pathstringyes
versionNumberintegeryes
parentIdstring | nullyes
authorobjectyes
guestNamestring | nullyes
originobject | nullyes
bodystringyes
quotestring | nullyes
anchorobject | nullyes
viastring | nullyes
resolvedAtnumber | nullyes
resolvedByobject | nullyes
resolvedViastring | nullyes
editedAtnumber | nullyes
editedByobject | nullyes
editedViastring | nullyes
revisionsintegeryes
createdAtnumberyes

PATCH /v1/comments/:id

Author only (a guest: with their key); old text kept as a revision

Body

FieldTypeRequiredNotes
bodystringyes
guestobjectno

Response

FieldTypeRequiredNotes
idstringyes
pathstringyes
versionNumberintegeryes
parentIdstring | nullyes
authorobjectyes
guestNamestring | nullyes
originobject | nullyes
bodystringyes
quotestring | nullyes
anchorobject | nullyes
viastring | nullyes
resolvedAtnumber | nullyes
resolvedByobject | nullyes
resolvedViastring | nullyes
editedAtnumber | nullyes
editedByobject | nullyes
editedViastring | nullyes
revisionsintegeryes
createdAtnumberyes

DELETE /v1/comments/:id

Author (a guest: with their key), or canPush; deletes the replies too

Body

FieldTypeRequiredNotes
guestobjectno

Response: 204, no body

GET /v1/comments/:id/revisions

Every version, oldest first (empty if never edited)

Response

FieldTypeRequiredNotes
revisionsobject[]yes

POST /v1/comments/:id/resolve

Thread author, or canPush on the space (403 otherwise)

Response

FieldTypeRequiredNotes
idstringyes
pathstringyes
versionNumberintegeryes
parentIdstring | nullyes
authorobjectyes
guestNamestring | nullyes
originobject | nullyes
bodystringyes
quotestring | nullyes
anchorobject | nullyes
viastring | nullyes
resolvedAtnumber | nullyes
resolvedByobject | nullyes
resolvedViastring | nullyes
editedAtnumber | nullyes
editedByobject | nullyes
editedViastring | nullyes
revisionsintegeryes
createdAtnumberyes

POST /v1/comments/:id/unresolve

Thread author, or canPush on the space (403 otherwise)

Response

FieldTypeRequiredNotes
idstringyes
pathstringyes
versionNumberintegeryes
parentIdstring | nullyes
authorobjectyes
guestNamestring | nullyes
originobject | nullyes
bodystringyes
quotestring | nullyes
anchorobject | nullyes
viastring | nullyes
resolvedAtnumber | nullyes
resolvedByobject | nullyes
resolvedViastring | nullyes
editedAtnumber | nullyes
editedByobject | nullyes
editedViastring | nullyes
revisionsintegeryes
createdAtnumberyes

POST /v1/spaces/:id/db/query

View; write: true needs push (401 signed out / 403, never downgraded)

Body

FieldTypeRequiredNotes
sqlstringyes
params(string | number | null | boolean | object)[]no
writebooleanno

Response

FieldTypeRequiredNotes
columnsstring[]yes
rows((string | number | null | object)[])[]yes
rowsReadnumberyes
rowsWrittennumberyes
truncatedbooleanyes

GET /v1/spaces/:id/db

View; tables, columns, row counts, size

Response

FieldTypeRequiredNotes
tablesobject[]yes
databaseSizenumberyes

GET /v1/spaces/:id/db/exists

View; { hasTables }, no row counts

Response

FieldTypeRequiredNotes
hasTablesbooleanyes

GET /v1/spaces/:id/db/guest-writes

Push; the named writes guests may run

Response

FieldTypeRequiredNotes
statementsobject[]yes

PUT /v1/spaces/:id/db/guest-writes

Push; replaces the set; each must be one write statement

Body

FieldTypeRequiredNotes
statementsobject[]yes

Response

FieldTypeRequiredNotes
statementsobject[]yes

GET /v1/spaces/:id/db/writes

Push; the write log, newest first, with guest name and origin

Query

FieldTypeRequiredNotes
limitintegerno (default 100)

Response

FieldTypeRequiredNotes
writesobject[]yes

GET /v1/spaces/:id/db/export

Push; attachment <spaceId>.sql, replays via db/query with write: true

Response: text/plain .sql dump

POST /v1/spaces/:id/db/reset

Admin; wipes every table; { before } undoes it via restore

Response

FieldTypeRequiredNotes
beforenumberyes

POST /v1/spaces/:id/db/restore

Admin; point-in-time restore, last 30 days

Body

FieldTypeRequiredNotes
atstring (date-time) | integeryes

Response

FieldTypeRequiredNotes
restoredTonumberyes
undoBookmarkstringyes