Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Claude Code sends command hooks a JSON object on standard input; HTTP hooks receive the same object as an application/json POST body. The payload combines shared session context with fields specific to the event that fired, so branch on hook_event_name and treat optional or newer fields as potentially absent.

How Claude Code delivers hook input

The transport depends on the hook handler: command hooks read JSON from stdin, while HTTP hooks receive it as the POST request body. Anthropic documents this in its Claude Code Hooks reference.

The event name is carried in hook_event_name. It identifies which event fired, but it does not make every payload conform to one complete, fixed schema. Common fields can be omitted for particular events, and each event adds its own inputs. Use the event reference for the exact schema relevant to your handler.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Which fields are shared across hook events?

Anthropic lists the following as common input fields, while noting that individual events may omit some of them:

Field Meaning and caveat
session_id Identifier for the current session.
prompt_id UUID for the user prompt being processed. It can help correlate hook output with OpenTelemetry prompt events; it is absent until the first user input.
transcript_path Path to the conversation JSON file. The file is written asynchronously and may not yet include the latest messages when a hook runs.
cwd Working directory when the hook is invoked.
scratchpad_dir Session scratchpad directory when available. It is absent if there is no scratchpad or the temporary directory is unavailable, and requires Claude Code v2.1.257 or later.
permission_mode Current mode, when included: default, plan, acceptEdits, auto, dontAsk, or bypassPermissions. It is not present on every event. The Manual mode is reported as default, not manual.
effort An object with a level such as low, medium, high, xhigh, or max. It appears in relevant tool-use contexts when the active model supports the effort parameter.
hook_event_name Name of the event that fired. Use it to choose the event-specific fields to inspect.
agent_id Present for hooks inside a subagent call; distinguishes that call from one on the main thread.
agent_type Agent name when running with --agent or inside a subagent. For a subagent, its type takes precedence over the session’s --agent value.

Only SessionStart hooks can receive model, and that field is not guaranteed to be present. PreModelSwitch and PostModelSwitch instead receive from_model and to_model.

How do event-specific fields differ?

The event catalog covers session setup, prompts, tools and permissions, subagents and tasks, stopping, configuration and workspace changes, compaction, model switching, MCP elicitation, and session termination. It includes events such as SessionStart, PreToolUse, PostToolUse, Stop, PreCompact, and SessionEnd. The live reference lists the full catalog and exact inputs; the examples below illustrate how fields vary by event.

Event Selected event-specific fields
SessionStart source indicates how the session started, such as startup, resume, clear, compact, or fork. It may also include model, agent_type, and session_title. Newer versions can add elapsed-time, context-token, and prompt-cache estimates on qualifying resumed or forked sessions.
Setup trigger is init or maintenance.
InstructionsLoaded Instruction-file details can include file_path, memory_type, and load_reason. Optional fields can describe path globs or the file that triggered a lazy load.
UserPromptSubmit prompt contains submitted text; a custom session_title may also be present. Pasted content can arrive expanded in the prompt.
UserPromptExpansion Includes expansion_type, command_name, command_args, command_source, and the original prompt.
MessageDisplay Includes turn_id, message_id, batch index, final, and new text in delta. Interactive sessions can invoke it for successive message batches; non-interactive runs invoke it once per assistant message.
PreToolUse Includes tool_name, tool_input, and tool_use_id. Input shape depends on the tool. MCP calls can also include mcp_server, which requires v2.1.274 or later.
PostToolUse Carries the tool input and result. For some Bash executions, tool_response.bashEditDiff can describe changed files; this best-effort public beta feature requires v2.1.269 or later.
PostToolUseFailure Includes tool identity and input, top-level error, and optional is_interrupt and duration_ms. Error-string format varies by tool.
PostToolBatch tool_calls is an array of resolved calls in a batch, including tool name, input, use ID, and response.
PermissionDenied Includes tool details and a reason; output can indicate whether the model may retry in applicable cases.
Notification Includes message, optional title, and notification_type.
SubagentStart Includes the subagent’s agent_id and agent_type.
SubagentStop Includes stop_hook_active, agent identifiers and type, agent_transcript_path, and last_assistant_message. The ordinary transcript_path remains the main-session transcript.
TaskCreated / TaskCompleted Includes task_id, task_subject, and optional task description and team or teammate names.
Stop Includes stop_hook_active, last_assistant_message, background-task information, and session cron information. Consult the reference for the current shape.
StopFailure Includes an error type, optional error details, and optional last assistant message.
TeammateIdle Includes teammate_name and team_name.
ConfigChange Includes configuration source and optionally file_path.
CwdChanged Includes old_cwd and new_cwd.
DirectoryAdded Includes the added directory and how it was added.
FileChanged Includes file_path and the file-change event.
WorktreeCreate / WorktreeRemove Includes the worktree name or worktree_path, respectively.
PreCompact / PostCompact Includes the compaction trigger; PreCompact can include custom instructions, while PostCompact includes the compacted summary.
PreModelSwitch / PostModelSwitch Includes the models involved; current versions can add context and cache estimates for pre-switch cost reporting.
Elicitation / ElicitationResult Includes MCP server and request or response details such as message, action, and optional form content.
SessionEnd Includes a reason explaining why the session ended.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How can a command hook parse the payload safely?

Read stdin once, then dispatch on the event name and access only fields relevant to that event. This shell example illustrates the pattern; it is not a tested script:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#!/usr/bin/env bash
payload=$(cat)
event=$(jq -r '.hook_event_name // empty' <<<"$payload")

case "$event" in
  PreToolUse)
    tool=$(jq -r '.tool_name // empty' <<<"$payload")
    ;;
  UserPromptSubmit)
    prompt=$(jq -r '.prompt // empty' <<<"$payload")
    ;;
esac

The official example reads tool_input.command from stdin for a Bash PreToolUse hook. Do not treat tool_input as a universal structure: Bash input includes a command, while a Write tool input includes file_path and content. Windows paths arrive with backslashes; Anthropic recommends normalizing separators before path matching.

What can make a field unavailable or stale?

  • Optionality: Absence is normal for fields such as permission_mode and SessionStart.model. Test for presence rather than assuming a field appears on every event.
  • Version gates: Check the minimum Claude Code version before depending on a recently added field. The live reference identifies minimum versions for newer inputs.
  • Transcript lag: Anthropic says the transcript is written asynchronously and may lag behind the in-memory conversation. For final response text, use last_assistant_message on Stop or SubagentStop when that field is supplied.
  • Best-effort diffs: Treat bashEditDiff as review assistance, not enforcement evidence. The reference describes it as public beta and potentially incomplete.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.