SpyBara
Go Premium

headless.md 2026-03-16 21:10 UTC to 2026-03-17 21:10 UTC

14 added, 0 removed.

2026
Tue 31 21:09 Mon 30 21:13 Sat 28 18:04 Fri 27 21:09 Thu 26 21:07 Wed 25 21:08 Tue 24 18:15 Mon 23 21:08 Sun 22 18:04 Sat 21 18:03 Fri 20 21:05 Thu 19 06:17 Wed 18 18:16 Tue 17 21:10 Mon 16 21:10 Sat 14 03:44 Fri 13 21:07 Thu 12 21:07 Wed 11 03:43 Tue 10 03:43 Mon 9 21:06 Sat 7 03:37 Fri 6 06:10 Thu 5 06:12 Wed 4 21:06 Sun 1 06:10

Run Claude Code programmatically

Use the Agent SDK to run Claude Code programmatically from the CLI, Python, or TypeScript.

The Agent SDK gives you the same tools, agent loop, and context management that power Claude Code. It's available as a CLI for scripts and CI/CD, or as Python and TypeScript packages for full programmatic control.

To run Claude Code programmatically from the CLI, pass -p with your prompt and any CLI options:

claude -p "Find and fix the bug in auth.py" --allowedTools "Read,Edit,Bash"

This page covers using the Agent SDK via the CLI (claude -p). For the Python and TypeScript SDK packages with structured outputs, tool approval callbacks, and native message objects, see the full Agent SDK documentation.

Basic usage

Add the -p (or --print) flag to any claude command to run it non-interactively. All CLI options work with -p, including:

This example asks Claude a question about your codebase and prints the response:

claude -p "What does the auth module do?"

Examples

These examples highlight common CLI patterns.

Get structured output

Use --output-format to control how responses are returned:

  • text (default): plain text output
  • json: structured JSON with result, session ID, and metadata
  • stream-json: newline-delimited JSON for real-time streaming

This example returns a project summary as JSON with session metadata, with the text result in the result field:

claude -p "Summarize this project" --output-format json

To get output conforming to a specific schema, use --output-format json with --json-schema and a JSON Schema definition. The response includes metadata about the request (session ID, usage, etc.) with the structured output in the structured_output field.

This example extracts function names and returns them as an array of strings:

claude -p "Extract the main function names from auth.py" \
  --output-format json \
  --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}'

Stream responses

Use --output-format stream-json with --verbose and --include-partial-messages to receive tokens as they're generated. Each line is a JSON object representing an event:

claude -p "Explain recursion" --output-format stream-json --verbose --include-partial-messages

The following example uses jq to filter for text deltas and display just the streaming text. The -r flag outputs raw strings (no quotes) and -j joins without newlines so tokens stream continuously:

claude -p "Write a poem" --output-format stream-json --verbose --include-partial-messages | \
  jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'

When an API request fails with a retryable error, Claude Code emits a system/api_retry event before retrying. You can use this to surface retry progress or implement custom backoff logic.

Field Type Description
type "system" message type
subtype "api_retry" identifies this as a retry event
attempt integer current attempt number, starting at 1
max_retries integer total retries permitted
retry_delay_ms integer milliseconds until the next attempt
error_status integer or null HTTP status code, or null for connection errors with no HTTP response
error string error category: authentication_failed, billing_error, rate_limit, invalid_request, server_error, max_output_tokens, or unknown
uuid string unique event identifier
session_id string session the event belongs to

For programmatic streaming with callbacks and message objects, see Stream responses in real-time in the Agent SDK documentation.

Auto-approve tools

Use --allowedTools to let Claude use certain tools without prompting. This example runs a test suite and fixes failures, allowing Claude to execute Bash commands and read/edit files without asking for permission:

claude -p "Run the test suite and fix any failures" \
  --allowedTools "Bash,Read,Edit"

Create a commit

This example reviews staged changes and creates a commit with an appropriate message:

claude -p "Look at my staged changes and create an appropriate commit" \
  --allowedTools "Bash(git diff *),Bash(git log *),Bash(git status *),Bash(git commit *)"

The --allowedTools flag uses permission rule syntax. The trailing * enables prefix matching, so Bash(git diff *) allows any command starting with git diff. The space before * is important: without it, Bash(git diff*) would also match git diff-index.

Customize the system prompt

Use --append-system-prompt to add instructions while keeping Claude Code's default behavior. This example pipes a PR diff to Claude and instructs it to review for security vulnerabilities:

gh pr diff "$1" | claude -p \
  --append-system-prompt "You are a security engineer. Review for vulnerabilities." \
  --output-format json

See system prompt flags for more options including --system-prompt to fully replace the default prompt.

Continue conversations

Use --continue to continue the most recent conversation, or --resume with a session ID to continue a specific conversation. This example runs a review, then sends follow-up prompts:

# First request
claude -p "Review this codebase for performance issues"

# Continue the most recent conversation
claude -p "Now focus on the database queries" --continue
claude -p "Generate a summary of all issues found" --continue

If you're running multiple conversations, capture the session ID to resume a specific one:

session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"

Next steps