Reports & breakdowns

The aggregate endpoints — headline numbers, traffic over time, per-page performance, and any dimension you want to group by. Every one of them takes the same window parameters.

The window

NameTypeRequiredDescription
sitestringNoSite id or site key. Optional when the key is scoped to one site.
daysintegerNoWindow length ending now. 1–400, default 30.
from / toISO instantNoAn explicit window, instead of days. Capped at 400 days — an unbounded window is a table scan.
include_bots0 | 1NoInclude sessions flagged as automated. Excluded by default.
limitintegerNoPage size on list endpoints. Each endpoint names its own maximum.

List your sites

bash
GET /v1/analytics/sites

The first call an integration makes: it turns a key into the site ids everything else takes. A key issued for one site returns that one site.

json
{
  "data": [
    {
      "id": "8f2b…",
      "name": "Marketing site",
      "domain": "example.com.au",
      "status": "active",
      "site_key": "hlda_site_xxxx",
      "created_at": "2026-08-01T04:12:00.000Z"
    }
  ],
  "scopes": ["analytics:read", "analytics:heatmaps"]
}

Overview

bash
GET /v1/analytics/overview?days=30
json
{
  "data": {
    "sessions": 4821,
    "visitors": 3907,
    "pageviews": 12044,
    "bounced_sessions": 1902,
    "converted_sessions": 118,
    "conversion_value": 284000,
    "identified_sessions": 63,
    "hot_sessions": 210,
    "total_clicks": 9331,
    "rage_clicks": 47,
    "dead_clicks": 212,
    "form_starts": 340,
    "form_submits": 118,
    "errors": 9,
    "total_active_ms": 214880000,
    "avg_active_ms": 44572,
    "avg_scroll_pct": 61.4,
    "avg_intent_score": 28.9,
    "p75_lcp_ms": 2140,
    "p75_inp_ms": 132,
    "p75_cls_x1000": 41,
    "first_seen_at": "2026-08-06T…",
    "last_seen_at": "2026-09-05T…"
  },
  "site": { "id": "8f2b…", "name": "Marketing site", "domain": "example.com.au" },
  "window": { "from": "…", "to": "…", "includeBots": false }
}
Tip:Vitals come back at the 75th percentile, not the mean — that is how Google grades them, and an average hides exactly the slow tail that fails the assessment. cls_x1000 is CLS multiplied by 1000 so it stays an integer; divide by 1000 to compare against the 0.1 threshold.

Reading the bounce number

A bounce here is not "one pageview". That definition marks someone who read one long article for four minutes as a failure. A visit counts as bounced only if it stayed on one page, spent under fifteen seconds engaged, scrolled less than halfway, and did nothing — no click, download, search or form.

Timeseries

bash
GET /v1/analytics/timeseries?days=30&bucket=day

bucket is day or hour. Buckets are UTC calendar boundaries rather than rolling windows, so two calls a minute apart return the same buckets — which is what makes the result comparable between runs.

json
{
  "data": [
    { "bucket": "2026-09-01T00:00:00.000Z", "sessions": 161, "visitors": 140,
      "pageviews": 402, "conversions": 4, "active_ms": 7120000 }
  ],
  "bucket": "day"
}

Pages

bash
GET /v1/analytics/pages?days=30&limit=50
NameTypeRequiredDescription
pathstringNoNormalised: query stripped, trailing slash gone, lowercased, and long numeric or uuid segments collapsed to :id.
pageviews / unique_sessionsintegerNoViews, and how many distinct visits produced them.
entries / exitsintegerNoSessions that started, and ended, on this page.
clicks / rage_clicksintegerNoAll click types, and the frustrated subset.
avg_dwell_ms / avg_scroll_pctnumberNoAveraged over page exits, so a page still open does not drag them down.
Note:Path normalisation is why a catalogue reports one /product/:id with ten thousand views rather than ten thousand pages with one view each. Pass the normalised form back to the heatmap endpoint.

Breakdown

bash
GET /v1/analytics/breakdown?dimension=channel&days=30

One endpoint rather than a dozen, because the answer has the same shape for every dimension and only the key changes.

NameTypeRequiredDescription
channeldimensionNoAcquisition channel. See Marketing inference for how it is decided.
source / medium / campaigndimensionNoUTM parameters, falling back to the referring host for source.
referrerdimensionNoReferring hostname, www stripped.
landing_pathdimensionNoWhere visits started.
country / region / citydimensionNoResolved at the edge from the connection.
device / browser / os / languagedimensionNoAudience shape. device is the viewport bucket: mobile, tablet or desktop.
companydimensionNoThe organisation behind the address, from reverse DNS. The B2B one: how an anonymous visit becomes an account name.
intent_banddimensionNocold, warm or hot.
json
{
  "data": [
    { "key": "organic_search", "sessions": 1840, "visitors": 1602, "pageviews": 4210,
      "conversions": 44, "conversion_value": 96000, "bounced": 690,
      "avg_active_ms": 51200, "avg_intent_score": 31.2 }
  ],
  "dimension": "channel"
}