---
title: "List recipients of a message"
method: GET
path: "/v1/email/messages/{message_id}/recipients"
tags: ["email-messages"]
---

# List recipients of a message

`GET /v1/email/messages/{message_id}/recipients`

## Request

- Base URL: `https://us1.platform.bird.com`
- URL: `https://us1.platform.bird.com/v1/email/messages/{message_id}/recipients`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `bird_session`

Returns the message's per-recipient delivery state as a cursor page: each entry is
one `to`/`cc`/`bcc` recipient with its role, current `status`, rejection or bounce
detail when delivery failed, and open/click counts. Use it to see which specific
addresses failed when the aggregate message `status` is mixed (for example
`partial_failure`).

This works for every email message, including one a broadcast sent. A broadcast
records one message per recipient, so such a message has exactly one recipient
here: the address its copy went to.

## Path parameters

- `message_id` string, required

## Query parameters

- `limit` integer
- `starting_after` string
- `ending_before` string

## Headers

- `X-Workspace-Id` string
- `X-Organization-Id` string

## Response `200`

Paginated list of recipients for this message.

- EmailRecipientList
  - `data` EmailRecipient[], required: Page of recipient objects for this email send.
    - `id` string, required
    - `parent_id` string, required
    - `role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
    - `recipient` string, email, required: Recipient email address.
    - `name` string, nullable: Display name provided for this recipient on the send, or null if none was given.
    - `status` 'accepted' | 'processed' | 'deferred' | 'delivered' | 'bounced' | 'complained' | 'rejected', 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).
    - `rejection_reason` 'recipient_suppressed' | 'transmission_failed' | 'generation_failure' | 'policy_rejection' | 'domain_unverified' | 'quota_exceeded' | 'recipient_not_allowed' | 'null', nullable: 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).
    - `bounce_type` 'hard' | 'soft' | 'undetermined' | 'admin' | 'block' | 'null', nullable: 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.
    - `bounce_code` string, nullable: SMTP reply code returned by the receiving mail server for `bounced` and `deferred` rows, or null when none was provided.
    - `bounce_description` string, nullable: Human-readable reason the receiving mail server gave for the bounce or deferral, or null when none was provided.
    - `processed_at` string, date-time, nullable: When the message was prepared and queued for delivery to the recipient's mail server, or null if that has not happened yet.
    - `delivered_at` string, date-time, nullable: When the recipient's mail server accepted the message, or null if not yet delivered.
    - `processing_latency_ms` integer, nullable: Time between the send being accepted and the message being prepared for delivery, in milliseconds. Null until processed.
    - `delivery_latency_ms` integer, nullable: Time between the message being prepared and the receiving mail server accepting it, in milliseconds. Null until delivered.
    - `total_latency_ms` integer, nullable: End-to-end accept → delivered time for this recipient, in milliseconds. Null until delivered.
    - `open_count` integer, required: Number of open events for this recipient.
    - `click_count` integer, required: Number of click events for this recipient.
  - `next` NextAction[]: 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.
    - `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.
    - `description` string, required: A short, human-readable label for the step, suitable for display.
    - `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.
    - `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.
    - `url` string, uri: 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` string, nullable, required: Cursor for the next page. Pass back as `starting_after` to advance forward. `null` when no next page exists.
  - `prev_cursor` string, nullable, required: Cursor for the previous page. Pass back as `ending_before` to step backward. `null` when no previous page exists.
  - `refresh_cursor` string, nullable, 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`.

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `403`: Insufficient permissions
- `404`: Resource not found
- `422`: The request has invalid field values, violates a business rule, or carries a query parameter the endpoint does not declare. Field validation errors use `type: validation_error` and include the affected fields in `details`. Business-rule errors identify the failed rule in `type`.
- `429`: Rate limit exceeded
- `500`: Internal server error

---

[API](https://skmtc.dev/messagebird/apis/bird-api.md) · [All operations](https://skmtc.dev/messagebird/apis/bird-api/llms.txt) · [OpenAPI document](https://skmtc.dev/messagebird/apis/bird-api/revisions/3e2a50466454?raw)
