Run sandbox tools in Cloudflare while OpenAI runs the agent and maintains session state. This guide uses webhook-managed provisioning with Cloudflare’s reference Worker.
How it works
- Your application creates an Agents API session and sends input.
- OpenAI sends session webhooks to a Worker in your Cloudflare account.
- The Worker starts or reconnects a session-specific Container running
codex exec-server. The executor connects outbound to OpenAI so the agent can run commands and work with files.
Your application uses the Agents API; the reference Worker manages sandbox provisioning. See Sandbox lifecycle for connection and recovery behavior.
Before you begin
You need a Cloudflare account with Containers access, an OpenAI application API key, and a separate restricted executor key. Follow executor authentication to configure the keys. Keep the application key outside the Container.
Create an agent and save its ID as OPENAI_AGENT_ID. Use the same agent ID in your application and the reference Worker.
Deploy the reference Worker
Cloudflare’s reference Worker includes the webhook handler, Container image, deployment configuration, and cleanup endpoint.
Generate a secret for the cleanup endpoint and save it as EXECUTOR_CLIENT_SECRET:
openssl rand -hex 32
Deploy the Worker in your Cloudflare account:
Deploy to Cloudflare
Enter these values when prompted:
| Variable | Value |
|---|---|
OPENAI_API_KEY | Key used by the Worker to retrieve session state |
OPENAI_EXECUTOR_API_KEY | Restricted key passed to codex exec-server |
OPENAI_AGENT_ID | Agent ID served by this Worker |
OPENAI_WEBHOOK_SECRET | pending-webhook-registration for the first deployment |
EXECUTOR_CLIENT_SECRET | Secret generated for cleanup |
Save the deployed Worker URL as WORKER_URL.
Register the webhook
Follow webhook setup to register $WORKER_URL/webhook in your OpenAI project. Enable the events listed by Cloudflare’s reference integration:
agent.session.createdagent.session.action_requiredagent.session.in_progressagent.session.idleagent.session.failed
Replace OPENAI_WEBHOOK_SECRET with the signing secret returned by OpenAI, then deploy the new Worker version. Check its configuration. These examples use standard HTTP clients to call the Worker:
import os
import urllib.request
url = os.environ["WORKER_URL"].rstrip("/") + "/health"
request = urllib.request.Request(url, method="GET")
with urllib.request.urlopen(request) as response:
print(response.read().decode())The response should contain both "configured": true and "webhook_configured": true.
An environment_connection required action is the signal to reconnect an offline executor. An idle event alone isn’t a safe shutdown signal; see lifecycle behavior.
Run a session
Follow the session steps with your application’s OPENAI_API_KEY and the same OPENAI_AGENT_ID configured in the Worker. Create a self-hosted session and ask the agent to write and read /workspace/hello.txt.
The Worker receives the session webhooks and connects the sandbox executor. Your application streams the agent’s output through the Agents API.
Save the session ID as SESSION_ID. To continue the conversation, open the session event stream before sending follow-up input. If the executor is offline, the new input requests an environment connection and waits for the Worker to reconnect it. Reconnection does not by itself restore files from a previous Container.
Run your application in a Worker
Cloudflare’s basic Worker application uses the @openai/agents-api TypeScript SDK to create sessions, send initial and follow-up input, and clean up resources. Its POST /demo endpoint runs the workflow.
This application also uses webhook-managed provisioning. Running your application in a Worker doesn’t mean it must provision the sandbox directly.
Cleanup
When the application no longer needs the sandbox, call the reference Worker’s authenticated cleanup endpoint:
import os
from urllib.parse import quote
import urllib.request
url = (
os.environ["WORKER_URL"].rstrip("/")
+ "/executors/"
+ quote(os.environ["SESSION_ID"], safe="")
)
request = urllib.request.Request(
url,
method="DELETE",
headers={"Authorization": "Bearer " + os.environ["EXECUTOR_CLIENT_SECRET"]},
)
with urllib.request.urlopen(request) as response:
print(response.read().decode())Delete the Agents API session separately. Session deletion does not emit a webhook, so perform both operations for immediate cleanup. Retrieve files you need before releasing the Container.
Advanced: Application-managed provisioning
For direct control of sandbox provisioning, use the Cloudflare Sandbox SDK with the application-managed lifecycle and executor connection instructions. Use one provisioning controller per session.
References
- Read Use Cloudflare Containers with OpenAI Agents API for configuration, lifecycle behavior, snapshots, and image customization.
- Read Cloudflare Sandbox documentation.
- Read Cloudflare Sandbox TypeScript SDK reference.