---
lastModified: 2026-08-25
---

# Streaming JSON

Amp's CLI can print each message as a JSON object on its own line. Use this output for
programmatic integrations or to monitor a conversation as it runs.

## Basic Usage

Use `--stream-json` with `--execute` to output streaming JSON instead of plain text.

Pass a prompt as an argument:

```shell-session
$ amp --execute "what is 3 + 5?" --stream-json
```

Continue an existing thread:

```shell-session
$ amp threads continue --execute "now add 8 to that" --stream-json
```

Provide the prompt through stdin:

```shell-session
$ echo "analyze this code" | amp --execute --stream-json
```

Streaming JSON input mode (see below for more information):

```shell-session
$ echo '{"type":"user","message":{"role":"user","content":[{"type":"text","text":"what is 2+2?"}]}}' | amp --execute --stream-json --stream-json-input
```

The `--stream-json` flag requires `--execute` mode. Add `--stream-json-thinking` to include
assistant thinking blocks. This extends the schema and is not compatible with Claude Code.

Each conversation starts with an `init` system message. User and assistant messages follow, and a
final `result` message contains the result and run statistics. Amp emits each message as a separate
JSON object.

## Example Output

Simple math query:

```shell-session
$ amp --execute "what is 3 + 5?" --stream-json
{"type":"system","subtype":"init","cwd":"/Users/orb","session_id":"T-f9941a55-3765-421e-972f-05dc1138c3a3","tools":["Bash","finder","create_file","edit_file","glob","Grep","mcp__postgres__query","oracle","Read","read_mcp_resource","read_web_page","Task","todo_read","todo_write","undo_edit","web_search"],"mcp_servers":[{"name":"postgres","status":"connected"}]}
{"type":"user","message":{"role":"user","content":[{"type":"text","text":"what is 3 + 5?"}]},"parent_tool_use_id":null,"session_id":"T-f9941a55-3765-421e-972f-05dc1138c3a3"}
{"type":"assistant","message":{"type":"message","role":"assistant","content":[{"type":"text","text":"8"}],"stop_reason":"end_turn","usage":{"input_tokens":10,"cache_creation_input_tokens":16256,"cache_read_input_tokens":0,"output_tokens":99,"max_tokens":968000,"service_tier":"standard"}},"parent_tool_use_id":null,"session_id":"T-f9941a55-3765-421e-972f-05dc1138c3a3"}
{"type":"result","subtype":"success","duration_ms":5400,"is_error":false,"num_turns":1,"result":"8","session_id":"T-f9941a55-3765-421e-972f-05dc1138c3a3"}
```

Tool usage example:

```shell-session
$ amp --execute "list files using a tool" --stream-json
{"type":"system","subtype":"init","cwd":"/Users/orb/project","session_id":"T-d2fc4acc-dd1d-497f-9609-ed0da22a7c95","tools":["Bash","finder" ,"create_file","edit_file","glob","Grep","mcp__postgres__query","oracle","Read","read_mcp_resource","read_web_page","Task","todo_rea d","todo_write","undo_edit","web_search"],"mcp_servers":[{"name":"postgres","status":"connected"}]}
{"type":"user","message":{"role":"user","content":[{"type":"text","text":"list files using a tool"}]},"parent_tool_use_id":null,"session_id":"T-d2fc4acc-dd1d-4 97f-9609-ed0da22a7c95"}
{"type":"assistant","message":{"type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_019cyniPYrSgaJitUSMyxyNV","name": "read", "input":{"path":"/Users/orb/project"}}],"stop_reason":"tool_use","usage":{"input_tokens":10,"cache_creation_input_tokens":13150,"cache_read_input_tokens": 0,"output_tokens":111,"max_tokens":968000,"service_tier":"standard"}},"parent_tool_use_id":null,"session_id":"T-d2fc4acc-dd1d-497f-9609-ed0da22a7c95"}
{"type":"user","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_019cyniPYrSgaJitUSMyxyNV","content":"[\"index.js\",\"README.md\"] ","is_error":false}]},"parent_tool_use_id":null,"session_id":"T-d2fc4acc-dd1d-497f-9609-ed0da22a7c95"}
{"type":"assistant","message":{"type":"message","role":"assistant","content":[{"type":"text","text":"Two files: index.js and README.md"}],"stop_reason":"end_tu rn","usage":{"input_tokens":7,"cache_creation_input_tokens":133,"cache_read_input_tokens":13150,"output_tokens":13,"max_tokens":968000,"service_tier":"standard "}},"parent_tool_use_id":null,"session_id":"T-d2fc4acc-dd1d-497f-9609-ed0da22a7c95"}
{"type":"result","subtype":"success","duration_ms":7363,"is_error":false,"num_turns":2,"result":"Two files: index.js and README.md","session_id":"T-d2fc4acc-dd1d-497f-9609-ed0da22a7c95"}
```

## Message Schema

When `--stream-json-thinking` is enabled, assistant content may include `thinking` and
`redacted_thinking` blocks.

Messages returned from the streaming JSON API use this schema:

```typescript
type StreamJSONMessage =
	// An assistant message
	| {
			type: 'assistant'
			message: {
				type: 'message'
				role: 'assistant'
				content: Array<
					| {
							type: 'text'
							text: string
					  }
					| {
							type: 'tool_use'
							id: string
							name: string
							input: Record<string, unknown>
					  }
					| {
							type: 'thinking'
							thinking: string
					  }
					| {
							type: 'redacted_thinking'
							data: string
					  }
				>
				stop_reason:
					'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | 'pause_turn' | 'refusal' | null
				usage?: {
					input_tokens: number
					cache_creation_input_tokens?: number
					cache_read_input_tokens?: number
					cache_creation?: {
						ephemeral_5m_input_tokens: number
						ephemeral_1h_input_tokens: number
					}
					output_tokens: number
					max_tokens?: number
					service_tier?: 'standard' | 'enterprise'
				}
			}
			parent_tool_use_id: string | null
			session_id: string
	  }

	// A user message in streaming JSON output
	| {
			type: 'user'
			message: {
				role: 'user'
				content: Array<
					| {
							type: 'text'
							text: string
					  }
					| {
							type: 'tool_result'
							tool_use_id: string
							content: string
							is_error: boolean
					  }
				>
			}
			parent_tool_use_id: string | null
			session_id: string
	  }

	// The last message when the run succeeds
	| {
			type: 'result'
			subtype: 'success'
			duration_ms: number
			duration_api_ms?: number
			is_error: false
			num_turns: number
			result: string
			session_id: string
			usage?: {
				input_tokens: number
				cache_creation_input_tokens?: number
				cache_read_input_tokens?: number
				cache_creation?: {
					ephemeral_5m_input_tokens: number
					ephemeral_1h_input_tokens: number
				}
				output_tokens: number
				max_tokens?: number
				service_tier?: 'standard' | 'enterprise'
			}
			permission_denials?: string[]
	  }

	// The last message when the run fails
	| {
			type: 'result'
			subtype: 'error_during_execution' | 'error_max_turns'
			duration_ms: number
			duration_api_ms?: number
			is_error: true
			num_turns: number
			error: string
			session_id: string
			usage?: {
				input_tokens: number
				cache_creation_input_tokens?: number
				cache_read_input_tokens?: number
				cache_creation?: {
					ephemeral_5m_input_tokens: number
					ephemeral_1h_input_tokens: number
				}
				output_tokens: number
				max_tokens?: number
				service_tier?: 'standard' | 'enterprise'
			}
			permission_denials?: string[]
	  }

	// The first message in a conversation
	| {
			type: 'system'
			subtype: 'init'
			cwd: string
			session_id: string
			tools: string[]
			mcp_servers: {
				name: string
				status:
					| 'awaiting-approval'
					| 'authenticating'
					| 'connecting'
					| 'reconnecting'
					| 'connected'
					| 'denied'
					| 'failed'
					| 'blocked-by-registry'
			}[]
			agent_mode?: string
	  }

	// A system error
	| {
			type: 'system'
			subtype: 'error_max_turns' | 'error_during_execution'
			error: string
			session_id: string
	  }
```

## Streaming JSON Input

Use `--stream-json-input` to let Amp read messages from stdin until it closes. Each line must be a
complete JSON object that uses this schema:

```typescript
type StreamJSONInputMessage = {
	type: 'user'
	steer?: boolean
	message: {
		role: 'user'
		content: Array<
			| {
					type: 'text'
					text: string
			  }
			| {
					type: 'image'
					source_path?: string
					source: {
						type: 'base64'
						media_type: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp'
						data: string
					}
			  }
		>
	}
}
```

For example, use `jq -c` to emit a text and image message as one line:

```shell-session
$ jq -c . <<'EOF' | amp -x --stream-json --stream-json-input
{
  "type": "user",
  "message": {
    "role": "user",
    "content": [
      {
        "type": "text",
        "text": "what do you see?"
      },
      {
        "type": "image",
        "source_path": "file:///Users/alice/images/example.jpg",
        "source": {
          "type": "base64",
          "media_type": "image/jpeg",
          "data": "..."
        }
      }
    ]
  }
}
EOF
```

`source_path` is optional. If you omit it, Amp generates one. The declared `media_type` must match
the decoded image bytes. User image blocks are accepted as input but omitted from streamed `user`
messages on stdout so the output remains compatible with Claude Code.

The `--stream-json-input` flag requires `--stream-json`.

When you use `--stream-json-input`, Amp exits only after the assistant is done and stdin has closed. This allows a program to send several user messages during one conversation:

```bash
#!/usr/bin/env bash

send_message() {
  local text="$1"
  echo '{"type":"user","message":{"role":"user","content":[{"type":"text","text":"'$text'"}]}}'
}

{
  send_message "what's 2+2?"
  sleep 10

  send_message "now add 8 to that"
  sleep 10

  send_message "now add 5 to that"
} | amp --execute --stream-json --stream-json-input
```

This script produces the following output:

```shell-session
$ ./script.sh
{"type":"system","subtype":"init","cwd":"/Users/orb","session_id":"T-addfb7a4-61d9-41e1-890b-7330aa54087a","tools":["Bash","finder","create_file","edit_file","glob","Grep","mcp__postgres__query","oracle","Read","read_mcp_resource","read_web_page","Task","todo_read","todo_write","undo_edit","web_search"],"mcp_servers":[{"name":"postgres","status":"connected"}]}
{"type":"user","message":{"role":"user","content":[{"type":"text","text":"what's 2+2?"}]},"parent_tool_use_id":null,"session_id":"T-addfb7a4-61d9-41e1-890b-7330aa54087a"}
{"type":"assistant","message":{"type":"message","role":"assistant","content":[{"type":"text","text":"4"}],"stop_reason":"end_turn","usage":{"input_tokens":10,"cache_creation_input_tokens":13993,"cache_read_input_tokens":0,"output_tokens":67,"max_tokens":968000,"service_tier":"standard"}},"parent_tool_use_id":null,"session_id":"T-addfb7a4-61d9-41e1-890b-7330aa54087a"}
{"type":"user","message":{"role":"user","content":[{"type":"text","text":"now add 8 to that"}]},"parent_tool_use_id":null,"session_id":"T-addfb7a4-61d9-41e1-890b-7330aa54087a"}
{"type":"assistant","message":{"type":"message","role":"assistant","content":[{"type":"text","text":"12"}],"stop_reason":"end_turn","usage":{"input_tokens":10,"cache_creation_input_tokens":36,"cache_read_input_tokens":13993,"output_tokens":76,"max_tokens":968000,"service_tier":"standard"}},"parent_tool_use_id":null,"session_id":"T-addfb7a4-61d9-41e1-890b-7330aa54087a"}
{"type":"user","message":{"role":"user","content":[{"type":"text","text":"now add 5 to that"}]},"parent_tool_use_id":null,"session_id":"T-addfb7a4-61d9-41e1-890b-7330aa54087a"}
{"type":"assistant","message":{"type":"message","role":"assistant","content":[{"type":"text","text":"17"}],"stop_reason":"end_turn","usage":{"input_tokens":10,"cache_creation_input_tokens":36,"cache_read_input_tokens":14029,"output_tokens":43,"max_tokens":968000,"service_tier":"standard"}},"parent_tool_use_id":null,"session_id":"T-addfb7a4-61d9-41e1-890b-7330aa54087a"}
{"type":"result","subtype":"success","duration_ms":21639,"is_error":false,"num_turns":3,"result":"17","session_id":"T-addfb7a4-61d9-41e1-890b-7330aa54087a"}
```

Set the top-level `steer` field to `true` if Amp should handle a queued message at the next
interruption point while the agent is busy.

## Claude Code Compatibility

Amp's stream JSON output tries to be compatible with Claude Code's format as much as possible.
When `--stream-json-thinking` is enabled, the output includes extra content block types that are not
part of Claude Code's public schema.
