A sandbox is a sandbox — a fully isolated Linux environment with its own filesystem, process tree, and network namespace. Each sandbox boots in approximately 125 milliseconds and runs until it times out or is explicitly killed.
Sandbox states
| State | Description |
|---|
creating | Sandbox is booting and preparing to accept commands |
running | Sandbox is active and commands can execute |
paused | Memory and filesystem state preserved, no CPU consumed |
killed | Sandbox destroyed and resources freed |
Create a sandbox
from declaw import Sandbox
sbx = Sandbox.create(
api_key="your-key",
domain="localhost:8080",
)
print(sbx.sandbox_id) # sbx-abc123
sbx.kill()
import { Sandbox } from '@declaw/sdk';
const sbx = await Sandbox.create({
apiKey: 'your-key',
domain: 'localhost:8080',
});
console.log(sbx.sandboxId);
await sbx.kill();
Create with full options
from declaw import Sandbox, SecurityPolicy, PIIConfig, ALL_TRAFFIC, SandboxLifecycle
sbx = Sandbox.create(
template="base",
timeout=300, # seconds until auto-kill
envs={"MY_VAR": "value"},
metadata={"project": "my-agent"},
network={
"allow_out": ["*.openai.com"],
"deny_out": [ALL_TRAFFIC],
},
security=SecurityPolicy(
pii=PIIConfig(enabled=True, types=["ssn", "credit_card", "email"]),
injection_defense=True,
audit=True,
),
lifecycle=SandboxLifecycle(
on_timeout="pause", # "kill" (default) or "pause"
auto_resume=True,
),
)
import { Sandbox, ALL_TRAFFIC } from '@declaw/sdk';
const sbx = await Sandbox.create({
template: 'base',
timeout: 300,
envs: { MY_VAR: 'value' },
metadata: { project: 'my-agent' },
network: {
allowOut: ['*.openai.com'],
denyOut: [ALL_TRAFFIC],
},
});
SandboxInfo model
The SandboxInfo object is returned by create(), get(), and list().
| Field | Type | Description |
|---|
sandbox_id | str | Unique identifier in sbx-* format |
template_id | str | Template used to create the sandbox |
name | str | None | Optional human-readable name |
state | SandboxState | Current state: creating, running, paused, killed |
metadata | dict[str, str] | User-defined key-value labels |
started_at | datetime | When the sandbox started |
end_at | datetime | None | Scheduled termination time |
Inspect a sandbox
info = sbx.get_info()
print(info.state) # SandboxState.running
print(info.started_at) # 2024-01-15T10:00:00Z
print(info.end_at) # 2024-01-15T10:05:00Z
print(sbx.is_running()) # True
const info = await sbx.getInfo();
console.log(info.state); // 'running'
console.log(info.startedAt); // Date
console.log(info.endAt); // Date — scheduled termination
List sandboxes
from declaw import Sandbox, SandboxQuery, SandboxState
# List all running sandboxes
result = Sandbox.list(
query=SandboxQuery(state=[SandboxState.RUNNING]),
limit=20,
)
for sbx_info in result.get("sandboxes", []):
print(sbx_info.sandbox_id, sbx_info.state)
const { sandboxes } = await Sandbox.list({
query: { state: 'running' },
limit: 20,
});
for (const info of sandboxes) {
console.log(info.sandboxId, info.state);
}
Connect to an existing sandbox
Use connect() to reconnect to a running or paused sandbox from a different process or after a restart.
sbx = Sandbox.connect("sbx-abc123")
result = sbx.commands.run("echo still here")
print(result.stdout)
const sbx = await Sandbox.connect('sbx-abc123');
const result = await sbx.commands.run('echo still here');
Extend timeout
# Extend to 10 minutes from now
sbx.set_timeout(600)
await sbx.setTimeout(600);
Pause and resume
Pausing a sandbox preserves the full memory state and filesystem. No CPU is consumed while paused. The sandbox can be resumed instantly.
sbx.pause()
# Later — resume by connecting
sbx = Sandbox.connect("sbx-abc123")
result = sbx.commands.run("echo resumed")
await sbx.pause();
// Resume by connecting
const resumed = await Sandbox.connect('sbx-abc123');
SandboxMetrics model
metrics_list = sbx.get_metrics()
for m in metrics_list:
print(m.cpu_usage_percent) # 12.4
print(m.memory_usage_mb) # 128.0
print(m.disk_usage_mb) # 45.2
print(m.timestamp) # datetime
const metrics = await sbx.getMetrics();
for (const m of metrics) {
console.log(m.cpuUsagePercent);
console.log(m.memoryUsageMb);
console.log(m.diskUsageMb);
}
| Field | Type | Description |
|---|
timestamp | datetime | When the metrics were sampled |
cpu_usage_percent | float | CPU usage as a percentage of allocated vCPUs |
memory_usage_mb | float | RAM consumed in megabytes |
disk_usage_mb | float | Rootfs space consumed in megabytes |
Resource configuration
Resources (vCPUs, memory, disk) are fixed at the template level — they cannot be overridden per sandbox. Sending a resources field in Sandbox.create() is rejected with HTTP 400 "resources field is not supported; set resources at template level".
To run with different resource sizing, build or select a template with the desired allocation. See Templates.
Each sandbox receives its own copy-on-write rootfs derived from the template. Template-derived resources are also validated against your account tier on every create — requests exceeding MaxVCPUs, MaxMemoryMB, or MaxStorageGiB return HTTP 403.
Kill a sandbox
# Always clean up in a try/finally block
sbx = Sandbox.create()
try:
result = sbx.commands.run("python3 my_script.py")
print(result.stdout)
finally:
sbx.kill()
const sbx = await Sandbox.create();
try {
const result = await sbx.commands.run('node script.js');
console.log(result.stdout);
} finally {
await sbx.kill();
}
Auto-injected environment variables
Every sandbox receives these environment variables automatically:
| Variable | Value | Description |
|---|
DECLAW_SANDBOX_ID | sbx-abc123 | Unique sandbox identifier |
DECLAW_TEMPLATE_ID | tpl-base | Template the sandbox was created from |
DECLAW_SANDBOX | true | Indicates code is running inside Declaw |
DECLAW_SECURITY_POLICY | JSON string | Active security policy (for introspection) |
Lifecycle configuration
from declaw import Sandbox, SandboxLifecycle
sbx = Sandbox.create(
timeout=300,
lifecycle=SandboxLifecycle(
on_timeout="pause", # "kill" (default) or "pause"
auto_resume=True, # resume when SDK activity arrives
),
)
With on_timeout="pause", the sandbox is preserved rather than destroyed when it times out. Combined with auto_resume=True, the next SDK call automatically wakes it up.
Maximum runtime is 24 hours for Pro tier and 1 hour for the Base tier. Pausing resets the runtime window.