grantiva console is the dashboard as a command tree. Everything you can do in the web dashboard — feature flags, apps, custom claims, devices, analytics, VRT review, release notes, feedback, support tickets, webhooks, alerts, API keys, team, the audit log, and org settings — has a subcommand, and every one of them takes --json.
Areas
Feature flags
flags, envs — flags, environments, targeting rules, per-device overrides, dry-run evaluation, and a live SSE stream.Apps, claims, devices
apps, claims, devices — register apps, author the custom claims minted into device JWTs, and inspect attested devices.Analytics
analytics — overview, event log, risk and compliance reports, CSV export.VRT and releases
vrt, releases — review and approve visual regression runs, author What’s New notes.Feedback and support
feedback, support — triage feature requests and work support tickets as the team.Organization
webhooks, alerts, keys, team, audit, org — endpoints, risk alerts, API keys, members, audit log, plan and usage.Authentication
Console commands act as an API key. Sign in once:~/.grantiva/auth.json:
Not authenticated. Run: grantiva auth login.
Scopes
Each command needs specific scopes on the key. A403 names the missing one:
Mint a scoped key from the terminal with
grantiva console keys create. A key can only create keys with scopes it holds itself.
Not every 403 is a missing scope. The API also answers 403 for plan limits and for rules like “this key cannot grant scopes it does not hold”. Those messages are shown verbatim rather than being rewritten into scope advice.
Conventions
These hold across every console command.--json prints the result as one JSON document on stdout, and suppresses progress narration. grantiva console flags watch --json is the exception in shape: it emits NDJSON, one compact {"event": …, "data": …} document per line.
Destructive verbs prompt. delete, revoke, and remove ask for confirmation on a TTY and refuse outright when stdin is not a TTY. Pass --yes to skip the prompt — it is required in CI.
flag_key, apps by bundle ID, claims by claim key, environments by slug. A UUID works everywhere the name does.
Bodies can come from files. Anywhere a --body, --rules, --external, --validation, or --conditions-json option takes text, @path reads it from a file instead:
Opening the dashboard
home, flags, apps, claims, devices, analytics, vrt, releases, feedback, support, webhooks, alerts, keys, team, audit, settings, billing.
The URL matches the API the CLI is signed in to, so a key pointed at a development API opens the development dashboard.