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

# Environment reference

> Look up every environment field, default, compute size, sandbox path, network rule, setup state, and limit.

This page lists every environment setting you can use, what each one does inside the sandbox, and the limits the API enforces. For step-by-step tasks, see [Set up an environment](/recursion/environments). For request and response schemas, open **Endpoints** in the sidebar and select **Environments**.

## Environment fields

Send these fields to `createEnvironment` and `updateEnvironment`. An update is partial: omitted fields keep their saved values.

| Field | Default | Description |
| - | - | - |
| `name` | Required | Label shown in lists. Up to 256 characters. |
| `provider` | Required | Runtime. Use a value from `listSandboxProviders`; today that is `runs`. See [Runtimes](#runtimes). |
| `description` | None | Note for people. The agent never sees it. |
| `resources` | Service default size | CPU and memory, or one GPU. See [Compute](#compute). |
| `pvc_size_gi` | Service default | Workspace disk in GiB. See [Workspace and lifecycle](#workspace-and-lifecycle). |
| `setup` | No script | Setup script and timeout. See [Setup](#setup). |
| `network_policy` | No internet | Which hosts the sandbox can reach. See [Network policy](#network-policy). |
| `privileged` | `false` | Lets the agent run Docker containers inside the sandbox. See [Privileged Docker](#privileged-docker). |
| `computer_use` | `false` | Adds a shared browser display for the `computer` tool. See [Computer use](#computer-use). |
| `idle_stop_after_seconds` | 30 minutes | Idle time before compute stops. The workspace is kept. |
| `stopped_delete_after_seconds` | Service default | Time before a stopped sandbox may be released. The setting does not expire the session or its workspace files. |
| `env_vars` | None | Plain-text environment variables. See [Environment variables](#environment-variables). |
| `mounts` | None | Files downloaded into the workspace when the sandbox starts. See [Mounts](#mounts). |
| `metadata` | None | Your own JSON. The service stores and returns it unchanged. |

### Fields the service sets

These appear in responses. The service sets them, so don't send them.

| Field | Description |
| - | - |
| `organization_id` | Organization that owns the environment, taken from your API key. |
| `environment_id` | Id to pass when you start a session. |
| `scope` | `organization` by default. Every member of your organization can see and use the environment, subject to their role. |
| `http_port` | `6901` when computer use is on. |
| `setup_verification` | Whether the setup script has passed for the current configuration. See [Setup verification](#setup-verification). |
| `setup_warnings` | Advice about risky script lines. See [Setup warnings](#setup-warnings). |
| `setup_updated_at` | When the setup script last changed. |
| `setup_updated_by_user_id` | Who last changed the setup script. |
| `created_at`, `updated_at` | RFC 3339 timestamps. |

For an Agent runner environment, responses always include `network_policy` and `privileged`. A `network_policy` of `{}` means unrestricted.

## Runtimes

The runtime (`provider`) decides what kind of sandbox the environment runs on. `listSandboxProviders` returns the runtimes API clients can choose, with a `displayName`, `description`, and `default` flag. The list is the same for every organization.

| `provider` | Console label | What you get |
| - | - | - |
| `runs` | **Agent runner** | Managed Linux compute with a persistent workspace, CPU and memory sizing, network policy, idle stop, setup verification, and a reusable setup image. The default runtime. |

The console uses the catalog's default runtime and does not show a runtime control. API clients still send `provider` when creating an environment; an existing environment's provider cannot be changed.

### What the sandbox starts with

Every environment starts from the Agent runner image: Debian-based Linux with Python 3 and uv, Node.js and npm, git, curl, and apt with `sudo`. Add anything else in the setup script. The agent's working directory is `/workspace`.

## Environment templates

`listEnvironmentTemplates` returns reviewed starting points. Each has an `id`, a `revision`, a `name` and `summary` for the console card, and a `definition` in the `createEnvironment` request shape. The console's **Choose a starting point** cards fill the create form from the same list. See [Start from a template](/recursion/environments#start-from-a-template).

## Compute

`resources` sizes the sandbox. Omit it, or choose **Use platform default** in the console, to use the service's default size.

| Field | Range | Description |
| - | - | - |
| `resources.cpu_milli` | 250 to 8000 | CPU in millicores. `1000` is one vCPU. `0` uses the default. |
| `resources.memory_mib` | 1024 to 32768 | Memory in MiB. `0` uses the default. |
| `resources.accelerator` | One GPU | Attaches one exclusive GPU: `type` is `gpu`, `name` is the GPU model (`a100`, `l4`, or `t4`), and `count` must be `1`, the default. `name` is required, and a model that isn't offered is rejected with `400 invalid_request` whose message lists the available models. A GPU sandbox always gets 8,000 millicores (8 vCPU) and 32,768 MiB (32 GiB) of memory, so omit `cpu_milli` and `memory_mib`. Omit `accelerator` for a CPU-only sandbox. |

In the console, expand **Compute**, set **Compute kind** to **GPU**, and pick a GPU model. Each model shows its memory and whether one is free now; availability is checked again when a sandbox starts.

For CPU sizes, the console offers these shortcuts, in 250-millicore and 1024-MiB steps:

| Shortcut | CPU | Memory |
| - | -: | -: |
| Light | 1 vCPU (1000) | 2 GiB (2048) |
| Standard | 2 vCPU (2000) | 4 GiB (4096) |
| Heavy | 4 vCPU (4000) | 8 GiB (8192) |
| Max | 8 vCPU (8000) | 32 GiB (32768) |

How sizes are checked:

* **CPU and memory must fit one machine together.** A pair that no machine offers is rejected with `400 invalid_request`, and the message names the most memory available at that CPU size.
* **Available compute can lower the ceiling.** CPU environments never exceed 8 vCPU or 32 GiB. The current provider catalog and a restricted network policy, including the default no-internet policy, can impose a smaller maximum; a rejected save returns `400 invalid_request` with the current limit.
* **Changing compute makes the setup verdict stale.** Run setup again after you resize.

## Workspace and lifecycle

| Field | Range | Behavior |
| - | - | - |
| `pvc_size_gi` | 1 to 100; `0` uses the default | Size of the persistent workspace disk. A setup run that fills it fails with hint `no_space`. |
| `idle_stop_after_seconds` | 120 to 7200 (2 hours); `0` uses the default of 30 minutes | After this long with no activity, compute stops and the workspace is kept. With computer use on, use `0` or at least 600. |
| `stopped_delete_after_seconds` | 3600 to 2592000; `0` uses the service default | After this long, a stopped sandbox may be released. This setting does not expire the session or its workspace files. |

Message the same session to reopen its workspace after an idle stop or later release. Its `/workspace` files can be used when the workspace reopens successfully. If it cannot reopen, contact support. Delete the session separately when you no longer need it. The API checks these ranges when you save; run a setup test afterward to verify the complete environment configuration.

### Sandbox paths

| Path | Contents |
| - | - |
| `/workspace` | The agent's working directory and persistent workspace. Put repositories and data here in the setup script. |
| `/workspace/.venv` | Python virtual environment. When the setup script creates it, the agent's commands use it automatically. |
| `/workspace/.managed-agents/outputs` | Deliverables. Files the agent saves here are kept with the session. Agents already know this path, so ask for a named file. See [Deliverables and artifacts](/recursion/artifacts). |
| `/workspace/.managed-agents/files` | Files you attach to the session, read-only. See [Files](/recursion/files). |

### Who shares a sandbox

* Each top-level session gets its own fresh sandbox from the environment. Sessions never share files through an environment.
* Subagents and teammates run in their root session's sandbox, so they can hand work over by file path. See [Multi-agent](/recursion/multi-agent).
* A change to the environment affects only sandboxes started after it. Running sessions keep the configuration they started with.

## Setup

| Field | Default | Description |
| - | - | - |
| `setup.script` | Empty (no setup) | Bash script run on fresh compute before the agent's first turn. Up to 64 KiB. No NUL bytes. |
| `setup.timeout_seconds` | 600 | Time limit for the whole script, 10 to 3600 seconds. A timeout exits with code `124`. |

How the script runs:

* As the sandbox user, not root, in a separate bash login shell with `set -eo pipefail`. The first failing line ends the run.
* With the environment's `env_vars`, `mounts`, and network policy. In a setup run, session credentials such as vault grants are never available to it.
* Exports, `source`, aliases, and shell functions don't carry over to the agent's commands.

On save, the service converts Windows line endings and trims trailing whitespace. A non-empty script is stored ending in one newline. In an update, `setup` replaces the whole object, and `{"script": ""}` removes the script.

### Setup warnings

`setup_warnings` lists advice. Warnings never block a save or a run.

| `code` | Meaning |
| - | - |
| `bash_lc_wrapper` | A line wraps its command in `bash -lc`. Write the command directly. |
| `curl_pipe_sh` | A line pipes a download into a shell. |
| `unpinned_install` | A package install doesn't pin a version. |
| `rm_rf_root` | A line removes files from `/`. |
| `ambiguous_system_python` | A line uses the system Python instead of `/workspace/.venv`. |
| `path_clobber` | A line replaces `PATH` instead of extending it. |
| `nonpersistent_shell_activation` | A line activates something that won't carry over to the agent's shell. |
| `legacy_setup_discarded` | Line `0`. The saved setup uses an old format that no longer runs. Enter it again as a script. |

Each warning has a `code`, a one-based `line` (`0` when it's about the save), and a `message`.

## Setup verification

`setup_verification` tells you whether the setup script has passed for the environment's current configuration. When a script exists, a session can start only when `status` is `verified`, `stale` is `false`, and the service kept a reusable image from the passing run. Otherwise `startSession` returns `422 environment_not_verified`.

| `status` | Meaning | Console **Setup** label |
| - | - | - |
| `not_applicable` | No setup script. Sessions can start. | **Ready** |
| `never` | A script exists but no run has recorded a verdict. | **Not verified** |
| `running` | A run is in flight and there is no passing verdict for the current configuration. | **Testing** |
| `verified` | The recorded setup verdict passed in a manual run or automatic runner refresh. Check `stale` too. | **Verified**, **Stale**, or **Re-testing**; **Image missing**, **Image failed**, or **Check image** when there is no usable reusable image |
| `failed` | The recorded setup verdict failed. | **Failed** |

| Field | Description |
| - | - |
| `status` | Current verdict, from the table above. |
| `stale` | `true` when a setting that affects setup changed after the recorded run. Always `false` for `not_applicable` and `never`. |
| `setup_run_id` | Run that produced the verdict. |
| `active_setup_run_id` | Manual run or automatic runner refresh in flight, if any. A verified verdict remains visible while it runs; sessions needing a new runner image wait for the refresh. |
| `at` | When the recorded run finished. |
| `verified_by_user_id` | Who requested the recorded run. |
| `fingerprint` | Opaque value identifying the configuration the run tested. Compare only for equality. |
| `last_run` | Summary of the recorded run. See the next table. |

**Changes that make the verdict stale:** `provider`, `setup` (script or timeout), `resources`, `pvc_size_gi`, `env_vars`, `mounts`, `network_policy`, and `privileged`. **Changes that don't:** `name`, `description`, `metadata`, `computer_use`, `idle_stop_after_seconds`, and `stopped_delete_after_seconds`.

### Last-run summary

| Field | Description |
| - | - |
| `last_run.setup_run_id` | Run summarized here. |
| `last_run.status` | `succeeded`, `failed`, or `cancelled`. |
| `last_run.phase` | Phase the run ended in. |
| `last_run.exit_code` | Script exit code. `124` means timeout. Absent when the script never started. |
| `last_run.failed_line` | One-based script line that failed, or `0` when unknown. |
| `last_run.failed_command` | That line as written, before variable expansion. |
| `last_run.stderr_tail` | Last lines of stderr, redacted, up to 2 KiB. |
| `last_run.hint_code` | Stable id of a recognized cause. Absent when the cause isn't recognized. |
| `last_run.hint` | Likely fix for a recognized cause. |
| `last_run.message` | One-sentence summary of the result. |
| `last_run.duration_ms` | Total run time, including starting compute. |

## Setup runs

A setup run executes the setup script on fresh compute, records its output, checks the compute, saves a reusable image, and releases the compute. Saving an environment never starts compute. After the save succeeds, call `createEnvironmentSetupRun` with its own `Idempotency-Key` to start a run.

| Field | Description |
| - | - |
| `setup_run_id` | Id of the run. |
| `kind` | `manual` (you started it to verify the environment), `runner_refresh` (the platform captured a new setup image after the runner changed), or `session` (an older session ran setup on its own compute). |
| `session_id` | The session, for `kind: "session"`. |
| `status` | See [Setup-run statuses](#setup-run-statuses). |
| `phase` | Current or final phase: `provision`, `gpu_check`, `setup`, `profile`, `commit`, or `cleanup`. |
| `exit_code`, `failed_line`, `failed_command`, `stderr_tail` | Same meaning as in `last_run`. |
| `hint_code`, `hint`, `message` | Same meaning as in `last_run`. |
| `failure_code` | Failure class for a run that didn't succeed, using the same codes as session failures, such as `environment_setup_failed`, `sandbox_capacity_unavailable`, or `sandbox_provision_timeout`. |
| `next_action` | The call to make next, as `operation_id`, `method`, and `path`. |
| `requested_by_user_id` | Who started a manual run. |
| `created_at`, `started_at`, `finished_at` | When the run was requested, started compute, and finished. |
| `duration_ms` | Total run time, including starting compute. |
| `log_lines`, `log_bytes` | Size of the stored log. The last line's `seq` equals `log_lines`. |
| `log_truncated` | `true` when output passed 4 MiB. The beginning of the log and `stderr_tail` are kept. |

### Setup-run statuses

| `status` | Meaning | Terminal |
| - | - | - |
| `queued` | Accepted, waiting to start compute. | No |
| `provisioning` | Fresh compute is starting. | No |
| `running` | The script and compute checks are running. | No |
| `succeeded` | The script and checks passed. The environment is verified for this configuration. | Yes |
| `failed` | Compute, the script, or a check failed. The environment records a failed verdict. | Yes |
| `cancelled` | Stopped by `cancelEnvironmentSetupRun`. No verdict is recorded. | Yes |

Only a failure in the `setup` phase points at your script. A run can succeed even if saving the reusable image fails; the console then shows **Setup passed, but its reusable image failed.** and sessions can't start until a later run saves one.

### Setup-run log lines

`getEnvironmentSetupRunLog` returns `lines`, a `next_after` cursor, the run's `status`, and `truncated`.

| Field | Description |
| - | - |
| `seq` | Position of the line in the run. Pass the last one as `after` to continue. |
| `stream` | `stdout`, `stderr`, `marker` (the script line about to run), or `system` (a phase outside your script). |
| `line` | One-based script line this output belongs to, when known. |
| `text` | The line, redacted, without its trailing newline. |
| `at` | When the line was captured. |

### Setup-run parameters

| Operation | Parameter | Range or requirement |
| - | - | - |
| `getEnvironmentSetupRun` | `wait_seconds` | Accepts 0 to 60; the server waits at most 5 seconds. |
| `getEnvironmentSetupRunLog` | `after` | `0` (default) reads from the start. |
| `getEnvironmentSetupRunLog` | `limit` | 1 to 2000, default 500. |
| `getEnvironmentSetupRunLog` | `wait_seconds` | Accepts 0 to 60; the server waits at most 5 seconds. To tail, use `0` and wait about two seconds between calls. |
| `listEnvironmentSetupRuns` | `limit` | 1 to 50, default 50. |
| `createEnvironmentSetupRun` | `Idempotency-Key` | Required. Use one key for each logical run, and reuse it with the same request if the response is lost. |

## Network policy

`network_policy` decides which hosts the sandbox can reach. It governs the setup script, the agent's commands, package managers, `git`, and websites the sandbox browser opens. Model calls, the agent's MCP servers, and the `web_search` and `web_fetch` tools don't go through the sandbox, so the policy doesn't affect them.

* A session started by an automation or from Slack, in an environment with any restricted policy (limited or no internet access), doesn't get the `web_fetch` tool.
* Tools of built-in integration apps, such as Jira and Confluence, run inside the sandbox. Recursion adds the hosts they need to a policy limited to specific hosts; a no-access policy blocks them.

```json theme={"theme":"css-variables"}
{
  "version": "v1",
  "rules": [
    {"match": {"host_glob": "registry.npmjs.org"}, "action": {"type": "allow"}},
    {"match": {"host_glob": "*.example.com"}, "action": {"type": "allow"}}
  ]
}
```

| Field | Description |
| - | - |
| `version` | `v1`. |
| `rules` | Ordered list, up to 200 rules. |
| `rules[].match.host_glob` | Host to match, such as `api.example.com`, `*.example.com`, or `*` for every host. |
| `rules[].action.type` | Use `allow` or `deny`. |

How rules apply:

* Rules are checked in order. The first rule that matches a host decides.
* Outbound traffic that no rule allows is blocked.
* A rule allows or blocks a whole host. Once allowed, sandbox code can send any request to it, including uploads.
* Unknown fields are rejected with `400 invalid_request`.

### Common policies

| Goal | `network_policy` |
| - | - |
| No internet (default for new environments) | `{"version": "v1", "rules": []}` |
| Only npm | `{"version": "v1", "rules": [{"match": {"host_glob": "registry.npmjs.org"}, "action": {"type": "allow"}}]}` |
| Everything except one host | `{"version": "v1", "rules": [{"match": {"host_glob": "blocked.example.com"}, "action": {"type": "deny"}}, {"match": {"host_glob": "*"}, "action": {"type": "allow"}}]}` |
| Unrestricted | `{}` |

### Hosts common tools need

| Tool | Hosts to allow |
| - | - |
| `git` and `gh` with GitHub | `github.com`, `api.github.com`, `codeload.github.com`, `objects.githubusercontent.com`, `github-cloud.s3.amazonaws.com` |
| pip or uv from PyPI | `pypi.org`, `files.pythonhosted.org` |
| npm | `registry.npmjs.org` |

Attaching a credential in a vault never opens the network. If the agent uses a credential from inside the sandbox, the policy must also allow the host. See [Authenticate with vaults](/recursion/vaults) and [GitHub access](/recursion/github).

### Defaults and updates

* **Create:** omitting `network_policy`, or sending `null`, stores `{"version": "v1", "rules": []}`: no internet. Send `{}` for unrestricted access.
* **Update:** omitting `network_policy` keeps the saved policy. A value you send replaces the whole policy.
* **Privileged Docker:** a nonempty policy cannot be combined with `privileged: true` on create or when access settings change. Use `{}` for unrestricted access before enabling privileged Docker.
* **Access precondition:** a PATCH that changes a saved policy other than `{}` (including the default no-internet policy), or turns `privileged` on, must include `expected_access` with the `network_policy` and `privileged` values from your last read. Missing returns `428 precondition_required`; out of date returns `412 precondition_failed`.
* **Console:** **Internet access** sets **Enabled** (`{}`) or **No access** (no rules). A saved host-rule policy shows as **Custom policy (saved)** until you pick a mode, which replaces it.
* **Verification:** any policy change makes the setup verdict stale.

## Privileged Docker

`privileged: true` lets the agent run Docker containers inside the sandbox. It's `false` by default and requires unrestricted internet access (`network_policy: {}`). The console's **Privileged Docker access** checkbox is available after you choose **Internet access → Enabled**. Changing either setting does not silently change the other. Turning privilege on needs `expected_access` in a PATCH and makes the setup verdict stale. If an existing environment has both limited internet access and privileged Docker, you can view it and edit other settings. To start a new session, enable unrestricted internet access or turn off privileged Docker. If no compute is available for the requested settings, saving or starting a session fails.

## Computer use

`computer_use: true` adds a shared browser display to the sandbox, which the agent controls with the `computer` tool. You can follow the recorded screens in the session. The service sets `http_port` to `6901` for the display. When the agent needs a person for a step such as a sign-in, it calls `handoff_to_user` and the session waits in `awaiting_human`; see [Sessions](/recursion/sessions).

* `idle_stop_after_seconds` must be `0` or at least 600.
* The browser follows the network policy. Under a restricted policy, allow each site the agent must visit.
* Turning computer use on or off doesn't make the setup verdict stale.

## Environment variables

`env_vars` is a map of names to plain-text values exported in the sandbox. Anyone who can view the environment can read the values, and so can any code the agent runs. Never put secrets here; use [vaults](/recursion/vaults) instead.

* `PATH` is rejected. The sandbox already selects `/workspace/.venv`; call tools by full path or prepend to `$PATH` inside a command.
* Variables the shell, the loader, or Python read at startup are rejected too: `BASH_ENV`, `HOME`, `SHELLOPTS`, `PS4`, `PYTHONPATH`, `PYTHONHOME`, `PYTHONUSERBASE`, `PYTHONWARNINGS`, `PYTHONPLATLIBDIR`, `LD_PRELOAD`, `LD_AUDIT`, `LD_LIBRARY_PATH`, `GCONV_PATH`, and `BASH_FUNC_*`. Set one inside the command that needs it instead, for example `PYTHONPATH=/workspace/src python main.py`.
* In an update, `env_vars` replaces the whole map. Send `{}` to clear it.
* Changing variables makes the setup verdict stale.

## Mounts

`mounts` downloads files into the workspace when a sandbox starts, so the agent finds input data on disk at its first turn.

```json theme={"theme":"css-variables"}
{
  "mounts": [
    {"source": "https://data.example.com/exports/customers.csv", "mount_path": "data/customers.csv"}
  ]
}
```

| Field | Description |
| - | - |
| `mounts[].source` | HTTPS URL of the file. |
| `mounts[].mount_path` | Where the file goes, relative to `/workspace`. It must name a file: it can't end in `/` or contain `..`. |

* Two mounts can't use the same path or one inside the other.
* Mounts are checked when a sandbox starts, not when you save. An invalid mount makes provisioning fail, so run a setup test after you change mounts.
* Anyone who can view the environment can read each `source` URL. Don't embed long-lived credentials in it.
* In an update, `mounts` replaces the whole list. Send `[]` to clear it.

## Sandbox tools that depend on the environment

The agent's tools run in the sandbox this environment defines. A few depend on its settings. For the full tool list, see [Tools](/recursion/tools).

| Tool | Depends on |
| - | - |
| `run_command`, `read_file`, `write_file`, `share_file` | Available in every Agent runner sandbox. Commands follow the network policy. |
| `computer` | `computer_use: true`. Websites follow the network policy. |
| `release_compute` | Root sessions only. Releases compute early and keeps the workspace. Subagents share their root's compute and can't release it. |

A tool being available never grants network access.

## Environment lifecycle

| Event | Effect |
| - | - |
| Create | Saves the definition. No compute starts. |
| Setup run | Starts fresh compute, runs the script, checks the compute, saves a reusable image, releases the compute, and records the verdict. |
| Start a session | Starts a fresh sandbox from the saved image, or from the runner image when there is no script. If the runner has changed, the platform first captures a matching setup image on dedicated compute; the session waits in provisioning and shows the setup run log. |
| Update | Saves the changes without starting a setup run. The changes apply to sandboxes started afterward; running sessions keep their configuration. |
| Idle stop | Stops compute and keeps the workspace. The next tool call restores it. |
| Stopped retention | Allows a stopped sandbox to be released. A later message can reopen the same session's workspace files. |
| Delete environment | Removes it from lists and reads. New sessions can't use it; running sessions keep their sandbox. There is no restore. |

## Limits

| Limit | Value |
| - | - |
| Name | 256 characters |
| CPU | 250 to 8000 millicores; the available compute or a restricted network policy can impose a lower maximum |
| Memory | 1024 to 32768 MiB; the available compute or a restricted network policy can impose a lower maximum |
| GPU | One per environment: `a100`, `l4`, or `t4` |
| Workspace disk | 1 to 100 GiB |
| Idle stop | 120 to 7200 seconds; 600 minimum with computer use |
| Stopped delete | 3600 to 2592000 seconds |
| Setup script | 64 KiB |
| Setup timeout | 10 to 3600 seconds, default 600 |
| Setup runs in flight | 1 per environment; 4 manual runs per organization |
| Setup-run log | 4 MiB per run; 2 KiB `stderr_tail` |
| Network policy | 200 rules |

For every product limit, see [Limits](/recursion/limits).

## Next steps

<CardGroup cols={2}>
  <Card title="Set up an environment" href="/recursion/environments">
    Create, verify, restrict, update, and delete environments.
  </Card>

  <Card title="Deliverables and artifacts" href="/recursion/artifacts">
    How agents save files to the outputs folder and how they're collected.
  </Card>

  <Card title="Security" href="/recursion/security">
    What reaches the sandbox and how credentials flow.
  </Card>

  <Card title="Troubleshooting" href="/recursion/troubleshooting">
    Fix common session and environment problems.
  </Card>
</CardGroup>
