CLI
Run the Deck Public API from your terminal with the official deck command.
CLI
@deck-io/cli is a command-line wrapper for the Deck Public API. The binary name is deck. It requires Node.js 20 or later.
The CLI talks to the Public API with a secret API key (dk_…). Organization is resolved from that key — you never pass orgId.
Install and run
The CLI package lives in this repo at packages/deck-cli. npm registry publish is not available yet, so run it from the monorepo:
pnpm --filter @deck-io/cli build
pnpm --filter @deck-io/cli exec deck --helpAfter a local build you can also run the bin directly:
node packages/deck-cli/dist/bin.js --helpDo not run npm publish for this package.
Once a maintainer publishes @deck-io/cli to npm, the intended install will be npm i -g @deck-io/cli or npx @deck-io/cli. That path is not available today.
Create a key
- Enable the Public API in Settings → Deck API
- Create a secret API key (
dk_us_…,dk_eu_…, ordk_au_…) - Copy the full secret immediately — Deck only shows it once
Publishable widget keys (pk_…) are not accepted. Widget ingest uses the Feedback SDK (@deck-io/feedback), not this CLI.
Login, logout, whoami
deck login --api-key dk_us_your_key_here
deck whoami
deck logoutdeck login stores the key in ~/.config/deck/config.json (file mode 0600, directory 0700). deck whoami calls GET /me and prints the Public API identity envelope. deck identity get is the generated equivalent of the same operation; whoami stays as a shortcut.
API key precedence
--api-keyDECK_API_KEY~/.config/deck/config.json
Host precedence
--base-urlDECK_API_BASEhttps://api.getdeck.io/api/v1
deck whoami --base-url https://api.getdeck.io/api/v1Output
JSON stdout matches the Public API envelope. Choose a format with --output:
| Flag | Result |
|---|---|
--output json | Compact JSON (default) |
--output pretty | Indented JSON |
--output table | Columns when data is an array of objects; otherwise pretty JSON |
Errors go to stderr as { "error": { "code": "...", "message": "..." } }. The CLI never prints your API key.
Writes
Mutating commands send Idempotency-Key. Deck generates a UUID unless you pass --idempotency-key. The key is printed on stderr so you can retry safely.
| Flag | Behavior |
|---|---|
--dry-run | Print method, URL, redacted headers, and body to stderr. Does not send. |
--yes | Skip confirmation for destructive requests (DELETE, or archive/delete in the path) |
--idempotency-key <key> | Use this 1–128 character key instead of a generated UUID |
When stdin is not a TTY, destructive commands require --yes. Without it the CLI exits non-zero and does not send the request.
Pagination
Each invocation sends one HTTP request. There is no --all.
Use the query flags the OpenAPI operation declares:
--limit--cursor(cursor pages)--offset(offset pages)
When pagination.has_more is true, pass the returned cursor or the next offset on a second command.
Command shape
Generated commands follow:
deck <resource> <verb> [--path-flags] [--query-flags] [--body JSON]Resource names come from OpenAPI tags (themes, insights, identity, build, …). Path parameters are required kebab flags ({themeId} → --theme-id). Request bodies accept --body JSON; some operations also accept scalar field flags such as --action.
Escape hatch for any path:
deck api GET /me
deck api GET /themes --limit 10Examples
deck themes list --limit 10 --output pretty
deck insights get --insight-id 11111111-1111-4111-8111-111111111111
deck themes create --body '{"name":"Onboarding"}'
deck build projects --action create --body '{"title":"Roadmap"}'
deck themes delete --theme-id 11111111-1111-4111-8111-111111111111 --yesdeck --help lists resource groups. deck themes list --help shows listThemes and the query flags from the spec.
Widget ingest
The CLI does not wrap POST /widgets/feedback. In-product widget ingest uses publishable keys and @deck-io/feedback. Manage those keys in Settings → Feedback Widget SDK, not Settings → Deck API.