# Commands (https://docs.billwave.example/cli/commands)

CLI Commands [#cli-commands]

Choosing an environment [#choosing-an-environment]

Every command that talks to the API needs to know which environment to target. The CLI never guesses — it resolves the **mode** from, in order:

1. `--mode sandbox` or `--mode live`
2. the `BILLWAVE_MODE` environment variable
3. the API key prefix: `billwave_sk_test_…` → sandbox, `billwave_sk_live_…` → live

With a legacy (unscoped) key and no `--mode`, the command exits with code `2` and tells you what to pass. If `--mode` contradicts the key's scope the command also refuses to run — before making any request.

`--prod` still works as a deprecated alias for `--mode live`.

Shared options [#shared-options]

| Option            | Description                                                                            |
| ----------------- | -------------------------------------------------------------------------------------- |
| `--mode <mode>`   | `sandbox` or `live`. Also `BILLWAVE_MODE`.                                             |
| `--key <api-key>` | API secret key. Also `BILLWAVE_SECRET_KEY`, else the key stored by `billwave connect`. |
| `--config <path>` | Path to `billwave.config.ts` (defaults to the usual names in the current directory).   |
| `--json`          | Print exactly one JSON document on stdout — no spinners, colours or prompts.           |

`BILLWAVE_API_URL` overrides the host for the selected mode (self-hosted / local API).

Exit codes [#exit-codes]

| Code | Meaning                                                                               |
| ---- | ------------------------------------------------------------------------------------- |
| `0`  | Success, including "nothing to do"                                                    |
| `1`  | The operation failed (API error, network error, sync rejected)                        |
| `2`  | Usage or configuration error (missing key or mode, key/mode mismatch, no config file) |
| `3`  | `diff --exit-code` found differences                                                  |

In `--json` mode failures are JSON too: `{ "ok": false, "error": { "code", "message", "hint?" }, "exitCode" }`.

init [#init]

Scaffold `billwave.config.ts` from your **sandbox** catalog. Runs `connect` first if no key is stored.

```bash
npx @digvijay-x1/billwave-cli init
```

connect [#connect]

Link the CLI to your organization through the browser. One approval issues a sandbox key and a live key; commands pick the one matching `--mode`.

```bash
npx @digvijay-x1/billwave-cli connect
```

sync [#sync]

Push your local catalog to the selected environment. Shows the diff and asks for confirmation unless `--yes` is passed.

```bash
npx @digvijay-x1/billwave-cli sync --mode sandbox
npx @digvijay-x1/billwave-cli sync --mode live --yes
```

**Options:**

* `--dry-run`: Show what would change without applying.
* `--yes`: Apply without the interactive prompt. Required together with `--json`.

**CI example** — preview, then apply:

```bash
BILLWAVE_SECRET_KEY=$SANDBOX_KEY npx @digvijay-x1/billwave-cli sync --dry-run --json
BILLWAVE_SECRET_KEY=$SANDBOX_KEY npx @digvijay-x1/billwave-cli sync --yes --json
```

`--json` output:

```json
{
  "ok": true,
  "command": "sync",
  "mode": "sandbox",
  "apiUrl": "https://sandbox.billwave.example/api/v1",
  "dryRun": true,
  "hasChanges": true,
  "applied": false,
  "changes": {
    "plans": { "added": ["pro"], "removed": [], "changed": [] },
    "features": { "added": [], "removed": [], "changed": [] },
    "creditSystems": { "added": [], "removed": [], "changed": [] },
    "creditPacks": { "added": [], "removed": [], "changed": [] },
    "total": 1
  }
}
```

When changes are applied the document also carries `"applied": true` and the server's `result` (`plans`, `features`, `creditSystems`, `creditPacks`, `warnings`).

pull [#pull]

Write the remote catalog for the selected environment into your local config.

```bash
npx @digvijay-x1/billwave-cli pull --mode sandbox
```

**Options:**

* `--force`: Overwrite an existing config file without asking.
* `--dry-run`: Print the generated config without writing it.

diff [#diff]

Compare your local config with the remote catalog.

```bash
npx @digvijay-x1/billwave-cli diff --mode live
npx @digvijay-x1/billwave-cli diff --mode live --exit-code   # exit 3 on drift, for CI
```

**Options:**

* `--exit-code`: Exit with code `3` when the catalogs differ.

validate [#validate]

Validate `billwave.config.ts` locally and confirm the selected environment is reachable with your key.

```bash
npx @digvijay-x1/billwave-cli validate --mode sandbox
```