Skip to main content

Overview

Hooks allow you to intercept and modify Claude’s behavior at specific points during execution. You can use hooks to add custom logic, validate tool usage, inject context, and control the conversation flow.

Available Hook Events

The SDK provides multiple hook events that fire at different points:

PreToolUse

Fires before a tool is executed - useful for validation and permission checks

PostToolUse

Fires after a tool completes successfully - useful for logging and reviewing output

PostToolUseFailure

Fires when a tool fails - useful for error handling and recovery

UserPromptSubmit

Fires when a user prompt is submitted - useful for adding context

Stop

Fires when execution stops - useful for cleanup

PreCompact

Fires before message history is compacted

SubagentStart

Fires when a subagent starts

SubagentStop

Fires when a subagent stops

Hook Function Structure

Hooks are async functions with a specific signature:

Parameters

  • input_data: Dictionary with hook-specific data (tool name, input, response, etc.)
  • tool_use_id: Unique ID for the tool execution (if applicable)
  • context: Additional context about the hook execution

Return Value

Return a HookJSONOutput dictionary with optional fields:
  • reason: Explanation of what the hook did
  • systemMessage: Message shown to the user
  • continue_: Whether to continue execution (default: true)
  • stopReason: Why execution was stopped (if continue_ is false)
  • hookSpecificOutput: Event-specific data

Registering Hooks

Register hooks using ClaudeAgentOptions:

PreToolUse Hook

Block or allow tool execution before it runs:

Permission Decisions

Use permissionDecision to explicitly allow or deny tool execution:

PostToolUse Hook

Review and augment tool output after execution:

UserPromptSubmit Hook

Add custom context when user prompts are submitted:

Stopping Execution

Use continue_ field to stop execution on certain conditions:

Multiple Hooks

You can register multiple hooks for the same event:
Hooks in the list are executed in order. If any hook returns continue_: False, subsequent hooks won’t execute.

Tool-Specific Hooks

Register different hooks for different tools:

Hook Timeouts

Set timeouts for long-running hooks:

Complete Working Example

Here’s a complete example combining multiple hook patterns:

Best Practices

Hooks block tool execution. Keep them fast and set timeouts for potentially slow operations.
If a hook doesn’t need to modify behavior, return an empty dict {} rather than None.
  • Use PreToolUse for validation and permission checks
  • Use PostToolUse for logging and output augmentation
  • Use UserPromptSubmit for context injection
When blocking or modifying behavior, always include clear reason and systemMessage fields.
Wrap hook logic in try-except to prevent hook failures from breaking execution:
Add logging to hooks for debugging and monitoring:

Next Steps

Permissions

Learn about tool permission management

Custom Tools

Create custom tools with hooks

Hook Types

Complete hook type reference

Examples

More hook examples