Volumes.create(...) and attach it to any number of sandboxes at create time via Sandbox.create(volumes=[...]). On boot, Declaw streams the blob from object storage and materializes its regular-file entries under the attachment’s mount_path before the first command runs.
Volumes are the right fit when you want to:
- Re-use the same dataset, model weights, or reference code across many short-lived sandboxes without re-uploading bytes each time
- Stage data before the sandbox exists (CI pipelines, fanout workloads)
- Let multiple parallel sandboxes read the same files without a per-sandbox upload step
Phase 1 contract
- Format: only gzip-compressed tar archives (
application/gzip). Any file-type metadata in the tar is honored; symlinks, hardlinks, device nodes, and entries containing..are dropped for safety. - Size: upload body is capped at 4 GiB.
- Semantics: read-at-boot. A volume is materialized into each sandbox’s overlay filesystem when it attaches. Writes inside the sandbox are private to that sandbox and never flow back to the volume.
- Ownership: a volume is strictly owner-scoped. You can attach only your own volumes.
Volumes.create()
Upload a tar.gz and register it.
Human-readable name. Not used for addressing — the server returns a stable
volume_id.The blob body.
bytes, a file-like object open in binary mode, and iterables of byte chunks are streamed as-is. A path-like pointing at a file or directory is tarred and gzipped in-memory (convenience for small trees; pre-build the archive for large ones).Content-Type header sent with the upload. Leave as default for Phase 1.
Override the API key from environment.
Override the API domain (e.g.
api.declaw.ai).Per-request timeout in seconds. Bump this for multi-GiB uploads (default
httpx timeout is 30s).Volume with volume_id, owner_id, name, blob_key, size_bytes, content_type, metadata, and created_at.
Volumes.list()
List all volumes owned by the caller, newest first.
Volumes.get()
Fetch metadata for a single volume.
NotFoundException if the volume does not exist or is owned by a different tenant.
Volumes.delete()
Delete the blob and the metadata row.
Attaching to a sandbox
Passvolumes=[...] to Sandbox.create():
One or more attachments. Each is either a
VolumeAttachment(volume_id, mount_path) dataclass or a plain {"volume_id": ..., "mount_path": ...} dict. mount_path must be an absolute path and must not target a system directory (/, /etc, /usr, /proc, /sys, /dev, /bin, /sbin, /lib, /lib64, /var, /run, /boot).volume_id can appear in many sandbox-create calls in parallel; each sandbox gets its own materialized copy on its overlay.
Async
Every call has an awaitable mirror:What Volume looks like
Errors
| Situation | Exception | HTTP |
|---|---|---|
| Volume not found or not owned by caller | NotFoundException | 404 |
mount_path is a system directory or relative | InvalidArgumentException | 400 |
Referenced volume_id doesn’t belong to caller at attach time | AuthenticationException | 403 |
| Upload body exceeds 4 GiB | InvalidArgumentException | 413 |