List broadcasts
/v1/email/broadcastsfor await (const broadcast of bird.broadcasts.list({ status: ["sent"] })) {
console.log(broadcast.id, broadcast.status);
}for broadcast in client.broadcasts.list(status=["sent"]):
print(broadcast.id, broadcast.status)for broadcast, err := range client.Broadcasts.List(context.Background(),
bird.BroadcastsListParams{Status: []bird.EmailBroadcastStatus{bird.EmailBroadcastStatusSent}}) {
if err != nil {
log.Fatal(err)
}
fmt.Println(*broadcast.Id, *broadcast.Status)
}foreach ($bird->broadcasts->list(['status' => ['sent']]) as $broadcast) {
echo $broadcast->getId(), ' ', $broadcast->getStatus(), PHP_EOL;
}bird email broadcasts listcurl -X GET "https://us1.platform.bird.com/v1/email/broadcasts" \
-H "Authorization: Bearer $TOKEN" \
--url-query "limit=25"{
"data": [
{
"id": "eb_01krdgeqcxet5s7t44vh8rt9mg",
"from": {
"email": "jane@acme.com",
"name": "Jane Doe"
},
"audience_id": "adn_01krdgeqcxet5s7t44vh8rt9mg",
"template": {
"id": "emt_01krdgeqcxet5s7t44vh8rt9mg",
"version_id": "emv_01krdgeqcxet5s7t44vh8rt9mg"
},
"category": "marketing",
"reply_to": [
{
"email": "jane@acme.com",
"name": "Jane Doe"
}
],
"status": "sent",
"failure_reason": null,
"failure_detail": null,
"recipient_count": 4820,
"sent_count": 4820,
"delivered_count": 4712,
"bounced_count": 96,
"complained_count": 12,
"open_count": 3104,
"click_count": 812,
"unique_opens_non_prefetched": 2140,
"unique_clicks": 693,
"out_of_band_bounces": 14,
"delivered_recipients": 4724,
"tags": [
{
"name": "category",
"value": "welcome"
}
],
"track_opens": true,
"track_clicks": true,
"created_at": "2026-09-01T09:14:02.418Z",
"scheduled_at": "2026-09-02T08:00:00Z",
"started_at": "2026-09-02T08:00:03.771Z",
"sent_at": "2026-09-02T08:11:47.902Z"
}
],
"next_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE0OjAzOjEwWlwiIiwiaSI6IjAxOTJmM2IxLTRjN2UtN2EyYi05ZDYxLThmM2E1YzJlN2I0MCJ9",
"prev_cursor": null,
"refresh_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE2OjQyOjAxWlwiIiwiaSI6IjAxOTJmM2IxLTllMDQtN2NkMy1iODE3LTJhNmY0ZDFjOGUwOSJ9"
}
Returns a paginated list of broadcasts in the workspace, newest first. created_after and created_before narrow the list to broadcasts created in a half-open window, which is how you page a single month or quarter rather than the whole history.
Paramètres de requête
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.
statusarrayFilter by lifecycle status. Repeat the parameter to match more than one status, for example ?status=accepted&status=sending.
audience_idstringFilter by audience. Only broadcasts that use this audience are returned.
tagstringFilter by tag. Pass name to match any broadcast that has that tag name, or pass name:value to match a specific tag pair, for example campaign:spring_launch.
qstringCase-insensitive literal substring match against the broadcast's tags or the referenced template's name. With email_management read access, also matches the subject in the effective language of the template version resolved when this broadcast's execution starts. Draft and scheduled broadcasts have no execution subject to search. Percent signs, underscores, and backslashes are literal characters.
created_afterstringLimits the response to resources created at or after this timestamp. Combine it with created_before to select a time window. Use an RFC 3339 timestamp with a timezone offset.
created_beforestringLimits the response to resources created before this timestamp. Combine it with created_after to select a time window. Use an RFC 3339 timestamp with a timezone offset.
Contenu de la réponse
dataPage of broadcast objects.
Afficher les attributs enfants
data.idBroadcast ID.
data.display_labelLabel for selecting this broadcast on list and single-broadcast reads. With email_management read access, uses the retained subject from the template version resolved when execution starts, then its non-generated name. Draft and scheduled broadcasts use the name. Omitted when no authoritative label is available; clients can show a localized Untitled broadcast fallback. Without that access, uses the canonical broadcast ID. Absent from mutation responses.
data.fromThe address this broadcast sends from. name is filled in when the broadcast was given a display name to send under. Left out on a draft that has not picked a sender yet.
Afficher les attributs enfants
data.from.emailEmail address.
data.from.nameDisplay name shown alongside the address in mail clients.
data.audience_idThe audience this broadcast sends to. When the send starts we turn the audience into a list of recipients, and you can read that list a page at a time with List recipients of a broadcast. Left out on a draft that has not picked an audience yet.
data.templateThe template this broadcast sends, and the language it sends in. A broadcast sends the template's published version, and the exact version is fixed when the broadcast is prepared for sending, so publishing a new version afterwards does not change what this broadcast sends. Null on a draft that has not chosen a template yet.
data.html_bytesSize of the HTML body this broadcast sends, in bytes, or 0 when its content has no HTML part. Measured on the template version the broadcast sends, using the selected language. Recipient merge values can change its size. Returned on a single broadcast read, and absent from the list and from the broadcast that creating, updating, sending or canceling one returns, none of which measure the content. Absent too when the broadcast has no template or its content can no longer be read.
data.text_bytesSize of the plain-text body this broadcast sends, in bytes, or 0 when its content has no plain-text part. Measured, and absent, the same way as html_bytes.
data.categoryWhat kind of email this is, which decides how suppressions apply to it. A marketing broadcast is held back from every suppressed address. A transactional one still goes to addresses suppressed for a complaint or an unsubscribe, because those suppressions are about marketing mail.
Possible values: marketing, transactional
data.ip_pool_idThe IP pool this broadcast sends from, or ipp_shared when it sends through the shared pool. Absent when it sends on your organization's default pool.
data.reply_toWhere replies to this broadcast go, if you want them somewhere other than the from address. Absent when you have not set one.
data.headersAny custom email headers set on the broadcast. Returned on a single broadcast read and on the broadcast that creating, updating, sending or canceling one returns, and absent from the list. The unsubscribe headers we add ourselves are not included.
data.statusWhere the broadcast itself has got to, separate from what happened to individual recipients: for that, read sent_count, delivered_count, bounced_count and complained_count below. When it is failed, failure_reason says why.
data.nextWhat to do next about this broadcast, given the state it is in. Each entry names one action and says why it is worth taking. Present on reads that compute it: an empty list means there is nothing to do, and the field is absent entirely on responses that do not report next actions.
data.failure_reasonWhy the broadcast failed. Set when status is failed, and null the rest of the time.
empty_audience: There was nobody to send to. Either the audience has no members, or every address in it is suppressed.audience_unavailable: The audience no longer exists, so there was nothing to resolve.content_invalid: The broadcast could not be set up to send.failure_detailexplains what went wrong. It is one of these:- The broadcast has no template, or the template it uses no longer exists. Choose an existing template and send the broadcast again.
- The template has no published version, or its published version has no subject and no body. Publish the template, or add content and publish it.
- The template uses a loop or reads a value that a broadcast cannot provide. Remove it, or use a contact property instead, then publish the template again.
- The template requires a language, but the broadcast has not selected one. Set
template.languageto one of the template's languages and send the broadcast again. - The selected language is not available on the published template version. Choose one of that version's languages, or publish a version that includes the selected language.
- The sending domain is no longer verified. Verify the domain again.
- The configured IP pool has no usable IP address.
- We could not hand the prepared message to the delivery system. This is a problem on our side.
insufficient_funds: There was not enough in the workspace balance to pay for the send.quota_exceeded: The send would have gone past your organization's daily or monthly email allowance, whichever runs out first. This can happen when the broadcast is being prepared, or partway through sending if the remaining recipients no longer fit.failure_detailgives you the count and the limit.internal_error: Something went wrong on our side. Retry, and open a support ticket if it keeps happening.
Possible values: empty_audience, audience_unavailable, content_invalid, insufficient_funds, quota_exceeded, internal_error, null
data.failure_detailA sentence explaining the failure in more detail than failure_reason does, and null when the broadcast has not failed. Show it to the person using your app. Do not write code that reads it, because the wording can change. Branch on failure_reason instead.
data.recipient_countNumber of recipients after suppressed addresses are removed from the audience. This is 0 until sending starts and the audience becomes a recipient list.
data.sent_countHow many recipients the broadcast has been sent to, counting every recipient whose status is processed or later. The number rises while the broadcast is sending and stops changing once the broadcast has finished. These counters are exact. The email stats endpoints report on the same sending but are approximate, so use these numbers when you need the precise count. Absent when the broadcast comes back from creating, updating, sending or canceling it, none of which read the counters. List and single-broadcast reads return 0 when no delivery events are recorded. When counters are unavailable, those reads still return 200 and omit the counters. Read the broadcast again for the numbers.
data.delivered_countHow many recipients' messages were accepted by their mail server. Absent when sent_count is.
data.bounced_countHow many recipients the message could not be delivered to at all. Absent when sent_count is.
data.complained_countHow many recipients marked the message as spam. Absent when sent_count is.
data.open_countHow many times the message was opened, added up across every recipient. One recipient opening it twice counts twice. Absent when sent_count is.
data.click_countHow many times a link in the message was clicked, added up across every recipient. One recipient clicking twice counts twice. Absent when sent_count is.
data.sending_ipsThe IP addresses this broadcast's messages went out from, up to 100 of them. A broadcast is spread across every address in its pool, so more than one can appear. The receiving mail systems name the address when they deliver, bounce or defer a message, so this stays absent until the first of those comes back. Returned on a single broadcast read, and absent from the list and from the broadcast that creating, updating, sending or canceling one returns, none of which read them. For delivery and latency broken down per address, read the sending-IP stats.
data.unique_opens_non_prefetchedHow many distinct recipients opened the message at least once, excluding opens auto-fetched by inbox privacy features (such as Apple Mail Privacy Protection and the Gmail image proxy). A recipient who opened several times, or whose inbox prefetched the message, counts once. Absent when sent_count is.
data.unique_clicksHow many distinct recipients clicked a link in the message at least once. A recipient who clicked several times counts once. Absent when sent_count is.
data.out_of_band_bouncesHow many recipients bounced after the message had already been accepted for delivery. A recipient who bounced this way more than once counts once. Absent when sent_count is.
data.delivered_recipientsHow many distinct recipients a delivery landed for. This is the denominator to measure unique_opens_non_prefetched, unique_clicks and complained_count against. It differs from delivered_count, which reports how many recipients are currently in the delivered state: a recipient who was delivered to and then complained moves to complained_count and leaves delivered_count, but stays here, because the message did reach them. Absent when sent_count is.
data.tagsLabels on this broadcast, each one a name and a value, that you can filter and search broadcasts by. Use tags for anything you want to find broadcasts by later, and metadata for data you only want handed back to you.
data.metadataAny JSON you want to keep on the broadcast. We store it and hand it back in webhook payloads, and that is all it does. If you want to search or filter by it, use tags instead.
data.track_opensWhether opens are tracked for this broadcast.
data.track_clicksWhether link clicks are tracked for this broadcast.
data.created_atWhen the broadcast was created.
data.scheduled_atWhen the broadcast is due to send, and absent when it is not scheduled.
data.started_atWhen the broadcast started sending. Absent until then. Compare with sent_at, which is when the broadcast finished sending.
data.sent_atWhen the last recipient was sent to and the broadcast became sent. Null until then. Compare with started_at, which is when the broadcast started sending.
data.canceled_atWhen the broadcast was canceled, and absent if it never was. This is when cancellation was requested, so it is set as soon as the status is canceling and does not move while the remaining sends stop and the status becomes canceled.
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.
Ressources associées
Poursuivez avec la documentation, les guides et les exemples sur ce sujet.