CLI Reference

Every banatie command: exact syntax, what it does, and what it prints.

Install

No install needed: run any command with npx (Node 18 or newer):

Run without installing
npx @banatie/cli <command>

Prefer a global banatie binary? Install once:

Global install
npm install -g @banatie/cli
Examples below use npx @banatie/cli and acme as the organization slug: replace it with yours. With a global install, drop the npx @banatie/cli prefix and use banatie.

Commands at a Glance

Command
What it does
signup <email> [--org-name <name>]Request the one-time login email for your address
org <org-slug> login <bnt_boot-token>Exchange the emailed one-time token for a permanent org token
org <org-slug> auth statusShow local login state (token preview only)
org <org-slug> auth logoutRemove the local login; the server token stays valid
org <org-slug> auth revokeInvalidate the token on the server and remove the local login
org <org-slug> auth rotateReplace the org token; the old one stops working
org <org-slug> project new <project-slug>Create a project (mints its first API key server-side)
org <org-slug> project listList the organization’s projects (metadata only)
org <org-slug> project connect <project-slug> --project-root <path>Link a local directory to a project (.banatie/project.json)
org <org-slug> project issue-api-key <project-slug> [--write-env <path>]Mint a new project API key
org <org-slug> project delete <project-slug> [<one-time-token>]Two-step destructive project delete
issue-api-key [--write-env <path>]Same as project issue-api-key, auto-detected from a connected directory

Auth Commands

These manage your personal organization token. How the login email works and where the token lives is covered in the authentication walkthrough.

signup

Request a login email
npx @banatie/cli signup [email protected]

Asks the server to email you the one-time login command. The reply is neutral by design, so it never reveals whether the address already has an account:

Output
Requested a login email for [email protected].
Check your inbox and run the one-time command from that email to finish login.

By default the organization name and slug derive from your email's local part. Seed them yourself with --org-name:

Signup with an organization name
npx @banatie/cli signup [email protected] --org-name "My Company"

login

Log in
npx @banatie/cli org acme login <bnt_boot-token>

Exchanges the one-time bnt_boot_ token from your login email for a permanent org token and stores it locally. Output:

Output
Logged in to organization "acme" ([email protected]).
Backend: https://api.banatie.app
Token: bnt_org_...4f2a1c
Config: ~/.banatie/config.json

auth status

Check login state
npx @banatie/cli org acme auth status

Reports the local login for that org and backend, never the raw token:

Output
Organization: acme
Backend: https://api.banatie.app
Email: [email protected]
Token: bnt_org_...4f2a1c

Not logged in? Every org-authenticated command prints the same hint:

Not-logged-in output
Not logged in to "acme" on https://api.banatie.app.
Run: banatie org acme login <bnt_boot-token>

auth logout

Log out locally
npx @banatie/cli org acme auth logout
Output
Logged out of "acme" locally.
Note: the organization token is still valid on the server. Run "auth revoke" to invalidate it.

auth revoke

Revoke the token
npx @banatie/cli org acme auth revoke
Output
Revoked the organization token for "acme" and removed local login.

auth rotate

Rotate the token
npx @banatie/cli org acme auth rotate

The old token is invalidated and the replacement is stored in the same call: use this first if you suspect a leak:

Output
Rotated the organization token for "acme".
New token: bnt_org_...9b21e4

Project Commands

project new

Create a project
npx @banatie/cli org acme project new my-app

Creates the project and mints its first API key server-side in one atomic step. Slugs use letters, numbers, and hyphens:

Output
Created project "my-app" (my-app) in "acme".
Key: bnt_...c5ddfa
Connect this repo:
  npx @banatie/cli org acme project connect my-app --project-root .

project list

List projects
npx @banatie/cli org acme project list
Output
Projects in "acme":
  my-app  —  my-app  (2026-07-05T17:55:54.567Z)

project connect

Connect a directory
npx @banatie/cli org acme project connect my-app --project-root .

Writes .banatie/project.json under the given root (--project-root defaults to the current directory). No key is minted: that's what issue-api-key is for:

Output
Connected project "my-app" in "acme" to Banatie.
Wrote: /path/to/your/repo/.banatie/project.json
Backend: https://api.banatie.app
Run `banatie org acme project issue-api-key my-app --write-env .env` to mint an API key.
Add .banatie/ to your .gitignore so the project link is not committed.

project issue-api-key

Mint a key into an env file
npx @banatie/cli org acme project issue-api-key my-app --write-env .env
Output
Issued a new API key for project "my-app".
Written to: /path/to/your/repo/.env
Key: bnt_...c5ddfa
Each call mints a new server-side key. Add the env file to .gitignore.

Without --write-env, the raw key goes to stdout instead:

stdout form
BANATIE_API_KEY=bnt_<your-key>
# Key: bnt_...c5ddfa
# Each call mints a new server-side key.

Inside a connected directory the short form needs no slugs: it walks up from the current directory to find .banatie/project.json:

Auto-detect form
npx @banatie/cli issue-api-key --write-env .env

project delete

Destructive and two-step. Step 1: request; nothing is deleted:

Step 1: request
npx @banatie/cli org acme project delete my-app
Output
A one-time delete confirmation for "my-app" was emailed to the organization owner.
Nothing has been deleted yet. Run the one-time command from that email to confirm.

Step 2: confirm with the emailed token. The CLI asks for interactive confirmation and refuses to run outside a real terminal:

Step 2: confirm
npx @banatie/cli org acme project delete my-app <one-time-token>
Non-TTY output
Refusing to delete non-interactively.
Run this in a terminal to confirm: banatie org acme project delete my-app <one-time-token>

Configuration

Variable
Default
Purpose
BANATIE_API_BASE_URLhttps://api.banatie.appWhich backend commands talk to
BANATIE_HOME~/.banatieWhere the CLI stores its config

Two files hold all CLI state:

~/.banatie/config.json: your login profiles, one per backend + organization pair: backend URL, org slug, email, the org token, and timestamps. This is the only place the permanent token lives.

.banatie/project.json (per repository): the project link written by project connect: backend URL, org slug, project slug, project id, and the connect timestamp. It holds no keys, but keep it out of version control anyway.

Profiles are scoped per backend, so you can be logged in to production and a local dev API at the same time: e.g. BANATIE_API_BASE_URL=http://localhost:3000 npx @banatie/cli org acme auth status.

Next Steps