Broadcast statistics
How the broadcast performed: copies sent, delivered, bounced, reported as spam and failed, and how many people opened, clicked and unsubscribed, as totals and as a series cut to `grain`.
Runs the real call on your workspace.
GET /broadcasts/{id}/stats
How the broadcast performed: copies sent, delivered, bounced, reported as spam and failed, and how many people opened, clicked and unsubscribed, as totals and as a series cut to grain.
Parameters
idstringrequired- In the path. A `brd_` id from `POST /broadcasts` or `GET /broadcasts`.
grainstring- Bucket width of the series: `minute`, `hour` or `day`. Defaults to `hour`.
offsetMinutesinteger- Minutes east of UTC to cut the buckets in, from -840 to 840. Defaults to 0. Pass `-new Date().getTimezoneOffset()` for the local zone.
daysinteger- Also reads a window this many days long, from 1 to 1095. It starts at the beginning of its first `grain` bucket and ends now. Leave it and `minutes` out for no window.
minutesinteger- The window in minutes, from 1 to 1576800, which wins over `days` when both are sent.
Example
Needs emails:read.
curl "$OE/broadcasts/brd_5a8c1e3f7b2d94a06c8e1f3b/stats?grain=day&days=7" -H "$AUTH"{ "object": "broadcast_stats", "broadcastId": "brd_5a8c1e3f7b2d94a06c8e1f3b", "grain": "day", "totals": { "recipients": 412, "pending": 0, "sent": 410, "delivered": 404, "bounced": 4, "complained": 1, "failed": 2, "opened": 187, "clicked": 52, "unsubscribed": 3, "opens": 296, "clicks": 71 }, "window": { "since": "2026-09-18T00:00:00.000Z", "delivered": 404, "bounced": 4, "complained": 1, "opened": 187, "clicked": 52, "unsubscribed": 3 }, "series": [ { "bucket": "2026-09-23", "delivered": 404, "opened": 161, "clicked": 45, "unsubscribed": 3 }, { "bucket": "2026-09-24", "delivered": 0, "opened": 26, "clicked": 7, "unsubscribed": 0 } ], "links": [ { "url": "https://acme.com/changelog", "label": "Read the changelog", "clicks": 48, "people": 39 }, { "url": "https://acme.com/pricing", "label": null, "clicks": 17, "people": 15 } ], "clients": [ { "client": "Apple Mail", "people": 92, "opens": 141 }, { "client": "Gmail", "people": 71, "opens": 109 }, { "client": null, "people": 24, "opens": 46 } ], "countries": [ { "country": "US", "people": 88 }, { "country": "DE", "people": 41 } ], "abTest": { "metric": "opens", "winner": "b", "variants": [ { "id": "a", "subject": null, "sent": 41, "opened": 15, "clicked": 4 }, { "id": "b", "subject": "Five things we shipped in September", "sent": 41, "opened": 21, "clicked": 6 } ] }}opened, clicked and unsubscribed count people, while opens and clicks count events. pending counts the copies still queued, scheduled or sending, and failed the copies that failed or were cancelled.
series is sparse and oldest first: one bucket per grain in which something happened. It counts each person once, at the first time it happened to them, so it adds up to the totals.
bucket is YYYY-MM-DD, YYYY-MM-DDTHH or YYYY-MM-DDTHH:MM, in the offset asked for.
window counts the copies delivered, bounced, reported as spam, opened, clicked and unsubscribed inside the window, and series then keeps only its buckets. totals always covers the whole broadcast. Without days or minutes, window is null.
links lists up to 10 links, most clicked first, each with the people who clicked it and its clicks. clients lists up to 8 email apps the copies were opened in and countries up to 10 countries they were opened from, each counting people. Opens a mail provider makes by itself, such as a privacy proxy fetching the images, are left out.
abTest is null unless the broadcast runs an A/B test. Then it holds the metric, the winner once one is picked, and for each version its id, its subject (null when it keeps the broadcast's own), the copies sent and the people who opened and clicked.
Refusals
| Status | Code | When |
|---|---|---|
| 400 | invalid_cursor | On the recipients list, a cursor that list did not hand out. |
| 403 | insufficient_scope | The key does not hold emails:read. |
| 404 | broadcast_not_found | The id names no broadcast in this workspace, or the key is limited to particular addresses or domains and the broadcast was sent from one it does not hold. |
| 404 | recipient_not_found | On GET /broadcasts/{id}/recipients/{emailId}, an emailId that is not a copy of this broadcast. |