Streaming

2026-01-12 stream-json ultrathink

Message Types

When you use the stream-JSON output format (--output-format stream-json), Claude Code returns newline-delimited JSON. Each line in the output is a complete JSON object with a type field that identifies what kind of message it is. This format makes it easy to parse the output programmatically and react to different events as they occur.

Type Description
initSession initialization message that includes the session_id, the list of available tools, and the model being used
userUser message or tool result being sent to Claude
assistantClaude's response, which may include thinking blocks, text blocks, or tool_use blocks
resultFinal summary message containing usage statistics and cost information

Result Message Structure

The final result message is emitted when the conversation turn completes. It provides a summary of what happened, including the total cost, duration, and detailed token usage breakdown. This is useful for tracking costs and understanding how much of your context window was consumed.

{ "type": "result", "result": "...", "session_id": "abc-123", "is_error": false, "total_cost_usd": 0.352, "duration_ms": 45000, "num_turns": 5, "usage": { "input_tokens": 51, "output_tokens": 5555, "cache_read_input_tokens": 147615, "cache_creation_input_tokens": 12190 } }

The result field contains the final text output, while is_error indicates whether the operation completed successfully. The usage object breaks down token consumption into input tokens (new content), output tokens (Claude's response), cache reads (reused from previous turns), and cache creation (newly cached content).

Session Logs

Claude Code stores detailed session logs on your local filesystem. These logs are located at:

~/.claude/projects/<project-hash>/logs/<session-id>.jsonl

Each line in the log file is a complete JSON message representing an event in the conversation. The key fields you will find in each message include:

  • timestamp — When the event occurred
  • sessionId — Unique identifier for this conversation session
  • type — The type of message (similar to the streaming types)
  • message.model — Which Claude model processed this request
  • message.content — The actual content (an array of blocks)
  • message.usage — Token usage statistics for this message

The content array contains different types of blocks depending on what Claude is doing:

Block Type Fields Notes
thinkingthinking, signatureInternal reasoning (not counted in output_tokens!)
texttextVisible output that you see in responses
tool_usename, input, idTool invocations with their parameters
Important
Thinking tokens are billed at the output rate but are not included in the output_tokens count in the usage statistics. This can make cost calculations tricky if you are only looking at visible token counts.

Streaming Events

When you use the --include-partial-messages flag, you receive granular stream_event entries that let you track the progress of Claude's response in real-time. This is useful for building interactive UIs that show typing indicators or stream text as it is generated.

Event Purpose
message_startIndicates that a new message is beginning
content_block_startA new content block is starting (could be tool_use or text)
content_block_deltaIncremental content update (contains input_json_delta or text_delta)
content_block_stopThe current content block has finished
message_deltaMessage-level metadata update (includes stop_reason)
message_stopThe entire message has finished

Tool arguments stream character-by-character via the input_json_delta field. This means you can watch tool calls being constructed in real-time, which is particularly useful for debugging or for showing users what Claude is about to do before it executes.

CLI vs Session Logs

There are important differences between the streaming output you get from the CLI and the session logs stored on disk. Understanding these differences is important when deciding which data source to use for your use case.

Feature CLI stream-json Session JSONL
Locationstdout~/.claude/projects/.../logs/
Has stream_event?Yes (with --include-partial-messages)No
Has init/result?YesNo
Sub-agent prompts (parent_tool_use_id)YesNo
Field namingsnake_case (tool_use_result)camelCase (toolUseResult)

The CLI output is designed for real-time consumption and includes all the metadata you need for building interactive applications. The session logs are more compact and focused on the conversation content itself, making them better suited for analysis and debugging after the fact.