Output and exit codes
Which stream carries what, when output is styled, what --format json prints, and what each exit code means.
Streams
Results go to stdout; prompts, progress, and diagnostics go to stderr, so piping stdout stays useful. coolship open --print | pbcopy copies only the URL, and coolship deploy > result.txt keeps the status lines and build log on the terminal while the final result lands in the file.
JSON
--format json prints one result object per command. The shapes are documented on each command page, and every result that names an application carries the same target object (see the command reference). logs --format json prints newline-delimited events, one object per line, for a single snapshot and when following. JSON mode never mixes human progress into stdout, and JSON output is never styled.
Values that may be secrets are masked in JSON as well, unless --show-values is given. The token never appears in any output; at debug verbosity only its last four characters are shown.
Styling
Human output is colored only when the stream it goes to is a terminal, and each stream is decided on its own, so coolship status | cat prints plain text while a prompt on the terminal is still styled. Styled elements are doctor markers, deployment statuses, Warning: and Error: prefixes, prompt questions, env diff markers, and key/value labels, using plain ANSI sequences.
Set NO_COLOR or pass --no-color to turn styling off everywhere; TERM=dumb and CI do the same. JSON output and the server's logs are never styled.
Verbosity
A run shows one of three levels. Normal is the default; for now, results name applications and deployments with their UUIDs at every level. Verbose adds one line on stderr for every request Coolship sends to Coolify: the method, the URL, the status (or no response), the time taken, and (retry N) for a retried read. Debug adds each request's and response's headers and bodies under that line, curl-style, with the token masked to its last four characters and control characters removed.
$ coolship status --verbose
GET https://coolify.example.com/api/v1/applications/mm4c0zpbrzx8z96t0qiw3tff 200 OK 84ms
…The level comes from the first of these that is set:
--debug, then--verbose(both long-only;-vis the version);COOLSHIP_VERBOSITY=normal|verbose|debug, for CI; any other value is invalid input;- the
verbositykey of the preferences file; - normal.
Verbose and debug output goes to stderr only, so stdout and --format json are the same at every level. Above normal, deploy, start, restart, and preview stream the build log unless --no-logs or the build_logs preference says otherwise (then it is held back and printed in full only if the deployment fails), and no spinner or stage checklist is drawn, so the request lines are never overwritten; the plain stage and status lines print instead, each finished stage with its duration and each status line with the time since the deployment was queued. Debug output shows request and response bodies in full, with only the token masked, so it includes the variable values env set and env push send and env pull returns, and any other secret a request or response carries; keep it out of shared CI logs.
Prompts
Commands that change something show their plan and ask for confirmation on stderr. When stdin is not a terminal there is no prompt: pass --yes (--replace for link) or the command refuses. link and init prompt for a choice only when it is genuinely ambiguous; q cancels a selection.
Exit codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | The operation failed. |
2 | Invalid input, configuration, or selection. |
130 | Interrupted. |
Errors are printed once, as a single Error: line on stderr, and classified into these codes at the process boundary. Some commands give a code a specific meaning: doctor exits 1 when any check fails, env diff --exit-code exits 1 when there are differences, and dev exits with the child process's status.