stop_reason
APIDefinition
A field in the Claude API response indicating why the model stopped generating. Values: 'end_turn' (natural completion), 'max_tokens' (hit limit), 'stop_sequence' (hit custom stop), 'tool_use' (wants to call a tool). The primary signal for controlling agentic loops.
Example Usage
In agentic loops, check stop_reason: 'tool_use' means continue the loop, 'end_turn' means the task is complete.
Why It Matters for the CCA-F Exam
The exam heavily tests `stop_reason` in agentic-loop scenarios. You must know all seven current values, distinguish `max_tokens` from `model_context_window_exceeded`, and explain why `refusal` should never be silently retried. Questions often present a loop that behaves incorrectly and ask which `stop_reason` handling is missing or wrong.
In Depth
Why `stop_reason` Is the Control Signal of Every Agentic Loop
Every messages API response includes a stop_reason field. This single field tells you why Claude stopped generating, and in any multi-step or agentic system it determines what happens next. Treating stop_reason as an afterthought — or worse, never reading it — is one of the most common causes of silent failures in Claude-powered applications.
The full current set of stop_reason values is:
end_turn— Claude finished naturally. No limit was hit, no tool was requested. In an agentic loop, this means the task is complete and the final response should be surfaced to the user.tool_use— Claude generated one or moretool_usecontent blocks and is waiting for results. You must execute the tool(s), collect the results, and resume the loop with a newmessagesrequest that includes thosetool_resultblocks.max_tokens— The response hit the max_tokens ceiling and was truncated. The content you received is incomplete. Increasemax_tokensor implement chunked output.stop_sequence— Claude emitted one of the strings you listed instop_sequences. This is an intentional signal — the model reached a controlled breakpoint you defined.pause_turn— A server-side tool in a hosted agentic loop paused execution (for example, awaiting human approval). Re-submit the request with the same conversation state to resume. This value appears only in server-managed tool loops.refusal— Claude declined to continue for safety or policy reasons. Do not blindly retry — a refusal is a signal to inspect and redesign the request, not an error to swallow. Surface it to the user or escalation handler.model_context_window_exceeded— The total input + output token count exceeded the context window. This is distinct frommax_tokens; the request itself was too large. The mitigation is context compression or conversation history eviction before retrying.
Reading `stop_reason` Before Content
The correct pattern for any response handler is to check stop_reason before reading the content. If the reason is refusal, the content field may be empty or partial — acting on it as if it were a complete response can propagate corrupt state through a pipeline. If the reason is max_tokens, the last sentence is cut mid-thought.
Loop Control Logic
For a standard tool-use loop, the decision tree is straightforward: tool_use → execute tools and continue; end_turn → done; anything else → error / escalation. The value of having a single, enumerated control signal is that your loop logic stays clean and exhaustive — you can write an explicit case for every possible value rather than guessing from response content.
Frequently Asked Questions
What is the difference between `max_tokens` and `model_context_window_exceeded`?
`max_tokens` means the *output* hit the ceiling you set with the `max_tokens` parameter — the response was cut short but the request itself was accepted and processed. `model_context_window_exceeded` means the *total* input + output token count exceeded the model's context window — the entire request was too large to process. The mitigations are different: for `max_tokens`, increase the parameter or chunk the output; for `model_context_window_exceeded`, shrink the input by compressing or evicting conversation history.
When does `pause_turn` appear and what should I do?
`pause_turn` appears in server-managed agentic loops when a built-in server-side tool (such as a human-approval gate) pauses execution. It signals that the loop is suspended, not terminated. You re-submit the conversation state — with any intermediate tool results — to resume. It is not an error; it is an expected checkpoint in long-running workflows.
If `stop_reason` is `refusal`, can I modify the prompt and retry immediately?
You can retry with a modified prompt, but you should not do so blindly in a tight loop. A `refusal` indicates a safety or policy boundary was reached. The correct response is to log the event, inspect the refusal context, determine whether the request can be redesigned to stay within policy, and — if appropriate — surface the situation to a human reviewer before retrying. Automated silent retries on `refusal` risk building systems that probe for policy boundaries.