Skip to main content

Overview

The StorageClient is the Room API for room-scoped files and folders. Use it to store shared inputs, outputs, artifacts, and attachments that humans, agents, and services in the same room need to read or write.

CLI commands

Start with the CLI help, then use a few common commands:
bash

Why use the Storage API?

  • Share files between people, agents, and deployed services without wiring separate object storage access.
  • Store outputs such as reports, logs, generated media, or intermediate artifacts.
  • Download file contents directly or get a downloadable URL when you need to hand a file to another system.

How it works

Paths are relative to the room storage root. Use upload or uploadStream to write files, download or downloadStream to read them back, and download_url / downloadUrl when you need a fetchable URL for another system. The API also emits file.updated, file.deleted, and file.moved events so other participants can react to changes.

Permissions and grants

upload / uploadStream and download / downloadStream / download_url require a storage grant on the participant token for the target path. Storage grants are path-based, which lets you give a service access to only part of room storage. In the current server implementation, list, exists, stat, and delete are not gated by storage grants. Use API Scopes and Service YAML for the full scope model.

Events

The storage system emits three types of events:
  • file.updated
    Triggered when a file is created or updated. Python and .NET handlers receive path and participant_id. JS/TS and Dart handlers receive a FileUpdatedEvent with .path.
  • file.deleted
    Triggered when a file is deleted. Python and .NET handlers receive path and participant_id. JS/TS and Dart handlers receive a FileDeletedEvent with .path.
  • file.moved Triggered when a file or folder is moved. Python and .NET handlers receive source_path, destination_path, and participant_id. JS/TS and Dart handlers receive a FileMovedEvent with .sourcePath and .destinationPath.
You can remove an event handler with:

API reference

Use the methods below to inspect room storage, upload and download files, and clean up stored artifacts. Each method is asynchronous, so you should await the call.

exists(path)

Description Checks if a file or folder exists at the given path. Parameters
  • path (str): The path to check.
Returns
  • (bool): True if the file or folder exists; False otherwise.
Example:

stat(path)

Description
Fetch basic metadata (exists, folder flag, created/updated timestamps) for a file or folder.
Parameters
  • path (str): The path to inspect.
Returns
  • StorageEntry | None: Entry when present; None if not found.
The server returns name, is_folder, created_at, and updated_at fields. SDKs that expose stat parse timestamps into native datetime types. Example:
  • Availability: Python, JavaScript/TypeScript, and Dart SDKs expose stat.

upload(path, data, overwrite=False, name=None, mime_type=None)

Description
Uploads a complete file payload in one call. Use this when you already have the bytes in memory.
Parameters
  • path (str): The destination file path.
  • data (bytes / Uint8Array / byte[]): The file contents to write.
  • overwrite (bool, optional): Whether to replace an existing file at that path.
  • name (optional): File-name metadata for the stored object. Defaults to the basename of path in SDKs that infer it.
  • mime_type / mimeType (optional): MIME type metadata. Python, JavaScript/TypeScript, and Dart infer a MIME type from the file name when omitted.
Returns
  • None
Example:

upload_stream(path, chunks, overwrite=False, chunk_size=65536, size=None, name=None, mime_type=None)

Description
Streams file contents chunk-by-chunk. Use this when you do not want to materialize the whole file in memory at once.
Parameters
  • path (str): The destination file path.
  • chunks: An async iterable / stream / IAsyncEnumerable<byte[]> of file chunks.
  • overwrite (optional): Replace an existing file at that path.
  • size (optional): Total byte size when you already know it.
  • chunk_size / chunkSize (optional): Pull size for streamed uploads.
  • name (optional): File-name metadata for the upload stream. Defaults to the basename of path in SDKs that infer it.
  • mime_type / mimeType (optional): MIME type metadata for the upload stream. Python, JavaScript/TypeScript, and Dart infer a MIME type from the file name when omitted.
Returns
  • None
Example:

download_stream(path, chunk_size=65536)

Description
Streams a file back as metadata plus data chunks. Use this for larger files or when you want to process the response incrementally.
Parameters
  • path (str): The file path to download.
  • chunk_size / chunkSize (optional): Requested chunk size for streamed downloads.
Returns
  • A stream / async iterator of binary chunks. The first chunk carries metadata such as file name, MIME type, and size.
Example:

download(path)

Description
Retrieves the content of a file from the remote storage. This loads the entire file into memory; use download_url for large files or streaming.
Parameters
  • path (str): The file path to download.
Returns
  • File-like Response: Contains the file’s raw data, typically accessible through a .data property.
Example:

download_url(path)

Description
Requests a downloadable URL for the specified file path, which can be used to fetch the file directly (e.g., via HTTP). The exact protocol or format of the returned URL may vary, and may be a signed URL if the backing storage provider supports it.
Parameters
  • path (str): The file path to retrieve a download URL for.
Returns
  • (str): A URL string you can fetch with your own HTTP or other suitable client.
Example:

list(path)

Description
Lists the contents of a folder, returning file and subfolder names along with a flag indicating if each entry is a folder. The server also returns created_at and updated_at timestamps; the Python SDK exposes them on StorageEntry.
Parameters
  • path (str): The folder path to list.
Returns
  • (list): A list of entries, each containing a name and is_folder property. Timestamps are available in SDKs that surface them.
Example:

delete(path, recursive=None)

Description
Deletes a file or folder at the given path. A file.deleted event is typically emitted afterward. To delete a folder, pass recursive=True where the SDK exposes that option, or call the raw storage.delete request with the recursive flag.
Parameters
  • path (str): The file path to delete.
  • recursive (bool, optional): Set True to delete folders recursively (Python helper or raw request).
Returns
  • None
Example:

move(source_path, destination_path, overwrite=False)

Description Moves or renames a file or folder. A file.moved event is typically emitted afterward. Parameters
  • source_path (str): The current file or folder path.
  • destination_path (str): The new file or folder path.
  • overwrite (bool, optional): Whether to replace an existing destination.
Returns
  • None
Example:

Example Workflow

A common use case:
  1. Check if a file exists.
  2. Upload data if it doesn’t exist.
  3. Later, download the file to verify or use the data.
  4. Delete the file when it’s no longer needed, reacting to the file.deleted event.
This sequence demonstrates basic upload, read, and deletion flows within a single session.