List events for a broadcast
/v1/email/broadcasts/{broadcast_id}/eventsfor await (const event of bird.broadcasts.listEvents("eb_01krdgeqcxet5s7t44vh8rt9mg", {
type: "email.bounced",
})) {
console.log(event.type, event.recipient_id, event.bounce_type);
}for event in client.broadcasts.list_events(
"eb_01krdgeqcxet5s7t44vh8rt9mg", type="email.bounced"
):
print(event.type, event.recipient_id, event.bounce_type)for event, err := range client.Broadcasts.ListEvents(context.Background(),
"eb_01krdgeqcxet5s7t44vh8rt9mg", bird.BroadcastsListEventsParams{Type: "email.bounced"}) {
if err != nil {
log.Fatal(err)
}
// bounce_type is absent unless the event is a bounce the server classified.
if event.BounceType != nil {
fmt.Println(event.Type, event.RecipientId, *event.BounceType)
}
}$events = $bird->broadcasts->listEvents('eb_01krdgeqcxet5s7t44vh8rt9mg', ['type' => 'email.bounced']);
foreach ($events as $event) {
echo $event->getType(), ' ', $event->getRecipientId(), ' ', $event->getBounceType(), PHP_EOL;
}bird email broadcasts list-events <broadcast-id>curl -X GET "https://us1.platform.bird.com/v1/email/broadcasts/{broadcast_id}/events" \
-H "Authorization: Bearer $TOKEN" \
--url-query "limit=25"{
"data": [
{
"id": "ev_01krdgeqcxet5s7t44vh8rt9mg",
"type": "email.delivered",
"occurred_at": "2026-07-01T12:00:03Z",
"recipient_id": "er_01krdgeqcxet5s7t44vh8rt9mg",
"bounce_type": "hard",
"bounce_code": "5.1.1",
"rejection_reason": "recipient_suppressed",
"link_name": "Faster exports, docs",
"country": "US"
}
],
"next": [
{
"kind": "operation"
}
],
"next_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE0OjAzOjEwWlwiIiwiaSI6IjAxOTJmM2IxLTRjN2UtN2EyYi05ZDYxLThmM2E1YzJlN2I0MCJ9",
"prev_cursor": null,
"refresh_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE2OjQyOjAxWlwiIiwiaSI6IjAxOTJmM2IxLTllMDQtN2NkMy1iODE3LTJhNmY0ZDFjOGUwOSJ9"
}
Returns the per-recipient delivery timeline for a broadcast, oldest first, as a cursor page. Each entry is one event, such as a send, an open, a click, or a bounce.
Parameters
broadcast_idstringID of the broadcast whose event timeline to read.
Query Parameters
limitintegerMaximum number of items to return per page.
starting_afterstringCursor from the next_cursor field of a previous list response. Returns items immediately after the cursor position in the current sort order.
ending_beforestringCursor 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.
typestringFilter by event type, for example email.bounced or email.opened. A broadcast timeline is recipient-scoped, so email.scheduled and email.canceled never appear on it; a canceled broadcast reports that in its own status.
Possible values (may grow over time): email.accepted, email.bounced, email.canceled, email.clicked, email.complained, email.deferred, email.delivered, email.list_unsubscribed, email.opened, email.out_of_band_bounce, email.processed, email.rejected, email.scheduled, email.unsubscribed
Response Payload
dataPage of timeline events for this email send, in chronological order.
nextWhat 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_cursorCursor for the next page. Pass back as starting_after to advance forward. null when no next page exists.
prev_cursorCursor for the previous page. Pass back as ending_before to step backward. null when no previous page exists.
refresh_cursorRefresh 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
Continue with the documentation, guides and examples for this topic.