# Agents CLI

> Install the Broadcast CLI to manage subscribers, broadcasts, sequences, templates, opt-in forms and every other part of the channel API from the terminal, or to wire your AI agents into email marketing.

Source: https://sendbroadcast.net/docs/agents-cli

The `broadcast` CLI is a lightweight command-line tool that wraps the Broadcast REST API. It's a single bash script with no dependencies beyond `curl` and optionally `jq`.

## Installation

Install the CLI with a single command:

```bash
curl -fsSL https://your-instance.com/agents/install | bash
```

This downloads the `broadcast` script to `~/.local/bin/broadcast` and makes it executable. The install script also detects your shell and adds `~/.local/bin` to your `PATH` if needed.

Note

Replace `your-instance.com` with your actual Broadcast instance URL. You can find the exact install command on the **Agents** page in your Broadcast dashboard.

## Authentication

After installation, authenticate with your API token:

Note

Use a **channel** API token. The CLI does not send `broadcast_channel_id`, which every channel-scoped request made with an admin API token requires. Admin-only work, such as managing users, goes through the API directly: see [Users API](https://sendbroadcast.net/docs/api-users).

```bash
broadcast login --token=YOUR_API_TOKEN --host=https://your-instance.com
```

This saves your credentials to `~/.config/broadcast/config` with restricted permissions (`chmod 600`).

### Verify Your Connection

```bash
broadcast whoami
```

This calls `GET /api/v1/whoami` and displays your token type, permissions, and channel information.

## Discovering Capabilities

Use the `prime` command to see everything your token can do:

```bash
broadcast prime
```

This returns a full capabilities manifest including:

- Platform information (version, host, mode)
- Your token type and permissions
- Channel status (subscriber count, email server readiness)
- Available API endpoints grouped by resource
- Rate limit information
- Usage tips

## Command Reference

### Authentication & Discovery

| Command | Description |
|---------|-------------|
| `broadcast login --token=X --host=Y` | Save credentials and verify connection |
| `broadcast whoami` | Show token info and permissions |
| `broadcast prime` | Show full capabilities manifest |
| `broadcast status` | Show channel health and readiness |

### Subscribers

| Command | Description |
|---------|-------------|
| `broadcast subscribers` (or `broadcast subscribers list`) | List subscribers |
| `broadcast subscribers find --email=X` | Find a subscriber by email |
| `broadcast subscribers create --email=X` | Create a new subscriber. Optional: `--first-name=X`, `--last-name=X`, and `--tag=X` (repeat it for several tags) |
| `broadcast subscribers update --email=X` | Update a subscriber: `--first-name=X`, `--last-name=X`, or `--data=JSON` |
| `broadcast subscribers tag --email=X --tag=Y` | Add a tag to a subscriber |
| `broadcast subscribers untag --email=X --tag=Y` | Remove a tag from a subscriber |
| `broadcast subscribers deactivate --email=X` | Deactivate a subscriber (`activate` reverses it) |
| `broadcast subscribers unsubscribe --email=X` | Unsubscribe a subscriber (`resubscribe` reverses it) |
| `broadcast subscribers redact --email=X --yes` | Erase a subscriber's personal data. This cannot be undone, so `--yes` is required |

### Broadcasts

| Command | Description |
|---------|-------------|
| `broadcast broadcasts` (or `broadcast broadcasts list`) | List broadcasts |
| `broadcast broadcasts show ID` | Show broadcast details |
| `broadcast broadcasts create --subject=X --body=Y` | Create a draft broadcast (or `--data=JSON`) |
| `broadcast broadcasts update ID` | Change `--subject`, `--body`, `--preheader`, or send `--data=JSON` |
| `broadcast broadcasts delete ID` | Delete a draft or scheduled broadcast |
| `broadcast broadcasts send ID` | Send a broadcast |
| `broadcast broadcasts schedule ID --at=ISO8601 [--timezone=Area/City]` | Schedule a broadcast |
| `broadcast broadcasts cancel-schedule ID` | Cancel a scheduled send |
| `broadcast broadcasts stats ID` | Show broadcast statistics |
| `broadcast broadcasts timeline ID` | Opens and clicks over time |
| `broadcast broadcasts links ID` | Clicks per link |

### Sequences

| Command | Description |
|---------|-------------|
| `broadcast sequences` (or `broadcast sequences list`) | List sequences |
| `broadcast sequences show ID [--steps]` | Show sequence details, with its steps if asked |
| `broadcast sequences create --label=X [--init-tag=X]` | Create a sequence (or `--data=JSON`) |
| `broadcast sequences update ID --init-tag=X` | Set the sequence's entry tag. `--init-tag=` clears it; `--label=X` renames the sequence |
| `broadcast sequences delete ID` | Delete a sequence |
| `broadcast sequences subscribers ID` | List the subscribers in a sequence |
| `broadcast sequences add ID --email=X` | Enroll a subscriber in a sequence |
| `broadcast sequences remove ID --email=X` | Remove a subscriber from a sequence |
| `broadcast sequences steps list SEQ_ID` | List a sequence's steps |
| `broadcast sequences steps show SEQ_ID STEP_ID` | Show one step (`delete` removes it) |
| `broadcast sequences steps create SEQ_ID --data=JSON` | Add a step |
| `broadcast sequences steps update SEQ_ID STEP_ID --data=JSON` | Change a step |
| `broadcast sequences steps move SEQ_ID STEP_ID --under=PARENT_ID` | Move a step under another step |

#### Moving subscribers between sequences

A sequence with an entry tag enrolls every subscriber who gains that tag, and removes them when the tag is taken away. Their history in the sequence is kept, and gaining the tag again later does not restart it.

Setting an entry tag on a sequence does not enroll subscribers who already have that tag; it applies from then on. A tag also never removes a subscriber you added with `broadcast sequences add`, so direct and tag-based enrollment can be mixed safely.

For example, to move a customer from a trial sequence to a customer sequence when they pay:

```bash
# One time: give each sequence an entry tag
broadcast sequences update 11 --init-tag=trial
broadcast sequences update 12 --init-tag=customer

# At signup
broadcast subscribers create --email=jane@example.com --first-name=Jane --tag=trial

# When they pay
broadcast subscribers untag --email=jane@example.com --tag=trial
broadcast subscribers tag --email=jane@example.com --tag=customer
```

You can also move a subscriber directly with `broadcast sequences remove 11 --email=jane@example.com` followed by `broadcast sequences add 12 --email=jane@example.com`. Both print a result: `enrolled`, `already_enrolled` or `removed`. `remove` exits with code 3 if the subscriber was not in the sequence.

`broadcast subscribers create --tag=X` adds the tags to the subscriber's existing ones, so running it for an address that is already subscribed never drops their other tags.

### Templates and Design

| Command | Description |
|---------|-------------|
| `broadcast templates` (or `list`) | List templates |
| `broadcast templates show ID` | Show a template (`delete ID` removes it) |
| `broadcast templates create --label=X --subject=X --body=X` | Create a template (or `--data=JSON`) |
| `broadcast templates update ID --subject=X` | Change `--label`, `--subject`, `--body`, `--preheader`, or send `--data=JSON` |
| `broadcast design` (or `show`) | Show the channel's email design (colors, fonts, logo) |
| `broadcast design update --data=JSON` | Change the brand kit (2.46.0 or later, Channel Settings write), for example `--data='{"channel_design":{"colors":{"accent":"#ff5500"}}}'`. See [Brand Kit API](https://sendbroadcast.net/docs/api-channel-design) |

### Channel Settings

Requires Broadcast 2.46.0 or later, and a token with the Channel Settings permissions.

| Command | Description |
|---------|-------------|
| `broadcast settings` (or `show`) | Show the channel settings: general, sender, unsubscribe page (with the legal links) and confirmation page |
| `broadcast settings update --data=JSON` | Change some settings, for example `--data='{"channel_settings":{"unsubscribe_page":{"legal_notice_url":"https://example.com/impressum"}}}'`. See [Channel Settings API](https://sendbroadcast.net/docs/api-channel-settings) |

### Segments

| Command | Description |
|---------|-------------|
| `broadcast segments` (or `list`) | List segments |
| `broadcast segments show ID` | Show a segment and its matching subscribers (`--page=N`) |
| `broadcast segments create --data=JSON` | Create a segment with its rules |
| `broadcast segments update ID --data=JSON` | Change a segment |
| `broadcast segments delete ID` | Delete a segment |

### Topics

| Command | Description |
|---------|-------------|
| `broadcast topics` (or `list`) | List subscriber topics |
| `broadcast topics show ID` | Show a topic |
| `broadcast topics create --data=JSON` | Create a topic, e.g. `--data='{"topic":{"name":"Webinars","custom_data_key":"sub_webinars"}}'` |
| `broadcast topics update ID --data=JSON` | Change a topic |
| `broadcast topics delete ID` | Delete a topic (refused while a broadcast or sequence uses it) |

### Opt-In Forms

| Command | Description |
|---------|-------------|
| `broadcast opt-in-forms` (or `list`) | List forms. Filter with `--param filter=X`, `--param enabled=true` |
| `broadcast opt-in-forms show ID` | Show a form with its blocks and settings |
| `broadcast opt-in-forms create --data=JSON` | Create a form |
| `broadcast opt-in-forms update ID --data=JSON` | Change a form |
| `broadcast opt-in-forms delete ID` | Delete a form |
| `broadcast opt-in-forms analytics ID [--start-date=X] [--end-date=X]` | Daily views and signups (dates as `YYYY-MM-DD`) |
| `broadcast opt-in-forms duplicate ID [--label=X]` | Copy a form |
| `broadcast opt-in-forms variant ID [--name=X] [--weight=N]` | Create an A/B test variant |
| `broadcast opt-in-forms thanks ID --heading=X --text=X` | Set the view shown after a signup |
| `broadcast opt-in-forms thanks --all --heading=X --text=X` | Do the same for every form in the channel |
| `broadcast opt-in-forms thanks ID --reset` | Bring back the built-in thank-you message |

#### Changing the thank-you message

After a signup, a form shows its post-submission view. `thanks` replaces that view with a heading and one or more text blocks, in the order you give them. Repeat `--text` for more paragraphs. Text is HTML and is shown as written.

With double opt-in, use it to tell new subscribers to click the confirmation link:

```bash
broadcast opt-in-forms thanks --all \
  --heading="One more step: check your email" \
  --text="We just sent you an email with a confirmation link. Click that link to start getting the newsletter." \
  --text="No email after a few minutes? Look in your spam, junk or promotions folder."
```

`thanks` is safe to run again: a form that already shows these blocks is not changed. `--all` reads the form list, so it needs `jq` or `python3`. It prints one line per form, `{"id":15,"result":"updated"}` or `{"id":15,"result":"failed","exit":3}`, continues after a failure, and exits with a non-zero code if any form failed. A/B variants are not in the form list; update one with `thanks VARIANT_ID`.

The API behind it is described in [Opt-In Forms API](https://sendbroadcast.net/docs/api-opt-in-forms).

### Transactional Email

| Command | Description |
|---------|-------------|
| `broadcast transactionals send --to=X --subject=X --body=X` | Send one email. Use `--template-id=N` in place of subject and body; `--reply-to`, `--preheader` are optional; or send `--data=JSON` |
| `broadcast transactionals show ID` | Show a sent transactional email |

### Email Servers

| Command | Description |
|---------|-------------|
| `broadcast email-servers` (or `list`) | List email servers |
| `broadcast email-servers show ID` | Show an email server (`delete ID` removes it) |
| `broadcast email-servers create --data=JSON` | Add an email server |
| `broadcast email-servers update ID --data=JSON` | Change an email server |
| `broadcast email-servers test ID` | Test the server's connection |

### Webhook Endpoints

| Command | Description |
|---------|-------------|
| `broadcast webhook-endpoints` (or `list`) | List webhook endpoints |
| `broadcast webhook-endpoints show ID` | Show an endpoint (`delete ID` removes it) |
| `broadcast webhook-endpoints create --data=JSON` | Add an endpoint |
| `broadcast webhook-endpoints update ID --data=JSON` | Change an endpoint |
| `broadcast webhook-endpoints test ID [--event-type=X]` | Send a test event |
| `broadcast webhook-endpoints deliveries ID` | List recent deliveries |

### Autopilots

| Command | Description |
|---------|-------------|
| `broadcast autopilots` (or `list`) | List autopilots |
| `broadcast autopilots show ID` | Show an autopilot (`delete ID` removes it) |
| `broadcast autopilots create --data=JSON` | Create an autopilot |
| `broadcast autopilots update ID --data=JSON` | Change an autopilot |
| `broadcast autopilots activate ID` | Activate (also `pause ID`, `deactivate ID`) |
| `broadcast autopilots run ID [--version=N]` | Queue a generation run |
| `broadcast autopilots runs ID` | List generation runs |

### Suppressions

| Command | Description |
|---------|-------------|
| `broadcast suppressions` (or `list`) | List the channel's suppressed addresses |
| `broadcast suppressions check --email=X` | Is this address suppressed, on the channel or globally? |
| `broadcast suppressions add --email=X` | Suppress an address (`remove` takes it off) |
| `broadcast suppressions bulk-add --emails=a@x.com,b@y.com` | Suppress many addresses (`bulk-remove` takes them off), or send `--data=JSON` |

### Any Endpoint

`broadcast api METHOD PATH [--data=JSON]` calls any endpoint and prints the response, for example `broadcast api GET /api/v1/prime`. Use it for anything the commands above do not cover.

### Options for Every Command

- **List commands** take `--page=N`, `--limit=N` and `--offset=N`, and `--param KEY=VALUE` (repeatable) for any other filter the API takes. For example: `broadcast subscribers list --param is_active=true --param "tags[]=vip"`.
- **Create and update commands** take `--data` with the request body exactly as the API expects it: `--data='{"template":{"label":"Welcome"}}'`, `--data=@template.json` to read a file, or `--data=-` to read standard input. The API reference pages list every field.

The CLI uses channel tokens, so admin-only endpoints (users, the global suppression list, copying an email server to another channel) are not commands. Call them through the API.

### General

| Command | Description |
|---------|-------------|
| `broadcast help` | Show command reference |
| `broadcast version` | Show the installed CLI version |
| `broadcast upgrade` | Replace the CLI with the latest version from your Broadcast instance |

The CLI is served by your own Broadcast instance, so after you upgrade Broadcast, run `broadcast upgrade` to pick up any new commands. It downloads the current script from `https://your-instance.com/agents/cli` (the host you logged in with) and installs it over the existing one.

## Output Formats

By default, the CLI outputs JSON. For human-readable output, use the `--format=table` flag:

```bash
broadcast subscribers --format=table
```

## Exit Codes

| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | Authentication error |
| 2 | Resource not found |
| 3 | Validation error |
| 4 | Server error |

## Configuration

The CLI stores its configuration at `~/.config/broadcast/config`:

```
BROADCAST_HOST=https://your-instance.com
BROADCAST_TOKEN=your-api-token
```

This file is created with `chmod 600` (owner read/write only) for security.

## Using with AI Agents

The CLI is designed to be used by AI agents. When you paste the introduction message from the Agents dashboard into an agent like Claude Code, it can use the `broadcast` CLI to manage your email marketing automatically.

Example agent workflow:

```
Agent: Let me check your Broadcast status.
> broadcast status

Agent: You have 1,234 active subscribers. Let me create a newsletter draft.
> broadcast broadcasts create --subject="Weekly Update" --body="<h1>This Week</h1>..."

Agent: Draft created (ID: 42). Would you like me to send it?
> broadcast broadcasts send 42
```
