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

# Cloud Environments

> Choose the container, network, and dependencies your agent runs in.

An Environment defines the container template a Session runs on: its environment type, networking policy, preinstalled dependencies, setup script, and metadata. You can build different Environments for different scenarios: a strictly isolated audit environment, an analytics environment with data-science libraries, or an open-network environment for general development.

## What an Environment Is

An Environment is the infrastructure layer beneath a Session:

* **Environment type** - `cloud` for managed cloud containers, or `self_hosted` for self-hosted execution.
* **Networking policy** - controls outbound network access.
* **Packages** - preinstalled system, Python, and Node.js dependencies.
* **Setup script** - a user shell script run after package installation during container preparation.

When a Session starts, an isolated runtime is created from the specified Environment template.

## Field Reference

| Field                 | Type         | Required | Description                                                 |
| --------------------- | ------------ | -------- | ----------------------------------------------------------- |
| `id`                  | string       | -        | System-generated, prefixed with `env_`                      |
| `type`                | string       | -        | Always `"environment"`                                      |
| `name`                | string       | Yes      | Environment name                                            |
| `description`         | string       | No       | Free-form description; defaults to `""`                     |
| `config`              | object       | Yes      | Environment configuration                                   |
| `config.type`         | string       | Yes      | Environment type: `"cloud"` or `"self_hosted"`              |
| `config.networking`   | object       | No       | Networking policy for `cloud` environments                  |
| `config.packages`     | object       | No       | Preinstalled package configuration for `cloud` environments |
| `config.setup_script` | string       | No       | Shell script run during sandbox preparation (max 64 KB)     |
| `metadata`            | object       | No       | Custom key/value metadata                                   |
| `archived_at`         | string\|null | -        | Archive time (ISO 8601), `null` when not archived           |
| `created_at`          | string       | -        | Creation timestamp                                          |
| `updated_at`          | string       | -        | Last update timestamp                                       |

## Config Types

`config.type` can be `"cloud"` or `"self_hosted"`.

For `self_hosted`, the config must be exactly:

```json theme={null}
{"type": "self_hosted"}
```

Self-hosted Environments do not launch a managed cloud container. External workers use the [Work API](/cloud-agents/api/environments/work/poll) to poll, acknowledge, heartbeat, and stop Session work for that Environment.

For `cloud`, the config can include `networking`, `packages`, and `setup_script`.

## Networking Policies

`config.networking` supports three request modes. **All modes require the object form** - passing a string shorthand like `"unrestricted"` returns 400.

| Mode      | Value                                                 | Description                                                        |
| --------- | ----------------------------------------------------- | ------------------------------------------------------------------ |
| Open      | `{"type": "unrestricted"}`                            | The container can reach any external address                       |
| Limited   | `{"type": "limited", "allow_package_managers": true}` | Only known-safe public services and package managers are reachable |
| Allowlist | `{"type": "allowed_hosts", "allowed_hosts": [...]}`   | Only the listed hosts are reachable                                |

Cloud Environment responses include these networking fields. Omitted fields are returned with defaults.

| Field                    | Type            | Default   |
| ------------------------ | --------------- | --------- |
| `type`                   | string          | `limited` |
| `allowed_hosts`          | array of string | `[]`      |
| `allow_package_managers` | boolean         | `false`   |
| `allow_mcp_servers`      | boolean         | `false`   |

### Open

```json theme={null}
{
  "config": {
    "type": "cloud",
    "networking": {"type": "unrestricted"}
  }
}
```

Use this for general development tasks that need to download dependencies or call external APIs.

### Limited

```json theme={null}
{
  "config": {
    "type": "cloud",
    "networking": {
      "type": "limited",
      "allow_package_managers": true
    }
  }
}
```

Use this when you don't need arbitrary outbound traffic but still want package managers to fetch dependencies.

### Allowlist

```json theme={null}
{
  "config": {
    "type": "cloud",
    "networking": {
      "type": "allowed_hosts",
      "allowed_hosts": [
        "api.github.com",
        "registry.npmjs.org",
        "pypi.org"
      ]
    }
  }
}
```

Use this for security-sensitive workloads where you must whitelist exactly which external services are reachable.

## Preinstalled Packages

Use `config.packages` to specify dependencies installed when the container starts:

```json theme={null}
{
  "config": {
    "type": "cloud",
    "networking": {"type": "unrestricted"},
    "packages": {
      "apt": ["git", "build-essential", "libssl-dev"],
      "pip": ["pandas", "numpy", "scikit-learn"],
      "npm": ["typescript", "eslint", "prettier"]
    }
  }
}
```

| Package manager | Field          | Description                   |
| --------------- | -------------- | ----------------------------- |
| apt             | `packages.apt` | Debian/Ubuntu system packages |
| pip             | `packages.pip` | Python packages               |
| npm             | `packages.npm` | Node.js packages              |

<Note>
  Preinstalled packages add to environment startup time. Only include packages you really need; install the rest on demand within the Session.
</Note>

## Setup Script

`config.setup_script` is a shell script executed during sandbox preparation, after `packages` are installed. It runs through `/bin/bash -lc`. Use it for initialization steps that cannot be expressed as `packages` - for example, cloning a repository, writing config files, or warming caches.

| Constraint   | Value                                              |
| ------------ | -------------------------------------------------- |
| Type         | string                                             |
| Max length   | 64 KB                                              |
| Interpreter  | `/bin/bash -lc`                                    |
| Timeout      | 10 minutes                                         |
| When it runs | Sandbox preparation, after `packages` installation |

```bash theme={null}
# Create an environment that clones the project and warms its dependency cache
curl -s -X POST https://api.qoder.com/api/v1/cloud/environments \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "node-with-init",
    "config": {
      "type": "cloud",
      "networking": {"type": "unrestricted"},
      "packages": {
        "npm": ["pnpm@9"]
      },
      "setup_script": "set -euo pipefail\n[ -d /workspace/.git ] || git clone https://github.com/me/repo /workspace\ncd /workspace && pnpm install --frozen-lockfile"
    }
  }' | jq .
```

On success a completion marker is written inside the sandbox so the script does not run twice in the same sandbox; when the sandbox is recreated, the script runs again. A non-zero exit aborts session startup, and the error response includes the exit code and a stderr excerpt.

## Create an Environment

```bash theme={null}
# Create a data-science Environment
curl -s -X POST https://api.qoder.com/api/v1/cloud/environments \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "data-science",
    "config": {
      "type": "cloud",
      "networking": {"type": "unrestricted"},
      "packages": {
        "apt": ["build-essential"],
        "pip": ["pandas", "numpy", "matplotlib", "scikit-learn", "jupyter"]
      }
    }
  }' | jq .
```

A successful call returns **200 OK**:

```json theme={null}
{
  "id": "env_019e44eb66bb748cabcd1489f6fa4428",
  "type": "environment",
  "name": "data-science",
  "description": "",
  "config": {
    "type": "cloud",
    "networking": {
      "type": "unrestricted",
      "allowed_hosts": [],
      "allow_package_managers": false,
      "allow_mcp_servers": false
    },
    "packages": {
      "type": "packages",
      "apt": ["build-essential"],
      "npm": [],
      "pip": ["pandas", "numpy", "matplotlib", "scikit-learn", "jupyter"]
    }
  },
  "metadata": {},
  "archived_at": null,
  "created_at": "2026-05-18T10:00:00Z",
  "updated_at": "2026-05-18T10:00:00Z"
}
```

## Create a Restricted-Network Environment

```bash theme={null}
# An environment that can only reach internal APIs
curl -s -X POST https://api.qoder.com/api/v1/cloud/environments \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "secure-internal",
    "config": {
      "type": "cloud",
      "networking": {
        "type": "allowed_hosts",
        "allowed_hosts": ["internal-api.mycompany.com", "git.mycompany.com"]
      },
      "packages": {
        "apt": ["git", "curl"]
      }
    }
  }' | jq .
```

## Read Environments

```bash theme={null}
# List all Environments
curl -s https://api.qoder.com/api/v1/cloud/environments \
  -H "Authorization: Bearer $QODER_PAT"
```

```bash theme={null}
# Get a single Environment
curl -s https://api.qoder.com/api/v1/cloud/environments/env_ds456 \
  -H "Authorization: Bearer $QODER_PAT"
```

## Update an Environment

```bash theme={null}
# Add new dependencies to an existing Environment
curl -s -X POST https://api.qoder.com/api/v1/cloud/environments/env_ds456 \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "data-science",
    "config": {
      "type": "cloud",
      "networking": {"type": "unrestricted"},
      "packages": {
        "apt": ["build-essential", "libpq-dev"],
        "pip": ["pandas", "numpy", "matplotlib", "scikit-learn", "jupyter", "sqlalchemy"]
      }
    }
  }' | jq .
```

<Note>
  Updating an Environment does not affect running Sessions. The new configuration applies to Sessions created after the update.
</Note>

## Choosing an Environment

| Scenario             | Recommended configuration                                             |
| -------------------- | --------------------------------------------------------------------- |
| General development  | `default` Environment, no extra setup                                 |
| Data analysis        | Preinstall pandas/numpy with open networking                          |
| Security audits      | Allowlist networking with minimal dependencies                        |
| Frontend development | Preinstall the Node.js toolchain with open access to the npm registry |
| CI/CD integration    | Preinstall git/docker CLI with allowlist networking                   |

## FAQ

**Q: How long do I have to wait after creating an Environment before I can use it?**

A: A new Environment is immediately usable. The actual container provisioning, including dependency installation, happens when a Session starts.

**Q: Can I pin package versions?**

A: pip and npm packages support pinning, such as `"pandas==2.1.0"` or `"typescript@5.0.0"`. apt packages use the default version from the system repository.

**Q: An incorrect networking setting is breaking my Agent. What should I do?**

A: Create a new Environment (or update the existing one) with corrected networking, then start a new Session.

**Q: How many Environments can I create per account?**

A: There is no hard limit. Create only what you need and use a naming convention to keep things organized.

## Next steps

<CardGroup cols={2}>
  <Card title="Start a session" icon="play" href="/cloud-agents/sessions">
    Combine an Agent and an Environment to start running tasks.
  </Card>

  <Card title="Agent setup" icon="user-gear" href="/cloud-agents/define-agent">
    Review Agent configuration.
  </Card>
</CardGroup>
