Reading the SMS click-through rollup (Insights → SMS click-through)
The link tracking analytics guide closes with a one-line pointer to this page. This guide is where that pointer lands: Insights → SMS click-through (/insights/sms-ctr) rolls every tracked short link up into a per-campaign (or per-queue) click-through rate — the channel-level answer the per-link view can’t give. If you need the per-link drill-down, go back to Link tracking; if you need the reconciliation math, mint mechanics, or email-parity reading, the SMS click-through parity guide covers those in depth. This page is the operator walkthrough of the rollup itself.
1. The tile map — what the page is made of
Open the dashboard sidebar’s Insights entry; the SMS click-through tile on the hub grid routes into/insights/sms-ctr. One card holds the whole page, top to bottom:
- Header — the title plus two
SegmentedControls: Group by (Campaign / Queue) and the time window (24h / 7d / 30d). - Totals strip — five KPI tiles aggregating every bucket in the window (Section 2).
- Bucket table — one row per campaign or queue, with the per-bucket counters and rates (Section 2).
- Pagination bar — appears only when the window holds more than 25 buckets.
2. KPI tiles and the bucket table
The totals strip carries five tiles, recomputed on every window change:- Sends (window) — outbound SMS in the window, whether or not they carried a tracked link.
- Sends with tracked links — the trackable slice: sends that carried at least one tracked short link.
- Sends clicked — sends whose tracked links recorded at least one click.
- Overall CTR — sends clicked ÷ sends with tracked links, formatted as a one-decimal percentage.
- Verified CTR — verified (bot- and preview-filtered) clicks ÷ sends with tracked links. This is the number that compares against the email channel’s Clicked metric.
— in both rate columns rather than a misleading zero.
Rows sort by tracked sends descending, so buckets where click-through was measurable rank first; the ordering is fixed and the column headers don’t re-sort. Campaign, variant, and link-level follow-up all start from this table (Section 4).
3. Filters and window semantics
Two controls scope every number on the page:- Group by: Campaign / Queue —
Campaignbuckets on thecampaign_idstamped at send time.Queuebuckets on the messaging-service id recorded at send time, falling back to the provider tag when no queue resolves — exactly the precedence the API’sgroupparameter uses. - Window: 24h / 7d / 30d — the trailing aggregation window, defaulting to 7 days. There is deliberately no 90d option here; the schema-backed enum is the three values above, unlike the links page’s wider 1–90 day range.
campaign_id on the campaign grouping, no resolvable queue on the queue grouping — collect in the unattributed bucket. That is a catch-all, not an error grouping; the fix lives at send time (stamp the key on the payload), and the parity guide’s unattributed-bucket section walks through it.
4. Actioning a CTR movement
Reading the number is the start; the page exists to tell you where to go next:- CTR dipped on one campaign — identify the bucket, then open Insights → Link tracking and scope it with
campaign_idfor the per-link breakdown: which URL dragged the rate, and whether raw vs verified says it’s real engagement loss or preview-fetch noise. - Comparing variants — when the campaign ran A/B variants, the campaign A/B testing guide is the read surface for variant-level splits; the rollup here is the campaign-level backstop that tells you whether the whole campaign regressed or one variant did.
- Queue grouping disagrees with campaign grouping — a queue bucket with low CTR and healthy campaign buckets usually means a routing change moved sends into a queue whose recipients behave differently; check the smart-send fallback chains guide if fallback swapping is in play.
- Tracked share is the problem, not CTR — if
untracked(sends − tracked) is the large number, no creative change moves CTR; shorten more of what you send. The parity guide covers the mint switches in precedence order. - Export for a spreadsheet or warehouse — the rollup numbers pull straight from the API (Section 5), which is the reliable way to snapshot tiles into a CSV pipeline. For the per-link CSV, the Export button on the Link tracking page writes a windowed file with summary, top-links, and timeline sections.
- Alert instead of watch — wire a threshold or anomaly rule so a degrading CTR pages you rather than waits for a manual read; the parity guide’s alerting section maps the two rule surfaces.
5. API parity
Every tile on the page maps to one endpoint —GET /api/v1/analytics/sms-click-through — with group and window taking exactly the control values (campaign/queue, 24h/7d/30d) plus page and pageSize (default 25, max 100). The response returns the paged rows, the window-wide totals object, and pagination under the standard { data, meta } envelope. Rate fields come back null when a bucket had no tracked sends — never a fabricated zero.
cURL
6. Common misreads
- Clicks vs link detection. The first is engagement; the second is coverage.
Clickscounts taps on links that were minted;Sends − Trackedis the volume that structurally cannot click. A high CTR on a smallTrackedbase is correct, not inflated — read the tracked share before the rate. - CTR vs delivered rate. The denominator is tracked sends, not delivered messages — SMS has no bounce equivalent, so undelivered sends stay in the denominator and depress CTR. If CTR moved, check delivery health first (usage and delivery anomaly alert rules) before treating it as an engagement problem.
- Raw vs verified CTR. Raw counts bot and link-preview fetches, which spike on send day; verified applies the same quality filter the per-link analytics use. Comparing raw SMS CTR to email’s Clicked metric is apples-to-oranges — email’s number is already filtered.
—is not zero. A bucket with no tracked sends has an undefined rate, and both the page and the API return null. Treating it as a 0.0% regression invents a problem.unattributedis not an error. It’s the catch-all bucket for sends with no resolvable campaign or queue key; its size is an attribution hygiene signal, not a pipeline fault.- The page has no 90-day window. The enum is 24h / 7d / 30d by design. For quarter-scale trend lines, pull the API on a schedule or use the Links insights endpoint’s wider range.
Troubleshooting
- The totals strip disagrees with the visible rows. It aggregates every bucket in the window, including pages beyond the one on screen — that is the correctness guarantee, not a bug.
- A campaign I sent today isn’t a row yet. Buckets appear once the rollup resolves attribution; the 60-second cache means a fresh send lands within about a minute. If it stays absent past that, the send carried no tracked link — check the mint switches.
- The empty state shows but I sent traffic this week. The window may be narrower than your send cadence (a 24h window reads empty between weekly waves). Widen to 7d, and confirm at least one send carried a tracked link — the empty state only clears on sends the pipeline could track.
See also
- Reading link tracking analytics — the per-link drill-down this rollup sits on top of.
- SMS click-through parity guide — reconciliation math, mint switches, unattributed-bucket fixes, and email-parity reading.
- Short links and click tracking — how links get minted, scored, and attributed.
- SMS click-through API reference — the endpoint behind every tile.
- Insights hub orientation — the tile grid and RBAC visibility for the Insights section.