Analytics
Linkstacked logs every public event server-side, so the data you query matches what visitors actually did — even if they're behind an ad-blocker.
Run a report
analyticsReport accepts a structured query input describing the slice
you want. The same input shape powers the dashboard charts.
query Report($input: AnalyticsQueryInput!) {
analyticsReport(input: $input) {
rows { dimension value count }
totals { views clicks conversions revenueCents }
range { from to granularity }
}
}{
"input": {
"from": "2026-04-01T00:00:00.000Z",
"to": "2026-05-01T00:00:00.000Z",
"granularity": "DAY",
"dimension": "REFERRER",
"linkId": null
}
}Supported dimension values: DAY, HOUR, LINK, COUNTRY,
DEVICE, REFERRER, BROWSER. Combinations are evaluated server-side
so a 365-day country breakdown is a single round-trip.
Per-link drilldown
linkAnalytics(linkId, range) returns time-series and conversion data
for one specific link — handy when your dashboard pivots from "all
profile activity" into a single link's funnel.
Export
The same data is exportable to CSV via the exportAnalyticsCSV
mutation, which returns a one-time signed URL. Handy for piping into a
warehouse load script:
URL=$(curl ... | jq -r '.data.exportAnalyticsCSV.url')
curl "$URL" -o analytics.csvSampling and freshness
Analytics aggregations refresh every 60 seconds for the last 24 hours
and every 5 minutes for older windows. If you need real-time
precision, fall back to linkAnalytics(linkId, range) with range: LAST_HOUR — that path skips the aggregation cache and reads the raw
event store.