Skip to main content

SMS click-through

The SMS click-through page answers the channel-level question per-link analytics can’t: “what is the click-through rate on this campaign or queue?” Per-link stats under Insights → Links show who clicked a given short URL; this panel rolls those rows up per campaign or messaging queue so SMS click-through compares side by side with the email channel’s Clicked metric. Everything the panel shows is a read-only rollup over the same short-link pipeline that mints tracked links on send, so it can never disagree with the per-link drill-down. For the deep walkthrough (reconciliation math, fixing the untracked share, email parity), see the SMS click-through parity guide; for where links get minted in the first place, see short links and click tracking.

Where to reach it

In the dashboard, open Insights → SMS click-throughs. The same aggregation is available over the API at GET /api/v1/analytics/sms-click-through — see the SMS click-through API reference.

What the panel reads

For each campaign or queue in the selected window, the table reports:
  • Sends — outbound SMS in the window, whether or not they carried a tracked link.
  • Tracked — sends that carried at least one tracked short link.
  • Clicked — sends whose tracked links recorded at least one click.
  • Clicks — raw clicks across the bucket’s links, including bot and link-preview traffic.
  • Verified — clicks that passed the bot/link-preview filter.
  • CTR — clicked sends divided by tracked sends. A bucket with no tracked sends shows , not a misleading zero.
  • Verified CTR — verified clicks divided by tracked sends. Use this when comparing against email’s bot-filtered Clicked metric.
A totals strip above the table aggregates the same numbers across every bucket in the window: total sends, sends with tracked links, sends clicked, overall CTR, and overall verified CTR. The totals cover the whole window, not just the page you’re viewing.

How the panel scopes

Two controls scope the numbers:
  • Group by: Campaign / QueueCampaign buckets on the campaign_id stamped at send time. Queue buckets on the messaging-service id recorded at send time, falling back to the provider tag when no queue resolves — the same precedence the API’s group parameter uses.
  • Window: 24h / 7d / 30d — the trailing aggregation window for every number on the panel.
Switching either control restarts the table at page 1, and the totals strip always covers every bucket in the window.

Reading the unattributed bucket

The unattributed row collects sends where the scoped key never resolved — no campaign_id on the campaign grouping, no resolvable queue on the queue grouping. It is not an error grouping; it catches one-off sends, compose-dialog sends, and older payloads. A large unattributed share means attribution is lost upstream, and the fix is to stamp the key at send time — put campaign_id on the outbound payload, or resolve the queue on your messaging service. Whether a send lands in Tracked at all is decided by the short-URL pipeline, in descending precedence:
  1. metadata.shorten_urls on the send payload — explicit per-send opt-in; rewrites every http(s):// URL in the body into a tracked link and stamps your campaign_id onto it.
  2. SMS auto-shorten (tenant channel setting, default ON) — rewrites URLs longer than 30 characters, but only when the minted short URL is strictly shorter than the original.
  3. WhatsApp auto-track (tenant channel setting, default ON) — the WhatsApp counterpart, which also mints for scheme-less www. spans.
Minting is fire-and-forget: if shortening fails, the original URL ships untouched and the send proceeds — a failed mint lowers the Tracked count, never fails the message. Both tenant settings live on the channel-settings pages in the dashboard. See the short links guide for the mint mechanics.

Verified clicks and bot filtering

The Verified column applies the same predicate the per-link analytics use: a click crosses the verified bar only when its quality score reaches 0.5 — user-agent present, and not a known bot or preview-fetch signature. Raw clicks stay in the store, so the filter lives at the read layer and retro-applies to already-collected data. Comparing raw CTR to email’s Clicked metric is apples-to-oranges — email’s number is already filtered, so use Verified CTR for cross-channel parity. For the scoring rules and why a missing user-agent scores below the bar, see short links and click tracking.

Troubleshooting

  • A bucket shows for CTR. The bucket had no tracked sends, so the rate is undefined — the panel and API return null rather than a misleading zero. Untracked volume (sends minus tracked) is visible per bucket; if that share is high, shorten more of what you send (see above).
  • Unattributed is your biggest bucket. Stamp campaign_id on the payload for campaign sends, or fix queue resolution on your messaging service — both are send-time decisions, not panel settings.
  • Raw and verified numbers disagree. Comparing raw CTR to email’s Clicked metric — email Clicked is bot-filtered, so line it up against Verified CTR instead.

See also