> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Reading link tracking analytics (Insights → Link tracking)

> Operator workflow for the /insights/links page: summary KPI cards, the top click-throughs ranking, the per-day click timeline, the per-link drill-down, CSV export, and the campaign-scoped API parity behind every tile.

# Reading link tracking analytics (Insights → Link tracking)

This is the post-send reading workflow: a campaign went out with tracked short links, and now you want to know what recipients tapped. The **Insights → Link tracking** page answers that in one screen — tenant-wide KPIs, a ranking of the most-clicked links, a day-by-day click chart, and a per-link drill-down — with CSV export and manual link management on the same page.

Everything on this page is read over the same endpoints the API serves, so what you see in the dashboard is exactly what you can pull programmatically (Section 9). Minting and attribution are covered end to end in [short links with click tracking](/guides/short-links-and-click-tracking) — this page references that guide rather than re-explaining the mint side.

## 1. Where to reach it

Open the dashboard sidebar's **Insights** entry — the **Link Tracking** tile on the hub grid routes into `/insights/links`. Direct URLs work the same: bookmark or share `/insights/links` and it renders straight to the page, inside the same workspace and org role your session resolved.

The page has six blocks, top to bottom: the header (window selector + export), the summary KPI cards, the click timeline, the top click-throughs ranking, then the **All links** management table with mint and delete. A fetch failure on the read query shows an error panel with **Retry** — it never renders a healthy-looking empty dashboard.

## 2. The summary KPI cards

Five cards sit across the top and recompute on every window change:

* **Total links** — short links minted on this workspace (all-time count, not window-scoped).
* **Clicks (window)** — raw click count inside the selected window, with a per-day sparkline behind the number.
* **Verified clicks** — the same count after bot and link-preview filtering, with a subtitle showing what share of raw clicks qualified as human (e.g. `42% of clicks`). A **verified click** means `quality_score >= 0.5`, exactly as defined in the [short links guide](/guides/short-links-and-click-tracking#5-click-quality-signals--human-vs-scanner).
* **Unique visitors** — distinct clickers in the window.
* **Avg clicks / link** — raw window clicks divided by total links.

The **window selector** in the header offers **24h, 7d, 14d, 30d, 90d**, defaulting to 7 days. On the API the same control is `window_days` on `GET /api/v1/links/insights` — default 7, accepted range 1–90. Out-of-range values clamp to the bounds rather than rejecting, so `window_days=365` returns the 90-day envelope, not a 422.

## 3. Top click-throughs — the ranking

The ranking card lists the ten most-clicked links in the window (the dashboard pins `top_limit=10`; the API accepts 1–50, default 10). Rows are sorted by raw click count descending, so a link heavy on link-preview fetches can outrank a link heavy on human taps. Read the two count columns together: **Clicks** is raw, **Verified** is human-filtered, **Unique** is distinct clickers — a high raw count paired with a near-zero verified count is the preview-fetch signature, not a breakout destination.

Each row's **Detail** action opens an inline summary (short code, campaign, destination, and the three counters) built from the ranking data itself — no extra request. The full click-history drill-down for a link lives in the **All links** table (Section 5).

When a link is missing from the ranking entirely: it had zero clicks in the selected window, or it sits below the top-N cutoff for a busy tenant. Widen the window, or find it in the **All links** table, which lists every link on the workspace regardless of rank.

## 4. Per-day click timeline

The timeline card plots one bar per day across the selected window — daily click count across every shortened URL, with the exact figure on hover. Read it against your send calendar: a stair-step spike landing the day a broadcast or campaign wave went out is the send correlating; a flat plateau with a sudden single-day spike is one link getting shared.

The series is raw clicks, so platform link-preview fetches inflate the bar on send day itself (WhatsApp and several messaging clients prefetch a link the moment it renders). Use the verified share subtitle on the KPI cards to discount send-day inflation before treating a spike as response data.

## 5. Per-link drill-down — the click history

In the **All links** table, clicking a row opens its **Link stats** dialog: the short code, total clicks, campaign, and destination, followed by the **Recent clicks** table — the 50 most recent click events, newest first, one row per click with a timestamp, type, IP, and country. The **Type** column is the raw vs verified split applied per click: a verified click renders as **Human**, a bot-classified click (see the verified predicate above) renders as **Bot** — so you can scroll the history and read exactly which events fell below the threshold, with no threshold kept hidden.

This is the device-forensics view — it shows IP and user context per click, unlike the per-contact loop (`GET /api/v1/links/contacts/{contactId}/clicks`), which deliberately drops those fields. A link with no taps yet shows an empty state ("No clicks recorded yet") rather than an empty table.

## 6. CSV export

The **Export** button in the header downloads `orbit-link-insights-<window>d-<date>.csv` — a snapshot of exactly what the page shows, for re-reading in a spreadsheet or feeding a warehouse. The file carries three sections back to back:

1. **Link Insights Summary** — `Metric,Value` rows: total links, clicks in the window, verified clicks, unique visitors, and average clicks per link.
2. **Top links** — columns `Short URL, Original URL, Campaign, Total clicks, Verified clicks, Unique visitors` (an un-attributed link's Campaign cell is empty).
3. **Click timeline** — `Date,Clicks` rows, one per day of the window.

The export inherits the window you selected, and the button stays inert until the first load completes — exporting before data arrives would render an empty file.

## 7. Minting and deleting from the same page

The **All links** table is also the management surface. **Create link** opens the manual mint dialog — paste a destination URL, optionally scope it to a campaign, and the minted short URL appears with a copy action. **Delete** runs through a confirmation dialog: the short URL stops redirecting immediately and its click history is removed with it — there is no way to delete a link while keeping its clicks.

Both flows are covered end to end in the [short links guide](/guides/short-links-and-click-tracking) — including `POST /api/v1/links` for manual mints and `DELETE /api/v1/links/:id` for deletes. This page is the dashboard's entry point into the same contract, not a separate surface.

## 8. Who sees the tile

The Link Tracking tile renders for every member of the workspace — owner, admin, developer, and viewer seats alike — per the hub's [RBAC visibility](/insights/overview#rbac-visibility) rules; the read endpoints are genuinely member-readable. Destructive actions are narrower: the create and delete controls render only for owner/admin/developer seats, matching the role guard `POST /api/v1/links` and `DELETE /api/v1/links/:id` enforce — a viewer reads the full analytics and drill-down but never sees the write buttons.

## 9. API parity

Every card on the page maps to a read endpoint you can call directly with your API key:

* `GET /api/v1/links/insights` — backs the KPI cards, the top click-throughs ranking, and the timeline in one call: the `summary` block, the `top_links` ranking, and the `timeline` series. Params: `window_days` (default 7, 1–90), `top_limit` (default 10, 1–50), and `campaign_id` for scoping.
* `GET /api/v1/links/:id/stats` — backs the drill-down dialog: the link record plus `recent_clicks` (row-level history, 50 rows, newest-first) and `clicks_by_day` (per-link daily aggregate, up to 30 days).
* `GET /api/v1/links/:id/clicks` — an alternative per-click history view over the same recorded click events; the dashboard drill-down reads the `stats` response instead.

Scopes behave exactly as the canonical rule in the [short links guide](/guides/short-links-and-click-tracking#7-tenant-level-totals--the-insights--link-tracking-rollup) states: **the tenant rollup is never the sum of your per-campaign totals.** Without `campaign_id`, `GET /api/v1/links/insights` intentionally includes every link the workspace minted — including the un-attributed bucket (one-off mints with no `campaign_id`, plus auto-shortened SMS/WhatsApp sends whose attribution arrives later through the originating message). Pass `campaign_id` when you want a campaign-only cut, and a "campaigns sum less than the tenant total" reading is the system working, not missing data.

For runnable request/response pairs against all three endpoints see the [link tracking analytics API samples](/guides/link-tracking-api-samples) guide; for request and response schemas see the [links API reference](/api-reference/links).

## Troubleshooting

* **My campaign totals don't add up to the tenant total.** Working as designed — the tenant rollup includes the un-attributed bucket. Scope with `campaign_id` for a campaign-only cut, exactly as Section 9 describes.
* **The top ranking looks inflated right after a WhatsApp send.** Raw clicks count link-preview fetches by design. Read the **Verified** column or the verified-share subtitle — the preview UA classifies below the verified threshold and drops out cleanly.
* **A link I know got clicks isn't in the ranking.** It ranked below the top-N cutoff in this window, or its clicks fell outside it. Widen the window or open it from the **All links** table.
* **The KPI row shows all zeros.** Check the window first — a 24h window on a weekly campaign reads empty between sends. If the error panel shows instead, use **Retry**: the page distinguishes a genuinely empty window from a failed fetch.

## See also

* [Short links with click tracking](/guides/short-links-and-click-tracking) — minting, branded short domains, attribution, and the `short_link.click` webhook.
* [Link tracking analytics API samples](/guides/link-tracking-api-samples) — runnable read-side samples for every endpoint on this page.
* [Short links cookbook](/guides/short-links-cookbook) — recipes for the mint and attribution surfaces.
* [Insights → SMS click-through](/insights/sms-ctr) — the channel-level CTR rollup that layers on top of link tracking.
* [Insights hub orientation](/insights/overview) — the tile grid this page joins from, including the RBAC visibility table.
