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.
The SDK handles authentication automatically — you never construct URLs or manage tokens directly.
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')import json
# String content
sandbox.files.write("/app/config.json", json.dumps({"debug": True}))
# With explicit permissions
sandbox.files.write("/app/run.sh", "#!/bin/sh\necho hello", mode="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')text = sandbox.files.read_text("/app/output.txt")
data = sandbox.files.read("/app/model.bin") # bytesGET /v1/files?path=/absolute/pathReturns raw bytes.
Delete
await sandbox.files.remove('/tmp/scratch', { recursive: true })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`)
}listing = sandbox.files.list("/app")
for entry in listing.entries:
print(entry.name, "(dir)" if entry.is_dir else f"{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 })sandbox.files.mkdir("/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' })sandbox.files.move("/tmp/output.json", "/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)info = sandbox.files.stat("/app/output.txt")
print(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')
}result = sandbox.files.exists("/app/data.csv")
if not result.exists:
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.