Hook event 19 of 33

Notification

Runs when Claude Code emits a notification, even when desktop notification display is disabled.

Exit code veto
Exit code cannot block
Matchers
permission_prompt, idle_prompt, auth_success, elicitation_dialog, elicitation_url_dialog, elicitation_complete, elicitation_response, agent_needs_input, agent_completed, quota_auto_resume_fired, quota_auto_resume_stale, or quota_auto_resume_disabled; omitted matches every type
if filter
Does not apply
Docs checked
2026-08-29

Every alert, shown or not

Claude Code emits alerts you never see on screen. Notification fires whenever one of them happens, whether or not the desktop notification is displayed. The matcher filters twelve types: permission_prompt, idle_prompt, auth_success, elicitation_dialog, elicitation_url_dialog, elicitation_complete, elicitation_response, agent_needs_input, agent_completed, quota_auto_resume_fired, quota_auto_resume_stale, and quota_auto_resume_disabled. Omit it and all twelve run the handler.

They fall into four groups: a permission prompt waiting on you, the session going idle, an MCP server’s elicitation dialog at each stage, and a quota-driven auto-resume in one of three states. A hook that only wants to know about an unanswered prompt matches permission_prompt and sleeps through the other eleven. The payload carries message, an optional title, and notification_type.

The only output that does anything

You cannot block or rewrite the alert. No exit code changes the notification. On exit 0, stdout and stderr go to the debug log. Exit 2 is ignored, exit status and stderr alike. On every code a valid terminalSequence still fires, producing whatever terminal effect the hooks reference allows for it. systemMessage and continue are discarded, and there is no decision field.

The mistake most people make first

You return {"systemMessage": "Claude needs you"} on permission_prompt, expecting a line on screen.

Nothing appears. The field is discarded on this event, as is everything else the hook prints. The prompt sits there as it would have without the hook.

Use terminalSequence for the terminal, or reach outside it: a desktop notifier or a webhook, a web address you call to notify another service, called from inside the hook is a side effect, and a side effect is the only thing this event can produce.