Every send of a broadcast is a run. A broadcast on a repeating schedule sends again and again from one record. Its headline numbers are the latest run's, and earlier runs keep their own (the last 50). Each person in a run has one delivery row (broadcast_delivery), and every number below is counted from those rows.
This skill only reads. It sends nothing.
Ask first
- Which broadcast? By name. If several match, list them with their status and when they ran, and ask.
- Which run? Only for a repeating broadcast. The default is the latest.
- What they want to know. The numbers, the people behind one of them, or why it failed.
Steps
1. Broadcast: find it and its state
Find the email_broadcast by data.name (or data.broadcastName). Note its sk, channel, status and currentRunId.
status | Means |
|---|---|
draft | never sent; there is nothing to report |
scheduled | waiting for its time |
pending | about to send; a sweep every five minutes starts it, or it is held by quiet hours (deferredReason = quiet_hours) |
sending / paused | a run is going / held where it is |
completed | the run is over and at least one message went |
failed | nothing went. The reason is errors[0].errorMessage, e.g. No recipients found, No sender accounts configured, email gateway not configured, The Bulk Email service agreement has not been accepted. |
cancelled | stopped; people not reached yet were not sent to |
A run with nobody new to send to ends completed with a note, e.g. Everyone on the list was already sent this.
Hands on: the broadcast's sk and status.
Check: open it (/broadcast?openId=<sk>). A sent broadcast opens on its Summary tab.
2. Broadcast: the numbers
call_appengine GET /broadcast/<sk>/stats (add ?runId=<id> for an earlier run; the runs list in the answer has every run's id, dates and numbers).
metrics | Counts the people whose row… |
|---|---|
total | was queued for the run |
sent | went out (sent, delivered, opened or clicked) |
failed | could not be sent, with a reason on the row |
delivered | the gateway confirmed delivered (see the warning) |
opened | has at least one open |
clicked | has at least one click |
bounced | bounced |
spamComplaints | was reported as spam |
unsubscribed | clicked this email's unsubscribe link |
rates (deliveryRate, openRate, clickRate, bounceRate) are percentages of total, not of sent. When reporting, also say how many were sent, so a list with failures doesn't look worse than it is. The broadcast record's own metrics.suppressed says how many were left out at send time as unsubscribed, bounced or complained.
Where the numbers come from:
- Email opens, clicks, bounces, complaints and deliveries come from the email gateway's events. Only Amazon SES events update the rows. On any other gateway these stay at 0, and that is not "nobody opened".
- Texts and WhatsApp: delivered and failed come from the carrier's status updates. A WhatsApp read counts as opened. Texts have no opens or clicks.
- Unsubscribed is the platform's own link, so it counts on every gateway.
delivered undercounts. A row moves from delivered to opened when the person opens it, and delivered counts only rows still at delivered. For "how many got it", give delivered + opened, and say that is the floor.
Hands on: the numbers, with sent and total. Check: the Summary → Overview tiles in the composer show the same figures. A broadcast with more than one run shows its runs there, newest first.
3. Broadcast: the people behind a number
GET /broadcast/<sk>/report?status=<filter>&page=1&pageSize=100 (and &runId=<id>). status is one of opened, clicked, unsubscribed, delivered, bounced, failed, or leave it out for everyone. Page through total.
Each row gives recipient (the address or number), status, error, from, subject, sentAt, deliveredAt, failedAt, unsubscribedAt, openCount and clickCount.
- Which links were clicked: read the
broadcast_deliveryrows themselves (find_recordswithdata.broadcastId= the sk,data.runId= the run,data.clickCount> 0). Each holdsclickedUrls. - Why sends failed: group the
failedrows byerrorand give the top reasons with their counts, not every row.
Hands on: the people, or the reasons. Check: Summary → Delivery log in the composer, filtered the same way.
4. Broadcast: who is off the list for good
GET /broadcast/suppression (with status, search, page, pageSize) lists the addresses the business may no longer bulk-email: counts of unsubscribed, complained and bounced, and for each address the reason and, when it came from a broadcast, its broadcastId.
Check: Broadcast → Unsubscribes (/broadcast?tab=suppression).
Stop
Nothing in this skill sends. Two things near it are the person's to decide:
- Putting an address back (
POST /broadcast/suppression/remove) only at that person's own request. Re-mailing someone who opted out is how a sending domain gets blocked. - Sending again to anyone. A follow-up to the people who didn't open is its own draft: Follow-up to people who didn't open.
When it's done
Tell the person, for the run asked about:
- when it went, how many were queued and how many were sent;
- delivered (as
delivered + opened), opened, clicked, unsubscribed, bounced, with the rates; - what failed and why, in a line or two;
- which numbers can't be trusted on their gateway (opens and clicks off SES; none for texts).
What it can't do yet
- Opens and clicks only on Amazon SES. Other gateways report none.
deliveredundercounts, as above.- The Analytics tab is a placeholder. It says "Analytics dashboard coming soon". Use each broadcast's Summary.
- The Summary's Activity tab is not this broadcast's. It lists the business's recent email events across every send.
- A bounce or spam report only blocks an address that already has a subscriber record. A contact who bounced but never had one stays on the list and is emailed again next time.
- No comparison across broadcasts. Read each one's stats.
Don'ts
- Don't report a 0% open rate as "nobody opened" before checking the gateway reports opens.
- Don't divide by
sentand call it the platform's rate. The platform's rates are oftotal. - Don't remove anyone from the suppression list, or start a send, from a reporting request.