Hotdata CLI
Command line interface for Hotdata.
Query, search, and join your data from one place — live databases, APIs, cloud storage, Iceberg catalogs, and files you upload — with plain SQL and a few commands.
Homebrew
brew install hotdata-dev/tap/cliBinary (macOS, Linux) — download from Releases.
From source (requires Rust)
cargo install --path .Stay current with hotdata upgrade, and enable tab completion with
hotdata completions bash|zsh|fish.
# 1. Sign in (or create an account with `hotdata auth register`)
hotdata auth login
# 2. Create a database and load some data — any parquet file, local or by URL
hotdata databases create --catalog demo
hotdata databases load --catalog demo --table trips \
--url https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2024-01.parquet
# 3. Query it
hotdata query "SELECT count(*) AS trips, round(avg(fare_amount), 2) AS avg_fare
FROM demo.public.trips"That's the core loop: create a managed database, put data in it, query it with PostgreSQL-dialect SQL. Everything else builds on that.
There are two ways to make your data queryable, and they compose:
- Connect — a live, synced view of an external source. The data stays where it is; Hotdata keeps the schema and cache fresh.
- Import — copy data into a managed database, either from a file you
have or from an external source via
hotdata ingest.
hotdata connections new # guided wizard
# or non-interactively:
hotdata connections create --name "prod-replica" --type postgres \
--config '{"host":"db.example.com","port":5432,"user":"reader","database":"app","password":"'"$DB_PASSWORD"'"}'
hotdata tables list # see what's now queryablehotdata connections create list shows every supported type, and
hotdata connections create list <type> -o json prints the exact config
fields it takes.
Pull data from SQL databases, APIs, S3/GCS/Azure buckets, or Iceberg catalogs into a managed database:
hotdata ingest datasources # browse: SQL dialects, ~150 API services,
# buckets, iceberg, api (bring-your-own)
# Add a datasource — validates credentials and discovers the schema, loads no data.
# Keep secrets out of argv with --config @file.json or @- (stdin):
hotdata ingest new-datasource --service postgres --config @conn.json --schema public
hotdata ingest new-datasource --service buckets --bucket-url s3://bucket/prefix --format parquet
hotdata ingest new-datasource --service iceberg --config @catalog.json --table ns.orders
# --name sets the FROM target (default: the connector name), so several
# datasources of one connector can coexist:
hotdata ingest new-datasource --service postgres --name prod_pg --config @conn.json
# Import — a plain SELECT against the datasource; returns immediately:
hotdata ingest new-import "SELECT * FROM prod_pg.orders WHERE status = 'open'"
hotdata ingest new-import --source prod_pg --all
hotdata ingest status <import-id> --wait # or one-shot: exits 0 done / 1 failed / 2 running
# The import lands in a managed database — query it like any other:
hotdata query --database <db-id> "SELECT count(*) FROM public.orders"Public buckets need no credentials. Re-run an import any time with
hotdata ingest trigger-import <import-id> — it refreshes the same database
from the source.
Managed databases load parquet directly (convert CSV/JSON first):
hotdata databases load --catalog demo --table listings --file ./listings.parquethotdata tables list # every queryable table, as connection.schema.table
hotdata tables list --connection-id <id> # with column names and types
hotdata query "<sql>" [-o table|json|csv] # PostgreSQL dialectLong-running queries fall back to async and print a query_run_id — poll with
hotdata query status <id> (exit codes: 0 done, 1 failed, 2 running).
Every result gets a result-id; re-fetch past results with
hotdata results <result-id> instead of re-running, and browse history with
hotdata queries list.
A query runs inside one managed database and sees its own tables plus any attached connections — attach a live source to join against it directly, no copying:
hotdata databases attach prod-replica --alias prod
hotdata query "
SELECT t.id, o.total
FROM demo.public.tickets t
JOIN prod.public.orders o ON o.ticket_id = t.id
"Create an index once, then search server-side — no embedding keys or client setup needed for vector search (the column is auto-embedded, and queries use the same model automatically):
hotdata indexes create --catalog demo --schema public --table trips \
--column notes --type bm25
hotdata search "airport surcharge dispute" --table demo.public.trips
hotdata indexes create --catalog demo --schema public --table trips \
--column notes --type vector
hotdata search "rides that mention lost items" --table demo.public.trips --type vectorSystem embedding providers come pre-configured; bring your own with
hotdata embedding-providers create.
The CLI is built to be driven programmatically:
- Every listing command takes
-o json|yaml; long-running commands expose script-friendly exit codes (query status,ingest status). - Authenticate non-interactively with an API key:
--api-key, orHOTDATA_API_KEYin the environment or a.envfile. hotdata databases run <cmd>launches a child process (an agent, a script) with credentials scoped to a single database.hotdata skills installinstalls bundled agent skills — Markdown playbooks that teach AI coding agents (Claude Code and friends) the full CLI surface.hotdata context push|show DATAMODELstores your data model as shared, server-side Markdown so humans and agents query with the same map.
Run hotdata <command> --help for full flags on any command.
| Command | What it does |
|---|---|
auth |
login, register, status, logout |
workspaces |
List workspaces, set the active one |
connections |
Live external sources: create, list, refresh |
databases |
Managed databases: create, load parquet, attach connections, scoped run |
tables |
List queryable tables and columns |
query |
Run SQL; status polls async runs |
queries / results |
Query history and stored results |
search |
BM25 and vector search over indexed columns |
indexes |
Create/list/delete sorted, bm25, vector indexes |
embedding-providers |
Manage embedding providers for vector indexes |
ingest |
Import from databases, APIs, buckets, Iceberg |
context |
Shared server-side Markdown (DATAMODEL, glossaries) |
jobs |
Background jobs (refreshes, index builds) |
skills |
Install/inspect the bundled agent skills |
completions |
Shell tab-completion scripts |
upgrade |
Upgrade the CLI in place |
Config lives at ~/.hotdata/config.yml (profile-keyed). Environment variables:
| Variable | Description | Default |
|---|---|---|
HOTDATA_API_KEY |
API key (overrides config file; also read from .env) |
|
HOTDATA_WORKSPACE |
Lock every command to one workspace | |
HOTDATA_API_URL |
API base URL | https://api.hotdata.dev/v1 |
HOTDATA_APP_URL |
App URL for browser login | https://app.hotdata.dev |
Precedence for the API key, lowest to highest: config file → HOTDATA_API_KEY → --api-key.
cargo build && cargo testRelease process: see docs/RELEASING.md.