Sandboxes
Sandbox File System
Reading, writing, listing files, creating checkpoints, and downloading artifacts from Banata sandbox environments.
Every sandbox has a /workspace directory that serves as the root for your project files. The file system API lets you read, write, and list files remotely without needing a terminal session.
Reading Files
curl "https://api.boxes.banata.dev/v1/sandboxes/fs/read?id=SANDBOX_ID&path=/workspace/output.json" \
-H "Authorization: Bearer br_live_..."Both id and path are required query parameters.
Writing Files
curl -X POST "https://api.boxes.banata.dev/v1/sandboxes/fs/write" \
-H "Authorization: Bearer br_live_..." \
-H "Content-Type: application/json" \
-d '{
"id": "SANDBOX_ID",
"path": "/workspace/config.json",
"content": "{\"key\": \"value\"}"
}'All three fields (id, path, content) are required. If the file already exists, it is overwritten. Parent directories are created automatically.
Writing and executing code
A common pattern is writing a script file and then executing it:
// Write a script
await fetch("https://api.boxes.banata.dev/v1/sandboxes/fs/write", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
id: sandboxId,
path: "/workspace/scraper.ts",
content: `
const res = await fetch("https://api.example.com/data");
const data = await res.json();
await Bun.write("/workspace/output.json", JSON.stringify(data, null, 2));
console.log("Done:", data.length, "records");
`,
}),
});
// Execute it
await fetch("https://api.boxes.banata.dev/v1/sandboxes/exec", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
id: sandboxId,
command: "cd /workspace && bun run scraper.ts",
}),
});Listing Directories
curl "https://api.boxes.banata.dev/v1/sandboxes/fs/list?id=SANDBOX_ID&path=/workspace" \
-H "Authorization: Bearer br_live_..."id is required. path defaults to /workspace if omitted.
Checkpoints
Save a snapshot of the workspace and outputs to persistent storage:
curl -X POST "https://api.boxes.banata.dev/v1/sandboxes/checkpoint" \
-H "Authorization: Bearer br_live_..." \
-H "Content-Type: application/json" \
-d '{"id": "SANDBOX_ID"}'Checkpoints capture the workspace state and upload it to cloud storage. This is useful for:
- Preserving work before ending a sandbox
- Creating restore points during long-running tasks
- Saving outputs for later retrieval
To enable checkpointing, you can set capabilities.storage.workspace to "checkpointed" when creating the sandbox:
{
"runtime": "bun",
"capabilities": {
"storage": { "workspace": "checkpointed" }
}
}Artifacts
Artifacts are files produced by a sandbox that are persisted to cloud storage independently of the workspace.
Listing artifacts
curl "https://api.boxes.banata.dev/v1/sandboxes/artifacts?id=SANDBOX_ID" \
-H "Authorization: Bearer br_live_..."Response:
{
"id": "SANDBOX_ID",
"artifacts": {
"workspaceKey": "workspaces/org123/sandbox456.tar.gz",
"checkpointKey": "checkpoints/org123/sandbox456.tar.gz",
"items": [
{
"key": "artifacts/org123/sandbox456/report.pdf",
"path": "/workspace/output/report.pdf",
"kind": "output",
"createdAt": 1772078705353,
"contentType": "application/pdf",
"sizeBytes": 245760
}
],
"updatedAt": 1772078710000
}
}Downloading artifacts
Get a signed download URL for any artifact:
curl "https://api.boxes.banata.dev/v1/sandboxes/artifacts/download?id=SANDBOX_ID&key=artifacts/org123/report.pdf&expiresIn=3600" \
-H "Authorization: Bearer br_live_..."Response:
{
"id": "SANDBOX_ID",
"key": "artifacts/org123/report.pdf",
"url": "https://storage.example.com/signed-url...",
"expiresInSeconds": 3600
}| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Sandbox session ID |
key | string | Yes | Artifact key from the artifacts list |
expiresIn | number | No | URL validity in seconds (1–86400, default: 3600) |
The returned URL can be used to download the file directly. It is valid for the specified duration (default 1 hour, maximum 24 hours).
The artifact key must belong to the specified sandbox session — you cannot download artifacts from other sessions.
Setting an Artifact Prefix
When creating a sandbox, you can set a custom prefix for artifact storage:
{
"runtime": "bun",
"capabilities": {
"storage": {
"artifactPrefix": "my-project/batch-1/"
}
}
}This organizes your artifacts under a predictable path structure.
Persistence Rules
| Location | During Session | Across Pause/Resume | After Ending |
|---|---|---|---|
/workspace | Persists | Persists | Destroyed (unless checkpointed) |
/tmp | Persists | May not persist | Destroyed |
| Artifacts | Available via API | Available via API | Available via API |
| Checkpoints | Available via API | Available via API | Available via API |
Error Responses
| Status | Body | Cause |
|---|---|---|
| 400 | Missing required field: path | path not provided on read/write |
| 400 | Missing required field: content | content not provided on write |
| 400 | Invalid expiresIn | Value not between 1–86400 |
| 403 | Artifact key is not associated with this sandbox | Trying to download another session's artifact |
| 404 | Sandbox session not found | Invalid session ID |
| 409 | Sandbox has no assigned machine | Session not yet assigned |
| 429 | Rate limit exceeded | Over 300 file operations per minute |
Next Steps
- Sandbox Execution — Running commands and code
- Sandbox Capabilities — Browser pairing, AI agents, and human handoff
- Sandboxes — Overview and session management