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

# Sandbox

> The Sandbox class - factory methods, sandbox methods, properties, and types.

The `Sandbox` class is the main entry point for the SDK. Python ships both a sync `Sandbox` and an `AsyncSandbox` with identical method names.

## Import

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  import { Sandbox } from "@superserve/sdk"
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  from superserve import Sandbox
  # Async variant with awaitable methods:
  from superserve import AsyncSandbox
  ```
</CodeGroup>

## Authentication

The SDK reads `SUPERSERVE_API_KEY` from the environment by default. Pass `apiKey` / `api_key` explicitly to override, and `baseUrl` / `base_url` to target a different control-plane URL.

```bash theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
export SUPERSERVE_API_KEY=ss_live_...
export SUPERSERVE_BASE_URL=https://api.superserve.ai  # optional
```

## Factory methods

### `Sandbox.create`

Create and boot a new sandbox. Synchronous - when the promise resolves, the VM is `active`.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  const sandbox = await Sandbox.create({
    name: "data-analyzer",
    timeoutSeconds: 3600,
    metadata: { env: "prod" },
    envVars: { OPENAI_API_KEY: "sk-..." },
    network: { allowOut: ["api.openai.com"], denyOut: ["0.0.0.0/0"] },
  })
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  from superserve import Sandbox, NetworkConfig

  sandbox = Sandbox.create(
      name="data-analyzer",
      timeout_seconds=3600,
      metadata={"env": "prod"},
      env_vars={"OPENAI_API_KEY": "sk-..."},
      network=NetworkConfig(
          allow_out=["api.openai.com"],
          deny_out=["0.0.0.0/0"],
      ),
  )
  ```
</CodeGroup>

**Options:**

| Option                                      | Type                     | Description                                                                                                                                                                  |
| ------------------------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                                      | `string`                 | **Required.** Human-readable sandbox name.                                                                                                                                   |
| `fromTemplate` / `from_template`            | `string \| Template`     | Template name, UUID, or `Template` instance to boot from. Defaults to `superserve/base`.                                                                                     |
| `fromSnapshot` / `from_snapshot`            | `string`                 | Snapshot UUID to boot from.                                                                                                                                                  |
| `timeoutSeconds` / `timeout_seconds`        | `number`                 | Auto-pause after this many seconds of active time (per session; re-armed on resume). See [Lifecycle](/sandbox/lifecycle#auto-pause).                                         |
| `autoDeleteSeconds` / `auto_delete_seconds` | `number`                 | Delete the sandbox once continuously paused for this many seconds (max 30 days, `0` = delete on pause). See [Lifecycle](/sandbox/lifecycle#auto-delete).                     |
| `metadata`                                  | `Record<string, string>` | String tags.                                                                                                                                                                 |
| `envVars` / `env_vars`                      | `Record<string, string>` | Env vars injected into every process.                                                                                                                                        |
| `secrets`                                   | `Record<string, string>` | Bind secrets to env vars (`ENV_VAR → secret name`). The agent sees a stand-in token; the real credential is attached to outbound requests. See [Secrets](/secrets/overview). |
| `network`                                   | `NetworkConfig`          | Egress allow/deny rules.                                                                                                                                                     |
| `apiKey` / `api_key`                        | `string`                 | Overrides `SUPERSERVE_API_KEY`.                                                                                                                                              |
| `baseUrl` / `base_url`                      | `string`                 | Overrides `SUPERSERVE_BASE_URL`.                                                                                                                                             |
| `signal`                                    | `AbortSignal`            | TypeScript only - abort the creation request.                                                                                                                                |

### `Sandbox.connect`

Reconnect to an existing sandbox by ID. Returns a live `sandbox` with a fresh access token. If the sandbox is currently `paused`, it is auto-resumed before returning so it's immediately usable.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  const sandbox = await Sandbox.connect("7a3f2b8c-1234-...")
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  sandbox = Sandbox.connect("7a3f2b8c-1234-...")
  ```
</CodeGroup>

### `Sandbox.list`

List sandboxes on the authenticated team. `metadata` filters combine with AND.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  const all = await Sandbox.list()
  const prod = await Sandbox.list({ metadata: { env: "prod" } })
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  all_boxes = Sandbox.list()
  prod = Sandbox.list(metadata={"env": "prod"})
  ```
</CodeGroup>

Returns an array of [`SandboxInfo`](#sandboxinfo).

### `Sandbox.killById` / `Sandbox.kill_by_id`

Delete a sandbox by ID without instantiating it. Idempotent.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  await Sandbox.killById("7a3f2b8c-1234-...")
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  Sandbox.kill_by_id("7a3f2b8c-1234-...")
  ```
</CodeGroup>

### `Sandbox.updateById` / `Sandbox.update_by_id`

Update a sandbox by ID without instantiating it. Unlike `connect(id)` followed
by `update(...)`, this does **not** resume a paused sandbox — so it's the right
way to arm auto-delete or change the auto-pause timeout on a box you want to
leave paused.
Same fields and clear-with-`null`/`None` semantics as [`update`](#update).

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  await Sandbox.updateById("7a3f2b8c-1234-...", { autoDeleteSeconds: 3600 })
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  Sandbox.update_by_id("7a3f2b8c-1234-...", auto_delete_seconds=3600)
  ```
</CodeGroup>

## Methods on `sandbox`

### `getInfo` / `get_info`

Fetch the current server-side state. Returns a fresh [`SandboxInfo`](#sandboxinfo) - the returned `sandbox`'s own `status` / `metadata` properties are snapshots and are **not** mutated.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  const info = await sandbox.getInfo()
  console.log(info.status)  // "active" | "paused" | "resuming" | "failed"
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  info = sandbox.get_info()
  print(info.status.value)  # "active" | "paused" | "resuming" | "failed"
  ```
</CodeGroup>

### `pause`

Checkpoint the VM state to disk. The sandbox transitions to `paused`. Returns nothing.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  await sandbox.pause()
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  sandbox.pause()
  ```
</CodeGroup>

### `resume`

Restore a paused sandbox. The backend rotates the per-sandbox access token; the SDK re-injects it into `sandbox.files` transparently.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  await sandbox.resume()
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  sandbox.resume()
  ```
</CodeGroup>

### `kill`

Delete the sandbox. Idempotent - swallows `404`.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  await sandbox.kill()
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  sandbox.kill()
  ```
</CodeGroup>

### `update`

Patch `metadata`, `network`, `autoDeleteSeconds`, and/or `timeoutSeconds` on a sandbox.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  await sandbox.update({
    metadata: { env: "staging" },
    network: { allowOut: ["api.openai.com"] },
  })

  // Auto-delete: a number arms the window, null disarms it.
  await sandbox.update({ autoDeleteSeconds: 3600 })
  await sandbox.update({ autoDeleteSeconds: null })

  // Auto-pause timeout: same set/clear contract.
  await sandbox.update({ timeoutSeconds: 900 })
  await sandbox.update({ timeoutSeconds: null })
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  sandbox.update(
      metadata={"env": "staging"},
      network=NetworkConfig(allow_out=["api.openai.com"]),
  )

  # Auto-delete: a number arms the window, None disarms it.
  sandbox.update(auto_delete_seconds=3600)
  sandbox.update(auto_delete_seconds=None)

  # Auto-pause timeout: same set/clear contract.
  sandbox.update(timeout_seconds=900)
  sandbox.update(timeout_seconds=None)
  ```
</CodeGroup>

On an already-paused sandbox, arming `autoDeleteSeconds` starts the countdown from the moment of the call — never retroactively from when the sandbox paused. See [Lifecycle](/sandbox/lifecycle#auto-delete).

### `attachSecret` / `attach_secret`

Bind a team secret to a live or paused sandbox under an environment variable. The sandbox sees a stand-in token; the real credential is swapped in for outbound requests to the secret's allowed hosts. Takes effect for processes started after the call; a paused sandbox applies it on resume.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  await sandbox.attachSecret("ANTHROPIC_API_KEY", "anthropic-prod")
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  sandbox.attach_secret("ANTHROPIC_API_KEY", "anthropic-prod")
  ```
</CodeGroup>

### `detachSecret` / `detach_secret`

Remove a secret binding by its environment-variable key. The stand-in token is revoked, so requests using it are refused — within about a minute for a process already running. A paused sandbox applies the change on resume.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  await sandbox.detachSecret("ANTHROPIC_API_KEY")
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  sandbox.detach_secret("ANTHROPIC_API_KEY")
  ```
</CodeGroup>

### `getNetworkLog` / `get_network_log`

The sandbox's network log — every outbound connection and secret-bearing request, newest first. Returns a `NetworkLogPage`. See the [Network log](/sandbox/network-log) guide for the full model.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  const page = await sandbox.getNetworkLog({ verdict: "blocked", limit: 100 })
  for (const e of page.events) console.log(e.kind, e.host, e.verdict ?? e.status)
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  page = sandbox.get_network_log(verdict="blocked", limit=100)
  for e in page.events:
      print(e.kind, e.host, e.verdict or e.status)
  ```
</CodeGroup>

| Option    | Type                                 | Description                                                                                                                                                                 |
| --------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `limit`   | `number`                             | Max events per page.                                                                                                                                                        |
| `before`  | `string`                             | Opaque pagination cursor — pass the previous page's `nextCursor` to page through results. Also accepts an RFC3339 timestamp as a time filter (rows strictly older than it). |
| `since`   | `string`                             | RFC3339 — rows at or newer than this.                                                                                                                                       |
| `verdict` | `"allowed" \| "blocked" \| "failed"` | Filter to connections with this verdict (excludes request rows).                                                                                                            |

`NetworkLogPage` has `events` ([`NetworkEvent[]`](/sandbox/network-log#two-kinds-of-rows)), `nextCursor` / `next_cursor`, and `hasMore` / `has_more`.

## Properties on `sandbox`

`id`, `name`, `status`, `metadata`, and `secrets` are read-only snapshots taken at construction. Call `getInfo()` / `get_info()` for fresh data.

| Property   | Type                                  | Description                                                                          |
| ---------- | ------------------------------------- | ------------------------------------------------------------------------------------ |
| `id`       | `string`                              | Unique sandbox UUID.                                                                 |
| `name`     | `string`                              | Human-readable name.                                                                 |
| `status`   | `SandboxStatus`                       | Status at construction time.                                                         |
| `metadata` | `Record<string, string>`              | Tags at construction time.                                                           |
| `secrets`  | `SandboxSecretBinding[] \| undefined` | Bound secrets (`envKey` → `secretName`, with a `revoked` flag) at construction time. |
| `commands` | `Commands`                            | See [Commands](/sdk-reference/commands).                                             |
| `files`    | `Files`                               | See [Files](/sdk-reference/files). Rebuilt after `resume()`.                         |

## Types

### `SandboxStatus`

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  type SandboxStatus = "active" | "paused" | "resuming" | "failed"
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  from enum import Enum

  class SandboxStatus(str, Enum):
      ACTIVE = "active"
      PAUSED = "paused"
      RESUMING = "resuming"
      FAILED = "failed"
  ```
</CodeGroup>

* `active` - running and ready to accept commands
* `paused` - stopped with state saved to disk
* `resuming` - transient, briefly visible while a paused sandbox is being restored to `active` (retry shortly)
* `failed` - the sandbox couldn't boot or resume; the entry remains until you delete it

Deletion removes the sandbox entirely - subsequent API calls return `404`.

### `SandboxInfo`

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  interface SandboxInfo {
    id: string
    name: string
    status: SandboxStatus
    vcpuCount: number
    memoryMib: number
    createdAt: Date
    timeoutSeconds?: number
    autoDeleteSeconds?: number
    autoDeleteAt?: Date // present only while paused with autoDeleteSeconds set
    network?: NetworkConfig
    metadata: Record<string, string>
  }
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  from datetime import datetime
  from pydantic import BaseModel

  class SandboxInfo(BaseModel):
      id: str
      name: str
      status: SandboxStatus
      vcpu_count: int
      memory_mib: int
      created_at: datetime
      timeout_seconds: int | None = None
      auto_delete_seconds: int | None = None
      # Set only while paused with auto_delete_seconds configured.
      auto_delete_at: datetime | None = None
      network: NetworkConfig | None = None
      metadata: dict[str, str]
  ```
</CodeGroup>

### `NetworkConfig`

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  interface NetworkConfig {
    allowOut?: string[]  // CIDRs or domain patterns
    denyOut?: string[]   // CIDRs only - use "0.0.0.0/0" to deny all
  }
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  from pydantic import BaseModel

  class NetworkConfig(BaseModel):
      allow_out: list[str] | None = None  # CIDRs or domain patterns
      deny_out: list[str] | None = None   # CIDRs only
  ```
</CodeGroup>

## Retries

GET and DELETE requests auto-retry on `429`, `502`, `503`, `504`, and network errors with exponential backoff + jitter (3 attempts max). POST and PATCH are not retried - the SDK surfaces the error so you can decide.

See [Errors](/errors).

## Errors

Sandbox methods commonly raise:

* `AuthenticationError` - missing or invalid API key
* `ValidationError` - bad request body
* `NotFoundError` - sandbox doesn't exist (except `kill` / `killById`, which swallow 404)
* `ConflictError` - wrong state (e.g., pausing an already-paused sandbox, or patching `network` while paused)
* `ServerError` - platform error

See [Errors](/errors) for the full hierarchy.
