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
| Field | Type | Required | Notes |
|---|---|---|---|
workspace | string | no |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
spaces | object[] | yes |
POST /v1/spaces
Body
| Field | Type | Required | Notes |
|---|---|---|---|
workspace | string | yes | |
name | string | yes | |
visibility | "public" | "members" | no (default "public") |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
id | string | yes | |
name | string | yes | |
workspace | object | yes | |
visibility | "public" | "members" | yes | |
guestComments | boolean | yes | |
guestWrites | boolean | yes | |
viewers | object | yes | |
latestVersion | integer | yes | |
path | string | yes | |
url | string | yes | |
shareUrl | string | null | yes | |
kind | "repo" | "room" | "app" | yes (default "repo") | |
permissions | object | yes | |
createdAt | number | yes |
GET /v1/spaces/:id
Response
| Field | Type | Required | Notes |
|---|---|---|---|
id | string | yes | |
name | string | yes | |
workspace | object | yes | |
visibility | "public" | "members" | yes | |
guestComments | boolean | yes | |
guestWrites | boolean | yes | |
viewers | object | yes | |
latestVersion | integer | yes | |
path | string | yes | |
url | string | yes | |
shareUrl | string | null | yes | |
kind | "repo" | "room" | "app" | yes (default "repo") | |
permissions | object | yes | |
createdAt | number | yes |
PATCH /v1/spaces/:id
Body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | no | |
visibility | "public" | "members" | no | |
guestComments | boolean | no | |
guestWrites | boolean | no | |
viewers | object | no |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
id | string | yes | |
name | string | yes | |
workspace | object | yes | |
visibility | "public" | "members" | yes | |
guestComments | boolean | yes | |
guestWrites | boolean | yes | |
viewers | object | yes | |
latestVersion | integer | yes | |
path | string | yes | |
url | string | yes | |
shareUrl | string | null | yes | |
kind | "repo" | "room" | "app" | yes (default "repo") | |
permissions | object | yes | |
createdAt | number | yes |
GET /v1/spaces/:id/head
Response
| Field | Type | Required | Notes |
|---|---|---|---|
latestVersion | integer | yes | |
commentsUpdatedAt | number | yes |
POST /v1/spaces/:id/push/plan
Body
| Field | Type | Required | Notes |
|---|---|---|---|
files | object[] | yes |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
baseVersion | integer | yes | |
missing | string[] | yes | |
diff | object | yes |
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
| Field | Type | Required | Notes |
|---|---|---|---|
files | object[] | yes | |
message | string | no |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
version | object | null | yes | |
diff | object | yes | |
url | string | yes |
GET /v1/spaces/:id/versions
Newest first
Response
| Field | Type | Required | Notes |
|---|---|---|---|
versions | object[] | yes |
GET /v1/spaces/:id/versions/:n
N = number or "latest"
Response
| Field | Type | Required | Notes |
|---|---|---|---|
version | object | yes | |
files | object[] | yes | |
diff | object | yes |
GET /v1/spaces/:id/files/*path
Request: ?v=<n>
Response
| Field | Type | Required | Notes |
|---|---|---|---|
versionNumber | integer | yes | |
file | object | yes | |
content | string | yes | |
rawUrl | string | null | yes |
GET /v1/spaces/:id/history/*path
Response
| Field | Type | Required | Notes |
|---|---|---|---|
entries | object[] | yes |
GET /v1/spaces/:id/comments
Query
| Field | Type | Required | Notes |
|---|---|---|---|
path | string | no | |
status | "open" | "resolved" | "all" | no (default "open") |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
threads | object[] | 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
| Field | Type | Required | Notes |
|---|---|---|---|
path | string | yes | |
body | string | yes | |
quote | string | no | |
anchor | object | no | |
parentId | string | no | |
versionNumber | integer | no | |
guest | object | no |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
id | string | yes | |
path | string | yes | |
versionNumber | integer | yes | |
parentId | string | null | yes | |
author | object | yes | |
guestName | string | null | yes | |
origin | object | null | yes | |
body | string | yes | |
quote | string | null | yes | |
anchor | object | null | yes | |
via | string | null | yes | |
resolvedAt | number | null | yes | |
resolvedBy | object | null | yes | |
resolvedVia | string | null | yes | |
editedAt | number | null | yes | |
editedBy | object | null | yes | |
editedVia | string | null | yes | |
revisions | integer | yes | |
createdAt | number | yes |
PATCH /v1/comments/:id
Author only (a guest: with their key); old text kept as a revision
Body
| Field | Type | Required | Notes |
|---|---|---|---|
body | string | yes | |
guest | object | no |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
id | string | yes | |
path | string | yes | |
versionNumber | integer | yes | |
parentId | string | null | yes | |
author | object | yes | |
guestName | string | null | yes | |
origin | object | null | yes | |
body | string | yes | |
quote | string | null | yes | |
anchor | object | null | yes | |
via | string | null | yes | |
resolvedAt | number | null | yes | |
resolvedBy | object | null | yes | |
resolvedVia | string | null | yes | |
editedAt | number | null | yes | |
editedBy | object | null | yes | |
editedVia | string | null | yes | |
revisions | integer | yes | |
createdAt | number | yes |
DELETE /v1/comments/:id
Author (a guest: with their key), or canPush; deletes the replies too
Body
| Field | Type | Required | Notes |
|---|---|---|---|
guest | object | no |
Response: 204, no body
GET /v1/comments/:id/revisions
Every version, oldest first (empty if never edited)
Response
| Field | Type | Required | Notes |
|---|---|---|---|
revisions | object[] | yes |
POST /v1/comments/:id/resolve
Thread author, or canPush on the space (403 otherwise)
Response
| Field | Type | Required | Notes |
|---|---|---|---|
id | string | yes | |
path | string | yes | |
versionNumber | integer | yes | |
parentId | string | null | yes | |
author | object | yes | |
guestName | string | null | yes | |
origin | object | null | yes | |
body | string | yes | |
quote | string | null | yes | |
anchor | object | null | yes | |
via | string | null | yes | |
resolvedAt | number | null | yes | |
resolvedBy | object | null | yes | |
resolvedVia | string | null | yes | |
editedAt | number | null | yes | |
editedBy | object | null | yes | |
editedVia | string | null | yes | |
revisions | integer | yes | |
createdAt | number | yes |
POST /v1/comments/:id/unresolve
Thread author, or canPush on the space (403 otherwise)
Response
| Field | Type | Required | Notes |
|---|---|---|---|
id | string | yes | |
path | string | yes | |
versionNumber | integer | yes | |
parentId | string | null | yes | |
author | object | yes | |
guestName | string | null | yes | |
origin | object | null | yes | |
body | string | yes | |
quote | string | null | yes | |
anchor | object | null | yes | |
via | string | null | yes | |
resolvedAt | number | null | yes | |
resolvedBy | object | null | yes | |
resolvedVia | string | null | yes | |
editedAt | number | null | yes | |
editedBy | object | null | yes | |
editedVia | string | null | yes | |
revisions | integer | yes | |
createdAt | number | yes |
POST /v1/spaces/:id/db/query
View; write: true needs push (401 signed out / 403, never downgraded)
Body
| Field | Type | Required | Notes |
|---|---|---|---|
sql | string | yes | |
params | (string | number | null | boolean | object)[] | no | |
write | boolean | no |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
columns | string[] | yes | |
rows | ((string | number | null | object)[])[] | yes | |
rowsRead | number | yes | |
rowsWritten | number | yes | |
truncated | boolean | yes |
GET /v1/spaces/:id/db
View; tables, columns, row counts, size
Response
| Field | Type | Required | Notes |
|---|---|---|---|
tables | object[] | yes | |
databaseSize | number | yes |
GET /v1/spaces/:id/db/exists
View; { hasTables }, no row counts
Response
| Field | Type | Required | Notes |
|---|---|---|---|
hasTables | boolean | yes |
GET /v1/spaces/:id/db/guest-writes
Push; the named writes guests may run
Response
| Field | Type | Required | Notes |
|---|---|---|---|
statements | object[] | yes |
PUT /v1/spaces/:id/db/guest-writes
Push; replaces the set; each must be one write statement
Body
| Field | Type | Required | Notes |
|---|---|---|---|
statements | object[] | yes |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
statements | object[] | yes |
GET /v1/spaces/:id/db/writes
Push; the write log, newest first, with guest name and origin
Query
| Field | Type | Required | Notes |
|---|---|---|---|
limit | integer | no (default 100) |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
writes | object[] | 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
| Field | Type | Required | Notes |
|---|---|---|---|
before | number | yes |
POST /v1/spaces/:id/db/restore
Admin; point-in-time restore, last 30 days
Body
| Field | Type | Required | Notes |
|---|---|---|---|
at | string (date-time) | integer | yes |
Response
| Field | Type | Required | Notes |
|---|---|---|---|
restoredTo | number | yes | |
undoBookmark | string | yes |