Direct File Operations for AI Agent Storage over HTTP, SDK, and CLI
Persistent storage is a core part of any serious AI agent system. Agents need somewhere to keep workspaces, caches, checkpoints, generated artifacts, and shared datasets that survive beyond one container lifetime.
Usually, the next step is obvious: mount the volume into a sandbox and let the agent read and write files through a normal POSIX path.
That is still the right model when the agent itself is doing the work.
But not every file operation belongs inside a running sandbox.
Sometimes you want to upload an input file before the agent starts. Sometimes you want to inspect an output artifact after the agent finishes. Sometimes you want a control-plane worker to scaffold a directory tree, rename a result, stream file change events, or connect external tooling to a persistent workspace. In all of those cases, forcing the operation through a sandbox mount adds another runtime, another lifecycle, and another place where state has to be coordinated.
Sandbox0 now supports direct file operations on Volumes by volume ID. The same persistent storage layer can be reached over raw HTTP, the SDKs, and the s0 CLI, without mounting the Volume into a Sandbox first.
Why Direct Volume File Operations Matter#
The simplest mental model is this: a sandbox is the execution plane, but a Volume is the storage plane.
Mounting a Volume into a sandbox is ideal when a process inside that sandbox needs filesystem access. But there is a second class of operations that are storage-oriented rather than process-oriented:
- seed a workspace before claiming a sandbox
- inspect outputs after a sandbox stops
- run platform automation against persistent agent data
- attach developer tooling to a Volume without starting a runtime
- watch a path for changes from outside the sandbox lifecycle
Without a direct file API, teams usually fall back to one of three awkward patterns:
Keep a sandbox alive just to do file I/O. This works, but it couples a simple storage operation to sandbox scheduling, TTLs, process state, and mount management.
Push files through context windows or ad hoc uploads. This breaks down quickly for anything beyond small snippets. It is expensive, lossy, and hard to automate safely.
Treat object storage as the app interface. That gives up normal filesystem semantics and forces every tool to know bucket layouts, object keys, and serialization rules.
Direct Volume file operations are the middle layer those systems are usually missing: persistent filesystem-backed storage that can be controlled independently of the sandbox runtime.
The Model: Same Volume, Separate Access Paths#
Sandbox0 Volumes are still the same persistent storage units described in the broader Sandbox0 storage model. They still support snapshots, forks, access modes, and sandbox mounts. What changes is how you reach the files.
You now have two valid ways to work with the same Volume:
- Mount it into a sandbox and use normal POSIX file operations from inside the runtime
- Address it directly by volume ID over HTTP, SDK, or CLI from outside the sandbox
This is not a second storage system and it does not create a duplicate copy of the data. It is the same Volume namespace with an additional access path.
Requests still go through the normal gateway chain and team-scoped authorization. Internally, storage-proxy lazily attaches the Volume for direct access and reclaims idle direct mounts later. In other words, the direct file path is integrated into the existing storage architecture instead of adding a separate service boundary.
What You Can Do Directly#
The direct Volume file API covers the core file operations most control-plane and tooling workflows need:
- read a file
- write a file
- create directories
- stat a path
- list a directory
- move or rename a file or directory
- delete a file or directory
- upload and download local files through the CLI
- watch a path over WebSocket for change events
The API surface mirrors the Sandbox file API closely, which matters for two reasons.
First, it is easier to reason about. If you already understand file operations inside a sandbox, the direct Volume interface feels familiar.
Second, the SDK and CLI can expose one consistent set of helpers:
- Go:
ReadVolumeFile,WriteVolumeFile,ListVolumeFiles,WatchVolumeFiles - Python:
client.volumes.read_file,write_file,list_files,watch_files - TypeScript:
client.volumes.readFile,writeFile,listFiles,watchFiles - CLI:
s0 volume files ...
That symmetry makes it practical to combine them in one workflow. A platform service can seed a Volume with the SDK, an agent can mount that Volume later, and an operator can inspect the result with the CLI afterward.
Raw HTTP, SDK, and CLI: Three Interfaces to the Same Storage Control Plane#
The raw HTTP form is the lowest-level interface. It is useful when you are integrating Sandbox0 storage into another service, job runner, controller, or internal platform.
Write a file:
bashcurl -X POST \ "$SANDBOX0_BASE_URL/api/v1/sandboxvolumes/vol_abc123/files?path=/docs/readme.txt" \ -H "Authorization: Bearer $SANDBOX0_TOKEN" \ -H "Content-Type: application/octet-stream" \ --data-binary @./README.txt
Read it back:
bashcurl \ "$SANDBOX0_BASE_URL/api/v1/sandboxvolumes/vol_abc123/files?path=/docs/readme.txt" \ -H "Authorization: Bearer $SANDBOX0_TOKEN" \ -o ./readme.txt
List a directory:
bashcurl \ "$SANDBOX0_BASE_URL/api/v1/sandboxvolumes/vol_abc123/files/list?path=/docs" \ -H "Authorization: Bearer $SANDBOX0_TOKEN"
If you prefer typed helpers and fewer raw requests, the SDKs wrap the same endpoints directly:
typescriptconst volumeId = "vol_abc123"; await client.volumes.mkdir(volumeId, "/workspace/input", true); await client.volumes.writeFile(volumeId, "/workspace/input/task.json", JSON.stringify({ repo: "example/repo", branch: "main", })); const entries = await client.volumes.listFiles(volumeId, "/workspace/input"); console.log(entries.map((entry) => entry.path));
And if the workflow is operator- or developer-driven, the CLI is often the cleanest interface:
bashs0 volume files mkdir vol_abc123 /workspace/input --parents s0 volume files upload vol_abc123 ./task.json /workspace/input/task.json s0 volume files ls vol_abc123 /workspace/input s0 volume files cat vol_abc123 /workspace/input/task.json
That mix matters operationally. The storage layer is accessible from automation, from application code, and from the command line without inventing different concepts for each one.
Where This Fits in an AI Agent Architecture#
The direct Volume file path is especially useful in workflows that are partly agent-driven and partly platform-driven.
1. Pre-staging Inputs Before an Agent Starts#
Suppose an orchestrator receives a task, builds an input manifest, and prepares a workspace before claiming a sandbox. With direct Volume file operations, that orchestrator can create the directory tree, upload configuration files, and write task metadata to the Volume first.
Only after the storage is ready does it need to claim a sandbox and mount the prepared Volume.
That separates storage setup from runtime scheduling cleanly.
2. Post-run Artifact Collection#
Many agent tasks produce outputs that need to be inspected, copied, archived, or handed to another system after the runtime is gone. If those artifacts live in a Volume, a control-plane worker can retrieve them directly by volume ID. There is no need to keep a sandbox alive just so another system can cat a file.
3. Local Tooling and Automation#
A CLI, CI job, or admin tool can manipulate persistent agent state directly:
- upload a seed dataset
- inspect whether an expected file exists
- move completed artifacts into an archive path
- stream change events from a directory
- download outputs for offline review
These are not agent tasks. They are platform tasks.
4. Shared Storage Across Independent Lifecycles#
One of the deeper benefits is lifecycle separation. The sandbox lifecycle and the storage lifecycle do not have to move in lockstep.
You can create and mutate a Volume before any sandbox exists. You can continue to inspect or modify that Volume after the sandbox is gone. You can even combine this with snapshots and forks:
- write base inputs directly to a parent Volume
- fork the Volume for multiple agents
- mount each fork into a different sandbox
- collect outputs from the forks directly over the file API
That is a cleaner architecture than treating every storage action as a side effect of an active container.
Direct File Operations Are Not a Replacement for Mounts#
This capability is important, but it is not a new universal default. Sandbox mounts still matter because agents need a real filesystem path when they run tools, compilers, package managers, shells, browsers, or application servers.
The clean way to think about it is:
Use sandbox mounts when the process inside the sandbox needs local filesystem semantics.
Use direct Volume file operations when an external system needs storage control without a runtime.
That boundary is what makes the feature useful. It lets you stop abusing one model for the other.
If your workload needs large-scale workspace movement, use snapshots, forks, or explicit upload/download flows depending on whether you need a point-in-time copy or a direct file transfer. If the task is a direct storage mutation or inspection, the Volume HTTP interface is the simpler tool.
Watching a Volume from Outside the Sandbox#
One detail that is easy to miss but architecturally important is file watching.
The direct file API is not limited to one-shot reads and writes. It also supports watching a path over WebSocket for events such as:
createwriteremoverenamechmodinvalidate
That means external tooling can react to persistent workspace changes without running inside the sandbox itself.
For example:
- a platform service can wait for an expected output file to appear
- a local developer tool can mirror activity from a shared Volume
- an orchestration layer can subscribe to a working directory and trigger follow-up steps when a file is written
This is one of the clearest signs that the feature belongs in the storage control plane, not only in the sandbox runtime plane.
Security and Access Model#
The direct Volume file path does not bypass the rest of Sandbox0's control model.
Requests still flow through the normal gateway path and remain team-scoped. The docs are explicit that read operations use sandboxvolumefile:read, while write, move, mkdir, and delete operations use sandboxvolumefile:write.
That matters if you want to let external tools or automation inspect a persistent workspace without giving them broader sandbox execution privileges. File access and runtime access can stay separate.
Operational Notes#
There are a few boundaries worth keeping explicit.
Paths are always resolved relative to the Volume root, using absolute logical paths such as /docs/readme.txt.
POST /files is overloaded intentionally: it writes file content by default, and creates directories when mkdir=true is set.
Directory deletion is recursive.
Large transfers are not what this interface is optimized for. The direct HTTP handler currently enforces a file size cap, so bulk data movement should still prefer the more appropriate workflow for the job, such as snapshots or explicit artifact upload/download.
That is a good design boundary. The direct Volume file path is for precise control-plane file operations, not for pretending every storage workflow is a giant HTTP upload.
FAQ#
Does this replace mounting Volumes into sandboxes?
No. It adds a direct access path for storage-oriented workflows outside the sandbox lifecycle. Agents running inside a sandbox still use mounts when they need a normal filesystem path.
Is this a different storage backend from mounted Volumes?
No. It is the same Volume namespace and the same persistent storage layer, reached through a different interface.
When should I use the direct file API?
Use the direct file API when you need explicit storage operations by volume ID: upload, download, stat, list, move, delete, or watch. Use snapshots or forks when you need point-in-time copies, branching, or rollback behavior.
Can I automate this entirely without raw HTTP?
Yes. The Go, Python, and TypeScript SDKs expose helpers for the same operations, and the s0 volume files commands cover common operator workflows from the CLI.
Can I watch for file changes without a running sandbox?
Yes. The direct Volume file API includes a WebSocket watch endpoint, and the SDKs and CLI expose watch helpers on top of it.
The direct file API is documented in the Volume HTTP section of the Sandbox0 docs. If the process inside the sandbox needs a normal filesystem path, see Volume Mounts. For the broader storage model — persistent Volumes, snapshots, forks, and access modes — see Persistent Storage for AI Agent Sandboxes.