The CLI calls the Kenso API with a Kenso API key (ken_ plus 43 characters). It sends the key as Authorization: Bearer <key> and never prints it, logs it or puts it in an error.
Log in with an API key
- In app.ken.so, go to Settings > Integrations > API keys and create a key.
- Pipe it to
kenso auth login --with-key. The key is read from stdin, never from a flag, so it stays out of your shell history and process list.
echo $KEY | kenso auth login --with-key
kenso auth login --with-key --profile client-a --workspace 1234 < key.txt
The CLI checks the key with GET /v1/me, then saves it to ~/.kenso/config.json (file mode 0600, folder mode 0700). It prints:
{"profile":"default","email":"[email protected]","workspaceId":"1234","workspaceCount":1}
When the key reaches several workspaces and you did not pass --workspace, no workspace is saved and the output carries "next":"kenso workspace list --q <name>". A key in the wrong format exits 2 (invalid_key_format). A key Kenso rejects exits 3.
Browser login
kenso auth login
kenso auth login --no-browser --device-name "build box"
Browser login is rolling out. Until it is on for your account, kenso auth login answers browser_login_unavailable (exit 3) with "next":"kenso auth login --with-key": use an API key as above.
When your workspace has it, the CLI prints a link and a code on stderr. You open the link, check the code and approve. The CLI then saves a new API key to the profile, the same kind you create in the app: it shows in your API key list, where you can revoke it. The CLI opens the browser itself only when no coding agent is detected and the machine has a display. An agent prints the link and asks you to open it. The login expires after 10 minutes (login_expired, exit 3), and a denied login exits 3 with access_denied.
CI, scripts and agents: use the environment
You do not need to log in on a machine that has the key in its environment:
export KENSO_API_KEY=ken_...
export KENSO_WORKSPACE_ID=1234
kenso auth status
KENSO_API_KEY wins over any saved profile. Store it as a secret in your CI or agent platform, never in a file in the repo.
Workspaces
A key reaches every workspace its user belongs to. Each command runs in one workspace, picked in this order:
--workspace <id>on the commandKENSO_WORKSPACE_ID- the workspace saved in the profile (
kenso workspace use)
kenso workspace list --q acme
kenso workspace use 1234
kenso campaigns list --workspace 5678
workspace list prints one page and says on stderr when there are more: add --all for every page. A command that needs a workspace when none is picked fails with workspace_required (exit 2) and "next":"kenso workspace list --q <name>".
Profiles
A profile holds a key, a workspace, an optional API URL and the email. Use one per client or per key:
kenso auth login --with-key --profile client-a < client-a-key.txt
kenso campaigns list --profile client-a
KENSO_PROFILE=client-a kenso auth status
The profile is --profile, else KENSO_PROFILE, else the active one (the last one you logged in to).
Check the setup
kenso auth status
kenso doctor
auth status prints who the key belongs to and when it expires, and warns on stderr when that is within 14 days:
{"email":"[email protected]","workspaceCount":3,"activeWorkspace":{"id":"1234","name":"Acme"},"keyExpiresAt":"2027-01-31T00:00:00Z","keySource":"profile","profile":"default"}
doctor prints the version, Node, the config folder, the profile, the key source, the API URL, the workspace and the detected agent, then four checks: node_version, config_permissions, api_reachable and key_valid. It exits 0 when every check passes, 3 when the key is missing or rejected, else 1.
Log out
kenso auth logout
kenso auth logout --profile client-a
This removes the profile and its key from this machine. The key itself stays valid until you revoke it at Settings > Integrations > API keys.
Where things live
| What | Default | Override |
|---|---|---|
| Config file with profiles and keys | ~/.kenso/config.json | KENSO_CONFIG_DIR |
| Run folders | ~/.kenso/runs/ | KENSO_RUNS_DIR |
| Cached workspace features (1 hour) | ~/.kenso/cache/ | follows KENSO_CONFIG_DIR |
| API | https://api.ken.so | KENSO_API_URL |
MCP (for kenso mcp) | https://mcp.ken.so/mcp | KENSO_MCP_URL |
--verbose prints each request line to stderr with the key redacted.