Prompt-based hooks
For decisions that require judgment rather than deterministic rules, use type: "prompt" hooks. Instead of running a shell command, Claude Code sends your prompt and the hook's input data to a Claude model, Haiku by default, to make the decision. You can specify a different model with the model field if you need more capability.
The model's only job is to return its decision as JSON:
"ok": true: the action proceeds"ok": false: what happens depends on the event:StopandSubagentStop: thereasonis fed back to Claude so it keeps working, unless the response also sets"impossible": trueto mark the condition as one that can never be satisfied, in which case Claude Code allows the stop and the turn endsPreToolUse: the tool call is denied; by default the turn ends and the denyreasonappears in the chat as a warning line. SetcontinueOnBlock: trueon the hook to instead return thereasonto Claude as the tool error, so it can adjust and continue. Before v2.1.210, the denyreasonwas returned to Claude as the tool error and the turn continuedPostToolUse: by default the turn ends and thereasonappears in the chat as a warning line. SetcontinueOnBlock: trueto feed thereasonback to Claude and continue the turn insteadPostToolBatch,UserPromptSubmit, andUserPromptExpansion: the turn ends and thereasonappears in the chat as a warning line
This example uses a Stop hook to ask the model whether all requested tasks are complete. If the model returns "ok": false because the condition isn't met yet, Claude keeps working and uses the reason as its next instruction:
json
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Check if all tasks are complete. If not, respond with {\"ok\": false, \"reason\": \"what remains to be done\"}."
}
]
}
]
}
}For full configuration options, see Prompt-based hooks in the reference.