> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.brevo.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.brevo.com/_mcp/server.

# CLI reference

[![npm version](https://img.shields.io/npm/v/@getbrevo/cli.svg)](https://www.npmjs.com/package/@getbrevo/cli)

The Brevo CLI (`@getbrevo/cli`) lets you create and manage OAuth apps, scaffold starter code, and run a local test server — all from the terminal.

## Installation

#### npm

```bash
npm install -g @getbrevo/cli
```

#### yarn

```bash
yarn global add @getbrevo/cli
```

#### Homebrew

```bash
brew install getbrevo/tap/brevo
```

**Requirements:** Node.js >= 20.15.0 (Homebrew installs Node automatically as a dependency).

Verify:

```bash
brevo --version
```

---

## Authentication commands

### `brevo login`

Authenticate with your Brevo account via browser.

```bash
brevo login
```

Opens `oauth-cli.brevo.com` in your browser. After signing in, credentials are saved to `~/.brevo/credentials.json`.

| Flag        | Description                   |
| ----------- | ----------------------------- |
| `--browser` | Force browser login (default) |
| `--json`    | Output result as JSON         |

**Example:**

```bash
brevo login
```

---

### `brevo logout`

Clear stored credentials.

```bash
brevo logout [--force]
```

| Flag      | Description                                                         |
| --------- | ------------------------------------------------------------------- |
| `--force` | Skip confirmation prompt (required in non-interactive environments) |
| `--json`  | Output result as JSON                                               |

**Example:**

```bash
brevo logout --force
```

Logout clears cached app credentials (client ID / client secret). Run `brevo app credentials --reveal-secret` before logging out if you need to save them.

---

### `brevo whoami`

Show the currently authenticated user.

```bash
brevo whoami
```

| Flag     | Description           |
| -------- | --------------------- |
| `--json` | Output result as JSON |

**Example:**

```bash
brevo whoami
# Authenticated as you@example.com (Acme Corp)
```

---

## App commands

### `brevo app init`

Guided setup — authenticate, create an app, and optionally scaffold starter code, in one flow.

```bash
brevo app init
```

No flags. Prompts for: app name, logo URL, distribution type, app type, OAuth callback URL, output directory, and whether to scaffold the Test OAuth App feature.

**Example:**

```bash
brevo app init
```

Use this for first-time setup. For scripted or automated flows, use `brevo app create` with flags — non-interactive runs stay base-project-only, with no prompts.

---

### `brevo app create`

Create a new OAuth app.

```bash
brevo app create [--name <name>] [--distribution <type>] [--redirect-uri <url>] [--logo-uri <url>]
```

| Flag                    | Description                                                                                                                              |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `--name <name>`         | App name                                                                                                                                 |
| `--distribution <type>` | Distribution type — `private` (default)                                                                                                  |
| `--redirect-uri <url>`  | Redirect URI — repeatable to add multiple URIs                                                                                           |
| `--logo-uri <url>`      | App logo URL (`http://` or `https://`). Optional. When omitted in an interactive shell, the command prompts for it; leave blank to skip. |
| `--json`                | Output result as JSON                                                                                                                    |

**Behavior:**

* Writes only the base project (`app-config.json`, `.gitignore`, `AGENTS.md`, `CLAUDE.md`, `README.md`) first, then — interactively — asks **"Scaffold the Test OAuth App?"** (default yes) before writing the OAuth test server code. Decline to stay base-only and add it later with [`brevo app scaffold`](#brevo-app-scaffold).
* Non-interactive runs (`--json`, or piped stdin) always stay base-only — the feature prompt is skipped, not defaulted to yes.
* Hard-errors if `app-config.json` already exists in the current directory. Run `brevo app scaffold` there instead to add a feature to that project.
* Under `--json`, a target directory that already existed reports `scaffoldSkipped` (also `scaffold_skipped`) instead of `scaffolded` — see the [`--json` note](#json-errors) on why both keys appear.

**Examples:**

```bash
# Interactive
brevo app create

# Non-interactive — base project only; follow up with `brevo app scaffold`
brevo app create --name "My App" --distribution private --redirect-uri http://localhost:3009/auth/callback

# Multiple redirect URIs
brevo app create --name "My App" \
  --redirect-uri http://localhost:3009/auth/callback \
  --redirect-uri https://staging.myapp.com/auth/callback

# With a logo
brevo app create --name "My App" --distribution private --logo-uri https://example.com/logo.png
```

---

### `brevo app list`

List all OAuth apps in your account.

```bash
brevo app list
```

| Flag     | Description           |
| -------- | --------------------- |
| `--json` | Output result as JSON |

**Example:**

```bash
brevo app list --json
```

---

### `brevo app credentials`

Show credentials for an app.

```bash
brevo app credentials [--app-id <id>] [--reveal-secret]
```

| Flag              | Description                                                           |
| ----------------- | --------------------------------------------------------------------- |
| `--app-id <id>`   | Target app ID. Omit to select interactively.                          |
| `--reveal-secret` | Show the client secret (hidden by default). Prompts for confirmation. |
| `--json`          | Output result as JSON                                                 |

**Examples:**

```bash
# Show credentials (secret hidden)
brevo app credentials --app-id e22eb778-a2a8-488a-a5e8-466b6dad9385

# Reveal client secret
brevo app credentials --app-id e22eb778-a2a8-488a-a5e8-466b6dad9385 --reveal-secret
```

---

### `brevo app upload`

Renamed from `brevo app update` in **v2.1.0**. The command no longer takes `--app-id`, `--name`, `--redirect-uri`, `--scope`, or `--logo-uri` flags — edit the field in `app-config.json`, then run `brevo app upload` to push the change. Running `brevo app update` (with or without its old flags) prints this migration message and exits with code `1` — nothing is forwarded or uploaded.

Push `app-config.json` to Brevo, validated and synced with the server.

```bash
brevo app upload [--yes] [--json]
```

| Flag     | Description              |
| -------- | ------------------------ |
| `--yes`  | Skip confirmation prompt |
| `--json` | Output result as JSON    |

**Behavior:**

* Always reads `app-config.json` from the current directory and pushes the whole file — there's no flag to edit a single field remotely. To change the app's name, redirect URLs, scopes, or logo, edit the corresponding field in `app-config.json` first, then run `brevo app upload`.
* Always fetches the app's current state from Brevo and shows a local-vs-server diff before doing anything else — including under `--yes` (which only skips the confirmation prompt) and `--json`.
* No differences: exits `0` with `Already up to date at version <version>.` and makes no network push — there's nothing to write back.
* A difference: prints the diff, asks to confirm (unless `--yes` or `--json`), pushes the whole file, and writes the server-confirmed state — including the resolved `version` — back to `app-config.json`.
* `distribution_type` is immutable after `app create`. If `app-config.json` disagrees with the server, `upload` refuses locally before showing the diff or pushing anything — create a new app with [`brevo app create`](#brevo-app-create) to change distribution.
* If `auth.scopes` still contains the deprecated `all` scope, `upload` refuses and points to `brevo app available-scopes` — replace it with specific scopes first.
* Scope values are format-validated locally (`^[A-Za-z0-9][A-Za-z0-9:_.-]*$`) but **not** cross-checked against the IdP catalog. Typos surface as `invalid_scope` errors at authorization time — run `brevo app available-scopes` first to confirm the spelling.
* Errors if `app-config.json` is missing, invalid, or lacks `app_id`.

**Examples:**

```bash
# Edit app-config.json, then push the change
brevo app upload

# Skip the confirmation prompt
brevo app upload --yes

# Machine-readable output
brevo app upload --json
```

**Lost your project folder?** Recover it with [`brevo app scaffold --app-id <id>`](#brevo-app-scaffold), then edit `app-config.json` and upload.

For a **UI app** (e.g. an [action link](/docs/apps-action-links)), `upload` diffs the `ui_app` block placement by placement instead — every changed value as `before → after`, added placements tagged `(new)`, dropped ones trailing `(removed)`. Because a UI app's configuration is shared by every account it's installed in, the command also warns that the app may already be installed and asks *"Proceed with upload and update every account this app is installed in?"* before pushing. `--yes` skips that question but still prints the warning.

---

### `brevo app install`

Install a UI app into a Brevo account.

```bash
brevo app install [account-id] [--app-id <id>] [--force]
```

| Flag            | Description                                                                                                                                         |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `[account-id]`  | Optional. A regular account installs into itself; a corporate account without one is prompted to pick a sub-account — pass it explicitly in scripts |
| `--app-id <id>` | Target app ID. Omit to select interactively — the picker offers only UI apps                                                                        |
| `--force`       | Skip confirmation prompt                                                                                                                            |

**Behavior:**

* Prints the app's configuration **as stored on the server** (its version, `extension_type`, and every placement) before asking to confirm — that snapshot, not your local `app-config.json`, is what the account will render.
* Refuses an app that isn't a UI app — there's nothing for an OAuth app to render.
* No separate publish step: a successful `brevo app upload` immediately changes what every account the app is installed in renders. Installing again isn't how you push an update — see [`brevo app upload`](#brevo-app-upload).

**Example:**

```bash
brevo app install --app-id e22eb778-a2a8-488a-a5e8-466b6dad9385
```

---

### `brevo app uninstall`

Uninstall a UI app from a Brevo account. Takes the same arguments as [`brevo app install`](#brevo-app-install) — `[account-id]`, `--app-id`, `--force`.

```bash
brevo app uninstall [account-id] [--app-id <id>] [--force]
```

---

### `brevo app available-scopes`

List every OAuth scope your app can request, grouped by category. Reads the live catalog from Brevo's OAuth server.

```bash
brevo app available-scopes [--json] [--web]
```

| Flag     | Description                                                             |
| -------- | ----------------------------------------------------------------------- |
| `--json` | Output the catalog as JSON instead of a printed table                   |
| `--web`  | Open a local browser page at `127.0.0.1:<port>` with search and refresh |

**Examples:**

```bash
# Print the catalog grouped by category
brevo app available-scopes

# Machine-readable output for scripting
brevo app available-scopes --json | jq '.scopes[].name'

# Searchable browser view
brevo app available-scopes --web
```

---

### `brevo app scaffold`

Two modes, chosen by whether the current directory already has an `app-config.json`:

* **With one** — adds a feature (the OAuth test server) to the app linked there.
* **Without one** — *bootstraps*: sets the directory up for an app you already have. This is the migration path off the removed `brevo app update --app-id`.

```bash
brevo app scaffold [--app-id <id>] [--overwrite] [--json]
```

| Flag            | Description                                                                     |
| --------------- | ------------------------------------------------------------------------------- |
| `--app-id <id>` | Set an empty directory up for an app you already have (bootstrap mode)          |
| `--overwrite`   | Overwrite existing feature files instead of merging (skips the conflict prompt) |
| `--json`        | Output result as JSON                                                           |

**Bootstrap mode — recovering a project:**

* With `--app-id <id>`, fetches that app and writes `app-config.json` plus the base files (`.gitignore`, `AGENTS.md`, `CLAUDE.md`, `README.md`), then continues into the feature prompt below.
* Without `--app-id`, interactively: asks **"Set up a project for an app you already have?"** (default yes), then shows a picker of your apps — so recovery doesn't require the app's ID in hand. Declining exits `0`.
* Under `--json` or off a TTY with no `--app-id`, it raises the same "no `app-config.json`" error rather than opening a picker — scripts must pass `--app-id` explicitly.
* Also asks for an output directory (default: the app name as a slug) and creates it — answer `.` to stay in the current directory.
* Refuses, before any network call: bootstrapping into a directory that's already inside an existing app project; `--app-id` naming a different app than the one the current directory is already linked to; and an output directory that's already a *different* app's project.

**Feature mode — adding to a linked project:**

* Reads the linked app from `app-config.json`, diffs it against the server, and on drift asks to update the local file to match before writing.
* If the feature's files already exist, asks **Overwrite / Merge / Cancel** (default Merge). `--overwrite` skips that prompt.

Generates 6 files for the OAuth test server — `src/oauth/server.js`, `handler.js`, `token-store.js`, `.env.example`, `.env.local`, `package.json` — with `.env.local` pre-populated with your credentials.

**Examples:**

```bash
# Add the OAuth test server to the app linked in this directory
brevo app scaffold

# Recover a project for an app you already have
brevo app scaffold --app-id e22eb778-a2a8-488a-a5e8-466b6dad9385

# Force a full rewrite of feature files
brevo app scaffold --overwrite

# Machine-readable output
brevo app scaffold --json
```

---

### `brevo app start`

Start a scaffolded feature server locally.

```bash
brevo app start oauth [--port <port>]
```

| Argument | Description                 |
| -------- | --------------------------- |
| `oauth`  | Start the OAuth test server |

| Flag            | Description                                                                       |
| --------------- | --------------------------------------------------------------------------------- |
| `--port <port>` | Override the default port (default: read from `app-config.json`, fallback `3009`) |

Run from inside your scaffolded project directory (where `app-config.json` is). Install dependencies first:

```bash
npm --prefix src/oauth install
# or: yarn --cwd src/oauth install
```

**Examples:**

```bash
# Start on default port
brevo app start oauth

# Start on a custom port
brevo app start oauth --port 3000
```

If you change the port, add the matching redirect URL to `auth.redirect_uris` in `app-config.json`, then run `brevo app upload` to push the change.

**Auto-registration.** When the resolved port has no matching `http://localhost:<port>/...` entry on the app, the CLI prompts to register it automatically — approving pushes the new URL to Brevo and updates `app-config.json`. In non-TTY/CI mode it hard-fails instead of silently mutating the remote app; add the URL to `auth.redirect_uris` in `app-config.json` and run `brevo app upload` to register it first.

---

### `brevo app delete`

Delete an OAuth app. This action cannot be undone.

```bash
brevo app delete [--app-id <id>] [--force]
```

| Flag            | Description                                  |
| --------------- | -------------------------------------------- |
| `--app-id <id>` | Target app ID. Omit to select interactively. |
| `--force`       | Skip confirmation prompt                     |
| `--json`        | Output result as JSON                        |

**Example:**

```bash
brevo app delete --app-id e22eb778-a2a8-488a-a5e8-466b6dad9385
```

---

## Function commands

[Brevo Functions](/docs/apps-brevo-functions) are serverless functions, running on Brevo's infrastructure, that calculate a contact attribute. They're currently in **closed beta** — [join the waitlist](/docs/apps-brevo-functions#join-the-waitlist) if your account doesn't have access yet.

Every command below also works under the shorter `brevo fn` alias — `brevo fn list`, `brevo fn init`, and so on.

### `brevo function init`

Create a new Brevo Function, interactively.

```bash
brevo function init
```

| Flag     | Description           |
| -------- | --------------------- |
| `--json` | Output result as JSON |

**Behavior:**

* Interactive only — requires a terminal; refuses under `--json` or piped input.
* If you have more than one Brevo Function app, prompts you to pick which one the function belongs to.
* Asks **"How would you like to create your function?"** — **Generate using AI** (describe what it should do, then the CLI streams through generation stages) or **Use a predefined template**.
* Previews the result against sample contacts from your account before you name or deploy anything.
* On the AI path, offers to iterate — describe changes and preview again — until you choose **Deploy**.
* Prompts for a name (must be unique among your functions), then warns **"This will activate the function and run it with real-time data"** before the final confirmation.

**Example:**

```bash
brevo function init
# or:
brevo fn init
```

---

### `brevo function deploy`

Deploy a draft Brevo Function — one generated by an earlier `brevo function init` session that wasn't deployed at the time.

```bash
brevo function deploy [--id <draft-id>] [--app-id <id>] [--json]
```

| Flag            | Description                                                                     |
| --------------- | ------------------------------------------------------------------------------- |
| `--id <id>`     | Draft ID to deploy. Shows a picker if omitted (interactive only)                |
| `--app-id <id>` | Brevo Function app to link the deployed function to. Prompts for one if omitted |
| `--json`        | Output result as JSON                                                           |

**Behavior:**

* `brevo function list --draft` shows draft IDs — drafts expire, so don't leave one unfinished for too long.
* Off a TTY (or under `--json`) with no `--id`, the draft picker can't be shown — pass `--id` explicitly.
* Runs the same sample-contact preview, naming, and deploy confirmation as `brevo function init` before activating.
* If deploy succeeds but linking to the app fails, the function is still deployed — the command reports the link failure separately rather than rolling back.

**Example:**

```bash
brevo function deploy --id draft-001 --app-id my-app-id --json
```

---

### `brevo function list`

List the Brevo Functions in your account.

```bash
brevo function list [--draft] [--json]
```

| Flag      | Description                                                      |
| --------- | ---------------------------------------------------------------- |
| `--draft` | List draft functions (not yet deployed) instead of deployed ones |
| `--json`  | Output result as JSON                                            |

**Example:**

```bash
brevo function list
brevo function list --draft
```

---

### `brevo function get`

Show one function's details — status, description, and formula.

```bash
brevo function get [--id <id>] [--json]
```

| Flag        | Description                            |
| ----------- | -------------------------------------- |
| `--id <id>` | Function ID. Shows a picker if omitted |
| `--json`    | Output result as JSON                  |

**Example:**

```bash
brevo function get --id fn-001
```

---

### `brevo function activate`

Activate a function so it runs and updates its linked contact attribute again.

```bash
brevo function activate [--id <id>] [--json]
```

| Flag        | Description                            |
| ----------- | -------------------------------------- |
| `--id <id>` | Function ID. Shows a picker if omitted |
| `--json`    | Output result as JSON                  |

**Example:**

```bash
brevo function activate --id fn-001
```

---

### `brevo function deactivate`

Deactivate a function without deleting it — it stops running but stays in your account.

```bash
brevo function deactivate [--id <id>] [--json]
```

| Flag        | Description                            |
| ----------- | -------------------------------------- |
| `--id <id>` | Function ID. Shows a picker if omitted |
| `--json`    | Output result as JSON                  |

**Example:**

```bash
brevo function deactivate --id fn-001
```

---

### `brevo function delete`

Delete a deployed Brevo Function. This action cannot be undone.

```bash
brevo function delete [--id <id>] [--force] [--json]
```

| Flag        | Description                            |
| ----------- | -------------------------------------- |
| `--id <id>` | Function ID. Shows a picker if omitted |
| `--force`   | Skip confirmation prompt               |
| `--json`    | Output result as JSON                  |

**Example:**

```bash
brevo function delete --id fn-001 --force
```

---

## Claude Code skill

The CLI ships a [Claude Code](https://claude.com/claude-code) skill so you can drive `brevo` commands — creating apps, managing scopes, running the local OAuth test server — straight from Claude Code, with the CLI's conventions and guardrails loaded as context.

```bash
brevo skill:cli install
```

| Command                              | Description                               |
| ------------------------------------ | ----------------------------------------- |
| `brevo skill:cli install [--json]`   | Install the `brevo-cli` Claude Code skill |
| `brevo skill:cli uninstall [--json]` | Remove the `brevo-cli` skill              |

Once installed, every `brevo` invocation auto-refreshes the skill when the CLI ships a newer version, so the guidance stays in sync with your installed CLI.

The skill format is specific to Claude Code. Other AI agents (Cursor, Copilot CLI, Gemini, Codex) shouldn't run `brevo skill:cli install` — refer to the `agent-context/AGENTS.md` file bundled with the package instead.

---

## Exit codes

| Code | Meaning                         |
| ---- | ------------------------------- |
| `0`  | Success                         |
| `1`  | General error                   |
| `2`  | Aborted (Ctrl+C or SIGTERM)     |
| `3`  | Authentication failure (401)    |
| `4`  | Network error (API unreachable) |
| `5`  | Not found (404)                 |

---

## JSON errors

Under `--json`, a command that fails writes one JSON document to stdout describing the failure — the human-readable message still goes to stderr:

```json
{
  "error": {
    "name": "ApiError",
    "message": "App not found",
    "exitCode": 5,
    "exit_code": 5,
    "code": "APP_NOT_FOUND",
    "statusCode": 404,
    "status_code": 404
  }
}
```

| Field         | Description                                                                                                        |
| ------------- | ------------------------------------------------------------------------------------------------------------------ |
| `name`        | Error class — `CliError`, `ApiError`, `AuthExpiredError`, or `AbortError`                                          |
| `message`     | Same text printed to stderr                                                                                        |
| `exit_code`   | Process exit code. **Deprecated:** `exitCode` is the same value, kept for compatibility                            |
| `code`        | Present on an `ApiError` when Brevo's API classified the failure, e.g. `APP_NOT_FOUND`                             |
| `status_code` | Present on an `ApiError` — the HTTP status. **Deprecated:** `statusCode` is the same value, kept for compatibility |

**Every `--json` document carries each camelCase key together with its snake\_case twin** — `appId` / `app_id`, `clientId` / `client_id`, `upToDate` / `up_to_date`, and so on (`brevo app create --json`'s `redirectUri` is returned as `redirect_uris` on both spellings). Nothing is removed yet, so an existing `jq .appId` keeps working — but the camelCase keys are deprecated and will be removed in the next major version. Write new scripts and examples against the snake\_case names.

---

## `app-config.json` schema

The scaffold writes `app-config.json` to the project root. `brevo app upload` pushes this file to Brevo.

```json
{
  "app_id": "e22eb778-a2a8-488a-a5e8-466b6dad9385",
  "app_name": "my-app",
  "version": "1",
  "logo_uri": "https://example.com/logo.png",
  "distribution_type": "private",
  "app_type": "oauth",
  "auth": {
    "scopes": ["contacts:read", "contacts:write", "crm:read", "crm:write"],
    "redirect_uris": ["http://localhost:3009/auth/callback"]
  }
}
```

| Field                | Type      | Description                                                                                                                                                                                                                        |
| -------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `app_id`             | string    | App ID assigned by Brevo — do not edit                                                                                                                                                                                             |
| `app_name`           | string    | Display name of your app                                                                                                                                                                                                           |
| `version`            | string    | Read-only. Tracks the app-store API's version for this app; updated automatically after each `brevo app upload`.                                                                                                                   |
| `logo_uri`           | string    | Optional `http://` or `https://` URL to your app's logo. Empty when not set. Edit this field, then run `brevo app upload` to push it.                                                                                              |
| `distribution_type`  | string    | Always `private`. Immutable after `app create` — `brevo app upload` refuses a changed value.                                                                                                                                       |
| `app_type`           | string    | Optional label written by `brevo app create` / `brevo app scaffold`: `oauth`, `ui`, or `function`. Informational only, never sent to Brevo — the presence of `ui_app` / `brevo_function` is what actually determines the app type. |
| `auth.scopes`        | string\[] | OAuth scopes your app requests. New apps default to `["contacts:read", "contacts:write", "crm:read", "crm:write"]`. See [Scopes](/docs/oauth-scopes) for the full catalog.                                                         |
| `auth.redirect_uris` | string\[] | Registered redirect URLs — must match exactly during authorization                                                                                                                                                                 |

**Migrated from an older CLI?** Before v2.1.0, this file used `auth.redirectUrls` (now `auth.redirect_uris`) and a top-level `distribution`, with an interim `auth.type` (both now `distribution_type`). Older keys are still read — the new key wins if both are present — and the file is rewritten to the current shape the next time a command writes it (`brevo app upload`, `app start`'s redirect-URL registration, `app credentials`, or `app scaffold`). `cliVersion` and `minCliVersion` are no longer written.

**Downgrading to an older CLI?** It reads only `redirectUrls`, so a file already migrated to `redirect_uris` looks to it like it has no redirect URLs. Harmless for most commands, but `brevo app start` may then offer to register a single local callback URL as the app's *entire* `redirect_uris`, dropping every real one. Upgrade the older CLI, or keep both keys during a transition — if it already happened, restore the list and run `brevo app upload`.

**Every key in `app-config.json` is snake\_case.** Files written by earlier CLI releases used `appId`, `appName`, `logoUri`, `appType`, and `auth.redirectUris`. The CLI still reads those and rewrites the file with the snake\_case keys the next time it writes it — including a `brevo app upload` or `brevo app scaffold` run that has nothing else to change. If your own scripts read `app-config.json`, switch them to the new names. Downgrading to an older CLI has the same caveat as the `redirectUrls` rename above: it reads only the camelCase keys, so a migrated file looks empty to it.

The scaffolded OAuth test server reads `auth.scopes` from `app-config.json` and joins it with spaces for the `scope=` query parameter. If the file is missing or unreadable, it falls back to an internal default that won't match your app's registered scopes — keep `app-config.json` in your project root and unmodified.

---

## Upgrading

#### npm

```bash
npm install -g @getbrevo/cli@latest
```

#### yarn

```bash
yarn global add @getbrevo/cli@latest
```

#### Homebrew

```bash
brew upgrade getbrevo/tap/brevo
```

The CLI checks for new versions after each command and prints a banner when one is available. Pass `--no-update-notifier` or set `BREVO_NO_UPDATE_NOTIFIER=1` to suppress it.