# Containers API (`/v1/containers`) — sandboxes for code interpreter and hosted shell **Status:** DOCUMENTED · LIVE_VERIFIED (2026-09-18: all 9 operations returned 200 with our key) **Sources:** https://developers.openai.com/api/reference/resources/containers · https://developers.openai.com/api/docs/guides/tools-code-interpreter · https://developers.openai.com/api/docs/guides/tools-shell · https://developers.openai.com/api/docs/pricing#built-in-tools · openapi-master.yaml `CreateContainerBody`, `ContainerResource`, `ContainerFileResource`, `ContainerListResource` **Last verified:** 2026-09-18 · fragment: `generated/fragments/endpoints/openai-containers-skills.json` ## Endpoints | Method / path | operationId | Body / query | Response | Live | |---|---|---|---|---| | `POST /v1/containers` | CreateContainer | JSON `{name*, file_ids[], expires_after {anchor:"last_active_at", minutes}, memory_limit: 1g\|4g\|16g\|64g, network_policy, skills[]}` | `container` | 200 | | `GET /v1/containers` | ListContainers | `limit` (1–100, default 20), `order` asc\|desc, `after`, `name` | `{object:"list", data[], first_id, last_id, has_more}` | 200 | | `GET /v1/containers/{container_id}` | RetrieveContainer | | `container` | 200 | | `DELETE /v1/containers/{container_id}` | DeleteContainer | | `{id, object:"container.deleted", deleted:true}` | 200 | | `POST /v1/containers/{container_id}/files` | CreateContainerFile | multipart `file` **or** JSON `{file_id}` | `container.file` | 200 (multipart) | | `GET /v1/containers/{container_id}/files` | ListContainerFiles | `limit`, `order`, `after` | list of `container.file` | 200 | | `GET /v1/containers/{container_id}/files/{file_id}` | RetrieveContainerFile | | `container.file` | 200 | | `DELETE /v1/containers/{container_id}/files/{file_id}` | DeleteContainerFile | | `{id, object:"container.file.deleted", deleted:true}` | 200 | | `GET /v1/containers/{container_id}/files/{file_id}/content` | RetrieveContainerFileContent | | raw bytes | 200 (`hello atlas`) | SDKs: Python `client.containers.{create,list,retrieve,delete}`, `client.containers.files.{create,list,retrieve,delete}`, `client.containers.files.content.retrieve` (verified in the code-interpreter example); Node `client.containers.*` same names. ## Objects (live) ```json {"id":"cntr_…","object":"container","created_at":1789782244,"status":"running","name":"atlas-tools-agent","memory_limit":"1g", "expires_after":{"anchor":"last_active_at","minutes":5},"last_active_at":1789782244} {"id":"cfile_…","object":"container.file","created_at":1789782244,"bytes":11,"container_id":"cntr_…","path":"/mnt/data/-hello.txt","source":"user"} ``` Auto containers created by `code_interpreter {container:{type:"auto"}}` or `shell {environment:{type:"container_auto"}}` appear with `name: "auto"` and `expires_after {last_active_at, 20}`. `network_policy` is echoed as `{type, allowed_domains}` when set. Spec statuses: `active`/`deleted` in prose; live value `running`. ## Lifecycle & limits (docs + live) - Expiration: 20 minutes without activity (auto) or `expires_after.minutes` from `last_active_at`; expired containers cannot be revived — create a new one and re-upload. Memory state (Python objects) is lost. - Files: uploaded via the files endpoint or copied with `file_ids`; model-created files are cited with `container_file_citation` annotations; user-downloadable artifacts belong under `/mnt/data`. - Network: disabled by default; `allowlist` requires org allow-list; `domain_secrets` inject credentials as placeholders. - Reuse: pass the id as `container` (code interpreter) or `{type:"container_reference", container_id}` (shell) while active. ## Billing (cited) Per 20-minute session per container: 1 GB $0.03 · 4 GB $0.12 · 16 GB $0.48 · 64 GB $1.92 (hosted shell and code interpreter). Our run: 7 auto/explicit 1 GB sessions ≈ $0.21 upper bound. ## Live evidence Sequence 2026-09-18: code interpreter auto container → `GET` (running, 1g, 20 min) → `GET files` (empty) → `GET /v1/containers?limit=2` → `DELETE`; then explicit `POST` (`memory_limit 1g`, `expires_after 5 min`) → multipart file create (`bytes 11`) → retrieve → content → delete file → delete container. Raw: `tmp-live/tools/container_*.json`. Example: `examples/openai/tools/code-interpreter/` (sh/py/ts).