AgentsEnvironments

Environments

⚠️
Preview — this feature is being built; the design below is the spec.

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

MethodPathPurpose
POST/v1/environmentsCreate an environment. Building starts at once.
GET/v1/environmentsList 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_logPlain-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"
}
FieldRequired on createDescription
nameYesUnique in the workspace, up to 64 characters.
base_imageNoOne 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.
packagesNoPackages to install at build time, by manager: apt, pip, npm. Pin versions for repeatable builds. Up to 200 in total.
setup_scriptNoShell script run once at build time, after packages. Up to 16 KB.
filesNoFiles from the Files API copied in at build time, each to an absolute path under /workspace. Up to 50 files, 500 MB in total.
networkNomode is none (no network), allowlist (only allowed_hosts, with *. wildcards) or open. Default none.
resourcesNocpu 1 to 8, memory_mb 512 to 16384, disk_mb 1024 to 51200. Defaults 1, 2048, 5120.
timeoutsNocommand_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_varsNoPlain environment variables. Do not put secrets here; they are readable in the API.
vault_secretsNoSecrets 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/out are uploaded to the Files API when the session ends and listed on the session as output_files;
  • every command the agent runs appears as a tool_call trace 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 network setting.
  • allowlist mode 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.

StatustypecodeWhen
400invalid_requestunknown_base_imagebase_image is not on the list.
400invalid_requestresource_out_of_rangeA resource or timeout is outside its range.
400invalid_requestinvalid_host_patternAn allowed_hosts entry is not a host name or *. wildcard.
404not_foundenvironment_not_foundNo such environment in this workspace.
409invalid_requestenvironment_in_useDelete while an agent or deployment references it.
409invalid_requestenvironment_not_readyA session was started on an environment whose first build has not finished or failed.

Limits and billing

LimitValue
Environments per workspace50
Build time20 minutes, then the build fails
Concurrent containers per workspace20 (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_script and files.
  • A later phase adds self-hosted environments that run in the customer’s cloud and connect out to Syntic.
Was this page helpful?