Volumes
Persistent disks that outlive sandboxes. Create a volume once, attach it, and keep the data.
A volume is a persistent disk that outlives any sandbox. A sandbox reads and writes an attached volume like a local directory. Use volumes for datasets, model weights, build caches, or application state that sandboxes reuse.
Volumes are feature-gated per org. Manage them in the dashboard or through the API.
Constraints
- A volume attaches to one sandbox at a time.
- A volume lives on one host. It attaches only to sandboxes on that host.
- Snapshots and backups do not capture volume data.
- A volume is not replicated. If its host is lost, the volume is lost.
Create a volume
| Field | Type | Default | Notes |
|---|---|---|---|
size_gb | int 1–500 | 1 | Fixed after create |
mount_path | string | /mnt/data | Mount point inside the sandbox |
sandbox_id | string | — | Place the volume on that sandbox's host; auto-attach if the sandbox runs |
The call is synchronous. It returns when the disk is ready. If create fails, the API removes the volume. There is nothing to poll or clean up.
A new volume returns in state available. Pass a sandbox_id for a running sandbox and it returns attached. Omit sandbox_id and the API picks the host.
import { Platinum } from "@platinum-dev/sdk";
const client = new Platinum({ url: process.env.PT_API_URL, token: process.env.PT_TOKEN });
const vol = await client.volumes.create({ size_gb: 10, sandbox_id: "sbx_01K…" });from platinum import Platinum
client = Platinum(token="pt_live_…", api_url="https://api.platinum.dev")
vol = client.volumes.create(size_gb=10, sandbox_id="sbx_01K…")pt volume create --size 10curl -sS -X POST "$PT_API_URL/v1/volumes" \
-H "Authorization: Bearer $PT_TOKEN" \
-d '{"size_gb": 10, "mount_path": "/mnt/data", "sandbox_id": "sbx_01K…"}'Attach at sandbox create
Pass volume_ids at create. The scheduler places the sandbox on the volumes' host. Each volume mounts at its own mount_path during boot.
const vol = await client.volumes.create({ size_gb: 10 });
const sbx = await client.sandboxes.create(
{ template: "pt-base", volume_ids: [vol.id as string] },
{ waitForRunning: true },
);vol = client.volumes.create(size_gb=10)
sbx = client.sandboxes.create(template="pt-base", volume_ids=[vol["id"]], wait_for_running=True)# no CLI flag — use: pt api POST /v1/sandboxes -d '{"template":"pt-base","volume_ids":["vol_…"]}'curl -sS -X POST "$PT_API_URL/v1/sandboxes?wait_for_state=running" \
-H "Authorization: Bearer $PT_TOKEN" \
-d '{"template": "pt-base", "volume_ids": ["vol_…"]}'Attach to a running sandbox
The sandbox must run on the volume's host. Attach returns when the volume is mounted.
Attachments survive stop and start. The volume comes back mounted. When you delete the sandbox, the volume returns to available with data intact. A failed start also releases the volume.
await client.volumes.attach("vol_…", "sbx_01K…", { mountPath: "/mnt/cache" });client.volumes.attach("vol_…", "sbx_01K…", mount_path="/mnt/cache")pt volume attach vol_… --sandbox sbx_01K… --mount-path /mnt/cachecurl -sS -X POST "$PT_API_URL/v1/volumes/vol_…/attach" \
-H "Authorization: Bearer $PT_TOKEN" \
-d '{"sandbox_id": "sbx_01K…", "mount_path": "/mnt/cache"}'Move data between sandboxes
Detach the volume, then attach it to another sandbox on the same host. Detach flushes all writes to disk. The next attach sees exactly what the last writer left.
List and get
Pass includeDeleted to include deleted volume records in the list.
const vols = await client.volumes.list();
const one = await client.volumes.get("vol_…");
const all = await client.volumes.list({ includeDeleted: true });vols = client.volumes.list()
one = client.volumes.get("vol_…")
all_ = client.volumes.list(include_deleted=True)pt volume list
pt volume get vol_…# routes are listed in /docs/api — or use the SDK or CLIDetach
await client.volumes.detach("vol_…");client.volumes.detach("vol_…")pt volume detach vol_…curl -sS -X POST "$PT_API_URL/v1/volumes/vol_…/detach" \
-H "Authorization: Bearer $PT_TOKEN" -d '{}'Delete
Delete removes the data for good. The record stays for include_deleted listings, but the data is not recoverable. Delete fails while the volume is attached — detach first.
await client.volumes.delete("vol_…");client.volumes.delete("vol_…")pt volume rm vol_…# route is listed in /docs/api — or use the SDK or CLI