> ## Documentation Index
> Fetch the complete documentation index at: https://docs.declaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Sandboxes

> Manage sandbox sandboxes: lifecycle, state, metrics, and configuration options.

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

```mermaid theme={null}
stateDiagram-v2
    [*] --> Creating: Sandbox.create()
    Creating --> Running: Sandbox ready
    Running --> Running: set_timeout() / commands.run()
    Running --> Paused: pause()
    Paused --> Running: connect() / auto_resume
    Running --> Snapshotting: create_snapshot()
    Snapshotting --> Running: Snapshot saved
    Running --> Killed: kill() / timeout expired
    Paused --> Killed: kill()
    Killed --> [*]
```

| 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

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from declaw import Sandbox

    sbx = Sandbox.create(
        api_key="your-key",
        domain="localhost:8080",
    )
    print(sbx.sandbox_id)  # sbx-abc123
    sbx.kill()
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    import { Sandbox } from '@declaw/sdk';

    const sbx = await Sandbox.create({
      apiKey: 'your-key',
      domain: 'localhost:8080',
    });
    console.log(sbx.sandboxId);
    await sbx.kill();
    ```
  </Tab>
</Tabs>

### Create with full options

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    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,
        ),
    )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    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],
      },
    });
    ```
  </Tab>
</Tabs>

## 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

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    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
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    const info = await sbx.getInfo();
    console.log(info.state);       // 'running'
    console.log(info.startedAt);   // Date
    console.log(info.endAt);       // Date — scheduled termination
    ```
  </Tab>
</Tabs>

## List sandboxes

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    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)
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    const { sandboxes } = await Sandbox.list({
      query: { state: 'running' },
      limit: 20,
    });
    for (const info of sandboxes) {
      console.log(info.sandboxId, info.state);
    }
    ```
  </Tab>
</Tabs>

## Connect to an existing sandbox

Use `connect()` to reconnect to a running or paused sandbox from a different process or after a restart.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    sbx = Sandbox.connect("sbx-abc123")
    result = sbx.commands.run("echo still here")
    print(result.stdout)
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    const sbx = await Sandbox.connect('sbx-abc123');
    const result = await sbx.commands.run('echo still here');
    ```
  </Tab>
</Tabs>

## Extend timeout

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    # Extend to 10 minutes from now
    sbx.set_timeout(600)
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    await sbx.setTimeout(600);
    ```
  </Tab>
</Tabs>

## 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.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    sbx.pause()

    # Later — resume by connecting
    sbx = Sandbox.connect("sbx-abc123")
    result = sbx.commands.run("echo resumed")
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    await sbx.pause();

    // Resume by connecting
    const resumed = await Sandbox.connect('sbx-abc123');
    ```
  </Tab>
</Tabs>

## SandboxMetrics model

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    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
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    const metrics = await sbx.getMetrics();
    for (const m of metrics) {
      console.log(m.cpuUsagePercent);
      console.log(m.memoryUsageMb);
      console.log(m.diskUsageMb);
    }
    ```
  </Tab>
</Tabs>

| 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](/features/templates).

<Note>
  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`.
</Note>

## Kill a sandbox

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    # 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()
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    const sbx = await Sandbox.create();
    try {
      const result = await sbx.commands.run('node script.js');
      console.log(result.stdout);
    } finally {
      await sbx.kill();
    }
    ```
  </Tab>
</Tabs>

## 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

```python theme={null}
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.

<Info>
  Maximum runtime is 24 hours for Pro tier and 1 hour for the Base tier. Pausing resets the runtime window.
</Info>
