Files
Read, write, and manage files in a sandbox
Each sandbox has an isolated ext4 filesystem. The files API lets you read, write, and manage paths directly — without running a shell command.
All file operations go through the data plane (https://{sandbox.domain}), authenticated with the sandbox's short-lived JWT.
Write a file
// String content
await sandbox.files.write('/app/config.json', JSON.stringify({ debug: true }))
// With explicit permissions
await sandbox.files.write('/app/run.sh', '#!/bin/sh\necho hello', '0755')POST /v1/files?path=/absolute/pathBody is raw bytes. Set the optional x-file-mode header to an octal string to control permissions (e.g. 755). Max size: 1 MB.
Read a file
const text = await sandbox.files.readText('/app/output.txt')
const bytes = await sandbox.files.read('/app/model.bin')GET /v1/files?path=/absolute/pathReturns raw bytes.
Delete
await sandbox.files.remove('/tmp/scratch', { recursive: true })DELETE /v1/files?path=/absolute/path&recursive=truerecursive=true is required to delete non-empty directories.
List directory
const listing = await sandbox.files.list('/app')
for (const entry of listing.entries) {
console.log(entry.name, entry.is_dir ? '(dir)' : `${entry.size}B`)
}GET /v1/files/list?path=/absolute/path&depth=1{
"path": "/app",
"entries": [
{ "name": "main.py", "is_dir": false, "size": 1024 }
],
"truncated": false
}truncated: true means more entries exist. List subdirectories individually or increase depth.
Create directory
await sandbox.files.mkdir({ path: '/app/logs', parents: true })POST /v1/files/mkdir{ "path": "/app/logs", "parents": true }parents: true creates intermediate directories (equivalent to mkdir -p).
Move or rename
await sandbox.files.move({ source: '/tmp/output.json', destination: '/app/result.json' })POST /v1/files/move{ "source": "/tmp/output.json", "destination": "/app/result.json" }Stat a path
const info = await sandbox.files.stat('/app/output.txt')
console.log(info.size, info.modified_at, info.permissions)GET /v1/files/stat?path=/absolute/path{
"name": "script.sh",
"path": "/app/script.sh",
"size": 42,
"modified_at": "2024-05-11T10:00:00Z",
"is_dir": false,
"permissions": "755",
"owner": "root",
"group": "root",
"symlink_target": ""
}Check existence
const { exists } = await sandbox.files.exists('/app/data.csv')
if (!exists) {
await sandbox.exec.run('python3 generate_data.py')
}GET /v1/files/exists?path=/absolute/path{ "exists": true, "entry_type": "file" }entry_type is "file", "directory", or "symlink".
Checkpoints include file state
File contents are captured by checkpoints. If you write a file and then create a checkpoint, a later restore brings the file back exactly as it was. See Checkpoints and Checkpoint Restore.