Habitat CLI for scripts and agents
Work with your music catalog, deals, and royalty data from a terminal.
The Habitat command-line interface (CLI) uses the same team API as your integrations.
Use hab in scripts or give this guide to your agent.
This guide covers CLI 0.3.0.
Download and install · Connect your team · Agent guide · API reference
Install
The CLI is available for macOS, Linux, and Windows. Files are served from Habitat’s public download storage. You do not need access to the source repository.
| Platform | Download |
|---|---|
| macOS, Apple silicon | Download archive |
| macOS, Intel | Download archive |
| Linux, x86-64 | Download archive |
| Linux, ARM64 | Download archive |
| Windows, x86-64 | Download ZIP |
Current version · SHA-256 checksums · Release manifest
Linux binaries require glibc 2.39 or later, as provided by Ubuntu 24.04. They do not run on Alpine Linux. The binaries are not signed or notarized. Check your organization's software policy before installation.
macOS and Linux
Download the installer, read it, then run it. It verifies the archive checksum and installs hab in ~/.local/bin.
It does not need administrator access. Run it again to update the CLI.
curl --fail --silent --show-error https://habitat.financial/install.sh -o install-hab.sh
less install-hab.sh
sh install-hab.sh
export PATH="$HOME/.local/bin:$PATH"
hab --version
Set HAB_VERSION=0.3.0 to install a specific version. Set HAB_INSTALL_DIR to change the installation directory.
For a manual installation, download the archive and checksums for the same version. Verify the checksum before extracting the archive.
Windows PowerShell
Download a version, verify its checksum, and extract it:
$version = (Invoke-RestMethod 'https://habitat.financial/downloads/cli/latest/VERSION').Trim()
$base = "https://habitat.financial/downloads/cli/$version"
$file = 'hab-x86_64-pc-windows-msvc.zip'
Invoke-WebRequest "$base/$file" -OutFile $file
$checksums = Invoke-RestMethod "$base/SHA256SUMS"
$line = ($checksums -split "`n" | Where-Object { $_.EndsWith(" $file") })
$expected = ($line -split '\s+')[0]
if (!$expected -or (Get-FileHash $file -Algorithm SHA256).Hash -ne $expected) { throw 'Checksum mismatch' }
Expand-Archive $file -DestinationPath .\hab-cli -Force
.\hab-cli\hab.exe --version
Add the extracted directory to your user Path to run hab from any directory. Repeat these steps to update.
Connect your team
Use your tenant's HTTPS origin as HABITAT_BASE_URL, without /api at the end.
The standard origin is https://app.habitat.financial. The CLI defaults to http://localhost:8000 if you do not configure it.
For an interactive session, sign in through your browser:
hab auth web-login --base-url https://app.habitat.financial
hab auth whoami --json
hab health --json
The browser shows the team and the available token scopes. A scope is permission to read or change a group of records. Sign-in grants your available read scopes. Select each write scope that the task needs. Each token belongs to one team. A token issued with Habitat staff Edit access expires after 24 hours. The team's editors can see these tokens in API Settings.
Save one profile for each team
A profile saves a team token and its origin. Replace the example team ID with your authorized team.
hab auth web-login --base-url https://app.habitat.financial --team 123 --profile label
hab auth list --json
hab --profile label auth whoami --json
hab --profile label payees list --json
hab auth use label
Without --profile, --team 123 saves the profile as team-123.
hab auth use label sets the default profile for reads.
When more than one token is saved, every command that changes data needs --profile NAME or HABITAT_PROFILE.
This rule also applies to logout. Check the selected team before each write.
To renew a saved profile, run hab --profile label auth web-login.
Renewal keeps its saved team. A successful sign-in attempts to revoke the previous token if browser sign-in issued it.
A replaced pasted token stays valid because another application may use it.
If the CLI reports a revocation failure, revoke the old token in API Settings.
hab auth whoami shows the selected profile, origin, masked token, and saved team and expiry details.
These details come from local configuration. The command does not validate the token with the server.
hab auth list lists saved profiles and expiry details without showing tokens.
To remove a saved profile, run hab --profile label auth logout.
Logout attempts to revoke its token on the server, then removes the local profile.
If revocation fails, the CLI warns you to revoke the token in API Settings.
Configure scripts and agents
For an agent or unattended script, provide HABITAT_BASE_URL and HABITAT_TOKEN through your secret manager.
The token must include its habitatkey_ prefix. The CLI adds the Authorization: Token header.
Do not include a real token in prompts, source files, or command examples.
To use a saved profile in a script, set HABITAT_PROFILE to its name.
Use either HABITAT_TOKEN or a named profile. Setting both is an error.
Logout refuses while HABITAT_TOKEN is set. Unset it before removing a saved profile.
Environment variables override the saved configuration.
The default file is ~/.config/habitat/config.toml. On Windows, this path is relative to your user profile directory.
Set HABITAT_CONFIG_DIR to use another directory. The file name remains config.toml.
Agent guide
- Read this guide and the OpenAPI schema.
- Confirm the tenant origin with the user. Ask for credentials through a secret manager.
- Use tokens with only the scopes needed for the task. Start with read scopes for inspection.
- Check
hab --versionandhab <resource> --helpbefore constructing commands. - Use
--jsonfor data output. Read errors from standard error and check the exit code. - Select the authorized team profile before a write. Read the target records and confirm the operation with the user.
- After a timeout, read the resulting state before retrying a write. A failed response does not prove that nothing changed.
The server enforces team ownership, token scopes, and module permissions. A CLI option cannot override them.
Scope names include content:read, payees:read, and statements:read. Writes need the corresponding :write scope.
Read the scope metadata for the full list.
Read records and earnings
The following identifiers are examples. Replace them with records from the authorized team.
hab tracks list --json
hab payees get 42 --json
hab tracks list --page 2 --json
hab payee-track-dsp-earnings list --filter payee_id=42 --filter period=2026-Q1 --json
hab track-dsp-earnings list --filter isrc=USABC2600001 --json
hab statement-sale-items list --filter isrc=USABC2600001 --json
Repeat --filter KEY=VALUE to supply API query parameters. Use the schema to find parameters supported by each endpoint.
Use --all to follow pagination and return a JSON array. Without it, paginated responses retain the API's results and next fields.
--all collects results in memory. Use individual pages for large datasets. Use --page separately from --all.
Prefer tracks for new work. records remains a legacy command.
Make authorized changes
Read the schema for required fields and allowed operations. For example, after approval:
hab --profile label payees update 42 --data '{"payee_name":"Example Artist"}' --json
Revenue streams support list, get, and update. Stores and overall period payee earnings are read-only.
The detailed earnings and statement sale item resources support list only.
The CLI also has commands for deals, royalty statements, and report generation. Use their --help output for required arguments.
Report generation can return a task identifier. Use the matching generation-status command before treating the report as complete.
Invite a payee
Invitation reads need payees:read. Creation, updates, deletion, and email actions need payees:write and the required team permissions.
Create the invitation first. Creation does not send email.
hab --profile label invitations list --filter payee_id=42 --json
hab --profile label invitations create --data '{"payee":42,"email":"[email protected]"}' --json
Use the invitation ID from the response for the next commands. The ID 81 below is an example.
After you confirm the recipient, queue the first email:
hab --profile label invitations send 81 --json
hab --profile label invitations get 81 --json
A queued response does not confirm delivery. Check the invitation status after the background task runs.
To email an already sent invitation again, use hab --profile label invitations resend 81 --json.
An accepted invitation cannot be changed or sent again.
Use a custom endpoint
hab raw get '/api/tracks/?page=2' --json
hab raw supports get, post, put, patch, and delete. Paths start with /api/.
Use --data for a JSON payload. It does not validate payload fields against the schema.
Non-JSON responses are wrapped in a raw field. Report commands return URLs; they do not download report files.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Command completed |
| 2 | Invalid arguments, JSON, or filter syntax |
| 4 | Missing token, authentication failure, or permission denial |
| 5 | Record or endpoint not found |
| 6 | API validation error |
| 10 | Connection, server, or other error |
--json applies to resource data and raw requests. Authentication setup commands still print status messages.
A 404 response does not prove that a record exists in another team. Respect the denial and keep the authorized tenant origin.
Documentation for agents
This page and its Markdown version use the same source.
Agents can also request /cli with Accept: text/markdown.
Start at llms.txt to find the guide, API schema, and other public documentation.