> ## Documentation Index
> Fetch the complete documentation index at: https://loops.so/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Campaigns

> Create, list, and update draft campaigns.

The `campaigns` command lets you manage [campaigns](https://loops.so/docs/api-reference/create-campaign.md) in your Loops account.

## `create`

Create a new draft campaign. This also creates an empty email message — use [`email-messages update`](https://loops.so/docs/cli/email-messages#update) to set its subject, sender, preview text, and LMX content.

```bash theme={"dark"}
loops campaigns create --name "March product update"
```

Target the campaign at an [audience segment](https://loops.so/docs/cli/audience-segments.md) and schedule it to send at a specific time:

```bash theme={"dark"}
loops campaigns create \
  --name "March product update" \
  --audience-segment-id cln0y4p6r003yl70i1j2k3l4m \
  --schedule-at 2026-07-01T12:00:00Z
```

### Flags

| Flag | Short | Description |
| - | - | - |
| `--name` | `-n` | Campaign name Required |
| `--audience-segment-id` | | [Audience segment](https://loops.so/docs/cli/audience-segments.md) ID to target. Pass `"null"` to clear. |
| `--campaign-group-id` | | [Campaign group](https://loops.so/docs/cli/campaign-groups.md) ID |
| `--mailing-list-id` | | Mailing list ID to target. Pass `"null"` to clear. |
| `--audience-filter` | | Inline JSON with an ad-hoc audience filter. Pass `"null"` to clear. |
| `--audience-filter-file` | | Path to a JSON file with an ad-hoc audience filter |
| `--schedule-at` | | Send at the given ISO 8601 timestamp (e.g. `2026-07-01T12:00:00Z`) |
| `--schedule-now` | | Send immediately when published |

> [!NOTE]
>
> `--audience-filter` and `--audience-filter-file` are two ways to supply the same ad-hoc filter, so they're mutually exclusive with each other — use `--audience-filter` for short inline JSON and `--audience-filter-file` to load it from a file. A filter can be combined with `--audience-segment-id`: when both are set, the filter is applied on top of the segment — contacts must match both. Setting a segment without a filter (or a filter without a segment) clears the other, so pass both together to keep both.

## `get`

Get a campaign by ID.

```bash theme={"dark"}
loops campaigns get cln0y4p6r003yl70i1j2k3l4m
```

The output includes a `url` field with the campaign's address in the Loops app. Every command that prints a campaign includes it.

Pass `--web` to open the campaign in the Loops web app instead of printing its details.

```bash theme={"dark"}
loops campaigns get cln0y4p6r003yl70i1j2k3l4m --web
```

### Flags

| Flag | Short | Description |
| - | - | - |
| `--web` | `-w` | Open in the Loops web app instead of printing details |

## `view`

Open a campaign in the Loops web app. Equivalent to [`get --web`](#get).

```bash theme={"dark"}
loops campaigns view cln0y4p6r003yl70i1j2k3l4m
```

## `list`

List campaigns.

```bash theme={"dark"}
loops campaigns list
```

Pass `--pick` to filter the list interactively with [fzf](https://github.com/junegunn/fzf) and copy the selected campaign ID to your clipboard. Requires `fzf` to be installed and on your `PATH`.

```bash theme={"dark"}
loops campaigns list --pick
```

### Flags

| Flag | Description |
| - | - |
| `--pick` | Interactively pick a campaign and copy its ID to the clipboard. Requires [fzf](https://github.com/junegunn/fzf). |
| `--per-page` | Results per page (10–50, default 20) |
| `--cursor` | Pagination cursor for a specific page |

## `update`

Update a draft campaign.

```bash theme={"dark"}
loops campaigns update cln0y4p6r003yl70i1j2k3l4m --name "April product update"
```

Retarget an existing campaign at a [campaign group](https://loops.so/docs/cli/campaign-groups.md) and send it immediately when published:

```bash theme={"dark"}
loops campaigns update cln0y4p6r003yl70i1j2k3l4m \
  --campaign-group-id clr4c8t0v008yl70x3y4z5a6b \
  --schedule-now
```

### Flags

| Flag | Short | Description |
| - | - | - |
| `--name` | `-n` | Campaign name |
| `--audience-segment-id` | | [Audience segment](https://loops.so/docs/cli/audience-segments.md) ID to target. Pass `"null"` to clear. |
| `--campaign-group-id` | | [Campaign group](https://loops.so/docs/cli/campaign-groups.md) ID |
| `--mailing-list-id` | | Mailing list ID to target. Pass `"null"` to clear. |
| `--audience-filter` | | Inline JSON with an ad-hoc audience filter. Pass `"null"` to clear. |
| `--audience-filter-file` | | Path to a JSON file with an ad-hoc audience filter |
| `--schedule-at` | | Send at the given ISO 8601 timestamp (e.g. `2026-07-01T12:00:00Z`) |
| `--schedule-now` | | Send immediately when published |

> [!NOTE]
>
> `--audience-filter` and `--audience-filter-file` are two ways to supply the same ad-hoc filter, so they're mutually exclusive with each other — use `--audience-filter` for short inline JSON and `--audience-filter-file` to load it from a file. A filter can be combined with `--audience-segment-id`: when both are set, the filter is applied on top of the segment — contacts must match both. Setting a segment without a filter (or a filter without a segment) clears the other, so pass both together to keep both.


## Related topics

- [Update a campaign](https://loops.so/docs/api-reference/update-campaign.md)
- [Get a campaign](https://loops.so/docs/api-reference/get-campaign.md)
- [Create a campaign](https://loops.so/docs/api-reference/create-campaign.md)
- [List campaigns](https://loops.so/docs/api-reference/list-campaigns.md)
- [Campaign groups](https://loops.so/docs/cli/campaign-groups.md)
