Use PreToolUse when a check must inspect or stop a proposed tool call before it runs. Use PostToolUse when the work needs the result of a successful call or should happen after execution. The key question is when the check must take effect: before the action, or after it.
Which hook fits the check?
| Requirement | Use | Why |
|---|---|---|
| Validate a proposed file path or command before it can have side effects | PreToolUse |
It runs before the tool call executes and can intervene, including by denying the call. |
| Inspect the tool’s returned result | PostToolUse |
It runs after successful execution and receives tool_response. |
| Log a completed call, add context, or review output | PostToolUse |
These tasks depend on, or follow, the completed operation. |
| Format or lint a file after a write | PostToolUse |
The write must happen before the handler can process the result. |
| Handle a tool execution failure | PostToolUseFailure |
The Python SDK documents this as a separate event with an error field. |
A successful PostToolUse handler cannot retroactively prevent the operation it observes. If the policy must stop execution, put it in a pre-hook. Anthropic describes pre-hooks for checks such as validating a planned write and post-hooks for uses such as formatting, linting, audit logging, and notifications (Anthropic’s hooks guide).
As an Amazon Associate I earn from qualifying purchases.
What each callback can inspect
PreToolUse: proposed action
The Python SDK’s pre-hook input includes the event name, tool_name, proposed tool_input, and tool_use_id, along with common session fields. Optional agent_id and agent_type identify subagent calls. This is the point to evaluate arguments such as a Bash command or file path and return a denial when policy requires it.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
PostToolUse: completed result
The post-hook input includes the event name, tool_name, the input used, tool_response, and tool_use_id, plus the optional subagent identifiers. Use it to inspect output, record the completed call, or provide additional context. The SDK reference distinguishes this successful-call event from PostToolUseFailure, which has an error field (Python Agent SDK reference).
#1 Best Overall
Register hooks in the Python Agent SDK
Python callbacks are asynchronous and receive (input, tool_use_id, context), returning a hook output. Register them through ClaudeAgentOptions.hooks; use HookMatcher to limit which tools trigger each callback. For example:
options = ClaudeAgentOptions(
hooks={
"PreToolUse": [
HookMatcher(matcher="Bash", hooks=[validate_bash_command]),
],
"PostToolUse": [
HookMatcher(matcher="Write|Edit", hooks=[post_write_handler]),
],
}
)
Here, the pre-hook is limited to Bash calls, while the post-hook covers Write and Edit calls. A matcher filters the tools that invoke the callback; an unfiltered matcher can be used when the handler should receive all tools. Anthropic’s Python example shows a pre-hook denying a Bash command that matches a configured pattern and a post-hook inspecting a response for an error string and returning a reason, system message, and additional context (official Python hooks example).
Rank #2
Choose the event and matcher deliberately
- Decide when the check must act. Choose
PreToolUsefor intervention before execution; choosePostToolUsefor work after a successful result exists. - Inspect the right data. A pre-hook evaluates
tool_nameand proposedtool_input. A post-hook can also inspecttool_response. - Limit the matcher to relevant tools. Use a matcher such as
Bash,Write, orWrite|Editwhen unrelated calls should not trigger the handler. - Handle failures separately if needed. Consider
PostToolUseFailurerather than assuming the successful-call event handles failures. - Check the installed SDK’s reference. Confirm callback signatures and event availability for the language and version in use. The Python reference notes that the TypeScript SDK supports additional events not yet available in Python.
The Python reference documents default hook timeouts of 600 seconds for most events and 30 seconds for UserPromptSubmit; these are SDK reference defaults and may vary by version. Consult the hooks reference and the Python SDK reference for current event behavior, matcher configuration, and decision outputs.
Quick Recap
Best Value
Rank #4
Rank #3
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.




