
One Command Isn't Enough: Claude Code's Four Hook Handler Types Explained
Chris Harper
2 min read
Jul 8, 2026 · 20:06 UTC
TL;DR: The June 2026 hooks intro covered only command (shell scripts) — there are now three more handler types (HTTP, prompt, agent) plus async: true to make any hook non-blocking.
The June 30 post showed one hook type: command — a shell script that blocks until it exits. Three more handler types were added since, each solving a problem the command type can't handle cleanly.
The four handler types
command — runs a shell script synchronously. Blocking by default; exit 2 cancels the tool call. Best for: secret scanning, file formatting, linters.
http — POSTs the hook event payload as JSON to a URL you control. Use this for:
- centralized validation that multiple engineers share (no script to distribute)
- logging directly to an observability stack (Datadog, Honeycomb, etc.)
- cross-team policy enforcement from a single server
{
"type": "http",
"url": "https://your-api.example.com/hooks/validate",
"timeout": 10
}
prompt — sends the hook payload to a Claude model (Haiku by default) with your yes/no question. Claude returns allow/deny with a reason. No regex, no script — just plain English:
{
"type": "prompt",
"prompt": "Does this bash command delete or overwrite files irreversibly? Return deny with reason if so."
}
agent — spawns a subagent with full tool access (up to 50 tool calls). Use when validation needs to read something: check a file before allowing an edit, run a linter before a commit, verify tests pass before pushing.
{
"type": "agent",
"prompt": "Read the file at tool_input.file_path and verify it passes ESLint. Return deny with lint errors if it fails."
}
Make any hook non-blocking: async: true
Add "async": true to any handler type to run it in the background — Claude doesn't wait for it. Use async for all logging, notification, and metrics hooks where you don't need to block:
{
"type": "http",
"url": "https://metrics.example.com/tool-events",
"async": true
}
Blocking hooks should stay synchronous (async PreToolUse can't veto). Everything else — PostToolUse logging, Notification hooks, session analytics — should be async.
Sources: Hooks reference — Claude Code Docs · Automate actions with hooks · Claude Code Hooks: Complete 2026 Reference (The Prompt Shelf)