List, search, patch, upload, and download·View as Markdown

Files

Base: /workspaces/{workspaceId}/buckets/{bucketId}/files

GET .../files · files:read

QueryDescription
prefixKey prefix filter
parentPrefixExact parent folder
searchCase-insensitive key contains (or semantic query)
tagFilter by tag
semantic=1CLIP/pgvector search when search is set
limitMax 500 (default 100)
offsetPagination
curl -s -H "Authorization: Bearer $FR_KEY" \
  "$BASE/workspaces/$WS/buckets/$BUCKET/files?search=italy&semantic=1&limit=10" | jq

File shape (serialized):

{
  "id": "...",
  "bucketId": "...",
  "workspaceId": "...",
  "key": "photos/italy.jpg",
  "parentPrefix": "photos/",
  "size": 12345,
  "lastModified": "...",
  "etag": "...",
  "contentType": "image/jpeg",
  "isFolder": false,
  "thumbnailKey": "...",
  "tags": ["travel", "italy"],
  "description": "...",
  "contentHash": null,
  "embeddingStatus": "ready",
  "enrichedAt": "...",
  "url": "https://cdn.example.com/photos/italy.jpg",
  "thumbnailUrl": "https://cdn.example.com/.thumbs/photos/italy.jpg"
}

Semantic hits may include distance.

url is the public CDN URL when the bucket has publicDomain. Use it to display or embed the file (images, markdown). It does not expire. thumbnailUrl is the public thumb when a thumbnail exists. Both are null when the bucket has no public domain — then call presign_view (inline display) or presign_download (attachment). S3 view/download presigns cannot be non-expiring. Public CDN cannot force a download.

Get / patch / delete

  • GET .../files/{fileId} · files:read
  • PATCH .../files/{fileId} · files:write — body { tags?, description? }
  • DELETE .../files/{fileId} · files:delete — Trash (or hard-delete if Trash is off)

Trash / move

  • POST .../files/trash · files:delete — { "keys": ["a.jpg"] }
  • POST .../files/move · files:write — { "moves": [{ "fromKey", "toKey" }] }

See Automations & Trash.

Similar

GET .../files/{fileId}/similar?limit=20 · files:read

Vector neighbors (requires embedding).

Folders

POST .../folders · files:write

{ "key": "albums/2026/" }

Upload

A PUT to the bucket does not list the file. file.rocks lists from its index. You must complete the upload.

Agents: use MCP. Call presign_upload, PUT, then complete_upload. Do not POST this REST upload-complete route from an agent HTTP client (Cloudflare 1010). Guide: Upload flow.

Presign

POST .../files/presign-upload · files:upload

{ "key": "inbox/shot.jpg", "contentType": "image/jpeg" }

Returns { url, key, method: "PUT", headers, next }. PUT the bytes to url.

Complete (register)

POST .../files/upload-complete · files:upload (not files:write)

{ "key": "inbox/shot.jpg", "size": 12345, "etag": "...", "contentType": "image/jpeg" }

After this, GET .../files returns the object. The file payload includes url / thumbnailUrl when the bucket has a public domain — use url to display the image. Tags still need PATCH .../files/{fileId} (files:write).

If the object is already in the bucket, you can call upload-complete / complete_upload with the key and skip presign+PUT.

Presign view / download

POST .../files/presign-download · files:download

{ "key": "photos/italy.jpg", "as": "view", "purpose": "preview" }

or { "fileId": "..." }.

FieldValues
asview (default, inline display) or download (attachment)
purposepreview (1 hour, default) or embed (7 days)
expiresInseconds, 60–604800, optional override

Returns { url, key, method, as, disposition, durable, purpose, expiresIn, expiresAt, note }.

  • as=view + publicDomain → durable CDN URL (file.url). Browser displays the file.
  • as=download → always a signed attachment URL (even with publicDomain). Browser saves the file. Expires.

MCP exposes these as two tools: presign_view and presign_download. S3-compatible buckets only for signed URLs.

Files · file.rocks docs