---
title: "nextmail broadcasts"
description: "Every command in this namespace, with its arguments, flags and examples."
url: "https://nextmail.sh/docs/cli/reference/broadcasts"
area: "CLI"
category: "Reference"
---

# nextmail broadcasts

Every command in this namespace, with its arguments, flags and examples.

## Commands

### `nextmail broadcasts preview`

Count who a broadcast to some audiences would reach

```bash
nextmail broadcasts preview --audience-ids <a,b> [flags]
nextmail broadcasts preview --data <json|@file|-> [flags]
```

Returns the numbers `send` would work from, without sending or writing anything: `recipients`, the people a broadcast to these audiences would reach now, `unsubscribed`, the contacts skipped because they have unsubscribed, and `suppressed`, the subscribed contacts skipped because their address is on the suppression list. A contact in several of the audiences counts once.

The count is taken at the moment of the call, so contacts who join or leave before a send change it. Only `--audience-ids`, `--exclude-audience-ids` and `--segment-id` are sent, so you can pass the same object you are about to give `send`.

- Scopes: `audiences:read`.
- Needs a sign-in.

**Flags**

- `--audience-ids <a,b>` (repeatable): 1 to 10 audience ids. One that names no audience in the workspace is a 404 `audience_not_found`, and All contacts, which no broadcast can go to, is a 422 `audience_is_everyone`. Required, here or in `--data`.
- `--exclude-audience-ids <a,b>` (repeatable): Up to 10 audiences whose members are left out of the count, as `send` leaves them out.
- `--segment-id <value>`: A saved segment that narrows the count to the contacts that match it, as `send` narrows the broadcast.
- `--data <json|@file|->`: The whole `body` as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

**Examples**

```bash
nextmail broadcasts preview --audience-ids aud_4c1b8e2a7d9f05c36b4e8a71,aud_7e3d9a1c5b2f84e06d9a3c51
```

Read the whole body from a JSON file

```bash
nextmail broadcasts preview --data @broadcast.json
```

Also available in: API [`POST /broadcasts/preview`](https://nextmail.sh/docs/api/reference/broadcasts#post-broadcasts-preview); TypeScript [`nextmail.broadcasts.preview()`](https://nextmail.sh/docs/sdk/reference/broadcasts#preview); Python [`broadcasts.preview()`](https://nextmail.sh/docs/python/reference/broadcasts#preview); Ruby [`broadcasts.preview`](https://nextmail.sh/docs/ruby/reference/broadcasts#preview); PHP [`broadcasts->preview`](https://nextmail.sh/docs/php/reference/broadcasts#preview); Go [`Broadcasts.Preview`](https://nextmail.sh/docs/go/reference/broadcasts#preview); Java [`broadcasts().preview`](https://nextmail.sh/docs/java/reference/broadcasts#preview); C# [`Broadcasts.PreviewAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#preview).

### `nextmail broadcasts send`

Send one message to everybody in one or more audiences

```bash
nextmail broadcasts send --audience-ids <a,b> --from <value> [flags]
nextmail broadcasts send --data <json|@file|-> [flags]
```

Creates a broadcast: one message sent to every contact in the audiences you name, as a separate copy for each person. Every copy has exactly one recipient and no cc or bcc, so nobody sees who else it went to, and every copy is an ordinary email with its own `msg_` id, events, tracking and webhooks. `emails.list({ broadcastId })` lists them. Copies are not filed in the Sent folder, because the broadcast is the record.

The promise settles straight away with the broadcast `queued`, or `scheduled` when you pass `--scheduled-at`, and the sending happens in the background, 50 people at a time. Poll `get` to follow `status` and `counts` as it goes.

Who gets it: every contact in at least one of `--audience-ids`, counted once however many of them hold it, except a person who has unsubscribed and an address on the suppression list. `--audience-ids` cannot name All contacts, the built-in audience of everyone the workspace has written to, because most of them never asked for its mail: that is a 422 `audience_is_everyone`. A contact added to one of the audiences after this call but before the sending reaches it is included. `counts.recipients` is the estimate taken at the call, and `preview` returns the same count without sending.

`subject`, `html` and `text` take merge fields, filled in from each contact: `{{firstName}}`, `{{lastName}}`, `{{name}}`, `{{email}}` and `{{unsubscribeUrl}}`. Each takes a fallback after a bar, so `{{firstName|there}}` reads there for a contact with no name. The first name is the first word of the contact's name and the last name is the rest. A custom field of the contact is `{{attributes.<key>}}`, such as `{{attributes.plan|Free}}`, and reads as its fallback, or as nothing, when the contact has no such field. Values are escaped in `html`, and any other `{{…}}` is left as written. With `template`, those five values are passed as props, but only the ones the template declares, except `unsubscribeUrl`, which every template receives.

Every copy carries the one-click unsubscribe headers mail clients and the large mailbox providers look for. A body or a template that does not place `{{unsubscribeUrl}}` itself gets a short footer with the link, in English, which also names the sender and shows the postal address once `marketingPostalAddress` is set through `settings.update`. Following the link unsubscribes the person from all of the workspace's marketing mail: every audience they are in shows `unsubscribedAt`, `suppressions.listUnsubscribes` lists them, and later broadcasts and automation emails skip them, even after they are added to an audience again. Their contact and mail sent to them one message at a time are not affected.

The whole send is checked against the plan's monthly sends before anything is written. A broadcast the allowance cannot cover throws 429 `send_quota_exceeded` and leaves nothing behind, and each copy counts as one send.

- Scopes: `emails:send`, `audiences:read`.
- Needs a sign-in.
- Asks you to confirm.

**Flags**

- `--audience-ids <a,b>` (repeatable): 1 to 10 audience ids such as `aud_9f2c4b7e1a0d63d84c5f2e7b`. A contact in several of them gets one copy. An id that names no audience in the workspace is a 404 `audience_not_found` and All contacts is a 422 `audience_is_everyone`, and either way nothing is sent. Required, here or in `--data`.
- `--exclude-audience-ids <a,b>` (repeatable): Up to 10 audiences whose members are left out, even when they are in one of `--audience-ids`, such as the customers who already bought. All contacts may be named here. An id that names no audience is a 404 `audience_not_found`.
- `--segment-id <value>`: A saved segment, from `segments.create`, that narrows the audiences: only the contacts that match its conditions get a copy. Its conditions are read when the broadcast is sent or scheduled and kept with it. An id that names no segment is a 404 `segment_not_found`.
- `--from <value>`: Sender as `news@acme.com`, `Acme <news@acme.com>` or `{ email, name }`. It must be an address the key may send as, otherwise 403 `from_address_forbidden`. Required, here or in `--data`.
- `--reply-to <value>`: Where replies go, the same for every copy.
- `--subject <value>` (default `""`): Required unless a template supplies it, at most 998 characters. Takes merge fields.
- `--html <value>`: HTML body, at most 1,000,000 characters, with merge fields. Without `{{unsubscribeUrl}}` in it an unsubscribe footer is added.
- `--text <value>`: Plain text body, at most 1,000,000 characters, with merge fields. Without `{{unsubscribeUrl}}` in it an unsubscribe line is added.
- `--template <json|@file|->`: A stored template instead of `html` and `text`, never beside them. The merge values reach it as props it declares, such as `firstName`, and `unsubscribeUrl` reaches every template. JSON shaped as `{ id: string, version?: number, props?: Record<string, unknown>, slots?: Record<string, unknown> }`, inline or from a file with @path.
- `--tracking <json|@file|->`: Open and link tracking for every copy. A field left out follows the address it is sent from when that address set it, and is on otherwise. JSON shaped as `{ opens?: boolean, clicks?: boolean }`, inline or from a file with @path.
- `--tags <json|@file|->` (repeatable, default `{}`): Up to 8 tags, keys of 1 to 64 letters, digits, `_` or `-`, values up to 256 characters. Every copy carries them, plus `broadcast_id`, which the server adds.
- `--utm <json|@file|->`: Campaign tags added to every http and https link in the body as `utm_source`, `utm_medium`, `utm_campaign`, `utm_term` and `utm_content`, so the visits show up in your web analytics. A link that already carries one keeps its own, and the unsubscribe link never gets them. Values are up to 100 characters, `campaign` up to 200. JSON shaped as `{ source?: string, medium?: string, campaign?: string, term?: string, content?: string }`, inline or from a file with @path.
- `--ab-test <json|@file|->`: An A/B test. `variants` holds 2 to 4 versions, each a `subject`, or a body as `html` and or `text`, that replaces the broadcast's own, so `{}` keeps it as it is. `testPercent` of the people (5 to 50, 20 unless set) get a variant, split evenly between them, and `metric` (`opens` unless set, or `clicks`) picks the winner once `waitMinutes` (30 to 4320, 240 unless set) have passed since the test went out. Everybody else then gets the winning variant. A tie goes to the earlier variant, and a template broadcast can only vary the subject. `get` shows where the test stands in `content.abTest`, and `stats` how each variant did. JSON shaped as `BroadcastAbTest`, inline or from a file with @path.
- `--scheduled-at <when>`: A `Date`, an ISO 8601 instant or a duration such as `PT2H` or `P1D`, in the future and at most 365 days out. Left out, the sending starts straight away.
- `--idempotency-key <value>`: Your own key, 1 to 255 characters of letters, digits, `_`, `.`, `:` or `-`. Left out, the SDK makes one for the call, so its own retries never send twice. Sending the same key again answers with the broadcast it created instead of a new one; the same key with a different body is a 422 `idempotency_key_reuse`.
- `--data <json|@file|->`: The whole `body` as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

**Examples**

The required values only

```bash
nextmail broadcasts send --audience-ids aud_4c1b8e2a7d9f05c36b4e8a71 --from 'Acme <news@acme.com>'
```

With optional flags

```bash
nextmail broadcasts send --audience-ids aud_4c1b8e2a7d9f05c36b4e8a71 --from 'Acme <news@acme.com>' --subject '{{firstName|Hello}}, the September release is out' --html '<p>Hi {{firstName|there}},</p><p>Here is what changed this month.</p><p><a href="{{unsubscribeUrl}}">Unsubscribe</a></p>' --scheduled-at PT2H
```

Read the whole body from a JSON file

```bash
nextmail broadcasts send --data @broadcast.json
```

Skip the confirmation, for scripts

```bash
nextmail broadcasts send --audience-ids aud_4c1b8e2a7d9f05c36b4e8a71 --from 'Acme <news@acme.com>' --yes
```

Also available in: API [`POST /broadcasts`](https://nextmail.sh/docs/api/reference/broadcasts#post-broadcasts); TypeScript [`nextmail.broadcasts.send()`](https://nextmail.sh/docs/sdk/reference/broadcasts#send); Python [`broadcasts.send()`](https://nextmail.sh/docs/python/reference/broadcasts#send); Ruby [`broadcasts.send`](https://nextmail.sh/docs/ruby/reference/broadcasts#send); PHP [`broadcasts->send`](https://nextmail.sh/docs/php/reference/broadcasts#send); Go [`Broadcasts.Send`](https://nextmail.sh/docs/go/reference/broadcasts#send); Java [`broadcasts().send`](https://nextmail.sh/docs/java/reference/broadcasts#send); C# [`Broadcasts.SendAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#send).

### `nextmail broadcasts list`

List one page of broadcasts, newest first

```bash
nextmail broadcasts list [flags]
```

Returns one page of the broadcasts in the workspace, newest first, each with live `counts`. `--audience-id` keeps the ones that were sent to that audience, alone or beside others.

Paging is keyset: `--limit` takes 1 to 100 and defaults to 25, and `nextCursor`, the id of the last broadcast on the page, goes back as `--cursor` while `hasMore` is true. Send the same `--audience-id` with every page.

The individual messages are not here. List the copies of one broadcast with `emails.list({ broadcastId })`.

Add `--all` to walk every page: a table on a terminal, one JSON object per line when piped or with `--ndjson`, and one `{ items, hasMore, nextCursor }` document with `--json`. `--max <n>` stops after that many items.

- Scopes: `emails:read`.
- Needs a sign-in.
- Aliases: `ls`.

**Flags**

- `--audience-id <value>`: Only the broadcasts that included this audience. An id that names no audience answers an empty page.
- `--limit <n>` (default `25`): Rows per page, a whole number from 1 to 100. The server defaults to 25.
- `--cursor <value>`: The `nextCursor` from the previous page, a broadcast id. One that names no broadcast in the workspace is a 400 `invalid_cursor`.
- `--all`: Fetch every page and stream the items as they arrive.
- `--max <n>`: Stop after this many items. Implies `--all`.
- `--ndjson`: Print every item as one JSON object per line. Implies `--all`

**Examples**

```bash
nextmail broadcasts list
```

With optional flags

```bash
nextmail broadcasts list --audience-id aud_4c1b8e2a7d9f05c36b4e8a71 --limit 10
```

Walk every page and stop after 100 items

```bash
nextmail broadcasts list --all --max 100
```

One JSON object per line when piped

```bash
nextmail broadcasts list --all > broadcasts.ndjson
```

Also available in: API [`GET /broadcasts`](https://nextmail.sh/docs/api/reference/broadcasts#get-broadcasts); TypeScript [`nextmail.broadcasts.list()`](https://nextmail.sh/docs/sdk/reference/broadcasts#list); Python [`broadcasts.list()`](https://nextmail.sh/docs/python/reference/broadcasts#list); Ruby [`broadcasts.list`](https://nextmail.sh/docs/ruby/reference/broadcasts#list); PHP [`broadcasts->list`](https://nextmail.sh/docs/php/reference/broadcasts#list); Go [`Broadcasts.List`](https://nextmail.sh/docs/go/reference/broadcasts#list); Java [`broadcasts().list`](https://nextmail.sh/docs/java/reference/broadcasts#list); C# [`Broadcasts.ListAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#list).

### `nextmail broadcasts get`

Read one broadcast and how far it has got

```bash
nextmail broadcasts get <id> [flags]
```

Returns one broadcast with `counts` read live from its copies, which makes this the call to poll while it sends.

`status` moves from `scheduled` or `queued` to `sending` and settles on `sent` once every copy handed over has gone out or failed. It reads `sending` for as long as copies are still waiting, even after the last person was reached and `completedAt` was set. `cancelled` and `failed` are the other two ends, and on `failed` `lastError` says why: the `from` address can no longer be sent from, the template stopped resolving, the plan ran out part way, the sending itself kept failing, or not one copy could be written.

`counts.recipients` is the estimate taken when it was created. `created` is the copies written, one per person reached, `skipped` the people passed over because their address was suppressed by then, and `failedToQueue` the people whose copy could not be written. `queued`, `sending`, `sent`, `failed` and `cancelled` count the copies by the state each one is in now.

- Scopes: `emails:read`.
- Needs a sign-in.
- Aliases: `show`, `view`.

**Arguments**

- `<id>` (required): A `brd_` id from `send` or `list`.

**Examples**

```bash
nextmail broadcasts get brd_5a8c1e3f7b2d94a06c8e1f3b
```

Print the raw JSON

```bash
nextmail broadcasts get brd_5a8c1e3f7b2d94a06c8e1f3b --json
```

Also available in: API [`GET /broadcasts/{id}`](https://nextmail.sh/docs/api/reference/broadcasts#get-broadcasts-id); TypeScript [`nextmail.broadcasts.get()`](https://nextmail.sh/docs/sdk/reference/broadcasts#get); Python [`broadcasts.get()`](https://nextmail.sh/docs/python/reference/broadcasts#get); Ruby [`broadcasts.get`](https://nextmail.sh/docs/ruby/reference/broadcasts#get); PHP [`broadcasts->get`](https://nextmail.sh/docs/php/reference/broadcasts#get); Go [`Broadcasts.Get`](https://nextmail.sh/docs/go/reference/broadcasts#get); Java [`broadcasts().get`](https://nextmail.sh/docs/java/reference/broadcasts#get); C# [`Broadcasts.GetAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#get).

### `nextmail broadcasts stats`

Read how a broadcast performed

```bash
nextmail broadcasts stats <id> [flags]
```

Resolves with the totals and a series for one broadcast. `totals` counts copies `sent`, `delivered`, `bounced`, `complained` (reported as spam) and `failed`, `pending` for the ones still waiting, and people who `opened`, `clicked` and `unsubscribed`, with `opens` and `clicks` as event counts. `series` is sparse and oldest first: one bucket per `grain` in which something happened, counting each person once at the first time it happened to them, so it adds up to the totals.

Pass `days` or `minutes` to also read what happened lately. `window` then counts the copies delivered, bounced, reported as spam, opened, clicked and unsubscribed inside it, and `series` keeps only its buckets, while `totals` still covers the whole broadcast. Without either, `window` is null.

- Scopes: `emails:read`.
- Needs a sign-in.

**Arguments**

- `<id>` (required): A `brd_` id from `send` or `list`.

**Flags**

- `--grain <value>` (default `"hour"`): Bucket width: `minute`, `hour` or `day`, defaulting to `hour`.
- `--offset-minutes <n>` (default `0`): Minutes east of UTC to cut the buckets in, from -840 to 840. Pass `-new Date().getTimezoneOffset()` for the local zone.
- `--days <n>`: Reads a window of this many days too, from 1 to 1095. It starts at the beginning of its first `grain` bucket and ends now.
- `--minutes <n>`: The window in minutes, from 1 to 1576800, which wins over `days` when both are sent.

**Examples**

The required values only

```bash
nextmail broadcasts stats brd_5a8c1e3f7b2d94a06c8e1f3b
```

With optional flags

```bash
nextmail broadcasts stats brd_5a8c1e3f7b2d94a06c8e1f3b --grain day
```

Print the raw JSON

```bash
nextmail broadcasts stats brd_5a8c1e3f7b2d94a06c8e1f3b --json
```

Also available in: API [`GET /broadcasts/{id}/stats`](https://nextmail.sh/docs/api/reference/broadcasts#get-broadcasts-id-stats); TypeScript [`nextmail.broadcasts.stats()`](https://nextmail.sh/docs/sdk/reference/broadcasts#stats); Python [`broadcasts.stats()`](https://nextmail.sh/docs/python/reference/broadcasts#stats); Ruby [`broadcasts.stats`](https://nextmail.sh/docs/ruby/reference/broadcasts#stats); PHP [`broadcasts->stats`](https://nextmail.sh/docs/php/reference/broadcasts#stats); Go [`Broadcasts.Stats`](https://nextmail.sh/docs/go/reference/broadcasts#stats); Java [`broadcasts().stats`](https://nextmail.sh/docs/java/reference/broadcasts#stats); C# [`Broadcasts.StatsAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#stats).

### `nextmail broadcasts analytics`

Read how broadcasts did over a time window

```bash
nextmail broadcasts analytics [flags]
```

Returns the numbers behind the Analytics tab of the Broadcasts page in one request: how the live broadcasts sent inside a window did, added up in `totals` and cut to `grain` in `series`, and one row per broadcast in `broadcasts` so they can be compared.

A copy counts when it was sent inside the window, and everything that happened to it afterwards counts with it, so an open today of a copy sent last week is in a 30 day window but not in a 1 day one. Test mode broadcasts are left out. `totals` and `series` add up the broadcasts named in `--broadcast-ids`, or every one when it is left out, while `broadcasts` always lists every broadcast in the window, newest first.

`series` is sparse and oldest first: a bucket in which nothing happened has no entry, so a chart must fill the gaps. It counts each person once, at the first time it happened to them. `grain` sets the bucket width and the key shape, `YYYY-MM-DD`, `YYYY-MM-DDTHH` or `YYYY-MM-DDTHH:MM`, and `--offset-minutes` shifts the boundaries so days break where the reader's day does. The window starts at the beginning of its oldest bucket, reported as `since`, and ends now, reported as `until`.

- Scopes: `emails:read`.
- Needs a sign-in.

**Flags**

- `--broadcast-ids <a,b>` (repeatable): Up to 50 broadcast ids for `totals` and `series` to add up, sent comma separated. Leave it out, or pass an empty array, for every broadcast in the window. An id with no copy in the window adds nothing, and more than 50 is a 422.
- `--days <n>` (default `30`): Window length in days, from 1 to 1095, defaulting to 30.
- `--minutes <n>`: Window length in minutes, from 1 to 1576800, which wins over `days` when both are sent.
- `--grain <value>` (default `"day"`): Bucket width: `minute`, `hour` or `day`, defaulting to `day`.
- `--offset-minutes <n>` (default `0`): Minutes east of UTC to cut the buckets in, from -840 to 840, defaulting to 0. Pass `-new Date().getTimezoneOffset()` for the local zone.

**Examples**

```bash
nextmail broadcasts analytics
```

With optional flags

```bash
nextmail broadcasts analytics --days 90
```

Print the raw JSON

```bash
nextmail broadcasts analytics --json
```

Also available in: API [`GET /broadcasts/analytics`](https://nextmail.sh/docs/api/reference/broadcasts#get-broadcasts-analytics); TypeScript [`nextmail.broadcasts.analytics()`](https://nextmail.sh/docs/sdk/reference/broadcasts#analytics); Python [`broadcasts.analytics()`](https://nextmail.sh/docs/python/reference/broadcasts#analytics); Ruby [`broadcasts.analytics`](https://nextmail.sh/docs/ruby/reference/broadcasts#analytics); PHP [`broadcasts->analytics`](https://nextmail.sh/docs/php/reference/broadcasts#analytics); Go [`Broadcasts.Analytics`](https://nextmail.sh/docs/go/reference/broadcasts#analytics); Java [`broadcasts().analytics`](https://nextmail.sh/docs/java/reference/broadcasts#analytics); C# [`Broadcasts.AnalyticsAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#analytics).

### `nextmail broadcasts list-recipients`

List who a broadcast went to and what happened to each copy

```bash
nextmail broadcasts list-recipients <id> [flags]
```

Resolves one page of the people a broadcast went to, one row per copy, sorted by address. Each row says the copy's status, when it was sent and delivered, whether it bounced or was reported as spam, how often it was opened and clicked, and whether the person unsubscribed from one of the broadcast's audiences after it went out.

Opens and clicks leave out image proxies and link scanners, and stay 0 when the broadcast went out with tracking off. `emailId` is the copy's `msg_` id, which `getRecipient` reads with its content and `emails.get` reads as a sent email.

Add `--all` to walk every page: a table on a terminal, one JSON object per line when piped or with `--ndjson`, and one `{ items, hasMore, nextCursor }` document with `--json`. `--max <n>` stops after that many items.

- Scopes: `emails:read`.
- Needs a sign-in.

**Arguments**

- `<id>` (required): A `brd_` id from `send` or `list`.

**Flags**

- `--filter <value>`: Keeps one group: `pending`, `sent`, `delivered`, `opened`, `not_opened` (sent and never opened), `clicked`, `bounced`, `complained`, `failed` (failed or cancelled) or `unsubscribed`. `BROADCAST_RECIPIENT_FILTERS` names them.
- `--q <value>`: Searches the address and the name, ignoring case.
- `--limit <n>` (default `50`): Page size, from 1 to 200. The server defaults to 50.
- `--cursor <value>`: The `nextCursor` of the previous page. Send the same `filter` and `q` with it.
- `--all`: Fetch every page and stream the items as they arrive.
- `--max <n>`: Stop after this many items. Implies `--all`.
- `--ndjson`: Print every item as one JSON object per line. Implies `--all`

**Examples**

The required values only

```bash
nextmail broadcasts list-recipients brd_5a8c1e3f7b2d94a06c8e1f3b
```

With optional flags

```bash
nextmail broadcasts list-recipients brd_5a8c1e3f7b2d94a06c8e1f3b --filter bounced
```

Walk every page and stop after 100 items

```bash
nextmail broadcasts list-recipients brd_5a8c1e3f7b2d94a06c8e1f3b --all --max 100
```

One JSON object per line when piped

```bash
nextmail broadcasts list-recipients brd_5a8c1e3f7b2d94a06c8e1f3b --all > broadcasts.ndjson
```

Also available in: API [`GET /broadcasts/{id}/recipients`](https://nextmail.sh/docs/api/reference/broadcasts#get-broadcasts-id-recipients); TypeScript [`nextmail.broadcasts.listRecipients()`](https://nextmail.sh/docs/sdk/reference/broadcasts#listRecipients); Python [`broadcasts.list_recipients()`](https://nextmail.sh/docs/python/reference/broadcasts#listRecipients); Ruby [`broadcasts.list_recipients`](https://nextmail.sh/docs/ruby/reference/broadcasts#listRecipients); PHP [`broadcasts->listRecipients`](https://nextmail.sh/docs/php/reference/broadcasts#listRecipients); Go [`Broadcasts.ListRecipients`](https://nextmail.sh/docs/go/reference/broadcasts#listRecipients); Java [`broadcasts().listRecipients`](https://nextmail.sh/docs/java/reference/broadcasts#listRecipients); C# [`Broadcasts.ListRecipientsAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#listRecipients).

### `nextmail broadcasts get-recipient`

Read one person's copy of a broadcast

```bash
nextmail broadcasts get-recipient <id> <email-id> [flags]
```

Resolves with one copy: the same row `listRecipients` gives, plus the `subject`, `html` and `text` exactly as that person received them, with the merge fields filled in and their own unsubscribe link. The HTML is from before open and click tracking was added.

- Scopes: `emails:read`.
- Needs a sign-in.

**Arguments**

- `<id>` (required): A `brd_` id from `send` or `list`.
- `<email-id>` (required): The `emailId` of the copy, from `listRecipients`.

**Examples**

```bash
nextmail broadcasts get-recipient brd_5a8c1e3f7b2d94a06c8e1f3b msg_01dad25067bc4dac966d515d
```

Print the raw JSON

```bash
nextmail broadcasts get-recipient brd_5a8c1e3f7b2d94a06c8e1f3b msg_01dad25067bc4dac966d515d --json
```

Also available in: API [`GET /broadcasts/{id}/recipients/{emailId}`](https://nextmail.sh/docs/api/reference/broadcasts#get-broadcasts-id-recipients-emailid); TypeScript [`nextmail.broadcasts.getRecipient()`](https://nextmail.sh/docs/sdk/reference/broadcasts#getRecipient); Python [`broadcasts.get_recipient()`](https://nextmail.sh/docs/python/reference/broadcasts#getRecipient); Ruby [`broadcasts.get_recipient`](https://nextmail.sh/docs/ruby/reference/broadcasts#getRecipient); PHP [`broadcasts->getRecipient`](https://nextmail.sh/docs/php/reference/broadcasts#getRecipient); Go [`Broadcasts.GetRecipient`](https://nextmail.sh/docs/go/reference/broadcasts#getRecipient); Java [`broadcasts().getRecipient`](https://nextmail.sh/docs/java/reference/broadcasts#getRecipient); C# [`Broadcasts.GetRecipientAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#getRecipient).

### `nextmail broadcasts cancel`

Stop a broadcast that is scheduled, queued or still sending

```bash
nextmail broadcasts cancel <id> [flags]
```

Stops a broadcast that is `scheduled`, `queued` or `sending`, including one that has reached everybody while some copies are still waiting to go. Nobody else is added, and every copy still waiting is cancelled. A copy already being handed over finishes, and copies that have gone cannot be recalled, so `counts.sent` keeps them and `counts.cancelled` shows what was stopped.

Once every copy has gone out there is nothing left to stop, and the call throws 409 `broadcast_not_cancellable`. A `failed` broadcast with copies still waiting can be cancelled to stop them, and one with nothing waiting is refused the same way. Cancelling a broadcast that is already cancelled resolves with it as it stands, so the call is safe to repeat, and the SDK retries it after a network failure.

- Scopes: `emails:send`.
- Needs a sign-in.
- Asks you to confirm.

**Arguments**

- `<id>` (required): The `brd_` id to cancel.

**Examples**

```bash
nextmail broadcasts cancel brd_5a8c1e3f7b2d94a06c8e1f3b
```

Skip the confirmation, for scripts

```bash
nextmail broadcasts cancel brd_5a8c1e3f7b2d94a06c8e1f3b --yes
```

Also available in: API [`POST /broadcasts/{id}/cancel`](https://nextmail.sh/docs/api/reference/broadcasts#post-broadcasts-id-cancel); TypeScript [`nextmail.broadcasts.cancel()`](https://nextmail.sh/docs/sdk/reference/broadcasts#cancel); Python [`broadcasts.cancel()`](https://nextmail.sh/docs/python/reference/broadcasts#cancel); Ruby [`broadcasts.cancel`](https://nextmail.sh/docs/ruby/reference/broadcasts#cancel); PHP [`broadcasts->cancel`](https://nextmail.sh/docs/php/reference/broadcasts#cancel); Go [`Broadcasts.Cancel`](https://nextmail.sh/docs/go/reference/broadcasts#cancel); Java [`broadcasts().cancel`](https://nextmail.sh/docs/java/reference/broadcasts#cancel); C# [`Broadcasts.CancelAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#cancel).

### `nextmail broadcasts create-draft`

Save a broadcast as a draft without sending it

```bash
nextmail broadcasts create-draft --from <value> [flags]
nextmail broadcasts create-draft --data <json|@file|-> [flags]
```

Saves a broadcast with `status` `draft`. Nothing is sent, nobody is counted against the plan and the audiences may still be empty, so a draft can be written over several sittings. `update` changes it, `sendDraft` sends it or schedules it, and `get` returns what it holds in `content`.

The body takes the fields `send` takes, except `scheduledAt`, which belongs to `sendDraft`. Only `from` is required. The sender, the audiences and a template are checked as they are saved, so a draft never names an address the key may not send as or an audience that does not exist.

- Scopes: `emails:send`, `audiences:read`.
- Needs a sign-in.

**Flags**

- `--from <value>`: Sender as `news@acme.com`, `Acme <news@acme.com>` or `{ email, name }`. It must be an address the key may send as, otherwise 403 `from_address_forbidden`. Required, here or in `--data`.
- `--audience-ids <a,b>` (repeatable, default `[]`): Up to 10 audience ids. Left out or empty, the draft has no audience yet and `sendDraft` refuses it until `update` gives it one.
- `--exclude-audience-ids <a,b>` (repeatable): Up to 10 audiences whose members are left out, even when they are in one of `--audience-ids`.
- `--segment-id <value>`: A saved segment that narrows the audiences when the draft is sent. It has to exist when the draft is saved and again when it is sent.
- `--reply-to <value>`: Where replies go, the same for every copy.
- `--subject <value>` (default `""`): At most 998 characters, with merge fields. Needed before sending unless a template supplies it.
- `--html <value>`: HTML body, at most 1,000,000 characters, with merge fields.
- `--text <value>`: Plain text body, at most 1,000,000 characters, with merge fields.
- `--template <json|@file|->`: A stored template instead of `html` and `text`, never beside them. JSON shaped as `{ id: string, version?: number, props?: Record<string, unknown>, slots?: Record<string, unknown> }`, inline or from a file with @path.
- `--tracking <json|@file|->`: Open and link tracking for every copy. JSON shaped as `{ opens?: boolean, clicks?: boolean }`, inline or from a file with @path.
- `--tags <json|@file|->` (repeatable, default `{}`): Up to 8 tags every copy carries.
- `--utm <json|@file|->`: Campaign tags added to every http and https link in the body as `utm_source`, `utm_medium`, `utm_campaign`, `utm_term` and `utm_content`. A link that already carries one of them keeps its own, and the unsubscribe link never gets them. JSON shaped as `{ source?: string, medium?: string, campaign?: string, term?: string, content?: string }`, inline or from a file with @path.
- `--ab-test <json|@file|->`: An A/B test, as `send` takes it: 2 to 4 `variants` of the subject or the body, the `testPercent` of the people that get them, the `metric` that picks the winner and the `waitMinutes` before it is picked. JSON shaped as `BroadcastAbTest`, inline or from a file with @path.
- `--data <json|@file|->`: The whole `body` as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

**Examples**

The required values only

```bash
nextmail broadcasts create-draft --from 'Acme <news@acme.com>'
```

With optional flags

```bash
nextmail broadcasts create-draft --from 'Acme <news@acme.com>' --audience-ids aud_4c1b8e2a7d9f05c36b4e8a71 --subject 'The October release' --text 'Hi {{firstName|there}}, here is what changed this month.'
```

Read the whole body from a JSON file

```bash
nextmail broadcasts create-draft --data @broadcast.json
```

Also available in: API [`POST /broadcasts/drafts`](https://nextmail.sh/docs/api/reference/broadcasts#post-broadcasts-drafts); TypeScript [`nextmail.broadcasts.createDraft()`](https://nextmail.sh/docs/sdk/reference/broadcasts#createDraft); Python [`broadcasts.create_draft()`](https://nextmail.sh/docs/python/reference/broadcasts#createDraft); Ruby [`broadcasts.create_draft`](https://nextmail.sh/docs/ruby/reference/broadcasts#createDraft); PHP [`broadcasts->createDraft`](https://nextmail.sh/docs/php/reference/broadcasts#createDraft); Go [`Broadcasts.CreateDraft`](https://nextmail.sh/docs/go/reference/broadcasts#createDraft); Java [`broadcasts().createDraft`](https://nextmail.sh/docs/java/reference/broadcasts#createDraft); C# [`Broadcasts.CreateDraftAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#createDraft).

### `nextmail broadcasts update`

Change a draft, or a scheduled broadcast before it starts

```bash
nextmail broadcasts update <id> [flags]
```

A partial update: a field you leave out keeps what it holds, and `null` clears `--reply-to`, `html`, `text`, `template` or `utm`. Sending any of `html`, `text` or `template` replaces the body as a whole, so a field of the three you leave out is cleared.

A draft takes every change and stays a draft. A `scheduled` broadcast takes changes until its sending starts, and each change is checked the way `send` checks a new one: the audiences still reach somebody and the plan still covers them, and `counts.recipients` is counted again. `--scheduled-at` moves a scheduled broadcast to another time. Once a broadcast is queued, sending or finished, the call throws 409 `broadcast_not_editable`.

- Scopes: `emails:send`, `audiences:read`.
- Needs a sign-in.
- Aliases: `edit`.

**Arguments**

- `<id>` (required): The `brd_` id of a draft or of a scheduled broadcast.

**Flags**

- `--audience-ids <a,b>` (repeatable): The new audiences, replacing the old list, up to 10.
- `--exclude-audience-ids <a,b>` (repeatable): The new list of audiences whose members are left out, replacing the old one.
- `--segment-id <value>`: A saved segment that narrows the audiences. Null takes it away.
- `--from <value>`: A new sender the key may send as.
- `--reply-to <value>`: Where replies go. Null takes it away.
- `--subject <value>`: A new subject, with merge fields.
- `--html <value>`: A new HTML body.
- `--text <value>`: A new plain text body.
- `--template <json|@file|->`: A stored template instead of `html` and `text`. JSON shaped as `{ id: string, version?: number, props?: Record<string, unknown>, slots?: Record<string, unknown> } | null`, inline or from a file with @path.
- `--tracking <json|@file|->`: Open and link tracking for every copy. JSON shaped as `{ opens?: boolean, clicks?: boolean }`, inline or from a file with @path.
- `--tags <json|@file|->` (repeatable): The new tags, replacing the old ones, up to 8.
- `--utm <json|@file|->`: New campaign tags for the links, replacing the old ones. Null takes them away. JSON shaped as `{ source?: string, medium?: string, campaign?: string, term?: string, content?: string } | null`, inline or from a file with @path.
- `--ab-test <json|@file|->`: A new A/B test, as `send` takes it, replacing the old one. Null takes it away. JSON shaped as `BroadcastAbTest | null`, inline or from a file with @path.
- `--scheduled-at <when>`: A new start for a scheduled broadcast, in the future and at most 365 days out. A draft is scheduled by `sendDraft`, so a draft refuses it with 422 `invalid_parameter`.
- `--data <json|@file|->`: The whole `patch` as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

**Examples**

With optional flags

```bash
nextmail broadcasts update brd_5a8c1e3f7b2d94a06c8e1f3b --audience-ids aud_4c1b8e2a7d9f05c36b4e8a71 --from news@acme.com --subject Draft
```

Print the raw JSON

```bash
nextmail broadcasts update brd_5a8c1e3f7b2d94a06c8e1f3b --audience-ids aud_4c1b8e2a7d9f05c36b4e8a71 --from news@acme.com --subject Draft --json
```

Also available in: API [`PATCH /broadcasts/{id}`](https://nextmail.sh/docs/api/reference/broadcasts#patch-broadcasts-id); TypeScript [`nextmail.broadcasts.update()`](https://nextmail.sh/docs/sdk/reference/broadcasts#update); Python [`broadcasts.update()`](https://nextmail.sh/docs/python/reference/broadcasts#update); Ruby [`broadcasts.update`](https://nextmail.sh/docs/ruby/reference/broadcasts#update); PHP [`broadcasts->update`](https://nextmail.sh/docs/php/reference/broadcasts#update); Go [`Broadcasts.Update`](https://nextmail.sh/docs/go/reference/broadcasts#update); Java [`broadcasts().update`](https://nextmail.sh/docs/java/reference/broadcasts#update); C# [`Broadcasts.UpdateAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#update).

### `nextmail broadcasts send-draft`

Send a draft now, or schedule it

```bash
nextmail broadcasts send-draft <id> [flags]
```

Turns a draft into a broadcast that goes out: `queued` straight away, or `scheduled` when you pass `--scheduled-at`. The draft is checked the way `send` checks a new broadcast, so it needs an audience, a body and a subject (or a template that supplies one), somebody it can reach, and room in the plan's monthly sends for every copy. From here it behaves like any broadcast: `get` follows it and `cancel` stops it.

A broadcast that is not a draft throws 409 `broadcast_not_draft`, so calling it twice never sends twice.

- Scopes: `emails:send`, `audiences:read`.
- Needs a sign-in.

**Arguments**

- `<id>` (required): The `brd_` id of the draft.

**Flags**

- `--scheduled-at <when>`: A `Date`, an ISO 8601 instant or a duration such as `PT2H`, in the future and at most 365 days out. Left out, the sending starts straight away.
- `--data <json|@file|->`: The whole `body` as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

**Examples**

The required values only

```bash
nextmail broadcasts send-draft brd_5a8c1e3f7b2d94a06c8e1f3b
```

With optional flags

```bash
nextmail broadcasts send-draft brd_5a8c1e3f7b2d94a06c8e1f3b --scheduled-at PT2H
```

Also available in: API [`POST /broadcasts/{id}/send`](https://nextmail.sh/docs/api/reference/broadcasts#post-broadcasts-id-send); TypeScript [`nextmail.broadcasts.sendDraft()`](https://nextmail.sh/docs/sdk/reference/broadcasts#sendDraft); Python [`broadcasts.send_draft()`](https://nextmail.sh/docs/python/reference/broadcasts#sendDraft); Ruby [`broadcasts.send_draft`](https://nextmail.sh/docs/ruby/reference/broadcasts#sendDraft); PHP [`broadcasts->sendDraft`](https://nextmail.sh/docs/php/reference/broadcasts#sendDraft); Go [`Broadcasts.SendDraft`](https://nextmail.sh/docs/go/reference/broadcasts#sendDraft); Java [`broadcasts().sendDraft`](https://nextmail.sh/docs/java/reference/broadcasts#sendDraft); C# [`Broadcasts.SendDraftAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#sendDraft).

### `nextmail broadcasts duplicate`

Copy a broadcast into a new draft

```bash
nextmail broadcasts duplicate <id> [flags]
```

Makes a new draft from any broadcast, a draft, a scheduled one or one that went out long ago: the same sender, audiences, left-out audiences, subject, body or template, tracking, tags and campaign tags. The time it was scheduled for is not copied. The original is not changed, and nothing is sent until `sendDraft`.

- Scopes: `emails:send`, `audiences:read`.
- Needs a sign-in.

**Arguments**

- `<id>` (required): The `brd_` id to copy.

**Examples**

```bash
nextmail broadcasts duplicate brd_5e8a2c1f9b3d74e06a5c2f81
```

Print the raw JSON

```bash
nextmail broadcasts duplicate brd_5e8a2c1f9b3d74e06a5c2f81 --json
```

Also available in: API [`POST /broadcasts/{id}/duplicate`](https://nextmail.sh/docs/api/reference/broadcasts#post-broadcasts-id-duplicate); TypeScript [`nextmail.broadcasts.duplicate()`](https://nextmail.sh/docs/sdk/reference/broadcasts#duplicate); Python [`broadcasts.duplicate()`](https://nextmail.sh/docs/python/reference/broadcasts#duplicate); Ruby [`broadcasts.duplicate`](https://nextmail.sh/docs/ruby/reference/broadcasts#duplicate); PHP [`broadcasts->duplicate`](https://nextmail.sh/docs/php/reference/broadcasts#duplicate); Go [`Broadcasts.Duplicate`](https://nextmail.sh/docs/go/reference/broadcasts#duplicate); Java [`broadcasts().duplicate`](https://nextmail.sh/docs/java/reference/broadcasts#duplicate); C# [`Broadcasts.DuplicateAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#duplicate).

### `nextmail broadcasts resend`

Send a broadcast again to the people who did not open it

```bash
nextmail broadcasts resend <id> [flags]
```

Creates a new broadcast with the same content that goes only to the people the first one reached and who have not opened it, optionally under a new subject. Somebody who has unsubscribed since, or whose address is now suppressed, is skipped as always. The new broadcast carries `content.resendOf`, the id it came from, and counts against the plan like any send.

The first broadcast has to have finished going out and to have tracked opens. Otherwise the call throws 409 `resend_unavailable`.

- Scopes: `emails:send`, `audiences:read`.
- Needs a sign-in.

**Arguments**

- `<id>` (required): The `brd_` id of the broadcast that went out.

**Flags**

- `--subject <value>`: A new subject for the second try, 1 to 998 characters, with merge fields. Left out, the first subject is used again.
- `--scheduled-at <when>`: When to start, in the future and at most 365 days out. Left out, the sending starts straight away.
- `--data <json|@file|->`: The whole `body` as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

**Examples**

The required values only

```bash
nextmail broadcasts resend brd_5e8a2c1f9b3d74e06a5c2f81
```

With optional flags

```bash
nextmail broadcasts resend brd_5e8a2c1f9b3d74e06a5c2f81 --subject 'In case you missed it: doors open on Friday' --scheduled-at P2D
```

Also available in: API [`POST /broadcasts/{id}/resend`](https://nextmail.sh/docs/api/reference/broadcasts#post-broadcasts-id-resend); TypeScript [`nextmail.broadcasts.resend()`](https://nextmail.sh/docs/sdk/reference/broadcasts#resend); Python [`broadcasts.resend()`](https://nextmail.sh/docs/python/reference/broadcasts#resend); Ruby [`broadcasts.resend`](https://nextmail.sh/docs/ruby/reference/broadcasts#resend); PHP [`broadcasts->resend`](https://nextmail.sh/docs/php/reference/broadcasts#resend); Go [`Broadcasts.Resend`](https://nextmail.sh/docs/go/reference/broadcasts#resend); Java [`broadcasts().resend`](https://nextmail.sh/docs/java/reference/broadcasts#resend); C# [`Broadcasts.ResendAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#resend).

### `nextmail broadcasts send-test`

Send a test copy of a broadcast to yourself or a few people

```bash
nextmail broadcasts send-test --from <value> [flags]
nextmail broadcasts send-test --data <json|@file|-> [flags]
```

Sends one copy of a broadcast to up to five addresses, to read it before it goes to an audience. It goes to the account address of the person the key or app acts for, the workspace owner for an API key, unless `to` names others. The merge fields are filled from the contact that has the address when there is one, and from a sample name otherwise, the subject starts with `[Test]`, the unsubscribe footer is added as it would be, and the unsubscribe link in it does nothing. Opens and clicks are not tracked, and campaign tags in `utm` are added to the links.

Nobody is added to an audience and no broadcast is created. Each copy counts as one send.

- Scopes: `emails:send`.
- Needs a sign-in.

**Flags**

- `--from <value>`: The sender, an address the key may send as. Required, here or in `--data`.
- `--to <a,b>` (repeatable): 1 to 5 addresses. Left out, the test goes to the account address of the person the key or app acts for.
- `--reply-to <value>`: Where replies go.
- `--subject <value>` (default `""`): Required unless a template supplies it, with merge fields.
- `--html <value>`: HTML body with merge fields.
- `--text <value>`: Plain text body with merge fields.
- `--template <json|@file|->`: A stored template instead of `html` and `text`. JSON shaped as `{ id: string, version?: number, props?: Record<string, unknown>, slots?: Record<string, unknown> }`, inline or from a file with @path.
- `--utm <json|@file|->`: Campaign tags added to the links, as the broadcast would add them. JSON shaped as `{ source?: string, medium?: string, campaign?: string, term?: string, content?: string }`, inline or from a file with @path.
- `--data <json|@file|->`: The whole `body` as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

**Examples**

The required values only

```bash
nextmail broadcasts send-test --from 'Acme <news@acme.com>'
```

With optional flags

```bash
nextmail broadcasts send-test --from 'Acme <news@acme.com>' --to me@acme.com --subject '{{firstName|Hello}}, doors open on Friday' --html '<p>Hi {{firstName|there}}, doors open at nine.</p>'
```

Read the whole body from a JSON file

```bash
nextmail broadcasts send-test --data @broadcast.json
```

Also available in: API [`POST /broadcasts/test`](https://nextmail.sh/docs/api/reference/broadcasts#post-broadcasts-test); TypeScript [`nextmail.broadcasts.sendTest()`](https://nextmail.sh/docs/sdk/reference/broadcasts#sendTest); Python [`broadcasts.send_test()`](https://nextmail.sh/docs/python/reference/broadcasts#sendTest); Ruby [`broadcasts.send_test`](https://nextmail.sh/docs/ruby/reference/broadcasts#sendTest); PHP [`broadcasts->sendTest`](https://nextmail.sh/docs/php/reference/broadcasts#sendTest); Go [`Broadcasts.SendTest`](https://nextmail.sh/docs/go/reference/broadcasts#sendTest); Java [`broadcasts().sendTest`](https://nextmail.sh/docs/java/reference/broadcasts#sendTest); C# [`Broadcasts.SendTestAsync`](https://nextmail.sh/docs/csharp/reference/broadcasts#sendTest).
