Hooks reference changedhooks
Nearest release: v2.1.314, published 4 hours after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 29 Oct 2026 19:24 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 29 Oct 2026 19:37 UTC.
Upstream edited
Recorded here
Lines+10added
Lines−3removed
From line
731
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits127to this page, all time
#### PreToolUse `ask` decisions in auto mode
The whole hunk
from line 731, old and new numbered
/
This page is larger than the 256 KiB this site keeps, so one side of the diff below stops where the stored text does.
from line 731
731731| `cwd` | Current working directory when the hook is invoked |
732732| `scratchpad_dir` | Path to the session's [scratchpad directory](https://code.claude.com/docs/en/claude-directory.md#session-scratchpad-directory), where Claude keeps temporary working files. Absent when the session has no scratchpad or the temp directory is unavailable. Requires Claude Code v2.1.257 or later |
733733| `permission_mode` | Current [permission mode](https://code.claude.com/docs/en/permissions.md#permission-modes): `"default"`, `"plan"`, `"acceptEdits"`, `"auto"`, `"dontAsk"`, or `"bypassPermissions"`. The mode labeled **Manual** arrives as `"default"`, never as `"manual"`, so scripts that match `"default"` keep working. Not all events receive this field. Check the JSON example in each [hook event](#hook-events) section |
734| `effort` | Object with a `level` field holding the [effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level) in effect when the hook runs: `"low"`, `"medium"`, `"high"`, `"xhigh"`, or `"max"`. If you set a level the active model doesn't support, `level` reports the level Claude Code ran instead; [Adjust effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level) says how it picks that level. The object matches the [status line](https://code.claude.com/docs/en/statusline.md#available-data) `effort` field. Present for events that fire within a tool-use context, such as `PreToolUse`, `PostToolUse`, `Stop`, and `SubagentStop`, when the current model supports the effort parameter. The level is also available to hook commands and the Bash tool as the `$CLAUDE_EFFORT` environment variable. |
734| `effort` | Object whose `level` is the [effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level) setting when the hook runs, including a skill's, subagent's, or `ultrathink` level: `"low"`, `"medium"`, `"high"`, `"xhigh"`, or `"max"`. Present for `PreToolUse`, `PostToolUse`, `Stop`, `SubagentStop`, and other events with a tool-use context, on models with effort. If the model doesn't support your level, `level` is the level that ran. A level you changed can show here before it [starts](https://code.claude.com/docs/en/model-config.md#when-a-new-effort-level-starts). `$CLAUDE_EFFORT` holds the same level. |
735735| `hook_event_name` | Name of the event that fired |
736736
737737`agent_id` and `agent_type` tell your script which agent a hook fired in, such as a subagent, an [in-process teammate](https://code.claude.com/docs/en/agent-teams.md#choose-a-display-mode), or the agent you chose with `--agent`:
from line 1964
19641964
19651965When a hook returns `"ask"`, the permission prompt displayed to the user includes a label identifying where the hook came from: `[settings]` for a hook from any settings file or from agent frontmatter, `[plugin:<name>]` for a plugin's hook, or `[skill]` for a hook from skill frontmatter. This helps users understand which configuration source is requesting confirmation.
19661966
1967A hook's `"ask"` also forces a permission prompt in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode): the classifier can still deny the tool call, but it can't approve the call silently.
1968
19691967```json theme={null}
19701968{
19711969 "hookSpecificOutput": {
from line 1982
19841982>
19851983> PreToolUse previously used top-level `decision` and `reason` fields, but these are deprecated for this event. Use `hookSpecificOutput.permissionDecision` and `hookSpecificOutput.permissionDecisionReason` instead. The deprecated values `"approve"` and `"block"` map to `"allow"` and `"deny"` respectively. Other events like PostToolUse and Stop continue to use top-level `decision` and `reason` as their current format.
19861984
1985#### PreToolUse `ask` decisions in auto mode
1986
1987In [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), a PreToolUse hook's `"ask"` normally sends the tool call to the permission prompt, and the [classifier](https://code.claude.com/docs/en/permission-modes.md#how-the-classifier-evaluates-actions) doesn't decide it. Some calls take a different path:
1988
1989* **Calls that Claude Code's own checks flag too**: these include writes to [protected paths](https://code.claude.com/docs/en/permission-modes.md#protected-paths) and commands that ask to [run outside the sandbox](https://code.claude.com/docs/en/sandboxing.md#the-unsandboxed-retry-escape-hatch). The classifier can deny one of these calls before any prompt appears. If it approves, the call normally still goes to the prompt.
1990* **`SubagentHandback` calls**: this tool delivers a subagent's report. No prompt appears for it, and the call runs even if the classifier objects.
1991
1992To stop a `SubagentHandback` call, return `"deny"`. Claude Code then tells the subagent, up to three times, that its report wasn't delivered and to call the tool again. If your hook keeps denying, the subagent ends without delivering a report through this tool, and the conversation waiting on it gets a note saying so.
1993
19871994#### Tools that require user interaction
19881995
19891996`AskUserQuestion` and `ExitPlanMode` require user interaction. In [non-interactive mode](https://code.claude.com/docs/en/headless.md) with the `-p` flag, Claude Code offers them only when the run has a [permission host](https://code.claude.com/docs/en/headless.md#turn-off-permission-prompts-in-unattended-runs) to receive the prompt, such as an Agent SDK `canUseTool` callback.
from line 3859
38523859
38533860Exit code 2 and a top-level `"decision": "block"` also block the response. [Other ways to decline an elicitation](#other-ways-to-decline-an-elicitation) covers which one takes effect when a hook combines them, what the user sees, and which versions ignored `decision`.
38543861
3855Claude Code discards `reason`, `systemMessage`, and `continue` from an ElicitationResult hook's JSON output, whichever `action` you return.
3856
3857## Prompt-based hooks
3858
3859In addition to command, HTTP, and MCP tool hooks, Claude Code supports prompt-based hooks (`type: "prompt"`) that use an LLM to evaluate whether to allow or block an action, and agent hooks (`type: "agent"`) that spawn an agentic verifier with tool access. Not all events support every hook type.
3860
3861Events that support all five hook types (`command`, `http`, `mcp_tool`, `prompt`, and `agent`):
3862
3863* `PermissionDenied`
3864* `PostToolBatch`
3865* `PostToolUse`
3866* `PostToolUseFailure`
3867* `PreToolUse`
3868* `Stop`
3869* `SubagentStop`
3870* `TaskCompleted`
3871* `TaskCreated`
3872* `TeammateIdle`
3873* `UserPromptExpansion`
3874* `UserPromptSubmit`
3875
3876`PermissionRequest` supports `command`, `http`, `mcp_tool`, and `prompt` hooks but not `agent` hooks. If you configure an agent hook on this event, Claude Code skips it
3862Claude Code discards `reason`, `systemMessage`, and `continue` from an ElicitationResult hook'
No line in this hunk matches that.