spatie/flare-cli
A command-line tool for interacting with the Flare API from your terminal. Log in via browser OAuth, device code, or API token, manage profiles and self-hosted servers, and securely store credentials for automation and CI workflows.
spatie/flare-cli is not a package you composer require into a Laravel app. It is a globally installed, framework-agnostic PHP CLI (built on Laravel Zero, shipped as a PHAR) that wraps the Flare HTTP API. Your spatie/laravel-flare SDK captures errors at runtime; this tool reads, queries, and mutates the same data from your terminal. Keep that boundary clear in your head — nothing the CLI does makes your app report errors.
Install (once per machine):
composer global require spatie/flare-cli
# Make sure the global bin dir is on PATH — this prints the path to add
composer global config bin-dir --absolute
flare --version
Authenticate. Pick the path that matches where you are:
| Context | Command |
|---|---|
| Laptop / desktop | flare login (browser OAuth + PKCE) |
| SSH, container, remote box | flare login --device (prints a code to enter elsewhere) |
| CI, scripts, cron | flare login --token with a personal access token |
Optionally name the connection so it's identifiable later in the Flare UI: flare login --name="Work laptop".
Verify before you query anything:
flare auth # which issuer / API base profile is active
flare get-authenticated-user # cheap round-trip that proves the token works
First real use case — morning triage. Get your project id, then pull unresolved errors:
flare list-projects
flare list-project-errors --project-id=<id>
That's the loop most Laravel developers will run daily: what broke since I logged off, then drill into a single occurrence with list-error-occurrences --error-id=<id> and get-error-occurrence --occurrence-id=<id>.
Where to look first. The command catalog is generated from the remote Flare API spec, so every endpoint has a command and flare <command> --help is the authoritative reference for flags. Run flare list (or flare --help) to see the whole surface. If you pair-program with an AI agent, run flare install-skill first — it drops the repo's agent skill into place so the agent knows how to drive the CLI without you writing a prompt novel.
The highest-value workflow: stop resolving errors by hand in the dashboard after every release. Deploy, wait a few minutes, verify the error count for the window, then bulk-resolve.
PROJECT=<id>
DEPLOY_START=$(date -u -d '15 minutes ago' +%Y-%m-%dT%H:%M:%SZ)
DEPLOY_END=$(date -u +%Y-%m-%dT%H:%M:%SZ)
flare get-project-error-occurrence-count \
--project-id=$PROJECT --start-date=$DEPLOY_START --end-date=$DEPLOY_END
# If clean, clear the backlog for the errors you just fixed
for ID in $(cat fixed-error-ids.txt); do
flare resolve-error --error-id=$ID
done
The inverse is equally useful: unresolve-error when a "fixed" error reappears, and snooze-error / unsnooze-error around a noisy refactor so the dashboard reflects signal, not churn.
FLARE_BASE_URLProfiles are keyed by issuer and API base, so production, staging, and self-hosted credentials coexist in ~/.flare/config.json. Point the CLI at a non-production Flare with:
export FLARE_BASE_URL=https://passport-oauth.test/api
flare login
An origin with no path defaults to /api; a non-default path is treated as a distinct profile. Use direnv/.envrc per repo directory so shell sessions can't accidentally run resolve-error against production.
- name: Install Flare CLI
run: |
composer global require spatie/flare-cli:^1.3 --no-interaction
echo "$(composer global config bin-dir --absolute)" >> "$GITHUB_PATH"
- name: Authenticate
run: flare login --token="${{ secrets.FLARE_TOKEN }}"
- name: Fail on new errors in the smoke-test window
run: |
count=$(flare get-project-error-occurrence-count \
--project-id="$PROJECT_ID" \
--start-date="$WINDOW_START" --end-date="$WINDOW_END")
echo "occurrences: $count"
Pin a major version (:^1.3) and prefer ephemeral runners — the credentials land in ~/.flare/config.json (mode 0600 in a 0700 dir). On self-hosted runners, add flare logout --all as a teardown step.
create-project uses a repeatable --field key=value syntax, which makes per-PR Flare projects scriptable:
flare create-project \
--field name="api-pr-1234" \
--field team_id=1 \
--field stage=staging \
--field technology=Laravel
# on PR close
flare delete-project --project-id=<id>
Capture the created id from the command output and inject it into the preview environment's FLARE_KEY so the Laravel SDK reports to the right place.
The monitoring endpoints are the reason to install this on a laptop rather than only in CI:
flare get-monitoring-summary --project-id=<id>
flare list-monitoring-aggregations --project-id=<id> --type=routes
flare get-monitoring-time-series --project-id=<id> --type=routes
flare get-monitoring-aggregation --type=routes --uuid=<uuid>
flare list-aggregation-traces --type=routes --uuid=<uuid>
flare get-trace --trace-id=<trace-id>
The drill-down (aggregation → traces → trace) mirrors the dashboard's slow-route investigation but keeps you in the terminal next to your profiler and your code.
Anything you want scheduled belongs in a console command that shells out, not in a controller:
use Illuminate\Support\Facades\Process;
$result = Process::run([
'flare', 'get-project-error-count',
'--project-id=' . config('services.flare.project_id'),
'--start-date=' . now()->subDay()->toIso8601String(),
'--end-date=' . now()->toIso8601String(),
]);
Caveat: if you need structured output (counts, arrays of errors) rather than human-readable text, skip the CLI and call the API directly with Http::withToken(config('services.flare.token')). The CLI is optimised for humans; verify its output shape before betting a scheduled job on string parsing.
flare get-team --team-id=<id> and flare remove-team-user --team-id=<id> --user-id=<id> let you fold Flare access into an offboarding script driven from your HR/identity source of truth, rather than relying on someone remembering to click through the dashboard.
composer require --dev spatie/flare-cli, it lands in vendor/bin and disappears from every repo that doesn't install it. Use a global install on workstations and an explicit per-job install in CI.PATH. The binary is only on PATH if you export Composer's global bin dir in the same job (see the GitHub Actions example above). This is the #1 "command not found" cause.composer global require is also the update command. There's no self-update; re-run the same require to upgrade, then re-read flare <command> --help for flag drift.https://flare.example.com/api/v1 and later running with FLARE_BASE_URL=https://flare.example.com selects a different profile and looks like you're logged out. Run flare auth first whenever a command reports missing credentials.flare logout needs the network. It revokes remotely before deleting local credentials. When Flare is unreachable (self-hosted server down, airgapped box), use flare logout --local-only. Use --all to wipe every configured profile.--token in a non-interactive shell. 1.2.0 fixed invalid tokens reporting as successful logins, but confirm the flag accepts an inline value in your CI shell — test it once in a dry-run job before wiring it into a required check.--field key=value is repetitive, not JSON. No --json payload for create-project; you pass each field separately, and enum-ish fields (stage, technology) are validated server-side. Let a bad value fail in a scratch project first.--start-date / --end-date is unspecified in the README. Check --help and lock the format in your scripts (ISO-8601 UTC is the safe assumption for APIs) so a locale-dependent date call doesn't silently shift your window.snooze-error duration is undocumented. Inspect --help before assuming a default window — you don't want errors silently suppressed for longer than you expect during an incident.flare login from an agent session. The browser and device flows are interactive by design. Have the human run flare login (or --device) once, then let automation use the resulting profile — or a --token credential in CI.flare install-skill is cheap and worth it. It teaches coding agents the auth model and command names, which cuts down on hallucinated flare invocations during debugging sessions.APP_DEBUG-swallowed exceptions — the CLI will show you a clean project and you'll believe it. Treat "zero errors" from this tool as a claim about what Flare received, not about what your app did.How can I help you explore Laravel packages today?