AC Bridge

How to get a notification when Codex finishes or needs approval

Last updated

The short answer Codex already notifies you: tui.notifications is on by default and fires when the terminal is not focused, including when Codex asks you a question. For a sound, a desktop toast or a phone push in any terminal, add a Stop hook for every finished turn and a PermissionRequest hook for approval requests to ~/.codex/hooks.json, then trust them once with /hooks. Codex has no hook for "needs input", but the built-in alert covers its questions. For Claude Code, see the Claude Code notifications guide.

Checked against the Codex docs on .

On this page: which signal fires when · built-in notifications · notify · hooks · your phone · the app and the IDE · when one does not fire · questions · a light instead.

Which Codex signal fires when

Codex has four signals you can use in the terminal. They differ in when they fire and in whether they care if you are looking at the terminal.

Signal Fires when Only when the terminal is unfocused?
tui.notifications Codex finishes a turn, asks for approval or asks you a question (all events when set to true) By default; set notification_condition = "always" to change it
notify A turn completes (agent-turn-complete, the only event) No
Stop hook Codex finishes responding at the end of a turn No
PermissionRequest hook Codex is about to ask for approval. It does not run for commands that need none. No

The gotcha Codex has no idle reminder and no needs-input hook event. Its hook events are Stop, PermissionRequest and others such as PreToolUse, but nothing that means "waiting for you". The built-in tui.notifications alert is the one signal that also covers a question.

1. Built-in notifications: tui.notifications

Nothing to install. tui.notifications defaults to true, and tui.notification_condition defaults to unfocused, so Codex alerts you only when the terminal is not the window you are looking at. Set the condition to always to be alerted regardless. tui.notification_method picks how: auto (the default) prefers an OSC 9 desktop notification, a terminal escape sequence some terminals turn into a desktop alert, and falls back to the terminal bell; osc9 or bel forces one. In ~/.codex/config.toml:

[tui]
notifications = true
notification_method = "auto"
notification_condition = "always"

Keep notifications = true rather than a list of event types. The setting also accepts a list such as ["agent-turn-complete", "approval-requested"], but a list that leaves the question event out turns question alerts off.

In practice, terminals without OSC 9 desktop support, such as Windows Terminal and the VS Code terminal, get the bell rather than a desktop alert. If you want a toast there, use a hook (section 3). Reference: configuration reference.

2. notify: run a program when a turn completes

notify runs an external program whenever Codex emits a supported event, and the only supported event is agent-turn-complete. The program receives one JSON argument, appended as the last argument, with type, thread-id, turn-id, cwd, input-messages and last-assistant-message. Put it in your own ~/.codex/config.toml, above the first [table] line, or TOML files it under that table. Codex ignores notify in a project's .codex/config.toml and prints a startup warning.

notify = ["notify-send", "Codex"]

That is the example from Codex's own configuration guide. For a tidier message, point notify at a small script that reads last-assistant-message from that JSON argument; the advanced configuration guide has the details. notify is the older mechanism: hooks are the newer, broader option and the one to start with.

3. Codex hooks: a notification on Stop and PermissionRequest

Hooks are on by default. Codex reads them from ~/.codex/hooks.json, ~/.codex/config.toml, <repo>/.codex/hooks.json and <repo>/.codex/config.toml; project-local hooks load only when that project's .codex/ layer is trusted. This file registers a notification for a finished turn and for an approval request:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "notify-send 'Codex' 'Finished' >/dev/null 2>&1",
            "async": true
          }
        ]
      }
    ],
    "PermissionRequest": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "notify-send 'Codex' 'Needs your approval' >/dev/null 2>&1",
            "async": true
          }
        ]
      }
    ]
  }
}

Trust a new hook once with /hooks

Before a non-managed hook can run, Codex requires you to review and trust the exact hook definition. New or changed hooks are marked for review and skipped until trusted, and Codex prints a startup warning telling you to open /hooks. Start Codex, type /hooks, review each hook and trust it. Change a command later and it needs trusting again. The hooks page explains the review step.

4. A notification on your phone

For the ChatGPT desktop app, the official path is the ChatGPT mobile app's remote connection to a Mac or Windows computer running the desktop app, described in the docs as a way to "get notified when ChatGPT completes a task or needs your attention". See remote connections.

For the terminal CLI, post to a push service from a hook. ntfy is a free one: subscribe to a topic in its app, then publish to that topic with curl. There is no sign-up, so the topic name works like a password. Pick one nobody could guess.

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "curl -s -o /dev/null -d \"Codex finished\" ntfy.sh/your-hard-to-guess-topic",
            "async": true
          }
        ]
      }
    ],
    "PermissionRequest": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "curl -s -o /dev/null -d \"Codex needs your approval\" ntfy.sh/your-hard-to-guess-topic",
            "async": true
          }
        ]
      }
    ]
  }
}

-o /dev/null matters: ntfy replies with JSON, and Stop parses its stdout. Do not use notify = ["curl", ...] instead. notify appends the event's JSON payload as the last argument, so curl would receive it as one more thing to fetch. Trust the hooks in /hooks as in section 3.

In the ChatGPT desktop app, on the web and in the IDE extension

The full list is on the notifications page.

When a Codex notification does not fire

Questions people ask

Does Codex notify me when it finishes?

Yes. The built-in tui.notifications alert is on by default and fires when the terminal is unfocused. For a toast or sound every time, add a Stop hook or a notify line, which fires on agent-turn-complete.

Does Codex notify me when it needs approval?

Yes. A PermissionRequest hook runs when Codex is about to ask for approval, and the built-in alert can cover it too. The hook does not run for commands that need no approval, and it needs trusting in /hooks first.

Does Codex tell me when it asks a question?

Through the built-in alert, yes: with tui.notifications = true Codex also alerts you when it asks a question. There is no needs-input hook event, and a filter list that omits those events turns question alerts off.

Why did my Codex hook not run?

Most often it has not been trusted. Codex skips a new or changed hook until you open /hooks and trust it. Also check that [features] hooks is not false and that the file is valid JSON.

Why do I get a bell instead of a desktop notification?

In auto mode Codex prefers OSC 9 and falls back to the bell. Windows Terminal and the VS Code terminal get the bell. Use a Stop hook with notify-send, terminal-notifier or a similar notifier for a desktop alert.

Should I use notify or a hook?

Start with a hook. Hooks are the newer, broader mechanism and cover both a finished turn (Stop) and an approval request (PermissionRequest). notify fires on agent-turn-complete only, and only from your user config.

How do I turn Codex notifications off?

Set tui.notifications = false for the built-in alert, delete the notify line, and remove any notifier entries from hooks.json. Setting [features] hooks = false switches off every hook, not only notifiers.

Or let a light show it

A sound needs you at the desk and listening, and a toast needs you looking at the screen. A light works from across the room, with headphones on, and adds no extra ping.

AC Bridge turns the smart lights and plugs you already own (Hue, LIFX, Govee, WiZ, Home Assistant and more) into a status light for Codex and Claude Code. On Codex, setup adds its entries to ~/.codex/hooks.json and keeps the hooks already there; type /hooks once inside Codex to trust them. In the example colours from our homepage, the lamp breathes blue while the agent works, flashes red when it needs permission and turns green when it has finished; you pick the colours, and give each project its own lamp or let one lamp follow several.

On Codex, needs permission lights up the moment Codex asks for approval, because it follows the PermissionRequest hook. Codex drives 19 of the 29 states. Your own Stop or PermissionRequest notifier keeps running alongside it, because every matching hook runs. See How the Claude Code status light works for the Claude Code side, and the Claude Code notifications guide for its free methods.

One plan: a 3-day free trial with your card taken up front, then £2.99 a month, charged when the trial ends. Cancel any time from your account; cancel before the trial ends and you pay nothing. It works with the Claude Code or Codex you already run, on Windows, macOS or Linux. There is no API key to buy.

LAN devices are driven straight from your machine and their keys never leave it; your account, settings, device list, usage counts and session states sync through our servers. Your prompts, code and session transcripts are never collected. Privacy policy.

Try it on your own lights Start the 3-day free trial, or read the setup docs and the status light guide first.