> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ns.rocks/llms.txt
> Use this file to discover all available pages before exploring further.

# Codex

> Run OpenAI Codex in a secure Nullspace machine.

The `codex` template supports `CODEX_API_KEY` or `OPENAI_API_KEY`.

## Run Codex

Create a machine from the `codex` template, run Codex headlessly, and clean up.
The SDK and CLI paths are equivalent — use the one that matches your workflow.

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  import os
  from nullspace import Machine

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

  with Machine.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 machine:
      result = machine.commands.run(
          'codex exec --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check "Create a hello world HTTP server in Go"',
          shell=True,
          cwd="/workspace",
          timeout=600,
      )
      print(result.stdout)
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace machine create \
    --template codex \
    --env "CODEX_API_KEY=${CODEX_API_KEY:-${OPENAI_API_KEY:-}}" \
    --env "OPENAI_API_KEY=${OPENAI_API_KEY:-${CODEX_API_KEY:-}}" \
    --timeout 600
  # machine create prints the id used below as mch_123
  nullspace machine exec mch_123 \
    --cwd /workspace \
    --timeout 600 \
    --shell 'codex exec --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check "Create a hello world HTTP server in Go"'
  nullspace machine kill mch_123
  ```
</CodeGroup>

### Interactive terminal

Open a PTY instead of a headless run to drive Codex interactively:

```bash theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
nullspace machine pty create mch_123 --cols 120 --rows 30
nullspace machine pty connect mch_123 --session-id ses_123
# then, inside the PTY:
codex
```

Use the `session_id` from `machine pty create` with `--session-id`.

## Work on a cloned repository

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
import os
from nullspace import GitHttpsAuth, Machine

with Machine.create(
    template="codex",
    envs={"CODEX_API_KEY": os.environ["CODEX_API_KEY"]},
    timeout=600,
) as machine:
    machine.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,
    )

    machine.commands.run(
        'codex exec --dangerously-bypass-approvals-and-sandbox --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 = machine.git.diff(path="/workspace/repo")
    print(diff)
```

## Schema-validated output

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
schema = '{"type":"object","properties":{"summary":{"type":"string"}},"required":["summary"]}'
machine.files.write("/workspace/schema.json", schema)

result = machine.commands.run(
    'codex exec --dangerously-bypass-approvals-and-sandbox --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:

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
result = machine.commands.run(
    'codex exec --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check --json "Find TODOs"',
    shell=True,
    cwd="/workspace/repo",
    timeout=600,
    on_stdout=lambda data: print(data, end=""),
)
```

## Related

* [Agent workspace example](../examples/agent)
* [Git helpers](../reference/git)
* [Fork](../machines/fork)
