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:
$ amp --execute "what is 3 + 5?" --stream-json Continue an existing thread:
$ amp threads continue --execute "now add 8 to that" --stream-json Provide the prompt through stdin:
$ echo "analyze this code" | amp --execute --stream-json Streaming JSON input mode (see below for more information):
$ 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:
$ 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:
$ 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:
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:
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:
$ 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:
#!/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:
$ ./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.