Event Types Reference
Complete catalog of all NDJSON events emitted by claude -p --output-format stream-json --verbose.
Top-Level Event Types
Every stdout line is a JSON object with a type field. These are the possible values:
| Type | When | Contains |
|---|---|---|
system |
First event of a run | Session metadata, tools, model |
stream_event |
During streaming | Content deltas, tool call fragments |
assistant |
After streaming completes | Fully assembled message |
result |
Final event | Cost, usage, session ID, errors |
rate_limit_event |
When rate limited | Reset time, limit type |
permission_request |
When tool needs approval | Tool name, input, options |
system (init)
The first event. Subtype is always init.
{
"type": "system",
"subtype": "init",
"cwd": "/Users/me/project",
"session_id": "abc-def-123",
"tools": ["Read", "Write", "Edit", "Bash", "Glob", "Grep", "LS", "Agent", "Task", "WebSearch", "WebFetch"],
"mcp_servers": [{"name": "my-server", "status": "connected"}],
"model": "claude-sonnet-4-20250514",
"permissionMode": "default",
"agents": [],
"skills": ["skill-name"],
"plugins": [],
"claude_code_version": "2.1.63",
"fast_mode_state": "disabled",
"uuid": "event-uuid"
}
Key fields:
session_id- store this for--resumetools- available tool names (varies by installation and MCP servers)model- the active modelmcp_servers- connected MCP servers and their statusclaude_code_version- for compatibility checks
stream_event
Wraps Anthropic API streaming events. Has a nested event object.
{
"type": "stream_event",
"event": { ... },
"session_id": "abc-def-123",
"parent_tool_use_id": null,
"uuid": "event-uuid"
}
The parent_tool_use_id is non-null when the event comes from a subagent (tool-within-tool execution).
Sub-event: message_start
Signals beginning of a new assistant message.
{
"type": "stream_event",
"event": {
"type": "message_start",
"message": {
"model": "claude-sonnet-4-20250514",
"id": "msg_abc123",
"role": "assistant",
"content": [],
"stop_reason": null,
"usage": {"input_tokens": 100, "output_tokens": 0}
}
}
}
Sub-event: content_block_start (text)
A text content block begins.
{
"type": "stream_event",
"event": {
"type": "content_block_start",
"index": 0,
"content_block": {"type": "text", "text": ""}
}
}
Sub-event: content_block_start (tool_use)
A tool call begins. Extract the tool name and id.
{
"type": "stream_event",
"event": {
"type": "content_block_start",
"index": 1,
"content_block": {
"type": "tool_use",
"id": "toolu_abc123",
"name": "Read",
"input": {}
}
}
}
Sub-event: content_block_delta (text)
Streaming text fragment. Append delta.text to your display.
{
"type": "stream_event",
"event": {
"type": "content_block_delta",
"index": 0,
"delta": {"type": "text_delta", "text": "Here is the "}
}
}
Sub-event: content_block_delta (tool input)
Streaming tool input JSON fragment. Accumulate partial_json to reconstruct the full tool input.
{
"type": "stream_event",
"event": {
"type": "content_block_delta",
"index": 1,
"delta": {"type": "input_json_delta", "partial_json": "{\"file_path\":\""}
}
}
Sub-event: content_block_stop
A content block (text or tool_use) is complete.
{
"type": "stream_event",
"event": {
"type": "content_block_stop",
"index": 0
}
}
Sub-event: message_delta
Message-level update with stop reason and usage.
{
"type": "stream_event",
"event": {
"type": "message_delta",
"delta": {"stop_reason": "end_turn"},
"usage": {"input_tokens": 100, "output_tokens": 250}
}
}
Stop reasons: "end_turn" (normal), "tool_use" (needs to call a tool), "max_tokens" (hit limit).
Sub-event: message_stop
Message streaming is complete.
{
"type": "stream_event",
"event": {"type": "message_stop"}
}
assistant
Assembled message after streaming completes. Contains all content blocks with their full content.
{
"type": "assistant",
"message": {
"model": "claude-sonnet-4-20250514",
"id": "msg_abc123",
"role": "assistant",
"content": [
{"type": "text", "text": "I'll read that file for you."},
{"type": "tool_use", "id": "toolu_abc123", "name": "Read", "input": {"file_path": "/tmp/test.txt"}}
],
"stop_reason": "tool_use",
"usage": {"input_tokens": 100, "output_tokens": 50}
},
"parent_tool_use_id": null,
"session_id": "abc-def-123",
"uuid": "event-uuid"
}
Use this event to get complete tool inputs (instead of reconstructing from input_json_delta fragments).
result
Final event of a run. Always present, even on errors.
Success
{
"type": "result",
"subtype": "success",
"is_error": false,
"duration_ms": 15234,
"num_turns": 3,
"result": "The file contains a list of...",
"total_cost_usd": 0.0034,
"session_id": "abc-def-123",
"usage": {
"input_tokens": 5000,
"output_tokens": 1200,
"cache_read_input_tokens": 3000,
"cache_creation_input_tokens": 500
},
"permission_denials": [],
"uuid": "event-uuid"
}
Error
{
"type": "result",
"subtype": "error",
"is_error": true,
"result": "Error: rate limit exceeded",
"session_id": "abc-def-123",
"duration_ms": 1200,
"num_turns": 0,
"total_cost_usd": 0,
"usage": {},
"permission_denials": [],
"uuid": "event-uuid"
}
Key fields:
total_cost_usd- cost of this runsession_id- store for--resumepermission_denials- tools denied during the run. Runtime sends{tool_name, tool_use_id}objects; types.ts declares it asstring[]. Treat as{tool_name: string, tool_use_id: string}[]in practice.num_turns- number of agentic turns taken
rate_limit_event
Emitted when the subscription rate limit is hit.
{
"type": "rate_limit_event",
"rate_limit_info": {
"status": "rate_limited",
"resetsAt": 1700000000,
"rateLimitType": "model"
},
"session_id": "abc-def-123",
"uuid": "event-uuid"
}
resetsAt is a Unix timestamp. Show the user a countdown or retry after that time.
permission_request
Emitted when Claude wants to use a tool that requires approval (stdin-based permission flow, not HTTP hooks).
{
"type": "permission_request",
"tool": {
"name": "Bash",
"description": "Execute a bash command",
"input": {"command": "npm install express"}
},
"question_id": "perm-abc-123",
"options": [
{"id": "allow", "label": "Allow Once", "kind": "allow"},
{"id": "allow-session", "label": "Allow for Session", "kind": "allow"},
{"id": "deny", "label": "Deny", "kind": "deny"}
],
"session_id": "abc-def-123",
"uuid": "event-uuid"
}
Respond via stdin with:
{"type":"permission_response","question_id":"perm-abc-123","option_id":"allow"}
Event Ordering Guarantees
system(init) is always the first eventresultis always the last eventstream_eventevents arrive in order within a content blockcontent_block_startalways precedes its corresponding deltas and stopassistantarrives after all stream events for that messagepermission_requestcan arrive at any point between init and resultrate_limit_eventcan arrive at any point