Everything starts with a single command. The claude -p flag (short for --print) runs Claude in headless mode — no interactive UI, just a prompt in and a response out. This is the foundation for every script, pipeline, and automation you will build.
Text Output Mode
The simplest way to call Claude from a terminal:
$ claude -p "What is the capital of France?"Paris is the capital of France.No metadata, no JSON — just the result field as plain text. This is the default output format when you use -p, and it is perfect for quick questions or piping a response directly into another command.
But for automation, you need more than the answer. You need the session ID, token counts, cost, and stop reason. That is where structured output comes in.
JSON Output Mode
Add --output-format json to get the full response envelope:
$ claude -p "Say exactly: Hello CLI Test" --output-format jsonEvery JSON response wraps the actual answer inside a typed envelope. The result field contains the same text you would see in text mode, but now it comes alongside metadata you can parse, log, and act on.
The JSON Envelope
Top-Level Fields
| Field | Type | Description |
|---|---|---|
type | string | Always “result” for a completed response |
subtype | string | ”success” or “error_max_budget_usd” if the cost limit was hit |
is_error | boolean | false on success — check this first in every response handler |
duration_ms | number | Wall-clock time including tool execution |
result | string | The text response, identical to what text mode returns |
stop_reason | string | ”end_turn” when Claude finished naturally, “max_tokens” if truncated |
session_id | string | UUID for this conversation — pass to —resume to continue it later |
total_cost_usd | number | Cost in USD for this single call |
usage | object | Token breakdown: input_tokens, cache_read_input_tokens, output_tokens |
permission_denials | array | Tools that were blocked by the permission system — empty when nothing was denied |
The total_cost_usd field is the cost for this single call, not a cumulative total. In a resumed session, each response reports only its own cost. If you need to track spend across an entire conversation, sum total_cost_usd from every call in the chain.
Pipe JSON output to jq for quick extraction on the command line:
claude -p ”…” —output-format json | jq ‘.result’
Stream-JSON Preview
When you need real-time output — for a typewriter UI, a progress indicator, or a long-running agent pipeline — there is a third format: stream-json.
$ claude -p "Say exactly: Hello CLI Test" --output-format stream-json --verboseThis emits NDJSON (newline-delimited JSON) events in real time, one JSON object per line. Each line has a type field that tells you what kind of event it is: system for initialization metadata, assistant for text responses, rate_limit_event for API status, and result for the final envelope.
The stream protocol is covered in depth in the Stream Protocol chapter, including how to parse partial messages for typewriter effects and how to handle tool-use events mid-stream.