# List recipients of a broadcast

`GET /v1/email/broadcasts/{broadcast_id}/recipients`

Returns recipient-level delivery state for a broadcast, paginated. This is who a broadcast reached and how far each one got.

The list is empty for a draft, scheduled, or accepted broadcast: recipients are resolved from the audience only once sending begins. Pass `to` to return just that address's row, which is how you answer "did this person get it?" on a send too large to page through.

## Code samples

### TypeScript

```ts
for await (const recipient of bird.broadcasts.listRecipients("eb_01krdgeqcxet5s7t44vh8rt9mg")) {
  console.log(recipient.recipient, recipient.status);
}
```

### Python

```py
for recipient in client.broadcasts.list_recipients("eb_01krdgeqcxet5s7t44vh8rt9mg"):
    print(recipient.recipient, recipient.status)
```

### Go

```go
for recipient, err := range client.Broadcasts.ListRecipients(context.Background(),
	"eb_01krdgeqcxet5s7t44vh8rt9mg", bird.BroadcastsListRecipientsParams{}) {
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(recipient.Recipient, *recipient.Status)
}
```

### PHP

```php
foreach ($bird->broadcasts->listRecipients('eb_01krdgeqcxet5s7t44vh8rt9mg') as $recipient) {
    echo $recipient->getRecipient(), ' ', $recipient->getStatus(), PHP_EOL;
}
```

### CLI

```sh
bird email broadcasts list-recipients <broadcast-id>
```

### cURL

```sh
curl -X GET "https://us1.platform.bird.com/v1/email/broadcasts/{broadcast_id}/recipients" \
  -H "Authorization: Bearer $TOKEN" \
  --url-query "limit=25"
```

## Example response `200`

```json
{
  "data": [
    {
      "id": "er_01krdgeqcxet5s7t44vh8rt9mg",
      "parent_id": "em_01krdgeqcxet5s7t44vh8rt9mg",
      "role": "to",
      "status": "accepted",
      "rejection_reason": "recipient_suppressed",
      "bounce_type": "hard",
      "bounce_code": "550",
      "bounce_description": "5.1.1 Unknown user"
    }
  ],
  "next": [
    {
      "kind": "operation"
    }
  ],
  "next_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE0OjAzOjEwWlwiIiwiaSI6IjAxOTJmM2IxLTRjN2UtN2EyYi05ZDYxLThmM2E1YzJlN2I0MCJ9",
  "prev_cursor": null,
  "refresh_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE2OjQyOjAxWlwiIiwiaSI6IjAxOTJmM2IxLTllMDQtN2NkMy1iODE3LTJhNmY0ZDFjOGUwOSJ9"
}
```

## Path parameters

- `broadcast_id` (string): ID of the broadcast whose recipients to read.

## Query parameters

- `limit` (integer): Maximum number of items to return per page.
- `starting_after` (string): Cursor from the `next_cursor` field of a previous list response. Returns items immediately after the cursor position in the current sort order.
- `ending_before` (string): Cursor from the `prev_cursor` or `refresh_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order. `prev_cursor` returns the preceding page. `refresh_cursor` anchors at the first row of that response, which on a newest-first sort is how to fetch the items that have appeared since.
- `to` (string): Return only the recipient at this address. Exact match, normalised to lowercase before comparison, so it returns at most one row.

## Response body

- `data` (array of object, required): Page of recipient objects for this email send.
- `data.id` (string, required): Recipient ID.
- `data.parent_id` (string, required): ID of the message or broadcast this recipient belongs to. For a message send, this is the message's `em_`-prefixed ID. For a broadcast, this field is also `em_`-prefixed, but currently does not resolve to a retrievable message.
- `data.role` (string, required)

  How this recipient appeared in the send request.

  Possible values: `to`, `cc`, `bcc`
- `data.recipient` (string, required): Recipient email address.
- `data.name` (nullable string): Display name provided for this recipient on the send, or null if none was given.
- `data.status` (string, required)

  Delivery status for this recipient:

  - `accepted`: The send has been taken and is being prepared for delivery.
  - `processed`: This recipient's message is on its way out.
  - `deferred`: The recipient's mailbox provider asked for a retry, and delivery attempts continue.
  - `delivered`: The recipient's mail server accepted the message.
  - `bounced`: Delivery permanently failed (see `bounce_type` for hard vs soft).
  - `complained`: The recipient reported the message as spam.
  - `rejected`: Delivery was never attempted (see `rejection_reason` for why).

  Possible values: `accepted`, `processed`, `deferred`, `delivered`, `bounced`, `complained`, `rejected`
- `data.rejection_reason` (nullable string)

  Present on `status: rejected` rows. Specifies why the recipient was rejected:

  - `recipient_suppressed`: The recipient is on the workspace suppression list, so
    delivery was never attempted.
  - `transmission_failed`: The message could not be transmitted for delivery.
  - `generation_failure`: The message could not be built for delivery (template or
    content issue).
  - `policy_rejection`: The message was refused by sending policy.
  - `domain_unverified`: The sending domain was not verified.
  - `quota_exceeded`: The organization's send quota was reached.
  - `recipient_not_allowed`: A recipient was not permitted for this send (for shared
    onboarding-domain sends, recipients must be verified workspace members).

  Possible values: `recipient_suppressed`, `transmission_failed`, `generation_failure`, `policy_rejection`, `domain_unverified`, `quota_exceeded`, `recipient_not_allowed`, `null`
- `data.bounce_type` (nullable string)

  Bounce classification for `bounced` and `deferred` rows, or null when the recipient
  has not bounced or the receiving server's response has not been classified.

  - `hard`: a permanent failure (invalid address or non-existent domain).
  - `soft`: a transient failure (mailbox full or server temporarily unavailable).
  - `block`: the receiving mail server blocked the sending IP for reputation reasons.
  - `admin`: an administrative refusal (relaying denied or blocklisted domain).
  - `undetermined`: the receiving server's response is ambiguous.

  Possible values: `hard`, `soft`, `undetermined`, `admin`, `block`, `null`
- `data.bounce_code` (nullable string): SMTP reply code returned by the receiving mail server for `bounced` and `deferred` rows, or null when none was provided.
- `data.bounce_description` (nullable string): Human-readable reason the receiving mail server gave for the bounce or deferral, or null when none was provided.
- `data.processed_at` (nullable string): When the message was prepared and queued for delivery to the recipient's mail server, or null if that has not happened yet.
- `data.delivered_at` (nullable string): When the recipient's mail server accepted the message, or null if not yet delivered.
- `data.processing_latency_ms` (nullable integer): Time between the send being accepted and the message being prepared for delivery, in milliseconds. Null until processed.
- `data.delivery_latency_ms` (nullable integer): Time between the message being prepared and the receiving mail server accepting it, in milliseconds. Null until delivered.
- `data.total_latency_ms` (nullable integer): End-to-end accept → delivered time for this recipient, in milliseconds. Null until delivered.
- `data.open_count` (integer, required): Number of open events for this recipient.
- `data.click_count` (integer, required): Number of click events for this recipient.
- `next` (array of object)

  What to do next, given what this page reports. Present only where the read computes it: an
  empty list means the answer you were looking for is here and there is nothing further to
  do. Absent entirely on reads that do not report next actions.
- `next.kind` (string, required)

  What you do about this step.

  - `operation`: call the operation named in `operation`, then
    read again.
  - `external`: act somewhere this API does not reach, then read
    again.
  - `wait`: nothing is asked of you, so read again later.
  - `terminal`: nothing you do resolves this, so stop retrying.

  Tolerate a value you do not recognize: show the `description` and
  offer no action.

  Possible values (may grow over time): `operation`, `external`, `wait`, `terminal`
- `next.description` (string, required): A short, human-readable label for the step, suitable for display.
- `next.operation` (string): The operationId to call. Present only when `kind` is `operation`. The operation's own schema says how to call it; this says only which one, and what to address it with.
- `next.params` (object): The parameters that address the operation, by name: `{"sender_id": "…"}` for an operation on `/v1/sms/senders/{sender_id}/requirements`. A parameter the operation takes in its query string is given the same way, so an operation addressed as `?subject_id=` carries `{"subject_id": "…"}`. Every parameter the call needs is here, whether its value came from the thing you were acting on or is fixed for this step, so you can make the call from this object alone. Present only when `kind` is `operation` and the operation names a subject. A request body, when the operation takes one, is described by the operation's own schema and never appears here.
- `next.url` (string): A URL to open. Present only when `kind` is `external`, and only when the step has one. An external step whose `description` says to go and do something with no URL to open is normal.
- `next_cursor` (nullable string, required): Cursor for the next page. Pass back as `starting_after` to advance forward. `null` when no next page exists.
- `prev_cursor` (nullable string, required): Cursor for the previous page. Pass back as `ending_before` to step backward. `null` when no previous page exists.
- `refresh_cursor` (nullable string, required): Refresh anchor, the first row of this response. Pass back as `ending_before` to fetch what precedes it in the current sort order. On a newest-first sort those are the items that have appeared since; on any other sort they are the items that sort earlier, so refreshing such a list means re-fetching it instead. Non-`null` whenever `data` is non-empty; `null` only on an empty page. Distinct from `prev_cursor`.

## Related resources

- [Getting started with email](/learn/email/getting-started-with-email) (video)
- [Email](/products/email) (product)
- [Build your first integration](/learn/paths/integration) (course)
- [Send your first email](/docs/get-started/send-your-first-email) (docs)

[Get an implementation brief](/learn/workspace?topic=email)
