# Sandboxes SDK for TypeScript — Usage and symbol reference


> *Render Sandboxes is in early access.*
>
> APIs, defaults, and limits might change during the early access period. Before using sandboxes in production workloads, discuss your use case with your Render contact.

## Setup

### 1. Install the SDK

From your TypeScript project directory:

```shell
npm install @renderinc/sdk
```

(Or `pnpm install`, `bun add`, etc.)

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

```shell
npm install @renderinc/sdk@latest
```

After installing, make sure `@renderinc/sdk` is listed as a dependency in your `package.json` file at version `^1.2` or later.

### 2. Import the client

The TypeScript SDK uses the asynchronous `Render` client. All sandbox methods return Promises.

```typescript
import { Render } from '@renderinc/sdk'

const sandboxes = new Render().experimental.sandboxes
const sandbox = await sandboxes.create()

const events = await sandboxes.exec(sandbox.id, 'echo hello')
for await (const event of events) {
  console.log(event)
}
```

The `Render` client constructor accepts the following optional parameters:

###### `Render(options?)`

Initializes a Render SDK client.

| Option | Description |
| --- | --- |
| `token` | The API key to use for authentication. Defaults to the `RENDER_API_KEY` environment variable. |
| `ownerId` | The default workspace ID for sandbox operations. Defaults to the `RENDER_WORKSPACE_ID` environment variable. |
| `region` | *During the early access period, all sandboxes run in the Oregon region, regardless of which region you provide.* The default region for sandbox operations. Defaults to the `RENDER_REGION` environment variable. |

## Sandbox lifecycle

###### `create(input?: SandboxCreateInput) -> Promise<Sandbox>`

Provisions a sandbox and returns immediately, usually with a status of `creating`. Pass either `snapshotId` or `snapshotName` to restore from an available snapshot. Wait for the sandbox to reach `running` before your first `exec`.

*On success:* Returns a [`Sandbox`](#sandbox) representing the initial state of the new sandbox.

*Throws:* [`SandboxSnapshotNotFoundError`](#sandboxsnapshotnotfounderror), [`SandboxSnapshotNotReadyError`](#sandboxsnapshotnotreadyerror), [`SandboxSnapshotPlanMismatchError`](#sandboxsnapshotplanmismatcherror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

Supported fields on `input` include:

| Field | Description |
| --- | --- |
| `ownerId` | The ID of the workspace that owns the sandbox. Defaults to the client configuration. If this value is not set here, it _must_ be set in the [client configuration](#2-import-the-client). Otherwise, this method throws `RenderError`. |
| `plan` | *During the early access period, this parameter has no effect.* All sandbox instances have 2 CPU and 4 GB RAM. The compute plan to use for the sandbox. |
| `timeoutSeconds` | The maximum sandbox lifetime, in seconds. The sandbox terminates when this time elapses. Defaults to `86400` (24 hours). |
| `networkPolicy` | The sandbox's outbound network policy. |
| `region` | *During the early access period, all sandboxes run in the Oregon region, regardless of which region you provide.* The Render region to create the sandbox in. Defaults to the client configuration, then the workspace default. |
| `env` | An object of environment variables to inject into the sandbox at creation. |
| `snapshotId` | The ID of an available snapshot to restore from. If you provide this value, do not provide `snapshotName`. |
| `snapshotName` | 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 `snapshotId`. |

###### `get(sandboxId, ownerId?) -> Promise<Sandbox>`

Fetches the current state of a sandbox. Use this method to poll for readiness. A missing or terminated sandbox raises `ClientError`.

*On success:* Returns the current [`Sandbox`](#sandbox) state.

*Throws:* [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

| Argument | Description |
| --- | --- |
| `sandboxId` | *Required.* The ID of the sandbox to retrieve. |
| `ownerId` | The ID of the workspace that owns the sandbox. Defaults to the client configuration. If this value is not set here, it _must_ be set in the [client configuration](#2-import-the-client). Otherwise, this method throws `RenderError`. |

###### `list({ ownerId?, status?, cursor?, limit? } = {}) -> Promise<{ sandbox, cursor }[]>`

Returns up to 100 sandboxes per page, newest first. Use `status` to filter by one or more values and `cursor` to fetch the next page. Terminated sandboxes are excluded by default; include `terminated` in the `status` filter to retrieve them.

*On success:* Returns an array of entries shaped as `{ sandbox: Sandbox, cursor: string }`.

*Throws:* [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

| Option | Description |
| --- | --- |
| `ownerId` | The ID of the workspace whose sandboxes to list. Defaults to the client configuration. If this value is not set here, it _must_ be set in the [client configuration](#2-import-the-client). Otherwise, this method throws `RenderError`. |
| `status` | One status or an array of statuses 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. |

###### `listGroups({ ownerId? } = {}) -> Promise<SandboxGroupWithCursor[]>`

Lists the workspace's sandbox groups. During the early access period, the result contains zero or one group. Use a group's ID for snapshot lookup, listing, and deletion.

*On success:* Returns an array of [`SandboxGroupWithCursor`](#sandboxgroupwithcursor) entries.

*Throws:* [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

| Option | Description |
| --- | --- |
| `ownerId` | The ID of the workspace whose sandbox groups to list. Defaults to the client configuration. If this value is not set here, it _must_ be set in the [client configuration](#2-import-the-client). Otherwise, this method throws `RenderError`. |

###### `terminate(sandboxId, ownerId?) -> Promise<void>`

Stops the sandbox and releases its slot against your concurrency cap. This operation is idempotent: terminating an already-terminated sandbox succeeds.

*On success:* Resolves with no value.

*Throws:* [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

| Argument | Description |
| --- | --- |
| `sandboxId` | *Required.* The ID of the sandbox to terminate. |
| `ownerId` | The ID of the workspace that owns the sandbox. Defaults to the client configuration. If this value is not set here, it _must_ be set in the [client configuration](#2-import-the-client). Otherwise, this method throws `RenderError`. |

## Runtime execution

###### `exec(sandboxId, command, ownerId?, signal?) -> Promise<AsyncGenerator<SandboxExecEvent>>`

Runs `command` through `bash -c` and returns an async generator of events: output chunks tagged `stdout` or `stderr`, then one final exit event. A non-zero exit code is a normal exit event, not an exception.

*On success:* Resolves with an async generator of [`SandboxExecEvent`](#sandboxexecevent) values.

*Throws:* [`SandboxExecStreamError`](#sandboxexecstreamerror), [`AbortError`](#aborterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

| Argument | Description |
| --- | --- |
| `sandboxId` | *Required.* The ID of the sandbox in which to run the command. |
| `command` | *Required.* The command to run through `bash -c`. |
| `ownerId` | The ID of the workspace that owns the sandbox. Defaults to the client configuration. If this value is not set here, it _must_ be set in the [client configuration](#2-import-the-client). Otherwise, this method throws `RenderError`. |
| `signal` | An optional `AbortSignal` used to cancel the request or stream. |

###### `upload(sandboxId, path, data, ownerId?, options?) -> Promise<void>`

Uploads bytes or a readable stream to a path in a sandbox. To upload a directory, send a tar archive and set `options.contentType` to `application/x-tar`; the sandbox extracts it.

*On success:* Resolves with no value.

*Throws:* [`AbortError`](#aborterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

| Argument | Description |
| --- | --- |
| `sandboxId` | *Required.* The ID of the destination sandbox. |
| `path` | *Required.* The destination path in the sandbox. |
| `data` | *Required.* The data to upload: a `Buffer`, `Uint8Array`, string, or Node.js `Readable` stream. |
| `ownerId` | The ID of the workspace that owns the sandbox. Defaults to the client configuration. If this value is not set here, it _must_ be set in the [client configuration](#2-import-the-client). Otherwise, this method throws `RenderError`. |
| `options` | An optional object with `contentType` and `signal` fields. |

###### `download(sandboxId, path, ownerId?, signal?) -> Promise<SandboxDownload>`

Downloads a file from a sandbox into memory.

*On success:* Returns a [`SandboxDownload`](#sandboxdownload) object containing the downloaded bytes and metadata.

*Throws:* [`AbortError`](#aborterror), [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

| Argument | Description |
| --- | --- |
| `sandboxId` | *Required.* The ID of the source sandbox. |
| `path` | *Required.* The path in the sandbox to download. |
| `ownerId` | The ID of the workspace that owns the sandbox. Defaults to the client configuration. If this value is not set here, it _must_ be set in the [client configuration](#2-import-the-client). Otherwise, this method throws `RenderError`. |
| `signal` | An optional `AbortSignal` used to cancel the request. |

## Snapshot management

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

Snapshot results include the snapshot ID, optional name, source sandbox ID, sandbox group ID, kind, status, plan, capture and expiration times, size in bytes, and any capture error.

Deleting a snapshot prevents future restores but does not affect sandboxes already restored from it. After a snapshot expires, you can no longer retrieve or restore it, and snapshot lists omit it.

###### `snapshots.create({ sandboxId, kind?, name?, expiresAt?, ownerId? }) -> Promise<SandboxSnapshot>`

Captures a running sandbox in a snapshot. The operation returns before capture completes. Wait for the snapshot's status to become `available` before restoring it. If the status becomes `failed`, check the snapshot's `error` field.

*On success:* Returns a [`SandboxSnapshot`](#sandboxsnapshot) representing the initial state of the new snapshot.

*Throws:* [`SandboxSnapshotNotReadyError`](#sandboxsnapshotnotreadyerror), [`ClientError`](#clienterror), [`ServerError`](#servererror)

| Option | Description |
| --- | --- |
| `sandboxId` | *Required.* The ID of the running sandbox to capture. |
| `kind` | The snapshot type: `filesystem` to capture the writable filesystem, or `runtime` to also capture memory and CPU state. Defaults to `filesystem`. |
| `name` | An optional, case-sensitive name for the snapshot. Names are scoped to the sandbox group, can be reused, and cannot begin with `snp-`. |
| `expiresAt` | A future ISO 8601 timestamp when the snapshot expires. Defaults to Render's snapshot lifetime. |
| `ownerId` | The ID of the workspace that owns the sandbox. Defaults to the client configuration. |

###### `snapshots.get({ sandboxGroupId, snapshotId, ownerId? }) -> Promise<SandboxSnapshot>`

Fetches a snapshot in the specified sandbox group. Use this method to poll the snapshot's status after capture.

*On success:* Returns the current [`SandboxSnapshot`](#sandboxsnapshot) state.

*Throws:* [`SandboxSnapshotNotFoundError`](#sandboxsnapshotnotfounderror), [`ClientError`](#clienterror), [`ServerError`](#servererror)

| Option | Description |
| --- | --- |
| `sandboxGroupId` | *Required.* The ID of the sandbox group that contains the snapshot. |
| `snapshotId` | *Required.* The ID of the snapshot to retrieve. |
| `ownerId` | The ID of the workspace that owns the sandbox group. Defaults to the client configuration. |

###### `snapshots.list({ sandboxGroupId, status?, cursor?, limit?, ownerId? }) -> Promise<SandboxSnapshotWithCursor[]>`

Lists up to 100 snapshots per page, newest first. Use `status` to filter by `creating`, `available`, or `failed`.

*On success:* Returns an array of [`SandboxSnapshotWithCursor`](#sandboxsnapshotwithcursor) entries.

*Throws:* [`ClientError`](#clienterror), [`ServerError`](#servererror), [`RenderError`](#rendererror)

| Option | Description |
| --- | --- |
| `sandboxGroupId` | *Required.* The ID of the sandbox group whose snapshots to list. |
| `status` | An array of snapshot statuses 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 snapshots to return. The API caps this value at 100. |
| `ownerId` | The ID of the workspace that owns the sandbox group. Defaults to the client configuration. If this value is not set here, it _must_ be set in the [client configuration](#2-import-the-client). Otherwise, this method throws `RenderError`. |

###### `snapshots.delete({ sandboxGroupId, snapshotId, ownerId? }) -> Promise<void>`

Deletes a snapshot in the specified sandbox group. You cannot delete a snapshot while its status is `creating`.

*On success:* Resolves with no value.

*Throws:* [`SandboxSnapshotNotFoundError`](#sandboxsnapshotnotfounderror), [`SandboxSnapshotNotReadyError`](#sandboxsnapshotnotreadyerror), [`ClientError`](#clienterror), [`ServerError`](#servererror)

| Option | Description |
| --- | --- |
| `sandboxGroupId` | *Required.* The ID of the sandbox group that contains the snapshot. |
| `snapshotId` | *Required.* The ID of the snapshot to delete. |
| `ownerId` | The ID of the workspace that owns the sandbox group. Defaults to the client configuration. |

## Error types

### Sandbox errors

These errors pertain to sandbox operations that cannot resolve required client configuration or encounter an unexpected response.

###### `RenderError`

Raised when an operation cannot resolve a required owner ID or encounters an unexpected sandbox response.

### Command execution errors

These errors pertain to running commands in a sandbox.

###### `SandboxExecStreamError`

Raised when the exec stream ends with a terminal error. Carries `status` and `message` properties.

### Cancellation errors

These errors pertain to an `AbortSignal` that aborts an exec, upload, or download operation.

###### `AbortError`

Raised when an operation is aborted.

### Snapshot errors

These errors pertain to creating, restoring, and managing sandbox snapshots.

###### `SandboxSnapshotNotFoundError`

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

###### `SandboxSnapshotNotReadyError`

Raised when restore requires an `available` snapshot, or deletion was attempted while capture was still `creating`.

###### `SandboxSnapshotPlanMismatchError`

Raised when a runtime snapshot is restored onto a different plan.

### API errors

These errors pertain to responses from the Render API.

###### `ClientError`

Raised when the API returns a 4xx response, including HTTP 429 for either the request rate or concurrency cap (see [Early access limits](sandboxes#early-access-limits)).

###### `ServerError`

Raised when the API returns a 5xx response.

## Additional types

### Sandbox types

###### `Sandbox`

Represents a sandbox returned by `create()` or `get()`, or included in a list result.

| Property | Description |
| --- | --- |
| `id` | The sandbox's ID. |
| `status` | The sandbox's current status. |
| `plan` | The sandbox's compute plan. |
| `networkPolicy` | The sandbox's outbound network policy. |
| `region` | The Render region in which the sandbox runs. |
| `timeoutSeconds` | The sandbox's maximum lifetime, in seconds. |
| `createdAt` | The time when the sandbox was created. |
| `terminatedAt` | The time when the sandbox was terminated, or `null` if it has not been terminated. |

### Sandbox group types

###### `SandboxGroup`

Represents a sandbox group returned in a [`SandboxGroupWithCursor`](#sandboxgroupwithcursor) entry.

| Property | Description |
| --- | --- |
| `id` | The sandbox group's ID. |
| `ownerId` | 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. |
| `isDefault` | Whether this is the workspace's default sandbox group. |
| `concurrencyLimit` | The maximum number of active sandboxes allowed in this group. |
| `createdAt` | The time when the sandbox group was created. |
| `updatedAt` | The time when the sandbox group was last updated. |
| `environmentId` | The ID of the associated environment, or `null` if the group has none. |

###### `SandboxGroupWithCursor`

Represents one sandbox group in a `listGroups()` result.

| Property | Description |
| --- | --- |
| `sandboxGroup` | The [`SandboxGroup`](#sandboxgroup) in this entry. |
| `cursor` | The cursor for this entry. |

### Snapshot types

###### `SandboxSnapshot`

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

| Property | Description |
| --- | --- |
| `id` | The snapshot's ID. |
| `sandboxGroupId` | The ID of the sandbox group that contains the snapshot. |
| `sourceSandboxId` | The ID of the sandbox from which the snapshot was captured. |
| `name` | The optional name assigned when the snapshot was created, or `null`. |
| `kind` | The snapshot type: `filesystem` or `runtime`. |
| `status` | The snapshot's current status. |
| `plan` | The compute plan of the source sandbox. |
| `requestedAt` | The time when snapshot capture was requested. |
| `capturedAt` | The time when capture completed, or `null` while the snapshot is still being created. |
| `expiresAt` | The time when the snapshot expires. |
| `sizeBytes` | The snapshot's size in bytes, or `null` until capture completes. |
| `error` | The capture error message, if capture failed; otherwise `null`. |

###### `SandboxSnapshotWithCursor`

Represents one snapshot in a `snapshots.list()` result.

| Property | Description |
| --- | --- |
| `snapshot` | The [`SandboxSnapshot`](#sandboxsnapshot) in this entry. |
| `cursor` | The cursor for this entry. |

### File transfer types

###### `SandboxDownload`

Represents a file downloaded by `download()`.

| Property | Description |
| --- | --- |
| `data` | The downloaded file contents as a `Buffer`. |
| `size` | The number of downloaded bytes. |
| `contentType` | The response content type, if provided. |

### Command execution types

###### `SandboxExecEvent`

Represents an event yielded by `exec()`.

An output event has `type: 'output'`, `stream: 'stdout' | 'stderr'`, and a `data` string. The final exit event has `type: 'exit'` and an `exit_code` number.


---

##### Appendix: Glossary definitions

###### region

Each Render service runs in one of the following regions: *Oregon*, *Ohio*, *Virginia*, *Frankfurt*, or *Singapore*.

Services in the same region can communicate over their *private network*.

Related article: https://render.com/docs/regions.md