CLI
The stackblaze CLI is a client for the same REST API the dashboard uses. It can only do what your account or token is allowed to do.
Every command prints its own help: stackblaze --help, stackblaze <command> --help, stackblaze <command> <subcommand> --help.
Install
Section titled “Install”Linux and macOS:
curl -fsSL https://stackblaze.com/install.sh | shWindows (PowerShell):
irm https://stackblaze.com/install.ps1 | iexThe installers download a standalone binary (no Node.js needed). On Linux and macOS it goes to ~/.local/bin (or /usr/local/bin when run as root); on Windows to %LOCALAPPDATA%\StackBlaze\bin, which is added to your user PATH.
| Installer variable | Purpose |
|---|---|
STACKBLAZE_VERSION |
Install a specific version, e.g. 1.0.0 (default: newest on the channel) |
STACKBLAZE_CHANNEL |
stable (default) or dev (prereleases) |
INSTALL_DIR |
Install location (install.sh) |
STACKBLAZE_INSTALL_DIR |
Install location (install.ps1) |
Update an installed CLI in place with stackblaze upgrade. There is no npm package; use the installers above.
Authenticate
Section titled “Authenticate”stackblaze loginlogin starts a browser sign-in: it prints a one-click URL and a code, opens your browser, and waits until you approve. The token is saved to ~/.config/stackblaze/config.json (file mode 600; override the path with STACKBLAZE_CONFIG).
- On a server or over SSH:
stackblaze login --browserlessprints the URL and code without opening a browser. - With an API token:
stackblaze login --token kbr_pat_… - With email and password (2FA supported, interactive terminal only):
stackblaze login --password
Create API tokens in the dashboard under Settings → API tokens.
In CI, skip login and set both environment variables. Commands read them on every run:
export STACKBLAZE_API_URL=https://api.stackblaze.cloudexport STACKBLAZE_TOKEN=kbr_pat_…stackblaze whoamiSTACKBLAZE_API_URL defaults to https://api.stackblaze.cloud; STACKBLAZE_TOKEN is required whenever no saved login exists. Flags (--token, --api-url) override the environment, which overrides the saved config. See login, logout, whoami.
Quick start
Section titled “Quick start”From a project folder:
stackblaze init # create a project (pipeline) and link this directorystackblaze up # create the app and stream the buildstackblaze logs # recent app logs (add -f to follow)stackblaze open # open the app's dashboard page (--app-url opens the app)initwrites.stackblaze/project.json, so later commands know which pipeline and phase to use.- In a git checkout with a remote,
upbuilds from the remote and current branch, not from local files: push your commits first. In a folder without a git remote (or with--local), it uploads the folder and builds that. See up. - Run
upagain to ship changes: it updates the existing app and deploys again. It also saves the app name in the link when none is set yet.
Scope and common flags
Section titled “Scope and common flags”Most commands act on one app, identified by a pipeline (project), phase (environment) and app (service). They are resolved in this order:
- Flags:
-p, --pipeline,--phase,-a, --app - Environment:
STACKBLAZE_PIPELINE,STACKBLAZE_PHASE,STACKBLAZE_APP - The nearest
.stackblaze/project.json, searching upward from the current directory (written by init, link, up)
When the phase is still unknown, app commands use production. Run stackblaze context to see what resolves.
| Flag | Purpose |
|---|---|
-p, --pipeline <name> |
Pipeline (project) |
--phase <name> |
Phase (environment) |
-a, --app <name> |
App (service) |
--token <token> |
API token for this call |
--api-url <url> |
API base URL for this call |
-o, --output <text|json> |
Output format |
--json |
Same as -o json |
-y, --yes |
Skip the confirmation prompt (destructive commands) |
Each command page lists the flags that command accepts. Flags go after the command name: stackblaze apps list -o json.
Output and exit codes
Section titled “Output and exit codes”Results (tables, lists, the line that says what happened) go to stdout. Progress, prompts, warnings and errors go to stderr. You can pipe a result without catching progress messages.
With -o json (or --json), stdout carries only the JSON result, and text that would have gone to stdout moves to stderr:
stackblaze apps list -o json | jq -r '.[].app'Streaming commands write one JSON record per line (NDJSON) instead: up --ci, builds logs --ci and logs -f --json.
Commands that take --wait (deployments rollback, addons add, templates deploy) print one JSON document with --wait --json: the command’s result with the readiness check under wait. A wait that does not end with the app running exits 1, so command --wait && next only continues on a running app. Commands that open an interactive session (ssh, shell, connect, run) and the local tooling commands (setup, completion, upgrade, docs) have no JSON mode. Set NO_COLOR=1 to turn off colour; colour is already off when output is not a terminal.
| Exit code | Meaning |
|---|---|
0 |
Success |
1 |
Usage or validation error, failed build or deploy, an app that did not become ready, or a declined confirmation |
2 |
Authentication: no credentials, or the API rejected the token (401/403) |
3 |
API or network error: the API returned an error, could not be reached, or timed out |
Destructive commands ask for confirmation. When stdin is not a terminal (CI) the prompt gets no answer and the command exits 1 without changing anything, so pass -y in scripts.
stackblaze run exits with the exit code of the command it runs, and ssh with the exit code of the remote shell.
Network tuning: STACKBLAZE_HTTP_TIMEOUT (seconds per request, default 60, 0 disables) and STACKBLAZE_HTTP_RETRIES (extra attempts for read requests, default 2).
CI and GitHub Actions
Section titled “CI and GitHub Actions”stackblaze up is safe to re-run, so the same command works on every push: the first run creates the app, later runs update it and build again. With --ci it streams the build as NDJSON, and the job fails when the build fails:
name: Deployon: push: branches: [main]jobs: deploy: runs-on: ubuntu-latest env: STACKBLAZE_API_URL: https://api.stackblaze.cloud STACKBLAZE_TOKEN: ${{ secrets.STACKBLAZE_TOKEN }} STACKBLAZE_PIPELINE: my-project STACKBLAZE_PHASE: production STACKBLAZE_APP: web steps: - uses: actions/checkout@v4 - name: Install StackBlaze CLI run: | curl -fsSL https://stackblaze.com/install.sh | sh echo "$HOME/.local/bin" >> "$GITHUB_PATH" - name: Deploy run: stackblaze up --ci --wait- Keep the
actions/checkoutstep:upreads the repository and branch from the checkout. upbuilds exactly the pushed commit: it reads it fromGITHUB_SHA(the pull request’s head commit onpull_requestevents),CI_COMMIT_SHAorBUILDKITE_COMMIT, and the--cideploy event includes it ascommitSha. CI checkouts are often a detached HEAD;upthen reads the branch fromGITHUB_HEAD_REF,GITHUB_REF_NAME,CI_COMMIT_REF_NAMEorBUILDKITE_BRANCH(see branch detection). The very first build of a brand-new app uses the head of the branch.--waitalso waits up to 90 seconds for the new version to be running. Drop it to finish when the build succeeds.- For an image app, run
stackblaze up --ci --wait --image ghcr.io/acme/web --tag "$GITHUB_SHA". Without--wait, an image deploy ends with"state":"submitted"because nothing checked that it runs.
If the app auto-deploys on push, you do not need this workflow.
up --ci record format
Section titled “up --ci record format”stackblaze up --ci streams NDJSON to stdout (one JSON object per line). Notices and upload progress go to stderr:
{"type":"deploy","pipeline":"my-project","phase":"production","app":"web","mode":"git","action":"updated","repository":"https://github.com/acme/web","branch":"main","buildstrategy":"nixpacks","changed":[]}{"type":"build","build":"web-1a2b3c","state":"Active"}{"type":"log","build":"web-1a2b3c","container":"build","message":"…"}{"type":"build","build":"web-1a2b3c","state":"Succeeded","success":true}type |
Fields | When |
|---|---|---|
deploy |
pipeline, phase, app, mode (git, upload or docker), action (created or updated), changed (settings changed on an existing app), plus repository, branch, buildstrategy (git), uploadId, sha256, sizeBytes, files (upload) or image, tag (docker) |
Once, after the app is created or updated |
build |
build, state (Active, Succeeded, Failed, …); the final record also has success |
First seen, then on every state change |
log |
build, container, message |
Each build log line, as it is written |
error |
message |
The build failed or timed out |
status |
ready, pipeline, phase, app, and when known phaseStatus, url, message, failed, timedOut, note |
With --wait, after the build |
status |
state: "submitted", ready: null, pipeline, phase, app, note |
Image deploys without --wait: the deploy was accepted, nothing checked that it runs |
Exit code is 1 when the build fails or times out, or when --wait ends without the app ready. builds logs --ci emits the same build, log and error records. Build logs stream live; set STACKBLAZE_BUILD_STREAM=poll to poll instead.
Command index
Section titled “Command index”Use the sidebar for every page. By task:
- Sign in and link: login, logout, whoami, init, link, unlink, context, list, status
- Deploy and operate: up, deploy, redeploy, restart, scale, down, resume, wait, open, inspect
- Observe and debug: logs, metrics, events, diagnose, ssh, shell, run, connect
- Resources: apps, pipelines, phases, builds, deployments, domain, variables, pending, env, addons, templates, functions, waf, volume, snapshots, files
- Manifests (Infrastructure as Code): plan, apply, export, destroy
- AI tooling: agent, setup (aliases: mcp, skills)
- Account and CLI: billing, audit, upgrade, completion, docs
Command aliases: addon, app, build, deployment, domains, function / func / fn / fns, ls (list), new (init), phase, pipeline, snapshot, template, vars / var, volumes.
The REST API is in the API reference.