Skip to main content
The codex template supports CODEX_API_KEY or OPENAI_API_KEY.

Run Codex

Create a sandbox from the codex template, run Codex headlessly, and clean up. The SDK and CLI paths are equivalent — use the one that matches your workflow.
import os
from nullspace import Sandbox

codex_api_key = os.environ.get("CODEX_API_KEY") or os.environ["OPENAI_API_KEY"]

with Sandbox.create(
    template="codex",
    envs={
        "CODEX_API_KEY": codex_api_key,
        "OPENAI_API_KEY": os.environ.get("OPENAI_API_KEY", codex_api_key),
    },
    timeout=600,
) as sandbox:
    result = sandbox.commands.run(
        'codex exec --full-auto --skip-git-repo-check "Create a hello world HTTP server in Go"',
        shell=True,
        cwd="/workspace",
        timeout=600,
    )
    print(result.stdout)

Interactive terminal

Open a PTY instead of a headless run to drive Codex interactively:
nullspace sandbox pty create sb_123 --cols 120 --rows 30
nullspace sandbox pty connect sb_123 --session-id ses_123
# then, inside the PTY:
codex
Use the session_id from sandbox pty create with --session-id.

Work on a cloned repository

import os
from nullspace import GitHttpsAuth, Sandbox

with Sandbox.create(
    template="codex",
    envs={"CODEX_API_KEY": os.environ["CODEX_API_KEY"]},
    timeout=600,
) as sandbox:
    sandbox.git.clone(
        "https://github.com/your-org/your-repo.git",
        path="/workspace/repo",
        auth=GitHttpsAuth(username="x-access-token", password=os.environ["GITHUB_TOKEN"]),
        depth=1,
    )

    sandbox.commands.run(
        'codex exec --full-auto --skip-git-repo-check -C /workspace/repo "Add error handling to all API endpoints"',
        shell=True,
        timeout=600,
        on_stdout=lambda data: print(data, end=""),
    )

    diff = sandbox.git.diff(path="/workspace/repo")
    print(diff)

Schema-validated output

schema = '{"type":"object","properties":{"summary":{"type":"string"}},"required":["summary"]}'
sandbox.files.write("/workspace/schema.json", schema)

result = sandbox.commands.run(
    'codex exec --full-auto --skip-git-repo-check --output-schema /workspace/schema.json "Summarize this repo"',
    shell=True,
    cwd="/workspace/repo",
    timeout=600,
)
print(result.stdout)

Streaming events

Use --json to emit JSONL events on stdout:
result = sandbox.commands.run(
    'codex exec --full-auto --skip-git-repo-check --json "Find TODOs"',
    shell=True,
    cwd="/workspace/repo",
    timeout=600,
    on_stdout=lambda data: print(data, end=""),
)