---
name: hooks-reference
description: CC hooks API — event types, payload shapes, exit codes, and where hooks run.
layer: reference
cc_feature: hooks
source: https://docs.claude.com/en/docs/claude-code/hooks
concept: hooks-api-surface
last_verified: 2026-04-18
ngram_overlap_score: null
review_status: approved
---

# Hooks — Reference

Hooks are shell commands or scripts that the Claude Code harness runs
in response to events. They give the harness — not Claude — the final
say on whether a tool call, prompt, or session action proceeds. Claude
cannot bypass a hook by prompting itself; the hook runs outside the
model's control loop.

## Event types

- **UserPromptSubmit** — fires when the user sends a prompt. Runs before
  Claude processes it. Common use: inject extra context, reject
  disallowed prompts.
- **PreToolUse** — fires before a tool call. Can deny the call. Common
  use: block destructive commands, require confirmation.
- **PostToolUse** — fires after a tool call completes. Sees the result.
  Common use: log side effects, redact output, trigger follow-up work.
- **Stop** — fires when the agent finishes a turn. Common use: commit
  reminders, session summaries.
- **Notification** — fires when Claude wants to show the user a
  notification (e.g., long-running task).
- **SessionStart** — fires when a session begins. Common use: print
  repo state, inject context.

## Payload shape

Hooks receive a JSON payload on stdin. Common fields:

- `session_id` — the current session identifier.
- `transcript_path` — path to the conversation transcript.
- `cwd` — current working directory.
- `tool_name` (PreToolUse, PostToolUse) — which tool is running.
- `tool_input` (PreToolUse) — the arguments to the tool.
- `tool_response` (PostToolUse) — the tool's result.
- `prompt` (UserPromptSubmit) — the submitted text.

Exact field availability depends on event type. Read the payload JSON
rather than assuming a schema.

## Exit codes and control

Hooks communicate back via exit code and stdout JSON:

- Exit 0, no stdout → proceed normally.
- Exit 0, stdout JSON with `decision` field → harness honors the
  decision (e.g., `{"decision": "block", "reason": "..."}`).
- Exit non-zero → harness treats as a denial or error, depending on
  event and hook type.

Some hook types support structured output beyond deny/allow (e.g.,
adding context to the prompt). Details differ per event.

## Where hooks live

- Project hooks: `.claude/settings.json` `hooks` field, paths relative
  to project.
- User hooks: `~/.claude/settings.json` (global).
- Plugin hooks: packaged with a plugin, activated when the plugin is
  enabled.

Hooks run in the harness process's shell, not in Claude's tool-use
sandbox. They can spawn subprocesses, read environment variables,
and touch the filesystem.

## Implications for architecture

- Hooks are the mechanism for **deterministic policy** (things that
  must always or never happen, regardless of what Claude decides).
- Hooks are load-bearing for security: prompt-injection-resistant
  defenses live here, not in prompts.
- Hooks add latency to every tool call they gate — keep them fast.
- Hook output is part of the context window; verbose hooks burn
  tokens quickly.
