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

# Sandboxes

> Cloud environments for commands, SSH, dev servers, and agent work

A sandbox is a real Linux machine in the cloud — your own microVM with root, up in seconds and yours to do anything with: run commands, SSH in, serve a dev URL behind a protected link, mount persistent storage, even a full browser desktop. Create one from the API, CLI, SDK, or dashboard; pause it when idle and it's waiting right where you left off, no rebuild.

## Create a sandbox

<CodeGroup>
  ```bash CLI theme={null}
  runtools sandbox create --name my-env --template base-ubuntu
  ```

  ```typescript SDK theme={null}
  const sandbox = await rt.sandbox.create({
    name: 'my-env',
    template: 'base-ubuntu',
  });

  await sandbox.waitForReady();
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.runtools.ai/v1/sandboxes \
    -H "X-API-Key: rt_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{"name":"my-env","template":"base-ubuntu"}'
  ```
</CodeGroup>

Creation returns as soon as the control plane has accepted the sandbox and started either a warm-pool claim or a cold boot. Use `runtools sandbox get`, `runtools sandbox watch`, or `await sandbox.waitForReady()` when you need to wait for SSH readiness.

## Templates

| Template         | Use                                                                         |
| ---------------- | --------------------------------------------------------------------------- |
| `base-ubuntu`    | Headless command-line development, package installs, test runs, build tasks |
| `desktop-ubuntu` | Browser desktop sessions and GUI-oriented automation                        |

## Command Execution

Command execution wakes a paused sandbox when possible before dispatching the command.

<CodeGroup>
  ```bash CLI theme={null}
  runtools sandbox exec my-env "npm test"
  ```

  ```typescript SDK theme={null}
  const result = await sandbox.exec('npm test', {
    cwd: '/workspace',
    timeout: 120000,
  });

  console.log(result.exitCode, result.stdout, result.stderr);
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.runtools.ai/v1/sandboxes/sandbox-abc123/exec \
    -H "X-API-Key: rt_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{"command":"npm test","cwd":"/workspace","timeout":120000}'
  ```
</CodeGroup>

## SSH

Register an SSH key once:

```bash theme={null}
runtools ssh-key add my-laptop --file ~/.ssh/id_ed25519.pub
```

Then connect:

```bash theme={null}
runtools sandbox ssh my-env
```

Password access is available for quick experiments:

```bash theme={null}
runtools sandbox create --name password-demo --password "temporary-password"
```

## Protected Dev URLs

Ask Runtools for a protected URL for any port:

```bash theme={null}
runtools sandbox url my-env --port 3000 --open
```

The REST endpoint is:

```bash theme={null}
curl "https://api.runtools.ai/v1/sandboxes/sandbox-abc123/url?port=3000" \
  -H "X-API-Key: rt_live_xxx"
```

Dev URL requests also wake a paused sandbox when possible. Desktop URLs normalize to the browser desktop route for desktop templates.

## Workspace Mounts

Mount org workspaces under `/workspace` or a safe subpath:

```bash theme={null}
runtools sandbox create \
  --name repo-env \
  --template base-ubuntu \
  --mount 9b84ef42-9c3a-4930-9d4c-45c7f5c22d8e:/workspace
```

SDK:

```typescript theme={null}
await rt.sandbox.create({
  name: 'repo-env',
  template: 'base-ubuntu',
  mounts: [{ workspaceId: '9b84ef42-9c3a-4930-9d4c-45c7f5c22d8e', path: '/workspace' }],
});
```

Only org workspaces can be mounted into sandboxes; Personal workspaces stay reserved for thread storage and personal cloud files. Mount targets must be `/workspace` or a safe subpath under `/workspace`.

For agents linked to this sandbox, the mounted workspace is their persistent filesystem memory. Anything the agent writes under `/workspace` remains in the workspace for future runs and for new sandboxes that mount the same workspace.

See [Workspaces](/features/workspaces) for workspace creation, file APIs, and the agent memory model.

## Pause, Resume, Destroy

```bash theme={null}
runtools sandbox pause my-env
runtools sandbox resume my-env
runtools sandbox destroy my-env --force
```

SDK:

```typescript theme={null}
await sandbox.pause();
await sandbox.resume();
await sandbox.destroy();
```

Pause/resume preserves lifecycle state for an existing sandbox. Named checkpoint, restore, and clone APIs are not part of the current public surface.

## Monitoring

The SDK subscribes to live state and metrics when you register listeners:

```typescript theme={null}
sandbox.on('status', (state) => {
  console.log(state.status, state.sshReady, state.vncReady);
});

sandbox.on('metrics', (m) => {
  console.log(m.cpuPercent, m.memUsedPercent);
});
```

The CLI has a live view:

```bash theme={null}
runtools sandbox watch my-env
```

Logs are available separately:

```bash theme={null}
runtools sandbox logs my-env --tail 100
```

## Common Fields

| Field                   | Description                                                                                                                                                 |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                    | Sandbox ID, such as `sandbox-abc123`                                                                                                                        |
| `name`                  | Optional friendly name. Most CLI commands accept ID or name                                                                                                 |
| `template`              | Template slug                                                                                                                                               |
| `status`                | `pending`, `creating`, `running`, `pausing`, `paused`, `resuming`, `destroying`, `destroyed`, `stopped`, `failed`, `error`, `suspected_missing`, `orphaned` |
| `tags`                  | String tags for filtering and deploy tracking                                                                                                               |
| `projectId`             | Optional dashboard project grouping                                                                                                                         |
| `mounts`                | Workspace mounts attached to the sandbox                                                                                                                    |
| `sshReady` / `vncReady` | Readiness flags for remote access                                                                                                                           |

Sandbox lists are paginated. By default, list views show active lifecycle states rather than destroyed or orphaned history.

## Best Practices

<AccordionGroup>
  <Accordion title="Use names for day-to-day CLI work">
    IDs are precise, but friendly names make repeated commands easier.
  </Accordion>

  <Accordion title="Mount persistent workspaces for important files">
    Sandbox-local files are removed when a sandbox is destroyed. Workspace mounts are the durable boundary.
  </Accordion>

  <Accordion title="Pause long-lived environments">
    Pause when you want to keep state for later. Destroy when the environment is no longer needed.
  </Accordion>
</AccordionGroup>
