List recipients of a message
GET
/v1/email/messages/{message_id}/recipients
bird email recipients <message-id>curl -X GET "https://us1.platform.bird.com/v1/email/messages/{message_id}/recipients" \
-H "Authorization: Bearer $TOKEN" \
--url-query "limit=25"Response200
{
"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"
}
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).
Parameters
message_id
string
ID of the message whose recipients to list, from the send response's id field.
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 field of a previous list response. Returns items immediately before the cursor position in the current sort order.
Response Payload
data
array of object
required
Page of recipient objects for this email send.
Show child attributes
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.
Show child attributes
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. Pass back as ending_before later to fetch items that have appeared since this response. Non-null whenever data is non-empty; null only on an empty page. Distinct from prev_cursor.