Performance tracking
Every campaign recipient is sent as an individual tracked email, so opens, clicks, bounces, and complaints surface per-contact in the dashboard and via webhooks.
A campaign is not a single send — it fans out into one tracked email per recipient. Each of those emails is logged exactly like a transactional `POST /emails` send, with its own id, status, and event timeline.
That means campaign performance reuses the same delivery, open, and click tracking as the rest of the platform — there is no separate analytics surface to learn.
What is tracked
- Delivery —
email.sent,email.delivered, andemail.delivery_delayedper recipient. - Engagement —
email.openedandemail.clicked, when open/click tracking is enabled on the sending domain. - Negative signals —
email.bouncedandemail.complained, which also add the address to your account suppression list. - Unsubscribes — recipients who opt out via the per-campaign unsubscribe link, flipping that contact to
unsubscribedin the audience.
Headline metrics
Open a sent campaign in the dashboard to see its performance right away. The headline insights are:
- Emails delivered — how many copies the receiving servers accepted.
- Open rate — the share of delivered emails that were opened.
- Click rate — the share of delivered emails with at least one tracked-link click.
- Replied, Bounced and Complained — the raw counts behind those signals.
Reading results
Each recipient email carries an event log you can read the same way as any other email:
- In the dashboard, open the campaign to see per-recipient status and aggregate delivery, open, and click counts.
- Via the API, retrieve an individual recipient email with `GET /emails/:id` to inspect its
last_eventand status. - Via webhooks, subscribe to the
email.*events to stream delivery and engagement to your own systems in real time. See Event types.
Aggregate stats endpoint
For a single rolled-up view, call GET /campaigns/:id/stats. It returns the campaign’s aggregate open and click counts (with the underlying delivered/sent totals, plus replies, bounces and complaints) and the top clicked links — the same numbers shown on the dashboard, fetched in one request.
import { Mailblastr } from 'mailblastr';
const mb = new Mailblastr('mb_xxxxxxxxx');
const { data, error } = await mb.campaigns.stats('CAMPAIGN_ID');
console.log({ data, error });It returns a campaign_stats object. The counts are total (one per recipient copy sent), delivered, opened, clicked, replied, bounced and complained — opened, clicked and replied are unique per recipient, not raw event counts. The rates object carries delivery, open, click, reply, bounce and complaint as percentages: open, click and reply are measured against delivered (falling back to total when no delivery events were recorded), while delivery, bounce and complaint are measured against total. Every rate is a percentage rounded to one decimal place (so 98.1, not 98.06). links lists the top clicked tracked links as { url, clicks }, ordered by clicks descending, and is capped at the 50 most-clicked links.
{
"object": "campaign_stats",
"campaign_id": "8f5c2a1e-7b3d-4f9a-9c12-2e6d4a7b8c90",
"total": 1240,
"delivered": 1216,
"opened": 498,
"clicked": 96,
"replied": 12,
"bounced": 18,
"complained": 1,
"rates": {
"delivery": 98.1,
"open": 41,
"click": 7.9,
"reply": 1,
"bounce": 1.5,
"complaint": 0.1
},
"links": [
{ "url": "https://yourdomain.com/whats-new", "clicks": 74 },
{ "url": "https://yourdomain.com/pricing", "clicks": 22 }
]
}The same fields (without object, campaign_id and links) are returned inline as the statistics field of `GET /campaigns/:id`. Errors: not_found if the campaign does not exist or is not yours.
Because bounces and complaints feed account-wide suppression, contacts that hard-bounce or complain are automatically excluded from subsequent campaigns — keeping your sender reputation healthy without manual list hygiene.