CloudCodeTree LogoCloudCodeTree
AI NewsTutorialsAbout
CloudCodeTree Logo
CloudCodeTree
  • AI News
  • Tutorials
  • About
← Back to AI News
One Command Isn't Enough: Claude Code's Four Hook Handler Types Explained

One Command Isn't Enough: Claude Code's Four Hook Handler Types Explained

Chris Harper

2 min read

Jul 8, 2026 · 20:06 UTC

AI
Workflow
Claude Code
Best Practices

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)