Environments
An environment is a configured, isolated container in which an agent’s code runs. When an agent uses code execution, a skill with scripts, or a shell or file tool, the commands run inside the session’s environment, never on shared hosts. You decide what is installed in it, which network destinations it can reach, how much CPU and memory it gets, and which files it starts with.
Define an environment once and reference it from any number of agent definitions or sessions. Each session gets its own fresh container built from the environment; containers are never shared between sessions.
When to use one
- The agent analyses data and needs Python packages such as
pandas. - The agent works on a code repository and needs
git, a language toolchain and your test runner. - The agent must call one internal API and nothing else on the internet.
- You need predictable resource limits for cost control.
Agents that only call your own function tools or built-in web tools need no environment.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /v1/environments | Create an environment. Building starts at once. |
GET | /v1/environments | List environments. |
GET | /v1/environments/{environment_id} | Read one, including build status. |
PATCH | /v1/environments/{environment_id} | Change settings. A change to the image or packages triggers a rebuild. |
GET | /v1/environments/{environment_id}/build_log | Plain-text log of the last build. |
DELETE | /v1/environments/{environment_id} | Delete. Refused while an agent references it. |
Base URL https://app.syntic.ai/v1 (the paths above already include /v1). Authenticate with a private key and send syntic-beta: agents-2026-11-01. Environments belong to the key’s workspace.
The environment object
{
"id": "env_01JC5B2D4F6H8K0M2P4R",
"type": "environment",
"name": "data-analysis",
"base_image": "syntic/python:3.12",
"packages": {
"apt": ["git"],
"pip": ["pandas==2.2.3", "matplotlib"],
"npm": []
},
"setup_script": "mkdir -p /workspace/out",
"files": [{ "file_id": "file_01JC3...", "path": "/workspace/data/prices.csv" }],
"network": {
"mode": "allowlist",
"allowed_hosts": ["api.internal.example.com", "*.pypi.org"]
},
"resources": { "cpu": 2, "memory_mb": 4096, "disk_mb": 10240 },
"timeouts": { "command_seconds": 300, "idle_minutes": 15, "max_lifetime_minutes": 240 },
"env_vars": { "TZ": "UTC" },
"vault_secrets": [{ "vault_id": "vlt_01JC2...", "name": "INTERNAL_API_TOKEN" }],
"build": { "status": "ready", "image_digest": "sha256:9f2c...", "finished_at": "2026-11-04T08:12:40Z", "error": null },
"created_at": "2026-11-04T08:10:02Z",
"updated_at": "2026-11-04T08:10:02Z"
}| Field | Required on create | Description |
|---|---|---|
name | Yes | Unique in the workspace, up to 64 characters. |
base_image | No | One of the Syntic base images: syntic/base (Debian, no language runtime), syntic/python:3.12, syntic/node:22, syntic/full (Python, Node, Go and common build tools). Default syntic/base. |
packages | No | Packages to install at build time, by manager: apt, pip, npm. Pin versions for repeatable builds. Up to 200 in total. |
setup_script | No | Shell script run once at build time, after packages. Up to 16 KB. |
files | No | Files from the Files API copied in at build time, each to an absolute path under /workspace. Up to 50 files, 500 MB in total. |
network | No | mode is none (no network), allowlist (only allowed_hosts, with *. wildcards) or open. Default none. |
resources | No | cpu 1 to 8, memory_mb 512 to 16384, disk_mb 1024 to 51200. Defaults 1, 2048, 5120. |
timeouts | No | command_seconds (one command, default 120, max 3600), idle_minutes (container stops when unused, default 10), max_lifetime_minutes (hard stop, default 120, max 1440). |
env_vars | No | Plain environment variables. Do not put secrets here; they are readable in the API. |
vault_secrets | No | Secrets injected as environment variables from a vault. The value is never shown to the model or returned by the API. |
build.status is queued, building, ready or failed. Sessions can only use a ready environment. While a rebuild runs, new sessions keep using the previous ready build.
Create an environment
curl -sS https://app.syntic.ai/v1/environments \
-H "Authorization: Bearer $SYNTIC_API_KEY" \
-H "Content-Type: application/json" \
-H "syntic-beta: agents-2026-11-01" \
-d '{
"name": "data-analysis",
"base_image": "syntic/python:3.12",
"packages": {"pip": ["pandas==2.2.3", "matplotlib"]},
"network": {"mode": "none"},
"resources": {"cpu": 2, "memory_mb": 4096}
}'Response: 201 Created with the object and build.status: "queued". Poll GET /v1/environments/{id}, or register a webhook for environment.build.succeeded and environment.build.failed.
Use it
Set environment_id on an agent definition, or override it per session with environment_id on POST /v1/sessions. Inside the container:
- the working directory is
/workspace, which persists for the life of the session’s container; - files the agent writes under
/workspace/outare uploaded to the Files API when the session ends and listed on the session asoutput_files; - every command the agent runs appears as a
tool_calltrace in the execution, with exit code and truncated output.
Security model
- Each session runs in its own container with its own kernel-level isolation. Nothing is shared between sessions or between workspaces.
- The container has no route to Syntic’s internal network, cloud metadata addresses or private IP ranges, whatever the
networksetting. allowlistmode resolves hosts at connection time and blocks anything not on the list, including redirects to other hosts.- Secrets from vaults are injected at container start and are not written to the image.
Errors
Errors use the error envelope.
| Status | type | code | When |
|---|---|---|---|
| 400 | invalid_request | unknown_base_image | base_image is not on the list. |
| 400 | invalid_request | resource_out_of_range | A resource or timeout is outside its range. |
| 400 | invalid_request | invalid_host_pattern | An allowed_hosts entry is not a host name or *. wildcard. |
| 404 | not_found | environment_not_found | No such environment in this workspace. |
| 409 | invalid_request | environment_in_use | Delete while an agent or deployment references it. |
| 409 | invalid_request | environment_not_ready | A session was started on an environment whose first build has not finished or failed. |
Limits and billing
| Limit | Value |
|---|---|
| Environments per workspace | 50 |
| Build time | 20 minutes, then the build fails |
| Concurrent containers per workspace | 20 (raised with rate-limit tier) |
Container time is billed per second of running container, rounded up to the nearest minute per session, at a rate that depends on cpu and memory_mb. Rates appear on Pricing when the feature launches. Builds are free. Zero-data-retention organizations can use environments; containers and their files are deleted when the session ends.
Build notes for the platform team
- Reuse the App Builder sandbox fleet with a separate node pool and strict egress rules; do not share pools with App Builder.
- Image builds are cached by a hash of
base_image,packages,setup_scriptandfiles. - A later phase adds self-hosted environments that run in the customer’s cloud and connect out to Syntic.