Drive
Knobs Drive stores workspace files in a folder tree. File bytes never transit the API: uploads go browser/client → Google Cloud Storage through a resumable session URI the API mints, and downloads use short-lived signed URLs.
All routes are workspace-scoped and accept a session JWT or API key.
Browsing
Section titled “Browsing”| Endpoint | Description |
|---|---|
GET /v1/workspaces/{wid}/drive/nodes |
List nodes; ?parentId= (root when empty), ?kind=, ?category=, ?q=, ?sort=, ?order=, ?limit=, ?cursor= → {nodes, nextCursor} |
GET /v1/workspaces/{wid}/drive/quota |
Storage usage {usedBytes, quotaBytes} |
curl -H "Authorization: Bearer knak_..." \ "https://api.knobs.io/v1/workspaces/{wid}/drive/nodes?parentId=&limit=50"Image nodes with a ready thumbnail include a transient signed previewUrl in the listing.
Folders
Section titled “Folders”| Endpoint | Description |
|---|---|
POST /v1/workspaces/{wid}/drive/folders |
Create a folder {parentId, name} |
POST /v1/workspaces/{wid}/drive/nodes |
Same create (generic node form, {parentId, name, kind}) |
Uploading a file
Section titled “Uploading a file”Three steps — open a session, PUT the bytes to storage, finalize:
| Endpoint | Description |
|---|---|
POST /v1/workspaces/{wid}/drive/uploads |
Open a resumable upload {parentId, name, mime, size} → 201 {node, uploadUrl, uploadHeaders} |
POST /v1/workspaces/{wid}/drive/nodes/{nid}/finalize |
Finalize after the bytes land: checksums, creates the revision, kicks off previews/indexing |
POST /v1/workspaces/{wid}/drive/uploads/{rpc...} |
RPC alias — {nid}:finalize is equivalent to the finalize call above |
# 1. open the sessioncurl -X POST https://api.knobs.io/v1/workspaces/{wid}/drive/uploads \ -H "Authorization: Bearer knak_..." \ -H "Content-Type: application/json" \ -d '{"parentId": "", "name": "report.pdf", "mime": "application/pdf", "size": 482113}'{ "node": { "id": "n_77aa…", "name": "report.pdf", "kind": "file", "status": "uploading" }, "uploadUrl": "https://storage.googleapis.com/…", "uploadHeaders": { "Content-Type": "application/pdf" }}# 2. put the bytes (resumable-capable; a single PUT works for small files)curl -X PUT --upload-file report.pdf -H "Content-Type: application/pdf" "<uploadUrl>"
# 3. finalizecurl -X POST -H "Authorization: Bearer knak_..." \ https://api.knobs.io/v1/workspaces/{wid}/drive/nodes/{nid}/finalizeUploads that would exceed the workspace storage quota fail with 402 quota_exceeded.
Downloading
Section titled “Downloading”| Endpoint | Description |
|---|---|
GET /v1/workspaces/{wid}/drive/nodes/{nid}/download-url |
Short-lived signed URL → {url} |
GET /v1/workspaces/{wid}/drive/nodes/{nid}/download |
Same response (alias) |
url=$(curl -s -H "Authorization: Bearer knak_..." \ https://api.knobs.io/v1/workspaces/{wid}/drive/nodes/{nid}/download-url | jq -r .url)curl -o report.pdf "$url"Sharing
Section titled “Sharing”| Endpoint | Description |
|---|---|
POST /v1/workspaces/{wid}/drive/nodes/{nid}/shares |
Grant {uid, role} on a node |
GET /v1/workspaces/{wid}/drive/nodes/{nid}/shares |
List grants + inheritance breaks |
Trash marks the top node; children follow. Purging is permanent and asynchronous.
| Endpoint | Description |
|---|---|
PATCH /v1/workspaces/{wid}/drive/nodes/{nid} |
Exactly one of {trash: true} or {restore: true} |
GET /v1/workspaces/{wid}/drive/trash |
List trashed nodes you can read |
DELETE /v1/workspaces/{wid}/drive/nodes/{nid} |
Permanently purge a trashed node → 202 (recursive, async) |
POST /v1/workspaces/{wid}/drive/trash:empty |
Purge everything in the trash → 202 {purging: n} |