Technical docs

Storage

Overview

Support reference for the org Storage page (`/storage`) and the org storage APIs behind it.

For the organization private API surface under `/api/private`, see `private-api.md`.

What users can do in `/storage`

  • Browse folders with URL-backed navigation via `?path=...`.
  • Switch between list and grid views.
  • Search the current folder, sort, hide/show columns, and filter by file type and modified date.
  • Select multiple items and bulk delete.
  • Create folders.
  • Upload by file picker, drag-and-drop, or folder upload.
  • Download files.
  • Copy file or folder paths.
  • Share folders with AI teammates.
  • Open non-folder items in Cowork via `/cowork?path=...`.

Current file actions in the UI

  • Files: `Download`, `Copy Path`, `Delete`.
  • Folders: `Share`, `Copy Path`, `Delete`.
  • The Storage UI does not currently expose rename, copy, or move actions, even though org APIs exist for them.
  • The code still contains an unused details panel, but `/storage` does not currently expose a working details action.

Upload rules

  • Allowed upload types: `png`, `jpg`, `jpeg`, `gif`, `webp`, `svg`, `pdf`, `docx`, `xlsx`, `pptx`, `txt`, `htm`, `html`, `md`, `csv`, `json`, `yaml`, `yml`.
  • Max upload size: `10 MB` per file.
  • In the `/storage` UI, individual files cannot be uploaded to root (`/`).
  • The org and private upload APIs still allow root uploads when `path` is omitted.
  • Root-level folder uploads are allowed.
  • Duplicate handling offers `Skip existing` and `Replace`.
  • Upload UI supports pause, resume, retry, cancel, and persistent progress.

Sharing behavior

  • Only folders can be shared.
  • Root (`/`) cannot be shared.
  • Sharing uses a dedicated dialog with AI teammates in the org, but Ally is not presented as a normal editable row there.
  • The dialog always shows an `Ally` row with both `Read` and `Write` checked and disabled.
  • The dialog text for Ally says `Full storage access is automatic.`
  • Ally is the only special system-backed teammate in this share list.
  • Permissions are `read` and `write`.
  • In the current dialog, enabling `write` also enables `read`.
  • If `write` is removed, `read` remains checked unless it is inherited from a parent share.
  • `read` is disabled when it is inherited or when `write` is checked, so the dialog never allows write-only access.
  • Parent-folder permissions appear as inherited (`from_parent: true`) and cannot be toggled from the child folder.
  • Deleting a folder or file path removes matching share records for that path and nested paths.

Indexing and search

  • Storage rows can show indexing states: `Indexed`, `Queued for indexing`, `Indexing…`, `Indexing failed`, `Not indexable`.
  • Vector indexing currently supports `.txt`, `.md`, `.docx`, `.pdf`, and `.pptx`.
  • Exact storage search is broader and can extract text from formats such as `docx`, `xlsx`, `pptx`, and `pdf`.
  • Valid uploads can still show `Not indexable`.

Org API routes

  • `GET /api/organizations/{orgId}/storage?path=...`
  • `GET /api/organizations/{orgId}/storage/stats?path=...`
  • `POST /api/organizations/{orgId}/storage/upload`
  • `GET /api/organizations/{orgId}/storage/download?path=...`
  • `DELETE /api/organizations/{orgId}/storage/file?path=...`
  • `POST /api/organizations/{orgId}/storage/folder`
  • `POST /api/organizations/{orgId}/storage/folder/rename`
  • `POST /api/organizations/{orgId}/storage/folder/copy`
  • `POST /api/organizations/{orgId}/storage/folder/move`
  • `GET /api/organizations/{orgId}/storage/file/content?path=...`
  • `PUT /api/organizations/{orgId}/storage/file/content`
  • `GET /api/organizations/{orgId}/storage/folder/share?path=...`
  • `POST /api/organizations/{orgId}/storage/folder/share`
  • `DELETE /api/organizations/{orgId}/storage/folder/share`

Cowork edit endpoints

  • `GET/PUT /storage/file/content` only allow existing `.txt` and `.md` files.
  • Upload is capped at `10 MB` by the API upload route. The cowork content route is existing-file only; current code does not show a separate content-endpoint size rule beyond file handling in the caller.

AI teammate storage permissions

  • Non-system AI teammates are still limited to folders explicitly shared with them.
  • `storage.list` returns only content inside shared folders for non-system AI teammates.
  • `storage.semantic_search` searches indexed documents inside readable shared folders for non-system AI teammates.
  • `storage.search`, `storage.read_file`, `storage.read_image`, and `storage.stat_file` require readable shared-folder access for non-system AI teammates.
  • `storage.get_temp_file_url` also requires readable shared-folder access for non-system AI teammates.
  • `storage.write_file` and `storage.edit_file` require writable shared-folder access for non-system AI teammates.
  • `storage.write_file` and `storage.edit_file` only support `.txt`, `.md`, `.htm`, `.html`, `.csv`, `.json`, `.yaml`, and `.yml`.
  • `storage.rename` requires the target path to be inside a writable shared folder for non-system AI teammates.
  • `storage.copy` requires readable source access and writable destination access for non-system AI teammates.
  • `storage.move` requires writable access to both source and destination for non-system AI teammates.
  • `storage.get_temp_file_url` returns a temporary HTTPS link for a readable file and is meant for external systems that need a URL instead of inline bytes.
  • Current temporary-link format is `{API_DOMAIN}/shared/files/{organization_id}/{run_id}/{document_id}`.
  • The temporary link only works while the workflow run that created it is still active; once the run completes or is aborted, the link expires.
  • `storage.get_temp_file_url` currently returns `File not found` when the file does not yet have an `OrganizationDocument` record.
  • Ally uses system-level storage access.

Realtime behavior

  • The backend emits `storage_file.created`, `storage_file.updated`, `storage_file.deleted`, `storage_file.renamed`, `storage_file.copied`, and `storage_file.moved`.
  • The current Storage file-list hook auto-refreshes on all six events.
  • Cowork document state also listens to rename and move events so an open document can follow its new path.

Private storage API (HTTPS)

  • The canonical private API reference now lives in `private-api.md`.
  • Private storage routes are under `{api_url}/api/private/storage`.
  • Current auth is `api-key: <TOKEN>` only.

Start building your AI team