# OpenAI Agents API with Render Sandboxes — Give Codex an isolated execution environment in your Render workspace.


> *Render Sandboxes is in public beta.*
>
> APIs, defaults, and limits might change during the beta period.

You can use [Render Sandboxes](sandboxes) with the [OpenAI Agents API](https://developers.openai.com/api/docs/guides/agents-api/environments/self-hosted) to integrate the Codex agent loop with isolated, self-hosted code execution in your Render workspace. OpenAI hosts the loop as usual, while the sandbox executes Codex's commands and file edits.

*This tutorial walks through running a basic coding agent that:*

1. Accepts a user prompt and sends it to Codex,
2. Executes Codex-generated commands in a [Render sandbox](sandboxes), and
3. Copies the resulting output files to the user's machine.

For details, see [How the agent runs](#how-the-agent-runs).

## Prerequisites

Before you start, make sure you have all of the following:

*Render*

- A Render [API key](https://dashboard.render.com/u/settings?add-api-key)
- Your Render workspace ID
    - Obtain this from the top of your workspace's *Settings* page in the [Render Dashboard](https://dashboard.render.com).

*OpenAI*

- Access to the [OpenAI Agents API](https://developers.openai.com/api/docs/guides/agents-api/overview)
- An [OpenAI API key](https://platform.openai.com/api-keys) with permission to manage Agents API sessions and run model inference
- A separate [environment key](https://platform.openai.com/agents?tab=environments&environment_view=keys), created on the *Agents* tab

*Installed tooling*

- Git
- Node.js 22 or later

## Setup

### 1. Clone the template

> *The template code for this tutorial is available on [GitHub](https://github.com/render-examples/openai-agents-api-sandbox).*

Clone the template and install its dependencies:

```shell
git clone https://github.com/render-examples/openai-agents-api-sandbox
cd openai-agents-api-sandbox
npm ci
```

### 2. Configure credentials

1. Copy the example environment file to `.env`:

    ```shell
    cp .env.example .env
    ```

    The file includes the following required environment variables:

    ```bash
    # Render
    RENDER_API_KEY=
    RENDER_WORKSPACE_ID=

    # OpenAI
    OPENAI_API_KEY=
    OPENAI_EXECUTOR_API_KEY=
    ```

2. Populate the values for these environment variables according to the table below:

| Environment variable | Description |
| --- | --- |
| `RENDER_API_KEY` | Your Render [API key](https://dashboard.render.com/u/settings?add-api-key). Starts with `rnd_` |
| `RENDER_WORKSPACE_ID` | Your Render workspace's ID, available at the top of its *Settings* page in the [Render Dashboard](https://dashboard.render.com). Starts with `tea-` |
| `OPENAI_API_KEY` | Your [OpenAI API key](https://platform.openai.com/api-keys), with [permissions to manage sessions and run model inference](https://developers.openai.com/api/docs/guides/agents-api/environments/self-hosted#authentication). The template uses this key locally to manage your OpenAI Agents API session. It is _not_ passed into the sandbox. |
| `OPENAI_EXECUTOR_API_KEY` | Your [OpenAI environment key](https://platform.openai.com/agents?tab=environments&environment_view=keys). Create it on the *Agents* tab in the same organization and project, and under the same user or service account, as your application API key. The template passes this key into the sandbox as `CODEX_API_KEY`. A regular API key can't be used in its place. |

### 3. Perform your first agent run

This example handles one prompt per run and does not support follow-up messages. Provide a task Codex can complete without additional input.

Run the agent with a prompt:

```shell
npm run agent -- "Create a hello world HTTP server in /workspace/output. Test it before you finish."
```

Codex's activity streams to your terminal, resembling the following:

```
provider      openai
preflight     passed
provision     sbx-...
environment   connected
prompt        submitted
progress      reasoning
progress      command_execution
progress      command_execution
agent         I created /workspace/output/server.js and confirmed it responds with "Hello, world!".
progress      message
result        task completed
outputs       copied 1 file to runs/run_.../output
cleanup       session deleted; sandbox terminated
```

In this example:

1. Codex created a web server and tested it inside the sandbox.
2. The runner copied the server to your machine.
3. The runner deleted the session and terminated the sandbox to clean up.

### 4. Customize agent capabilities (optional)

> *These customization methods are specific to this template.*
>
> For general-purpose customization of Render Sandboxes, see [Configuring sandbox behavior](sandboxes-creating#configuring-sandbox-behavior).

| Customization | Description |
| --- | --- |
| *Toolchain* | You can install additional command-line tools for Codex to use inside the sandbox. Add installation commands to `scripts/install-executor.sh`, and add their download hosts to `INSTALL_DESTINATIONS` in `src/launch-policy.ts`. The template uploads this script to each new sandbox and executes it there before starting `codex exec-server`. |
| *Network access* | You can customize the sandbox's [network access](sandboxes-creating#network-access) to allow outbound traffic to additional HTTPS destinations. Add the desired hostnames to `RUNTIME_DESTINATIONS` in `src/launch-policy.ts` to include them in the sandbox's allowlist. |
| *Run timeout* | You can set a time limit for the overall agent run, including sandbox setup, task execution, and output collection. Pass `--timeout <seconds>` or set `AGENT_TIMEOUT_SECONDS` (the default is `600`). The runner also derives a separate sandbox lifetime from this value in `src/agent.ts`. |
| *Outputs* | You can choose where generated output files are saved on your machine. Pass `--output ` to specify a local destination directory. The default is `runs/<run_id>/output`. To change which files the template collects from the sandbox, edit `src/outputs.ts`. |

To change Codex's [instructions](https://developers.openai.com/api/docs/guides/agents-api/configuration), edit `createSession()` in [`src/openai.ts`](https://github.com/render-examples/openai-agents-api-sandbox/blob/main/src/openai.ts). To use a different model, set `OPENAI_MODEL` in `.env`.

## How the agent runs

The template runs on your local machine. Its [`src/agent.ts`](https://github.com/render-examples/openai-agents-api-sandbox/blob/main/src/agent.ts) coordinates each run through the following stages:

------

##### Session creation

From your local machine, the template checks your Agents API access and calls the OpenAI API to create a session with a `self_hosted` environment.

OpenAI returns the environment ID and remote URL that the template will use to connect the sandbox to the session.

##### Sandbox creation

The template creates a Render sandbox and waits until it's running. It passes the environment key into the sandbox as `CODEX_API_KEY`, as defined in [`src/launch-policy.ts`](https://github.com/render-examples/openai-agents-api-sandbox/blob/main/src/launch-policy.ts).

##### Codex CLI startup

The template installs a pinned release of the Codex CLI inside the sandbox with [`scripts/install-executor.sh`](https://github.com/render-examples/openai-agents-api-sandbox/blob/main/scripts/install-executor.sh), verifying its npm integrity hash.

It opens the session's event stream on your local machine, then starts `codex exec-server` inside the sandbox to connect it to the session.

##### Task execution

After OpenAI reports that the environment is connected, the template submits your prompt from your local machine.

OpenAI runs the agent loop on its infrastructure. When Codex requests a command or file edit, the `codex exec-server` process executes it inside the sandbox and sends the result back to OpenAI.

The template streams session events and Codex's response to your terminal.

##### File collection and cleanup

When Codex finishes its turn, the template downloads regular files from `/workspace/output` in the sandbox to `runs/<run_id>/output` on your machine. It then deletes the session and terminates the sandbox.

Cleanup also runs after a failure, a timeout, `Ctrl+C`, or `SIGTERM`. Session deletion and sandbox termination are attempted independently. If cleanup fails, follow the instructions under [Troubleshooting](#troubleshooting).

Each run also saves the following files under `runs/<run_id>/`:

- `run.json`: Resource IDs, network policy, and cleanup status, without credentials.
- `events.jsonl`: Session events.
- `executor.log`: Sandbox setup and executor logs.
- `result.txt`: Codex's final response.

------

## Security considerations

- *Your OpenAI application API key never enters the sandbox.*

    Any code that Codex executes in the sandbox can read the sandbox's environment variables, including the environment key. Make sure that any values you set are safe to expose.

    The environment key only permits connecting environments. Keep other permissions disabled, as described in [OpenAI's authentication guidance](https://developers.openai.com/api/docs/guides/agents-api/environments/self-hosted#authentication).

- *Credential brokering for Render Sandboxes is [not yet generally available](sandboxes#beta-limitations).*

    The template currently sets the environment key as an environment variable during sandbox creation. This behavior is defined entirely in `src/launch-policy.ts`.

- *Sandbox [network access](sandboxes-creating#network-access) is managed via allowlist.*

    The template allows access to `api.openai.com`, `codex-cloud-environments.chatgpt.com`, and `registry.npmjs.org`. The npm registry host remains allowed throughout the run, even after installation finishes.

    Tool inputs and outputs pass through OpenAI, because OpenAI hosts the agent loop.

## Troubleshooting

###### Preflight fails.

Confirm your Agents API access and that your OpenAI API key can manage sessions.

###### The environment never connects.

Check the `[executor:stderr]` lines and `runs/<run_id>/executor.log`. If they show `403 Forbidden: missing required scope api.agents.environments.connect`, replace the executor key with an environment key from the [Agents tab](https://platform.openai.com/agents?tab=environments&environment_view=keys). Make sure it belongs to the same organization, project, and user or service account as your application API key.

###### The run fails with &quot;Your account is not active&quot;.

The environment connected, but OpenAI refused the first model request. Check your organization's [billing settings](https://platform.openai.com/settings/organization/billing/), then run the agent again.

###### The task never starts.

Open `runs/<run_id>/events.jsonl` and confirm that the `agent.session.environment.connected` event arrived before the prompt was submitted.

###### The agent produces no output files.

Inspect `runs/<run_id>/events.jsonl` and `result.txt`. Output files are optional, so prompts that need files should ask Codex to write them under `/workspace/output`.

###### Cleanup is incomplete.

If a cleanup step fails, the runner prints the commands that finish it, with the resource IDs filled in. Delete the session and terminate the sandbox independently.

The commands read your credentials from your shell, so load `.env` from the template directory before you run them:

```shell
set -a && source .env && set +a
```

The command that terminates a sandbox requires version 2.33.0 or later of the [Render CLI](cli).

If session or sandbox creation fails without a clear answer from the API, the runner also prints a `reconcile` command that lists recent resources, so you can find and delete one that might have been created.
