Skip to content

altertable-ai/altertable-cli

Repository files navigation

Altertable CLI

npm License: MIT

Query and manage your Altertable data platform from the terminal.



Quick start

# 1. Install
curl -fsSL https://install.altertable.ai | sh

# 2. Configure credentials
altertable profile --configure

# Or non-interactive (CI/scripts):
altertable profile --configure --api-key atm_xxxx --env production
altertable profile --configure --user your_username --password your_password

# 3. Verify (optional — the wizard verifies by default)
altertable profile show

# 4. Query
altertable query "SELECT * FROM users LIMIT 10"

Installation

Install script

Recommended for most users:

curl -fsSL https://install.altertable.ai | sh

npm

npm install -g @altertable/cli

Requires Bun at runtime (used as the JS engine when running the npm package).

Prebuilt binaries

Download the platform binary from GitHub Releases. Each release ships:

Asset Description
altertable-darwin-arm64 macOS Apple Silicon
altertable-darwin-x64 macOS Intel
altertable-linux-x64 Linux x86-64
altertable-linux-arm64 Linux ARM64
altertable-cli.js Bun bundle (bun altertable-cli.js)
checksums.txt SHA-256 checksums for all assets

Verify and install:

shasum -a 256 -c checksums.txt --ignore-missing
chmod +x altertable-linux-x64
sudo mv altertable-linux-x64 /usr/local/bin/altertable
altertable --version

From source

git clone https://github.com/altertable-ai/altertable-cli.git
cd altertable-cli
git submodule update --init --recursive
chmod +x bin/altertable
export PATH="$PWD/bin:$PATH"
altertable --version

Updates

Check for a newer CLI and install it:

altertable update
altertable update --install

altertable update --install is origin-aware:

  • prebuilt release binaries update from GitHub Releases, verify checksums.txt, then replace the current binary atomically;
  • npm-style installs use the package manager (npm, Bun, pnpm, or Yarn) and verify the installed altertable --version;
  • source checkouts are not auto-installed by default; update them with git pull or choose an explicit install method.

The CLI also performs a silent daily update check after successful human-facing commands. Notices are written to stderr only, never to stdout, and are disabled for --json, --agent, CI, and non-TTY output.

Control automatic notices:

altertable update --status
altertable update --check-interval weekly
altertable update --check-interval never

Set ALTERTABLE_NO_UPDATE_CHECK=1 or ALTERTABLE_UPDATE_CHECK=never to disable automatic checks from the environment. Package-manager installs use npm by default and detect Bun, pnpm, or Yarn when available; set ALTERTABLE_UPDATE_INSTALLER=bun|npm|pnpm|yarn to override. Set ALTERTABLE_UPDATE_INSTALL_METHOD=auto|package-manager|github-binary or pass --install-method to choose an installer strategy.


Authentication

The CLI talks to two independent APIs with separate auth schemes:

Plane Purpose Auth
Management (control) profile show, catalogs Browser OAuth or API key
Lakehouse (data) query, upload, upsert, append HTTP Basic

Most users need both. Run the interactive wizard or configure each plane with flags:

# Interactive wizard (TTY) — configures management and lakehouse
altertable profile --configure

# Plane-specific wizards
altertable profile --configure --scope management
altertable profile --configure --scope lakehouse

# Non-interactive (scripts/CI)
altertable profile --configure --api-key atm_xxxx --env production
altertable profile --configure --user your_username --password your_password
altertable profile --configure --data-plane-url https://api.example.com
altertable profile show

# Verify stored credentials
altertable profile status

Passing --user and --api-key in a single invocation is not allowed. Run two separate profile --configure calls — one per plane.

Management API key

altertable profile --configure --api-key atm_xxxx --env production

# Pipe the key from a secret store
printf '%s' "$KEY" | altertable profile --configure --api-key-stdin --env production

Or via environment variables:

export ALTERTABLE_API_KEY="atm_xxxx"
export ALTERTABLE_ENV="production"

Browser login (OAuth)

Sign in interactively with your browser instead of pasting an API key:

altertable login          # opens your browser, stores an OAuth session
altertable logout         # clears stored credentials and settings for all profiles

Lakehouse credentials

altertable profile --configure --user your_username --password your_password

Prefer reading secrets from stdin to avoid exposing them in process listings:

printf '%s' 'your_password' | altertable profile --configure --user your_username --password-stdin
printf '%s' "$KEY" | altertable profile --configure --api-key-stdin --env production

Plane URLs default to HTTPS. --data-plane-url can be saved by itself without changing credentials; --control-plane-url must be saved with a management credential so failed login/configure attempts do not leave a stale control-plane override. Localhost HTTP (http://localhost, http://127.0.0.1) works without extra flags; other HTTP URLs require --allow-insecure-http.

Or via environment variables:

# Option 1: pre-encoded HTTP Basic token
export ALTERTABLE_BASIC_AUTH_TOKEN="your_basic_auth_token"

# Option 2: username/password
export ALTERTABLE_LAKEHOUSE_USERNAME="your_username"
export ALTERTABLE_LAKEHOUSE_PASSWORD="your_password"

Dual-plane model

Rules for updating credentials:

  • Separate profile --configure invocations — lakehouse and management credentials coexist in the active profile.
  • Within one profile --configure invocation — only one plane may be written.
  • Within the same plane — a new value replaces the previous one.
  • Environment variables override stored credentials when set.
  • altertable logout removes both planes and resets endpoint overrides for all profiles.

Profiles

Named profiles store credentials and endpoint overrides per environment. Global display defaults (query_layout, query_max_width, query_pager) stay in the root config and apply to all profiles.

Profile names can be provided explicitly, or derived from an organization slug and environment as <org>_<env>. Derived names are normalized to lowercase safe profile names, for example Acme + Production becomes acme_production.

# Browser login creates or reuses the signed-in org_env profile and switches to it
altertable login

# Or store the signed-in session in the current profile
altertable login --replace-profile

# Set up multiple environments with explicit profile names
altertable profile create acme_staging --api-key atm_xxx --env staging
altertable profile create acme_prod --api-key atm_yyy --env production

# Switch the sticky active profile
altertable profile use acme_staging

# Or choose interactively
altertable profile switch

# Use a profile for one command
altertable --profile acme_production profile show

# Use a profile for the current shell, including direnv
eval "$(altertable profile env acme_staging)"

# Or generate a .envrc snippet
altertable profile direnv acme_staging > .envrc

# Inspect profiles
altertable profile list
altertable profile current
altertable profile status
altertable profile show --name acme_staging

Advanced profile commands manage endpoint overrides and inspect existing profiles:

# Verify credentials and show the profile (identity + credential details)
altertable profile status --name acme_staging

# Print a shell snippet for direnv or manual use
altertable profile env acme_staging
altertable profile direnv acme_staging

# Rename a profile
altertable profile rename acme_staging acme_stage

Profile selection precedence: --profile flag → ALTERTABLE_PROFILE env var → active_profile config → default.

Scope Stored there
Global root config Active profile and display/update preferences such as query layout, query width, and update checks
Profile-specific config Credentials metadata, endpoint overrides, organization/principal metadata, and credential expiry timestamps

profile status runs live credential verification and then renders profile show (identity and credential details, including OAuth and auto-provisioned lakehouse credential expiry when present) followed by the verification result. profile show --config additionally prints the config dir, profile config file, and secret store paths.

Credential precedence

Management plane

Priority API key Environment slug Control-plane base
1 (highest) ALTERTABLE_API_KEY ALTERTABLE_ENV ALTERTABLE_MANAGEMENT_API_BASE
2 profile secret api-key profile api_key_env profile management_api_base
3 (default) https://app.altertable.ai

Lakehouse plane

Priority Credentials Data-plane base
1 ALTERTABLE_BASIC_AUTH_TOKEN ALTERTABLE_API_BASE
2 ALTERTABLE_LAKEHOUSE_USERNAME + ALTERTABLE_LAKEHOUSE_PASSWORD profile api_base
3 stored basic token / user+password https://api.altertable.ai

Note: Setting ALTERTABLE_ENV overrides the slug in /environments/{env}/… paths without changing the Bearer token. Make sure the env var, stored api_key_env, and API key permissions all refer to the same environment.

You can also override endpoints per-command with flags:

Purpose Flag Environment variable
Management / control plane --control-plane-url ALTERTABLE_MANAGEMENT_API_BASE
Lakehouse / data plane --data-plane-url ALTERTABLE_API_BASE

Commands

Lakehouse

Query

altertable query "SELECT * FROM users LIMIT 10"

# Human layout and script-friendly formats
altertable query "SELECT * FROM events LIMIT 3"
altertable query "SELECT * FROM events LIMIT 3" --layout auto
altertable query "SELECT * FROM events LIMIT 3" --layout table
altertable query "SELECT * FROM events LIMIT 3" --layout line
altertable query "SELECT * FROM events LIMIT 3" --columns uuid,event,timestamp
altertable query "SELECT * FROM events LIMIT 3" --max-width 24

# Serialized output
altertable query "SELECT 1" --format csv
altertable query "SELECT 1" --format json
altertable query "SELECT 1" --format markdown

# Long results — pipe through a pager
altertable query "SELECT * FROM big_table" --pager always
altertable query "SELECT * FROM big_table" --pager never

# JSON for scripting
altertable --json query "SELECT 1"

# Agent-friendly preset (structured JSON, no pager or terminal styling)
altertable --agent query "SELECT 1"

Use --format human|json|csv|markdown for serialized output (default human). Human output respects --layout auto|table|line (default auto), --columns, --max-width, and --pager auto|always|never. auto picks a table when it fits and line layout when the table would be too wide. --format json|csv|markdown skips pager and layout controls. For machine-readable query output, prefer --format json or the global --agent preset.

Set display defaults in ~/.config/altertable/config:

query_layout=auto       # auto | table | line
query_max_width=32      # integer >= 8
query_pager=auto        # auto | always | never

Append and upload

altertable append --catalog my_cat --schema public --table users --data '{"id": 1}'
altertable append --catalog my_cat --schema public --table users --data '{"id": 2}' --sync

altertable upload --catalog my_cat --schema public --table users --mode overwrite --format csv --file data.csv
altertable upsert --catalog my_cat --schema public --table users --primary-key id --format csv --file data.csv

Inspect async operations

altertable query show <query-uuid>
altertable query cancel <query-uuid> --session-id <uuid>
altertable append status <append-id>

Management

Product-level commands stay at the top level. The full management REST surface is available via altertable api (HTTP invoker):

altertable profile show
altertable catalogs list
altertable catalogs create --engine altertable --name "My Catalog"

# Explore the bundled OpenAPI contract
altertable api spec
altertable api spec --json   # raw JSON document
altertable api routes        # index of paths and methods
altertable api routes createDatabase

# HTTP calls — path is relative to /rest/v1 (base URL from config)
altertable api /whoami
altertable api GET /whoami
altertable api GET /environments/production/connections
altertable api GET '/environments/production/connections?limit=10'
altertable api -X GET /service_accounts -f label="CI Bot"
altertable api POST /service_accounts -f label="CI Bot"
altertable api /service_accounts -f label="CI Bot" -F enabled=true
altertable api POST /environments/production/databases -f name=Analytics
altertable api POST /environments/production/databases --body '{"name":"Analytics"}'
altertable api POST /environments/production/databases --body @payload.json
altertable api DELETE /service_accounts/sa_abc123
altertable api PATCH /environments/production/connections/conn_1 --body '{"name":"Renamed"}'

Use --env <slug> to substitute {environment_id} in paths copied from api routes. Prefer full paths like /environments/production/... when the environment is known. The method defaults to GET, switches to POST when request parameters or a body are provided, and can be overridden with -X/--method. Use -f/--raw-field for string parameters and -F/--field for typed values (true, false, null, integers, or @file). Forced GET and DELETE requests put fields in the query string; POST, PATCH, and PUT use fields as the JSON body unless --body/--input is supplied, in which case fields become query parameters.

For advanced or provider-specific payloads, pass raw JSON with --body or @file:

altertable api POST /environments/production/connections --body @postgres-connection.json

Shell completion

Install completion for bash, zsh, or fish:

altertable completion install

The CLI detects your shell from $SHELL, writes the completion script to the standard user directory, and updates your shell startup file when bash or zsh needs it. Open a new terminal, or reload your shell, to start using completion.

You can also choose a shell explicitly:

altertable completion install zsh
altertable completion install fish

If you need a manual install, generate the script without writing files:

# bash
altertable completion generate bash > ~/.local/share/bash-completion/completions/altertable

# zsh
altertable completion generate zsh > ~/.local/share/zsh/site-functions/_altertable

# fish
altertable completion generate fish > ~/.config/fish/completions/altertable.fish

The compatibility aliases altertable completion bash, altertable completion zsh, and altertable completion fish also print raw scripts. Running altertable completion in an interactive terminal opens a small menu; in non-interactive terminals it prints usage guidance. Tab completion covers top-level commands, subcommands up to two levels deep, command-specific flags on leaf commands, and global flags (--json, --agent, --debug). Regenerate or reinstall scripts after upgrading the CLI.


Global flags

These flags apply to every command and must be placed before the subcommand:

Flag Description
--profile <name> Use a named profile for this invocation
--json Output raw JSON (machine-readable success; JSON error envelope on stderr)
--agent Agent preset: structured JSON output, no pager, colors, or terminal styling
--debug, -d Enable debug output
--connect-timeout <s> HTTP connect timeout in seconds (default: 5)
--read-timeout <s> HTTP read timeout in seconds (default: 60; 0 = unlimited for streams)

Per-request read timeout on query, upload, and upsert:

altertable query "SELECT ..." --read-timeout 180
altertable --read-timeout 120 query "SELECT ..."
altertable --connect-timeout 10 upload --catalog my_cat --schema public --table users --mode overwrite --format csv --file large.csv
altertable --connect-timeout 10 upsert --catalog my_cat --schema public --table users --primary-key id --format csv --file large.csv

Stream endpoints (lakehouse query streams) treat --read-timeout 0 as unlimited once connected.


Scripting

Use --json or --agent for machine-readable output. On failure the error is a JSON object on stderr; stdout remains empty.

Output tiers

With --json, success stdout follows one of three contracts:

  1. Raw API — verbatim API response body (most api * commands).
  2. Normalized query{ metadata, columns, rows } from query --format json, query --json, or altertable --agent query (stable scripting contract).
  3. CLI envelope — CLI-shaped objects such as { catalogs: [...] } from catalogs list --json, { profiles: [...] } from profile list --json, or { cli_config, profile, details } from profile show --json.

Human mode defaults management list/get output to tables unless --format is set.

Exit codes

Code Meaning
0 Success
1 Usage, validation, or unexpected CLI error
2 Authentication failed (HTTP 401)
3 Permission denied (HTTP 403)
4 Not found (HTTP 404)
5 Conflict (HTTP 409)
6 Validation error (HTTP 422)
7 Rate limited (HTTP 429)
8 Server error (HTTP 5xx)
9 Network or timeout error
10 Configuration error (missing credentials)

Error envelope

JSON error objects on stderr have the following fields: error (always true), code (stable snake_case identifier), message, exit_code, and optional details and status.

if ! out=$(altertable --json profile show 2>err.json); then
  code=$(jq -r .exit_code err.json)
  msg=$(jq -r .message err.json)
  echo "Failed ($code): $msg" >&2
  exit "$code"
fi
echo "$out" | jq .

Without --json, errors are printed as [ERROR] … lines on stderr.


Development

See DEVELOPMENT.md.

License

MIT

About

Query and manage your Altertable data platform from the terminal

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

3 watching

Forks

Packages

 
 
 

Contributors

Languages