# Sandboxes SDK for Python — Usage and symbol reference

> This article is part of the [Render Sandboxes documentation bundle](https://render.com/docs/sandboxes/all). Fetch the bundle for all related articles in one Markdown document.


> *Render Sandboxes is in public beta.*
>
> APIs, defaults, and limits might change during the beta period.

## Setup

### 1. Install the SDK

From your Python project directory:

```shell
pip install render
```

*If you already have the SDK installed,* make sure you're using version `1.8.0` or later:

```shell
pip install --upgrade render
```

After installing, make sure to add `render>=1.8.0` as a dependency in your application's `requirements.txt`, `pyproject.toml`, or equivalent.

### 2. Import the client (sync or async)

The Python SDK provides separate classes for synchronous (`Render`) and asynchronous (`RenderAsync`) usage. Both clients support the methods in this reference.

**Tab: Sync client**

```python
from render import Render # highlight-line

sandboxes = Render().sandboxes # highlight-line
sandbox = sandboxes.create(wait=True)

for event in sandboxes.exec(sandbox.id, "echo hello"):
    print(event)
```

**Tab: Async client**

```python
import asyncio
from render import RenderAsync # highlight-line

async def main():
    sandboxes = RenderAsync().sandboxes # highlight-line
    sandbox = await sandboxes.create(wait=True)

    async for event in sandboxes.exec(sandbox.id, "echo hello"):
        print(event)

asyncio.run(main())
```

The method examples below use the sync client. With `RenderAsync`, await each method call except `exec`, which returns an async iterator to use with `async for`.

Import sandbox-specific types and errors from `render.sandbox`.

###### `Render(*, token=None, base_url="https://api.render.com", owner_id=None, region=None)`

Initializes a synchronous Render SDK client.

| Parameter | Description |
| --- | --- |
| `token` | The API key to use for authentication. Defaults to the `RENDER_API_KEY` environment variable. |
| `owner_id` | The default workspace ID for sandbox operations. Defaults to the `RENDER_WORKSPACE_ID` environment variable. |
| `region` | A compatibility parameter that does not affect sandbox placement. The sandbox group determines the region. Currently, sandboxes run in Oregon. |
| `base_url` | The base URL of the Render API. Defaults to `https://api.render.com`. |

###### `RenderAsync(*, token=None, base_url="https://api.render.com", owner_id=None, region=None)`

Initializes an asynchronous Render SDK client.

| Parameter | Description |
| --- | --- |
| `token` | The API key to use for authentication. Defaults to the `RENDER_API_KEY` environment variable. |
| `owner_id` | The default workspace ID for sandbox operations. Defaults to the `RENDER_WORKSPACE_ID` environment variable. |
| `region` | A compatibility parameter that does not affect sandbox placement. The sandbox group determines the region. Currently, sandboxes run in Oregon. |
| `base_url` | The base URL of the Render API. Defaults to `https://api.render.com`. |

## Sandbox lifecycle

###### `create(*, owner_id=None, plan=None, timeout_seconds=None, idle_timeout_seconds=None, network_policy=None, region=None, env=None, snapshot_id=None, snapshot_name=None, sandbox_group_id=None, wait=False) -> Sandbox`

Creates a sandbox in the specified workspace. By default, this method returns before the sandbox is running. Pass `wait=True` to wait until it's running.

To restore from a snapshot, provide either `snapshot_id` or `snapshot_name`, but not both. Set `sandbox_group_id` to the snapshot's group ID. Restoring into a different group is not supported. See [Restoring from a snapshot](/docs/sandboxes-snapshots.md#restoring-from-a-snapshot).

*On success:* Returns a [`Sandbox`](#sandbox) object. If `wait` is enabled, the returned sandbox has a status of `running`.

*Raises:* [`SandboxCreateWaitError`](#sandboxcreatewaiterror), [`SnapshotNotFoundError`](#snapshotnotfounderror), [`SnapshotNotReadyError`](#snapshotnotreadyerror), [`SnapshotPlanMismatchError`](#snapshotplanmismatcherror), [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
sandbox = sandboxes.create(
    plan="2c-4g",
    timeout_seconds=300,
    wait=True,
)
print(sandbox.id, sandbox.status)
```

------

###### Parameter

`owner_id`

###### Description

The ID of the workspace that owns the sandbox. Defaults to the [client configuration](#2-import-the-client-sync-or-async).

This value must be set here or in the client configuration.

---

###### Parameter

`sandbox_group_id`

###### Description

The ID of the sandbox group to create the sandbox in. Defaults to the workspace's default group. See [Sandbox groups](/docs/sandboxes-creating.md#sandbox-groups).

---

###### Parameter

`plan`

###### Description

The compute plan to use for the sandbox: `1c-2g`, `2c-4g`, `4c-8g`, or `8c-16g`. See [Compute plans](/docs/sandboxes-limits.md#compute-plans).

Defaults to `1c-2g`. When restoring from a snapshot, defaults to the source sandbox's plan. A runtime snapshot requires the same plan.

---

###### Parameter

`timeout_seconds`

###### Description

The maximum time the sandbox can run continuously, in seconds. The sandbox terminates when this time elapses. If the sandbox is suspended and later resumed, this timeout restarts.

*If you omit this field:*

- If restoring from a snapshot, the sandbox inherits the source sandbox's runtime timeout, including if disabled. The runtime timeout restarts when the sandbox is restored.
- Otherwise, the sandbox defaults to `86400` (24 hours).

Set to `0` to disable the runtime timeout and let the sandbox run indefinitely. Other values must be between `60` and `2592000` (30 days). See [Runtime timeout limits](/docs/sandboxes-limits.md#general-limits).

Automatic idle suspension is configured separately with `idle_timeout_seconds`.

---

###### Parameter

`idle_timeout_seconds`

###### Description

The period of inactivity before the sandbox is suspended, in seconds. Executing a command or transferring files resumes it automatically.

*If you omit this field:*

- If restoring from a snapshot, the sandbox inherits the source sandbox's idle timeout, including if disabled.
- Otherwise, the sandbox defaults to `900` (15 minutes).

Set to `0` to disable automatic idle suspension. Other values must be between `300` (5 minutes) and `86400` (24 hours). See [Idle suspension](/docs/sandboxes-creating.md#idle-timeout).

---

###### Parameter

`network_policy`

###### Description

The sandbox's outbound network policy. Provide a `NetworkPolicy` object or a policy type string (`"allow-all"`, `"deny-all"`, or `"allow-list"`).

*If you omit this field:*

- If restoring from a snapshot, the sandbox inherits the source sandbox's network policy.
- Otherwise, the sandbox defaults to `"allow-all"`.

To specify allowed destinations, provide a `NetworkPolicy` with `rules`. See all supported fields below.

---

###### Parameter

`region`

###### Description

A compatibility parameter that does not affect sandbox placement. The sandbox group determines the region. Currently, sandboxes run in Oregon.

---

###### Parameter

`env`

###### Description

A dictionary of environment variables to inject into the sandbox at creation, with variable names as keys and string values.

See [Environment variable limits](/docs/sandboxes-limits.md#general-limits). The API does not return these values in sandbox details.

---

###### Parameter

`snapshot_id`

###### Description

The ID of an available snapshot in the same sandbox group to restore from.

If you provide this value, do not provide `snapshot_name`.

---

###### Parameter

`snapshot_name`

###### Description

The name of an available snapshot to restore from (case-sensitive). Resolves to the most recently available snapshot with that name in the sandbox group.

If you provide this value, do not provide `snapshot_id`.

---

###### Parameter

`wait`

###### Description

Controls how the method waits for the sandbox to become ready before returning.

Provide one of the following:

- A `SandboxWaitOptions` object containing wait settings. See all supported options below.
- `True` to wait with the default settings listed below.
- `False` (default) to return without waiting.

The wait begins after the create request returns. If it fails, this method raises [`SandboxCreateWaitError`](#sandboxcreatewaiterror), which includes the new sandbox's ID.

---

###### *Supported `network_policy` fields*

---

###### Parameter

`type`

###### Description

*Required.* The policy type: `"allow-all"`, `"deny-all"`, or `"allow-list"`.

---

###### Parameter

`rules`

###### Description

*Required for `allow-list`.* A list of `EgressRule` objects specifying destinations the sandbox can access over HTTPS. Omit for `allow-all` or `deny-all`.

Each `EgressRule` accepts these parameters:

- `domain` (*required*): A lowercase hostname such as `api.example.com`, or a wildcard such as `*.example.com`. Do not include a scheme, port, or path. An exact hostname does not include its subdomains.
- `protocol`: Must be `"https"` if provided. Defaults to `"https"`.

Provide between 1 and 100 rules. Other outbound traffic is blocked.

---

###### *Supported `wait` options*

---

###### Parameter

`timeout_seconds`

###### Description

The maximum time to wait, in seconds. Defaults to `60`.

---

###### Parameter

`interval_seconds`

###### Description

The initial delay between status checks, in seconds. The delay doubles with each attempt until reaching at least 2 seconds.

Defaults to `0.25`. Must be greater than `0`.

------

To specify wait settings, import `SandboxWaitOptions` from `render.sandbox`:

```python
from render.sandbox import SandboxWaitOptions

sandbox = sandboxes.create(
    wait=SandboxWaitOptions(timeout_seconds=120, interval_seconds=0.5),
)
```

A failed wait does not terminate the sandbox. Use the `sandbox_id` on `SandboxCreateWaitError` to [terminate](#terminate) it if needed. For an async create call, use `SandboxWaitOptions` to bound the wait instead of wrapping the call in `asyncio.wait_for`, which can cancel it without returning the new sandbox's ID.

###### `wait_until_running(sandbox_id, *, timeout_seconds=60, interval_seconds=0.25, owner_id=None) -> Sandbox`

Waits for the sandbox with the specified ID to become ready and returns its details.

To create a sandbox and wait for it in a single call, use [`create`](#create) with `wait=True`.

*On success:* Returns a [`Sandbox`](#sandbox) object with a status of `running`.

*Raises:* [`SandboxNotRunningError`](#sandboxnotrunningerror), [`SandboxWaitTimeoutError`](#sandboxwaittimeouterror), [`SandboxNotFoundError`](#sandboxnotfounderror), [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
sandbox = sandboxes.wait_until_running("sbx-abc123")
print(sandbox.status)
```

| Parameter | Description |
| --- | --- |
| `sandbox_id` | *Required.* The ID of the sandbox. |
| `timeout_seconds` | The maximum time to wait, in seconds. Defaults to `60`. |
| `interval_seconds` | The initial delay between status checks, in seconds. The delay doubles with each attempt until reaching at least 2 seconds. Defaults to `0.25`. Must be greater than `0`. |
| `owner_id` | The ID of the workspace that owns the sandbox. Defaults to the [client configuration](#2-import-the-client-sync-or-async). This value must be set here or in the client configuration. |

Raises `SandboxNotRunningError` if the sandbox is `errored`, `terminated`, `suspending`, or `suspended`. A failed wait does not terminate the sandbox.

With the sync client, a status request already in progress can finish after the wait timeout. With the async client, the timeout also bounds in-progress status requests.

###### `from_id(sandbox_id, *, owner_id=None) -> Sandbox`

Retrieves the details of the sandbox with the specified ID.

*On success:* Returns a [`Sandbox`](#sandbox) object.

*Raises:* [`SandboxNotFoundError`](#sandboxnotfounderror), [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
sandbox = sandboxes.from_id("sbx-abc123")
print(sandbox.status)
```

| Parameter | Description |
| --- | --- |
| `sandbox_id` | *Required.* The ID of the sandbox. |
| `owner_id` | The ID of the workspace that owns the sandbox. Defaults to the [client configuration](#2-import-the-client-sync-or-async). This value must be set here or in the client configuration. |

###### `list(*, owner_id=None, status=None, cursor=None, limit=None, sandbox_group_id=None) -> SandboxList`

Lists sandboxes in the specified workspace, newest first. Terminated sandboxes are excluded by default. Include `"terminated"` in the status filter to retrieve them.

*On success:* Returns a [`SandboxList`](#sandboxlist) page.

*Raises:* [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
page = sandboxes.list(status="running", limit=20)
for sandbox in page.sandboxes:
    print(sandbox.id)
```

| Parameter | Description |
| --- | --- |
| `owner_id` | The ID of the workspace that owns the sandbox. Defaults to the [client configuration](#2-import-the-client-sync-or-async). This value must be set here or in the client configuration. |
| `status` | One status string or a sequence of status strings to filter results by. |
| `cursor` | A cursor from a previous response. Use this to retrieve the next page of results. |
| `limit` | The maximum number of sandboxes to return. The API caps this value at `100`. |
| `sandbox_group_id` | The ID of a sandbox group to filter results by. Omit to list sandboxes across the workspace. |

To paginate, pass the returned `next_cursor` as `cursor` on the next call. Continue until a page contains no sandboxes.

###### `terminate(sandbox_id, *, owner_id=None) -> None`

Terminates the sandbox with the specified ID and permanently deletes its filesystem. Terminating an already-terminated sandbox succeeds.

*On success:* Returns `None`.

*Raises:* [`SandboxNotFoundError`](#sandboxnotfounderror), [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
sandboxes.terminate("sbx-abc123")
```

| Parameter | Description |
| --- | --- |
| `sandbox_id` | *Required.* The ID of the sandbox. |
| `owner_id` | The ID of the workspace that owns the sandbox. Defaults to the [client configuration](#2-import-the-client-sync-or-async). This value must be set here or in the client configuration. |

## Runtime execution

###### `exec(sandbox_id, command, *, owner_id=None) -> Iterator[SandboxExecEvent] | AsyncIterator[SandboxExecEvent]`

Executes a shell command in the specified sandbox and streams its output. Commands are executed with `bash -c`. A suspended sandbox resumes automatically.

A nonzero exit code is reported in the final exit event and does not raise an exception.

*On success:* Returns an iterator of [`SandboxExecEvent`](#sandboxexecevent) values: a regular iterator with `Render`, or an async iterator with `RenderAsync`.

*Raises:* [`SandboxNotFoundError`](#sandboxnotfounderror), [`SandboxExecStreamError`](#sandboxexecstreamerror), [`SandboxExecError`](#sandboxexecerror), [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
from render.sandbox import SandboxExecExit, SandboxExecOutput

for event in sandboxes.exec("sbx-abc123", "echo hello"):
    if isinstance(event, SandboxExecOutput):
        print(event.data, end="")
    elif isinstance(event, SandboxExecExit):
        print(f"Exit code: {event.exit_code}")
```

| Parameter | Description |
| --- | --- |
| `sandbox_id` | *Required.* The ID of the sandbox. |
| `command` | *Required.* The shell command to execute. |
| `owner_id` | The ID of the workspace that owns the sandbox. Defaults to the [client configuration](#2-import-the-client-sync-or-async). This value must be set here or in the client configuration. |

###### `copy_to(sandbox_id, local_path, remote_path, *, owner_id=None) -> None`

Uploads a local file or directory to the specified sandbox. A suspended sandbox resumes automatically.

For directories, the SDK transfers the directory's contents to `remote_path`. Symlinks are preserved, and sockets, FIFOs, and other special files are skipped.

*On success:* Returns `None`.

*Raises:* [`SandboxNotFoundError`](#sandboxnotfounderror), [`SandboxFileNotFoundError`](#sandboxfilenotfounderror), [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
sandboxes.copy_to("sbx-abc123", "./inputs", "/home/render/inputs")
```

| Parameter | Description |
| --- | --- |
| `sandbox_id` | *Required.* The ID of the sandbox. |
| `local_path` | *Required.* The local file or directory to upload, as a string or `os.PathLike` object. |
| `remote_path` | *Required.* The destination path in the sandbox. Relative paths resolve under `/home/render`. Absolute paths resolve from the filesystem root. |
| `owner_id` | The ID of the workspace that owns the sandbox. Defaults to the [client configuration](#2-import-the-client-sync-or-async). This value must be set here or in the client configuration. |

###### `copy_from(sandbox_id, remote_path, local_path, *, owner_id=None) -> str`

Downloads a file or directory from the specified sandbox. A suspended sandbox resumes automatically.

Directories are extracted into `local_path`. For a file, `local_path` is the destination filename, or an existing directory in which to save the file.

*On success:* Returns the local path written.

*Raises:* [`SandboxNotFoundError`](#sandboxnotfounderror), [`SandboxFileNotFoundError`](#sandboxfilenotfounderror), [`SandboxDownloadError`](#sandboxdownloaderror), [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
path = sandboxes.copy_from("sbx-abc123", "/home/render/output", "./output")
print(path)
```

| Parameter | Description |
| --- | --- |
| `sandbox_id` | *Required.* The ID of the sandbox. |
| `remote_path` | *Required.* The file or directory path in the sandbox to download. Relative paths resolve under `/home/render`. Absolute paths resolve from the filesystem root. |
| `local_path` | *Required.* The local destination path, as a string or `os.PathLike` object. |
| `owner_id` | The ID of the workspace that owns the sandbox. Defaults to the [client configuration](#2-import-the-client-sync-or-async). This value must be set here or in the client configuration. |

## Snapshot management

Access snapshot methods through `render.sandboxes.snapshots`.

###### `snapshots.create(sandbox_id, *, kind=None, name=None, expires_at=None, owner_id=None, wait=False) -> Snapshot`

Captures the state of a running sandbox in a snapshot. By default, this method returns before capture completes. Pass `wait=True` to wait until the snapshot is available.

The source sandbox continues running after capture.

*On success:* Returns a [`Snapshot`](#snapshot) object. If `wait` is enabled, the returned snapshot has a status of `available`.

*Raises:* [`SnapshotCreateWaitError`](#snapshotcreatewaiterror), [`SandboxNotFoundError`](#sandboxnotfounderror), [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
snapshot = sandboxes.snapshots.create(
    "sbx-abc123",
    kind="filesystem",
    name="prepared-environment",
    wait=True,
)
print(snapshot.id)
```

------

###### Parameter

`sandbox_id`

###### Description

*Required.* The ID of the sandbox.

---

###### Parameter

`kind`

###### Description

The snapshot type: `"filesystem"` to capture the writable filesystem, or `"runtime"` to also capture memory and CPU state.

Defaults to `"runtime"`.

---

###### Parameter

`name`

###### Description

A case-sensitive name for the snapshot. Names are scoped to the sandbox group, can be reused, and cannot begin with `snp-`.

---

###### Parameter

`expires_at`

###### Description

A future, timezone-aware `datetime` when the snapshot expires. Defaults to 30 days after the snapshot creation request. Check the returned `expires_at` field for the expiration time.

---

###### Parameter

`owner_id`

###### Description

The ID of the workspace that owns the sandbox group. Defaults to the client configuration. If neither is set, the API determines the workspace from the sandbox group.

---

###### Parameter

`wait`

###### Description

Controls how the method waits for the snapshot to be available before returning.

Provide one of the following:

- A `SandboxWaitOptions` object containing wait settings. See all supported options below.
- `True` to wait with the default settings listed below.
- `False` (default) to return without waiting.

The wait begins after the create request returns. If it fails, this method raises [`SnapshotCreateWaitError`](#snapshotcreatewaiterror), which includes the new snapshot's IDs.

---

###### *Supported `wait` options*

---

###### Parameter

`timeout_seconds`

###### Description

The maximum time to wait, in seconds. Defaults to `300`.

---

###### Parameter

`interval_seconds`

###### Description

The initial delay between status checks, in seconds. The delay doubles with each attempt until reaching at least 2 seconds.

Defaults to `0.25`. Must be greater than `0`.

------

To specify wait settings, import `SandboxWaitOptions` from `render.sandbox`:

```python
from render.sandbox import SandboxWaitOptions

snapshot = sandboxes.snapshots.create(
    "sbx-abc123",
    wait=SandboxWaitOptions(timeout_seconds=600),
)
```

A failed wait does not cancel capture. `SnapshotCreateWaitError` includes the new snapshot's `snapshot_id` and `sandbox_group_id`. For an async create call, use `SandboxWaitOptions` to bound the wait instead of wrapping the call in `asyncio.wait_for`, which can cancel it without returning the new snapshot's IDs.

###### `snapshots.wait_until_available(*, sandbox_group_id, snapshot_id, timeout_seconds=300, interval_seconds=0.25, owner_id=None) -> Snapshot`

Waits for the snapshot with the specified ID to be available and returns its details.

To capture a snapshot and wait for it in a single call, use [`snapshots.create`](#snapshots-create) with `wait=True`.

*On success:* Returns a [`Snapshot`](#snapshot) object with a status of `available`.

*Raises:* [`SnapshotFailedError`](#snapshotfailederror), [`SnapshotWaitTimeoutError`](#snapshotwaittimeouterror), [`SnapshotNotFoundError`](#snapshotnotfounderror), [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
snapshot = sandboxes.snapshots.wait_until_available(
    sandbox_group_id="sbg-abc123",
    snapshot_id="snp-abc123",
)
print(snapshot.status)
```

| Parameter | Description |
| --- | --- |
| `sandbox_group_id` | *Required.* The ID of the sandbox group. |
| `snapshot_id` | *Required.* The ID of the snapshot. |
| `timeout_seconds` | The maximum time to wait, in seconds. Defaults to `300`. |
| `interval_seconds` | The initial delay between status checks, in seconds. The delay doubles with each attempt until reaching at least 2 seconds. Defaults to `0.25`. Must be greater than `0`. |
| `owner_id` | The ID of the workspace that owns the sandbox group. Defaults to the client configuration. If neither is set, the API determines the workspace from the sandbox group. |

Raises `SnapshotFailedError` if capture fails. A failed wait does not cancel capture.

With the sync client, a status request already in progress can finish after the wait timeout. With the async client, the timeout also bounds in-progress status requests.

###### `snapshots.from_id(*, sandbox_group_id, snapshot_id, owner_id=None) -> Snapshot`

Retrieves the details of the snapshot with the specified ID.

*On success:* Returns a [`Snapshot`](#snapshot) object.

*Raises:* [`SnapshotNotFoundError`](#snapshotnotfounderror), [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
snapshot = sandboxes.snapshots.from_id(
    sandbox_group_id="sbg-abc123",
    snapshot_id="snp-abc123",
)
print(snapshot.status)
```

| Parameter | Description |
| --- | --- |
| `sandbox_group_id` | *Required.* The ID of the sandbox group. |
| `snapshot_id` | *Required.* The ID of the snapshot. |
| `owner_id` | The ID of the workspace that owns the sandbox group. Defaults to the client configuration. If neither is set, the API determines the workspace from the sandbox group. |

###### `snapshots.list(*, sandbox_group_id, status=None, cursor=None, limit=None, owner_id=None) -> SnapshotList`

Lists snapshots in the specified sandbox group, newest first. Deleted and expired snapshots are excluded.

*On success:* Returns a [`SnapshotList`](#snapshotlist) page.

*Raises:* [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
page = sandboxes.snapshots.list(sandbox_group_id="sbg-abc123")
for snapshot in page.snapshots:
    print(snapshot.id, snapshot.status)
```

| Parameter | Description |
| --- | --- |
| `sandbox_group_id` | *Required.* The ID of the sandbox group. |
| `status` | One status string or a sequence of status strings to filter results by: `"creating"`, `"available"`, or `"failed"`. |
| `cursor` | A cursor from a previous response. Use this to retrieve the next page of results. |
| `limit` | The maximum number of snapshots to return. The API caps this value at `100`. |
| `owner_id` | The ID of the workspace that owns the sandbox group. Defaults to the client configuration. This value must be set here or in the client configuration. |

To paginate, pass the returned `next_cursor` as `cursor` on the next call. Continue until a page contains no snapshots.

###### `snapshots.delete(*, sandbox_group_id, snapshot_id, owner_id=None) -> None`

Deletes the snapshot with the specified ID. Deletion prevents future restores and does not affect sandboxes already restored from it.

You cannot delete a snapshot while its status is `creating`. Deleting an already-deleted or expired snapshot succeeds.

*On success:* Returns `None`.

*Raises:* [`SnapshotNotFoundError`](#snapshotnotfounderror), [`SnapshotNotReadyError`](#snapshotnotreadyerror), [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
sandboxes.snapshots.delete(
    sandbox_group_id="sbg-abc123",
    snapshot_id="snp-abc123",
)
```

| Parameter | Description |
| --- | --- |
| `sandbox_group_id` | *Required.* The ID of the sandbox group. |
| `snapshot_id` | *Required.* The ID of the snapshot. |
| `owner_id` | The ID of the workspace that owns the sandbox group. Defaults to the client configuration. If neither is set, the API determines the workspace from the sandbox group. |

## Sandbox groups

###### `list_groups(*, owner_id=None, cursor=None, limit=None) -> SandboxGroupList`

Lists sandbox groups in the specified workspace. Use a group's ID when creating sandboxes or managing snapshots.

*On success:* Returns a [`SandboxGroupList`](#sandboxgrouplist) page.

*Raises:* [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
page = sandboxes.list_groups()
for group in page.groups:
    print(group.id, group.name)
```

| Parameter | Description |
| --- | --- |
| `owner_id` | The ID of the workspace that owns the sandbox. Defaults to the [client configuration](#2-import-the-client-sync-or-async). This value must be set here or in the client configuration. |
| `cursor` | A cursor from a previous response. Use this to retrieve the next page of results. |
| `limit` | The maximum number of groups to return per page. Defaults to `20`. Must be between `1` and `100`. |

To paginate, pass `next_cursor` as `cursor` and continue until a page contains no groups.

###### `create_group(name, *, owner_id=None, region=None) -> SandboxGroup`

Creates a sandbox group in the specified workspace.

*On success:* Returns a [`SandboxGroup`](#sandboxgroup) object.

*Raises:* [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
group = sandboxes.create_group("Agent environments", region="oregon")
print(group.id)
```

| Parameter | Description |
| --- | --- |
| `name` | *Required.* The name of the sandbox group. |
| `owner_id` | The ID of the workspace that owns the sandbox. Defaults to the [client configuration](#2-import-the-client-sync-or-async). This value must be set here or in the client configuration. |
| `region` | The region for the sandbox group. Currently, only `"oregon"` is supported. Omit to use the workspace default. |

###### `get_group(sandbox_group_id) -> SandboxGroup`

Retrieves the details of the sandbox group with the specified ID.

*On success:* Returns a [`SandboxGroup`](#sandboxgroup) object.

*Raises:* [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
group = sandboxes.get_group("sbg-abc123")
print(group.concurrency_limit)
```

| Parameter | Description |
| --- | --- |
| `sandbox_group_id` | *Required.* The ID of the sandbox group. |

###### `update_group(sandbox_group_id, *, concurrency_limit) -> SandboxGroup`

Updates the sandbox group's concurrency limit.

*On success:* Returns a [`SandboxGroup`](#sandboxgroup) object with the effective concurrency limit.

*Raises:* [`RateLimitError`](#ratelimiterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

```python
group = sandboxes.update_group("sbg-abc123", concurrency_limit=10)
```

| Parameter | Description |
| --- | --- |
| `sandbox_group_id` | *Required.* The ID of the sandbox group. |
| `concurrency_limit` | *Required.* The maximum number of active sandboxes in the group. Must be at least `1`. Render applies its concurrency cap, so setting a higher value does not raise that cap. See [Concurrency](/docs/sandboxes-limits.md#concurrency-per-group). |

## Error types

All SDK-specific errors inherit from `RenderError`. Import common errors from `render.client.errors` and sandbox-specific errors from `render.sandbox`.

The SDK can also raise standard Python exceptions, such as `ValueError` for invalid parameter values.

### Sandbox errors

###### `RenderError(Exception)`

The base class for SDK-specific errors.

###### `SandboxNotFoundError(ClientError)`

Raised when the sandbox does not exist or is no longer retrievable.

### Command execution errors

These errors pertain to executing commands in a sandbox.

###### `SandboxExecStreamError(RenderError)`

Raised when the sandbox reports a terminal error in the command event stream. Includes the reported `status` and `message`.

###### `SandboxExecError(RenderError)`

Raised when the command event stream ends without a final exit event or contains invalid event data.

### File transfer errors

These errors pertain to copying files to or from a sandbox.

###### `SandboxFileNotFoundError(ClientError)`

Raised when the requested path does not exist in the sandbox.

###### `SandboxDownloadError(RenderError)`

Raised when a download cannot be written or extracted safely.

### Readiness errors

These errors pertain to waiting for sandboxes and snapshots to be ready.

###### `SandboxNotRunningError(RenderError)`

Raised when waiting for a sandbox that is `errored`, `terminated`, `suspending`, or `suspended`. Includes `sandbox_id` and `sandbox_status`.

###### `SnapshotFailedError(RenderError)`

Raised when waiting for a snapshot whose capture failed. Includes `snapshot_id` and `snapshot_error`, the capture error message if one is available.

###### `SandboxWaitTimeoutError(TimeoutError)`

Raised when the sandbox does not reach `running` before the wait times out. Includes `sandbox_id`, `timeout_seconds`, and `last_status`.

###### `SnapshotWaitTimeoutError(TimeoutError)`

Raised when the snapshot does not become `available` before the wait times out. Includes `snapshot_id`, `timeout_seconds`, and `last_status`.

###### `SandboxCreateWaitError(RenderError)`

Raised when `create` creates a sandbox but the wait for it to become ready fails.

Includes `sandbox_id` and `cause`, the underlying error. The sandbox continues to exist. Use [`terminate`](#terminate) to stop it.

###### `SnapshotCreateWaitError(RenderError)`

Raised when `snapshots.create` creates a snapshot but the wait for it to be available fails.

Includes `snapshot_id`, `sandbox_group_id`, and `cause`, the underlying error. Capture is not canceled.

### Snapshot errors

These errors pertain to restoring from snapshots and managing snapshots.

###### `SnapshotNotFoundError(ClientError)`

Raised when the snapshot cannot be found in the specified group, including after deletion or expiration.

###### `SnapshotNotReadyError(ClientError)`

Raised when restoring from a snapshot that is not `available`, or deleting a snapshot that is still `creating`.

###### `SnapshotPlanMismatchError(ClientError)`

Raised when restoring a sandbox from a runtime snapshot onto a different compute plan.

### API errors

These errors pertain to requests to the Render API.

###### `ClientError(RenderError)`

Raised when the API returns a 4xx response. Includes `code` when the API provides an error code. Capturing a sandbox that is not running raises this error with the code `sandbox_not_running`.

###### `RateLimitError(ClientError)`

Raised when the API returns HTTP 429 because of a request rate or concurrency limit. See [Sandbox limits](/docs/sandboxes-limits.md).

###### `ServerError(RenderError)`

Raised when the API returns a 5xx response.

###### `TimeoutError(RenderError)`

Raised when an API request times out. Also the parent class of `SandboxWaitTimeoutError` and `SnapshotWaitTimeoutError`. This is the SDK's `TimeoutError`, imported from `render.client.errors`.

## Additional types

###### `Sandbox`

Represents a sandbox returned by a sandbox method or included in a [`SandboxList`](#sandboxlist).

| Property | Description |
| --- | --- |
| `id` | The sandbox's ID. |
| `status` | The sandbox's current status: `creating`, `running`, `suspending`, `suspended`, `resuming`, `errored`, or `terminated`. |
| `plan` | The sandbox's compute plan. |
| `network_policy` | A `NetworkPolicy` object with `type` and `rules` fields. See the supported [`network_policy` fields](#create). |
| `region` | The Render region in which the sandbox runs. |
| `timeout_seconds` | The sandbox's runtime timeout, in seconds. `0` indicates that the timeout is disabled. This timeout restarts if the sandbox is suspended and later resumed. |
| `idle_timeout_seconds` | The period of inactivity before the sandbox is suspended, in seconds. `0` disables automatic idle suspension. See [Idle suspension](/docs/sandboxes-creating.md#idle-timeout). |
| `sandbox_group_id` | The ID of the sandbox group that contains the sandbox. |
| `created_at` | The time when the sandbox was created, as a `datetime`. |
| `terminated_at` | The time when the sandbox was terminated, as a `datetime`, or `None` if it has not been terminated. |

###### `SandboxList`

Represents one page of sandboxes returned by `list()`.

| Property | Description |
| --- | --- |
| `sandboxes` | A list of `Sandbox` objects in this page. |
| `next_cursor` | The cursor to pass on the next request. `None` when the current page is empty. |

###### `SandboxGroup`

Represents a sandbox group returned by a group method or included in a [`SandboxGroupList`](#sandboxgrouplist).

| Property | Description |
| --- | --- |
| `id` | The sandbox group's ID. |
| `owner_id` | The ID of the workspace that owns the sandbox group. |
| `name` | The sandbox group's name. |
| `region` | The Render region that the sandbox group belongs to. |
| `is_default` | Whether this is the workspace's default sandbox group. |
| `concurrency_limit` | The effective limit on active sandboxes in this group. Suspended sandboxes do not count toward the limit. See [Concurrency](/docs/sandboxes-limits.md#concurrency-per-group). |
| `created_at` | The time when the sandbox group was created, as a `datetime`. |
| `updated_at` | The time when the sandbox group was last updated, as a `datetime`. |
| `environment_id` | The ID of the associated environment, or `None` if the group has none. |

###### `SandboxGroupList`

Represents one page of sandbox groups returned by `list_groups()`.

| Property | Description |
| --- | --- |
| `groups` | A list of `SandboxGroup` objects in this page. |
| `next_cursor` | The cursor to pass on the next request. `None` when the current page is empty. |

###### `Snapshot`

Represents a snapshot returned by a `snapshots` method or included in a `SnapshotList`.

| Property | Description |
| --- | --- |
| `id` | The snapshot's ID. |
| `sandbox_group_id` | The ID of the sandbox group that contains the snapshot. |
| `source_sandbox_id` | The ID of the sandbox from which the snapshot was captured. |
| `name` | The optional name assigned when the snapshot was created, or `None`. |
| `kind` | The snapshot type: `filesystem` or `runtime`. |
| `status` | The snapshot's current status: `creating`, `available`, or `failed`. |
| `plan` | The compute plan of the source sandbox. |
| `requested_at` | The time when snapshot capture was requested, as a `datetime`. |
| `captured_at` | The time when capture completed, as a `datetime`, or `None` while the snapshot is still being created. |
| `expires_at` | The time when the snapshot expires, as a `datetime`. |
| `size_bytes` | The snapshot's size in bytes, or `None` until capture completes. |
| `error` | The capture error message if capture failed, otherwise `None`. |

###### `SnapshotList`

Represents one page of snapshots returned by `snapshots.list()`.

| Property | Description |
| --- | --- |
| `snapshots` | A list of `Snapshot` objects in this page. |
| `next_cursor` | The cursor to pass on the next request. `None` when the current page is empty. |

###### `SandboxExecOutput`

Represents an output event yielded by `exec()`.

| Property | Description |
| --- | --- |
| `stream` | The output stream: `stdout` or `stderr`. |
| `data` | The output text. |

###### `SandboxExecExit`

Represents the final event yielded by `exec()`.

| Property | Description |
| --- | --- |
| `exit_code` | The command's exit code. |

###### `SandboxExecEvent`

The `SandboxExecEvent` type is a `SandboxExecOutput` or `SandboxExecExit` object yielded by `exec()`.
