- In short
- Claude Code headless mode is the non-interactive way to run the agent, enabled by adding the -p (print) flag. It sends one prompt, prints the result to standard output, and exits with a status code, so scripts, cron jobs, and CI/CD pipelines can drive Claude Code without a human at the terminal.
What Claude Code headless mode is
Claude Code headless mode is the way you run the agent when no human is sitting at the terminal. You switch it on by adding the -p flag (short for --print) to a claude command. In this mode Claude Code takes a single prompt, does the work, prints the result to standard output, and then exits with a status code. There is no chat loop, no prompt for the next instruction, and no permission dialog waiting for you to press a key. That behaviour is exactly what a continuous-integration runner, a cron job, or a shell script needs.
The contrast is with the default interactive mode you use day to day. When you type claude on your own machine, it opens a session that stays alive, shows you each step, and pauses to ask before it edits files or runs commands. That conversational design is excellent for a developer, but it is fatal in automation: a script has no way to answer those prompts. The -p flag is the switch that turns a conversational tool into a one-shot command-line program.
- Headless mode (the -p flag)
- A non-interactive invocation of Claude Code in which a single prompt is sent with the -p flag, the response is printed to standard output, and the process exits with a status code, enabling use inside scripts, cron jobs, and CI/CD pipelines.
Why an interactive session breaks a pipeline
Picture a GitHub Actions workflow whose review step simply runs claude "review the diff and report issues". On a developer laptop that opens an interactive session and works fine. On the runner it does something very different: it launches the same interactive session, immediately needs input or a permission decision, and finds an empty, non-attached terminal. Nothing answers. The job sits there until the workflow's wall-clock timeout fires, then fails with no useful output. To the team it looks like Claude Code is broken or hopelessly slow, when the real cause is that an interactive program was asked to run where no human exists.
This is the single most common first mistake teams make when wiring Claude Code into CI, and it is precisely the trap this knowledge point sets. The fix is not a bigger timeout, a faster model, or a different runner. It is one flag. Adding -p tells Claude Code to do its work once and return, which is the only shape of execution a pipeline can actually consume.
The anatomy of a headless invocation
A minimal headless call is just claude -p followed by the prompt, for example claude -p "summarise the changes on this branch". From there a handful of flags make the run dependable in automation. The --allowedTools flag pre-approves specific tools so Claude does not stop to ask for permission mid-run; a call such as claude -p "run the tests and fix failures" --allowedTools "Bash,Read,Edit" lets the agent execute and edit without prompting. The --output-format flag controls how the response comes back, which the next knowledge point covers in depth.
There is also a --bare flag built specifically for CI. Normally claude -p still auto-discovers your hooks, skills, MCP servers, auto memory, and CLAUDE.md, so a run can behave differently depending on what happens to be configured on a given machine or in a teammate's home directory. Adding --bare skips that discovery and runs only with the flags you pass explicitly, which is what makes a CI run reproducible across every machine. Anthropic documents --bare as the recommended mode for scripted and SDK calls. One more boundary worth memorising: user-invoked skills like /code-review are only available in interactive mode, so inside a -p run you describe the task in the prompt rather than calling a slash command.
Exit codes and how CI reads success or failure
A pipeline does not read prose; it reads exit codes. A headless Claude Code run returns 0 when it succeeds and a non-zero code when it errors, which is the same contract every Unix command-line tool follows. That means you can chain a Claude step with && and ||, gate later steps on it, or let the CI system mark the job red automatically when the command fails. Treating Claude Code as an ordinary exit-code-returning program is what lets it slot into an existing pipeline without special handling.
This is also why headless mode composes so cleanly with shell tooling. Because the result lands on standard output and the status lands in the exit code, you can redirect the output to a file, pipe it into another command, or capture it in a variable for a later step. The agent behaves like grep or jq from the pipeline's point of view: it consumes input, produces output, and reports whether it worked.
Piping data in and out
Headless mode reads standard input, so you can feed data straight into a run instead of asking Claude to go and fetch it. A common pattern pipes a diff or a log into the prompt, for instance git diff main | claude -p "report any typos in this diff". Piping the diff in means Claude does not even need Bash permission to read it, which keeps the run both simpler and safer. On the way out, claude -p "summarise this project" > summary.txt redirects the answer to a file your next step can pick up. These small Unix habits are the whole point of headless mode: it makes an AI agent behave like a well-mannered command in a larger script.
Headless mode is the Agent SDK from the command line
When you run claude -p, you are not running a stripped-down version of the tool, you are driving the Agent SDK, the same engine that powers an interactive Claude Code session. Anthropic describes the Agent SDK as giving you "the same tools, agent loop, and context management that power Claude Code", exposed three ways: as the CLI you call with -p, and as Python and TypeScript packages for fully programmatic control. Recognising that headless mode is the SDK, not a lesser mode, explains why the agent can still read files, run the test suite, and edit code inside a pipeline, the full agent loop is intact, and only the human-facing chat shell is gone.
That framing also sets expectations about what a -p run loses. The pieces it gives up are the interactive affordances, the permission dialog, the running transcript, the slash commands, not the reasoning loop. Anything you would normally approve by pressing a key you now pre-declare with a flag, and anything you would normally trigger with a slash command you now express as a plain-language instruction in the prompt. This is also why user-invoked skills like /code-review are unavailable headlessly: those commands belong to the interactive shell, so inside automation you describe the task you want done instead. The mental model that serves you on the exam is short: same engine, no keyboard.
One operational note is worth tracking. From June 15, 2026, Anthropic bills claude -p and Agent SDK usage on subscription plans against a separate monthly Agent SDK credit rather than against your interactive limits. That is a billing detail rather than an exam fact, but it reinforces the underlying point that headless runs are treated as a distinct, automatable surface of the product, governed and metered on their own terms.
Permission modes for a locked-down run
--allowedTools is the precise instrument: you name exactly which tools may run without a prompt. When you want a baseline posture for the whole run rather than an explicit list, you reach for --permission-mode. Two modes matter in CI. acceptEdits lets Claude write files without asking and auto-approves common filesystem commands such as mkdir, touch, mv, and cp, while other shell commands and network calls still need an allow rule. dontAsk is the locked-down option: it denies anything that is not already in your permissions.allow rules or the built-in read-only command set, so a misbehaving prompt cannot reach for a tool you never sanctioned, and the run aborts cleanly instead.
The distinction the exam cares about is intent. --allowedTools answers "what may this run touch?"; --permission-mode answers "what is this run's default stance toward permission?". A read-only audit job pairs dontAsk with a short allow list; a job that must apply fixes leans on acceptEdits. Either way the objective is the same one the -p flag started: remove every point at which the run would otherwise stop and wait for a human decision. A pipeline can only consume a command that never blocks, so every permission surface has to be settled before the run begins, not during it.
Operational edges that bite in CI
Two smaller behaviours deserve a place in memory, because they surface as confusing pipeline failures rather than obvious errors. First, piped standard input is capped at 10MB. If you pipe an oversized diff or log past that ceiling, Claude Code does not silently truncate. It exits with a clear error and a non-zero status, which the pipeline reads as a failed step. The documented workaround is to write the large content to a file and reference its path in the prompt instead of piping it. Second, if a -p run starts a background Bash task such as a dev server or a watch build, that task is terminated about five seconds after Claude returns its final result and standard input closes. The brief grace period lets a task that finishes right after the result still flush its output, but it means you cannot rely on a backgrounded process outliving the headless run.
Both behaviours flow from the same contract that makes headless mode usable: a -p invocation is a bounded, single-shot command that produces a result and exits. Anything that would hold it open indefinitely, an oversized pipe or a never-exiting background process, is deliberately cut off so the pipeline step always terminates. Internalising that the run is finite by design is what lets you reason about its edges instead of being surprised by them.
How this knowledge point is tested
Domain 3 carries 20% of the Claude Certified Architect exam, and Scenario 5, Claude Code for Continuous Integration, is where this knowledge point lives. Questions rarely ask you to recite what -p stands for. Instead they describe a symptom: a pipeline job that never finishes, a workflow that times out with empty output, or an engineer puzzled that the same command works locally but stalls on the runner. Your job is to recognise that the command is running interactively and that the remedy is the -p flag. Recognising headless mode as the prerequisite for everything else in Task 3.6, structured JSON output, independent review instances, incremental reviews, and full pipeline design, is what lets the rest of the domain make sense.
Worked example
A team wires a nightly security scan into GitHub Actions and the job hangs until the workflow timeout.
The workflow step runs claude "scan the codebase for hardcoded secrets and list them". Locally the engineer who wrote it sees Claude open, think, and answer, so they assume the same will happen in CI. The nightly run tells a different story: every job stays in progress for the full 60-minute limit, then fails. No findings, no error message, just a timeout.
Walk through what the runner actually did. It launched claude with no -p, so Claude opened an interactive session and, before scanning anything, needed either input or permission to use a tool. On a CI runner there is no attached terminal and no human, so that request hangs unanswered. The wall-clock timeout is the only thing that eventually ends the job.
The fix is a one-line change: claude -p "scan the codebase for hardcoded secrets and list them" --allowedTools "Read,Grep" --bare. Now the run is non-interactive, the two read-only tools are pre-approved so nothing pauses for permission, and --bare guarantees the same behaviour on every runner. The job prints its findings to standard output and exits 0, and the next step can act on the result. Nothing about the model or the runner changed, only the execution mode did.
Common misconceptions to avoid
The exam rewards architects who can name the real cause of a stalled pipeline rather than chasing the wrong lever.
Misconception
A Claude Code job that hangs in CI just needs a longer timeout or a faster model to finish.
What's actually true
Misconception
The -p flag is only about printing output, so I can leave it off as long as I capture stdout.
What's actually true
Misconception
Once I add -p, the run is fully reproducible across machines, so --bare is just an optimisation.
What's actually true
A team adds a step that runs `claude 'run the linter and summarise the issues'` in their GitHub Actions workflow. The job runs until it times out after 60 minutes with no output. What is the root cause and the correct fix?
People also ask
What does the -p flag do in Claude Code?
How do I run Claude Code in a CI pipeline?
What is the difference between headless and interactive mode in Claude Code?
Watch and learn
Official Anthropic Academy lessons first, then hand-picked walkthroughs. Videos load only when you press play.
The Claude Code SDK
Why watch: Driving Claude Code programmatically/headless is the non-interactive (-p) mode that makes CI usage possible.
More videos for this concept
References & primary sources
Master this concept with Archie
Practice it inside an adaptive study session. Archie, your Socratic AI tutor, tracks your mastery with Bayesian Knowledge Tracing and schedules the perfect next review.