Tracking & Reporting

Dave Hilditch

Every email Super Speedy Emails sends is logged. Every event your email provider reports back (delivered, opened, clicked, bounced, complained, unsubscribed) is recorded against that send. This page covers what gets tracked, where to view it, and what the various states mean.

Delivery/open/click/bounce tracking requires a connected provider (such as Mailgun) that reports events back via webhook. With None (wp_mail) selected, sending still works and is logged as sent, but the log can’t progress to delivered/opened/etc. because nothing reports back. See Choosing & Configuring an Email Provider. The examples below use Mailgun, the fully-supported provider today.


The Dashboard — your at-a-glance view

The Super Speedy Emails → Dashboard is the first thing to check day to day. It shows your subscriber, list, and form counts, your most recent subscribers, and a per-list subscriber breakdown — a quick read on whether signups are flowing and which lists are growing. Use it as the “is everything healthy?” glance; use the per-campaign and per-subscriber reports below when you need detail on a specific send.

“Did my campaign land?” — the everyday workflow

After sending a campaign, this is the loop most people actually run:

  1. Open the campaign under SSE Emails → Campaigns and read its report (Sent / Delivered / Opened / Clicked / Bounced / Complained / Unsubscribed — detailed below).
  2. Sent but not Delivered yet? Delivery webhooks arrive over seconds-to-minutes. Give it a little time, then refresh. If Delivered stays well below Sent, check your provider’s own dashboard and your DNS/authentication.
  3. High Bounced? Your list has stale addresses — see Bounces, Complaints & Deliverability. The bounced addresses are now auto-suppressed.
  4. Any Complained? Even a few on a marketing send is a signal to look at your content/frequency; the complainers are auto-unsubscribed from marketing.
  5. Chasing one person? Use the per-subscriber Email history (below) — it answers “did this customer get it?” definitively.

If you’re testing rather than sending for real, the report still populates in Log-only/Redirect modes (filter by the test_mode column), so you can rehearse and read the outcome without emailing anyone. See Test Modes.

What gets recorded per message

When SSE attempts a send, it creates a row in sse_email_log before asking wp_mail() to dispatch:

ColumnMeaning
subscriber_idWho it’s going to
emailCaptured at send-time (in case the subscriber row changes later)
campaign_id / automation_idWhat sent it (nullable for ad-hoc transactional)
categorynewsletter / product_support / etc.
legal_basisconsent / legitimate_interest / service
subjectThe subject as sent
statusqueued → sent → delivered → opened / clicked / bounced / complained
test_modelive / log_only / redirect
mailgun_message_idThe Message-Id from MailGun’s accept response
opened_at / clicked_at / bounced_at / complained_at / unsubscribed_atFirst-event timestamps
open_count / click_countCumulative event counters
contextJSON snapshot of merge data (order_id, post_id, etc. — for support replies)

The row starts at status = queued. When the queue drainer hands it to wp_mail(), it flips to sent. Webhook events from MailGun then progress it through delivered / opened / clicked / etc.


What the statuses mean

StatusWhat just happened
queuedThe send pipeline has accepted the message; it’s waiting in the queue.
sentwp_mail() returned true; the message is in MailGun’s hands.
deliveredMailGun says the receiving mail server accepted it.
openedRecipient opened the email (tracking pixel loaded).
clickedRecipient clicked a tracked link. (Sets clicked_at; opened_at is also set if not already.)
bouncedPermanent (hard) failure — the receiving server rejected the message. Inserts a global suppression row automatically (the address can’t receive anything).
complainedRecipient marked it as spam. Inserts a marketing suppression row automatically — they stop getting marketing, but essential transactional mail (receipts, security) is unaffected.
failedwp_mail() returned false — the message never left WordPress. Check your provider / SMTP plugin configuration.

Important nuance about opens and clicks: MailGun’s open tracking depends on the recipient’s email client loading remote images. Apple Mail Privacy Protection pre-fetches everything, which inflates open rates. Many corporate email gateways strip tracking pixels entirely. So opens are a floor on engagement, not a precise measurement.

Clicks are more reliable, but only because they require an active recipient action.


Per-campaign report

Open any sent campaign from SSE Emails > Campaigns. The detail page shows:

  • Sent — total messages queued (after suppression mask)
  • Delivered — confirmed delivery webhook count
  • Opened — unique opens (counted once per recipient even if they opened 5 times)
  • Clicked — unique clicks
  • Bounced — permanent failures
  • Complained — spam complaints
  • Unsubscribed — clicks on the unsubscribe link

Each row also shows the first event timestamps so you can see how fast a campaign got picked up.


Per-subscriber email history

On any subscriber’s detail page (SSE Emails > Subscribers > [click subscriber]), there’s an Email history tab listing every send to that address, with category, subject, status, timestamps.

This is critical for support. When a customer says “I never got my license email”, you can:

  1. Look up their subscriber row.
  2. Open Email history.
  3. See: license email was sent on date X, MailGun accepted it, status is delivered (or bounced, or never got past sent).
  4. Reply with confidence: “Our records show it was delivered at 14:23 — please check your spam folder” or “It bounced at delivery time — what’s the exact address spelling?”

Without this trail, the answer is always a guess.


Where webhook events live

Your provider’s events arrive at a webhook route (for Mailgun, /wp-json/sse/v1/mailgun-webhook, configured in MailGun Setup). Each event is:

  1. Cryptographically verified before it’s trusted — Mailgun events are HMAC-verified against the signing key, with a replay window. (Forged events from an unverified source are rejected, so nobody can fake a bounce to suppress an address.)
  2. Persisted raw to sse_email_events (append-only, full payload).
  3. Matched to the corresponding sse_email_log row via the sse_log_id variable injected when sending.
  4. The log row’s status + first-event timestamp + count is updated, and bounce/complaint/unsubscribe events add the appropriate suppression automatically.

Raw events are kept indefinitely. Day-to-day reporting reads from the aggregated columns on sse_email_log; raw events are for forensic deep-dives (e.g. “what was the exact bounce reason from the receiving server?”).


Filtering and bulk views

Useful queries you can run directly:

Bounce rate per campaign

SELECT
  campaign_id,
  COUNT(*) AS total,
  SUM(status = 'bounced') AS bounces,
  ROUND(100 * SUM(status = 'bounced') / COUNT(*), 2) AS bounce_pct
FROM wp_sse_email_log
WHERE campaign_id IS NOT NULL
GROUP BY campaign_id
ORDER BY bounce_pct DESC;

Per-category complaint rate

SELECT
  category,
  COUNT(*) AS total,
  SUM(status = 'complained') AS complaints
FROM wp_sse_email_log
GROUP BY category;

A complaint rate above ~0.1% on marketing categories is a warning sign — MailGun starts throttling deliverability around 0.3-0.5%.

Recent failed sends

SELECT email, subject, error, created_at
FROM wp_sse_email_log
WHERE status = 'failed'
ORDER BY created_at DESC
LIMIT 50;

If you see a lot of these clustered in time, your SMTP/MailGun plugin is having issues.


What about tracking-pixel privacy?

MailGun’s open tracking inserts a 1×1 transparent image hosted on MailGun. This is the standard mechanism but has well-known privacy trade-offs:

  • It leaks the recipient’s IP / approximate location to MailGun.
  • Apple Mail Privacy Protection fakes all opens.
  • Privacy-focused recipients reasonably consider it intrusive.

Open and click tracking are the provider’s, not SSE’s — SSE neither inserts the pixel nor rewrites links; it only receives the resulting webhook events and records them in sse_email_log / sse_email_events. So you enable or disable tracking in MailGun’s own settings (open tracking / click tracking per domain), not via SSE. With tracking off, SSE still logs delivery and bounce/complaint events; you just won’t get open/click counts.

For a plain-text-first newsletter, click tracking is usually the more useful signal anyway, and it doesn’t require pixel loading — MailGun does it by rewriting links.

Prerequisite: SSE sends through wp_mail; it does not route mail to MailGun itself. For any of this tracking to work you need a separate plugin (the official MailGun plugin, or an SMTP plugin with a MailGun mailer) routing wp_mail through MailGun, plus the MailGun webhook configured (see MailGun Setup). In the SSE admin, open/click counts are shown per Campaign; support/product-update emails record the same events but have no dedicated open/click report on the Support Emails screen — view those in the MailGun dashboard.


What does NOT get tracked

  • The text of the actual email body. We log subject + category + context, but the rendered body is regenerated from the campaign template + merge data at send time. If you delete the campaign, you can no longer reconstruct what specific people saw.
  • Email reads in offline mode (no tracking pixel can phone home).
  • Forwards (no way to detect).
  • The recipient’s IP / location (not logged from MailGun events).

Compliance: the audit trail

Combining the columns on sse_email_log gives a complete GDPR audit trail:

  • legal_basiswhy we sent it (consent / legitimate_interest / service)
  • categorywhat type of communication
  • sse_subscribers.confirmed_atwhen consent was given (for marketing)
  • sse_suppressions.created_atwhen consent was withdrawn
  • unsubscribed_at on the log row — whether this specific message was the unsubscribe trigger

If someone asks under right-of-access (GDPR Article 15) “show me every email you ever sent me”, an export query against sse_email_log filtered by subscriber_id is the complete answer.


Retention

Currently nothing is auto-pruned. The audit log grows with every send. A site sending 10k newsletter emails a week will accumulate ~520k log rows a year; at ~1KB per row that’s ~500MB. Workable but not free.

A retention policy is on the roadmap — likely “keep raw events for 90 days; keep log rows forever but compress old context JSON.” For now, monitor the table size and consider archiving old rows if it becomes a concern.


Leave a Reply

Your email address will not be published. Required fields are marked *

×
1/1