WarpLink
Concepts

Link Analytics

How WarpLink counts clicks, deduplicates them, filters bots, and joins installs to the links that drove them, per plan retention window.

WarpLink records every click and every attributed install when it happens, shows recent taps in the dashboard within minutes, and reports them per link and per campaign. Deep linking, install attribution, and real-time analytics come from the same SDK, so the numbers describe the same links you configured, not a separate system you reconcile by hand.

What Counts as a Click

A click is recorded when a visitor's request reaches a link and is not a bot. Recording happens on a path separate from the redirect itself, so counting never delays the person tapping the link.

Before a click is ever written, WarpLink checks the request's user agent against a bot and crawler list. A bot request never becomes a click: it is excluded at that check, not filtered out afterward, so there is no "bot clicks" number to subtract. A bot that WarpLink recognizes as a social media or chat crawler gets an HTML page with Open Graph and Twitter Card tags instead, for a rich preview. A real visitor gets the redirect, and that request is what gets counted.

Unique Clicks

Unique clicks answer a narrower question than total clicks: how many distinct visitors, not how many taps. WarpLink computes uniqueness server side, at the moment a click is written: clicks are deduplicated per link and IP-derived identifier over a rolling twenty-four hour window, computed exactly for that rule.

A click counts as unique per combination of link, visitor address, and that rolling twenty-four hour window. One person tapping the same link four times in an hour is one unique click and four total clicks. The same person tapping it again the next day adds a second unique click.

Joining Installs to Clicks

Installs are attributed back to the link click that drove them and shown per link alongside your click numbers. The match itself, referrer, device ID, probabilistic match, or raw signals, and the confidence score behind each one, is covered in Install attribution.

Retention by Plan

How far back you can look is set by your plan. Retention is enforced, not just marketed: data older than the window is removed on a schedule, not merely hidden from view.

PlanRetention
Free90 days retained, last 30 days readable
Starter180 days
Growth365 days
Scale3 years
Unlimited3 years

Free Plan Analytics Limits

Redirects always work. A link never stops routing visitors because of a click limit, on any plan. Links on your app's own aplnk.to address never stop redirecting. A custom domain serves while your plan includes it: the Free plan includes a 90-day trial (about 3 months), and after a paid plan ends there is a grace period of up to 30 days (see plan changes).

Free has every traffic analytics feature, with two limits on how it reads.

Last 30 days. A Free org reads the last 30 days of analytics. Free data is still kept for 90 days, so an upgrade shows the older days at once. A date range that starts before the last 30 days is refused, not shortened: the dashboard marks the locked days in the date picker, and REST and MCP return LOOKBACK_EXCEEDED (403) with details.earliest_allowed, the first instant a Free org may read. A comparison works on Free only when the earlier period also starts inside the last 30 days. Exports follow the same 30 days.

Frozen at the click limit. Once a Free org reaches its 10,000 monthly clicks, analytics freeze instead of going dark. Every figure stops at the moment the limit was reached and stays readable. Clicks keep being stored, and they appear after an upgrade, or when the next billing period starts and analytics go live again. REST and MCP reads say so: the receipt carries paused as { reached_at, limit }, the effective window ends at that moment, and a warning explains why. Paid plans are never frozen. The dashboard warns you at 50, 80, and 90 percent of your limit before that happens.

What each limit actually does

SituationFreePaid plans
Over your monthly click capRedirects keep working. Analytics freeze at the moment the limit was reached, and clicks are still recorded. They appear after an upgrade or in the next billing period. No extra charge.Redirects keep working. Analytics is never frozen. No extra charge.
Custom domain trialOne trial domain for 90 days (about 3 months). That domain's click history is deleted every 30 days. Links on the trial domain stop redirecting once the 90 days end, unless you upgrade.Not applicable. Paid custom domains have no resets and serve while your plan includes them, with a grace period of up to 30 days after a paid plan ends.

See Custom Domains for the trial in full.

Reading Analytics

In the dashboard, clicks are recorded at tap time, and recent taps show in the dashboard within minutes. The Analytics page reads Today, 7 days, 30 days, 90 days, or a custom range, and breaks the same clicks down by country, referrer, device, operating system, browser, campaign source, app, and tap source, per link or org wide. Trends run through the current day in your organization's reporting time zone, with the still-running day marked as in progress rather than shown as a lower total. The page leads with a headline sentence and the key numbers, then the trend against the previous period, a breakdown grid, and a links leaderboard of top movers, new links, and active links with no taps. The Compare Links page puts two to five links next to each other over the same window.

Check up to 25 values within a dimension to filter by all of them at once, and combine checked values across more than one dimension: values checked in the same dimension are an OR (any of them matches), and dimensions combine with AND (every checked dimension must match). Turn on the comparison switch to see the totals against the previous period, side by side. Once a dimension has two or more values checked, a Combined/Split control appears: Combined keeps one OR'd total and trend line, and Split draws one line and one total per checked value, up to five series at a time, with the rest counted but not drawn.

Some states say what they are, in words, instead of showing a number that looks final. A period outside your plan's retention window says that, instead of showing zero. On a Free plan, a range that starts before the last 30 days says it is locked and names the first day you can read. A Free org at its click limit sees the figures as they stood when the limit was reached, marked as paused.

For a copy you can move elsewhere, export raw click rows as CSV, including UTM term and content and whether each row was the unique click. An export covers the whole organization or one link. Exports respect your plan's retention window the same way the dashboard does, and record the reporting time zone they were built with, so a zone change afterward never relabels a file you already downloaded. An export starts processing as soon as you create it and is usually ready within minutes. The file stays available to download for 7 days after it completes. An AI client can do the same through the export_analytics MCP tool, which creates, checks, and downloads an export with the same retention window and CSV shape.

An AI client can also pull a link's totals, unique clicks, a time series (including installs per day), and its redirect versus app open split, through the MCP server's get_link_analytics tool. Daily buckets follow the organization's reporting timezone, and an optional timezone input (an IANA name such as UTC) chooses another. For the same numbers the Analytics page shows, use query_analytics, described below. The tool needs either the analytics:read or the links:read scope and is free on every plan, sharing the standard 60 requests a minute. It follows the same Free plan limits as the dashboard: a range that starts before the last 30 days returns LOOKBACK_EXCEEDED with details.earliest_allowed (as the tool error text and as structuredContent), and once a Free plan org has used its monthly clicks, the totals stop at the moment the limit was reached and the result carries paused as { reached_at, limit }, until the next billing period or a move to a paid plan.

The match tile on the Overview shows the share of new installs that asked which link brought them and were tied to a link someone tapped. Next to the rate sits a health status. It rests on the match rate among new installs where a tap was found, which leaves out installs that had no tap on record:

StatusMatch rate where a tap was found
Healthy80% or more
Needs attention50% to under 80%
LowUnder 50%

The status appears once at least 50 such installs are counted. Before that the tile says "Not enough installs yet". The rate is cut to one decimal, never rounded up, so a rate shown as 80.0% is never judged below Healthy. The "Why installs don't match" page, linked from the tile, lists the reasons installs were not tied to a link, biggest first. Over REST and MCP, attempt_match_rate keeps its numerator and denominator and gains tap_found with numerator, denominator, display, and status (healthy, needs_attention, low, or not_enough_installs).

The Analytics page signals over MCP and the REST API

For why the page was rebuilt this way, read what changed in WarpLink analytics, and why.

The query_analytics MCP tool and GET /v1/analytics return what the Analytics page shows, from the same query service, so a number read by an AI client or a script matches the page for the same window, filters, and reporting time zone. Seven surfaces are available:

SurfaceWhat it returns
overviewOrg totals, installs, and top links
linkOne link's totals and daily series
exploreOne dimension (country, referrer, device, and so on) as rows. Add row_series for each row's share, previous count, change, and sparkline, and search to narrow the values
changeA side-by-side comparison of 2 to 5 links
summaryThe KPIs (clicks, unique clicks, installs, click to install rate, app open share) with change and sparkline, the headline sentence, the top movers, and a spike flag
trendThe chart series by granularity (hour, day, or week), with the previous period aligned bucket by bucket
leaderboardLinks by change (movers), links created in the window (new), or active links with no taps (silent)

Every ratio is returned as a numerator and a denominator, never as a rounded percent, and a zero denominator means the rate is undefined. The dashboard draws four key numbers; app_open_share is returned by REST and MCP only. Click to install rate is installs for the taps in the window, over browser taps. Under a filter or a member's own-links scope, installs are the installs linked to a tap.

Filters accept several values for one dimension (any of them matches), up to 25 per dimension. summary, trend, and leaderboard compare with the previous period by default; send compare=none to turn that off. Hourly buckets need a window of at most 7 days, and weekly buckets need at least 14 days. Days, weeks, and hours are labeled in your organization's reporting time zone, the one set in Settings, unless you send timezone.

Hover details, chart zoom, and copying a view link are dashboard-only. Everything else on the page has an equivalent here, under the same plan retention, Free plan 30-day look-back, and Free plan click-limit freeze.

Reporting time zone

Every dashboard chart buckets and labels its days in your organization's reporting time zone, set on the Settings page. Exports resolve the date range you select in that same zone and record it with the file, though each row's timestamp stays in UTC. A new organization defaults to the time zone of whoever signed up. Changing it relabels your existing charts the next time you view them, but an export you already created keeps the time zone it was made with. Only an owner or admin can change it; every member can see it.

See Real-time analytics for the commercial overview, the API reference for GET /v1/analytics, and the glossary for terms like click deduplication and UTM parameters.

On this page