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

# Analytics

> Read a site's core analytics: timeseries, dimension breakdowns, goal conversions, Web Vitals, and the on-demand DETAILS drill-downs (locations, campaigns, pages).

Read a site's core analytics: timeseries, dimension breakdowns, goal conversions, Web Vitals, and the on-demand DETAILS drill-downs (locations, campaigns, pages). A site is addressed by `{siteKey}` (UUID or domain). All endpoints require `Authorization: Bearer {token}`.

Every endpoint accepts the shared [date range](/api/conventions#date-ranges) parameters (`range`, or `from`/`to`) and, unless noted otherwise, the shared [dashboard filters](/api/conventions#filters) as query parameters. Money fields (`revenue`, `recurring_revenue`, and their `_new`/`_renewal`/`_refunds` splits) follow the [Conventions](/api/conventions#money) money contract — integers in minor units, never floats. The site's [Overview](/api/sites#site-overview) endpoint (topline metrics + previous-period delta) is documented in [Sites](/api/sites) — this page covers the deeper reads.

### Timeseries

```http theme={null}
GET /api/sites/{siteKey}/stats/timeseries
```

Per-bucket metrics across the resolved range, zero-filled for buckets with no matching events.

**Path parameters**

| Parameter | Type   | Required | Description          |
| --------- | ------ | -------- | -------------------- |
| `siteKey` | string | Yes      | Site UUID or domain. |

**Query parameters** — [date range](/api/conventions#date-ranges) and [filters](/api/conventions#filters) only; no dimension-specific params.

**Response** — a flat object:

| Field                       | Type      | Description                                                                                                             |
| --------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------- |
| `kpi`                       | object    | `{ metric: "recurring_revenue", label: "Charges", currency }` — chart money bars. Always present.                       |
| `labels`                    | string\[] | Bucket start instants, ISO 8601 UTC.                                                                                    |
| `visitors`                  | int\[]    | Unique visitors per bucket.                                                                                             |
| `pageviews`                 | int\[]    | Pageviews per bucket.                                                                                                   |
| `sessions`                  | int\[]    | Sessions per bucket.                                                                                                    |
| `views_per_visit`           | float\[]  | Pageviews per session per bucket.                                                                                       |
| `bounce_rate`               | float\[]  | Percentage of single-pageview sessions per bucket.                                                                      |
| `avg_session_seconds`       | float\[]  | Average session duration (seconds) per bucket.                                                                          |
| `revenue`                   | int\[]    | Net revenue per bucket (payments minus refunds), minor units. **Present only** when the range has at least one payment. |
| `recurring_revenue`         | int\[]    | Recurring subset of `revenue`. Same presence rule.                                                                      |
| `revenue_new`               | int\[]    | First-time (non-renewal, non-refund) charges per bucket. Same presence rule.                                            |
| `revenue_renewal`           | int\[]    | Renewal charges per bucket (payment `renewal` flag). Same presence rule.                                                |
| `revenue_refunds`           | int\[]    | Refunded revenue per bucket, as a positive magnitude. Same presence rule.                                               |
| `recurring_revenue_new`     | int\[]    | Recurring subset of `revenue_new`. Same presence rule.                                                                  |
| `recurring_revenue_renewal` | int\[]    | Recurring subset of `revenue_renewal`. Same presence rule.                                                              |
| `recurring_revenue_refunds` | int\[]    | Recurring subset of `revenue_refunds`. Same presence rule.                                                              |
| `paying_visitors`           | int\[]    | Unique visitors with a positive payment in the bucket. Same presence rule.                                              |
| `mrr_change`                | int\[]    | Signed list-price MRR movement per bucket (cents). **Present when** Stripe is connected.                                |

Status: `200 OK`.

<CodeGroup>
  ```bash title="curl" theme={null}
  curl "https://clickbase.so/api/sites/example.com/stats/timeseries?range=last_7_days" \
    -H "Authorization: Bearer {token}" \
    -H "Accept: application/json"
  ```

  ```javascript title="JavaScript" theme={null}
  await fetch('https://clickbase.so/api/sites/example.com/stats/timeseries?range=last_7_days', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
  ```

  ```python title="Python" theme={null}
  requests.get('https://clickbase.so/api/sites/example.com/stats/timeseries', params={'range': 'last_7_days'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
  ```
</CodeGroup>

### Breakdown

```http theme={null}
GET /api/sites/{siteKey}/stats/breakdown
```

Rank the values of one dimension by volume over the resolved range.

**Path parameters**

| Parameter | Type   | Required | Description          |
| --------- | ------ | -------- | -------------------- |
| `siteKey` | string | Yes      | Site UUID or domain. |

**Query parameters**

| Parameter   | Type   | Required | Description                                                                                                                                                                                                                                                      |
| ----------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dimension` | string | Yes      | One of `path`, `entry_path`, `exit_path`, `referrer_domain`, `channel`, `source`, `campaign`, `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `browser`, `os`, `device`, `screen`, `language`, `country`, `region`, `city`, `event_name`. |
| `limit`     | int    | No       | 1–100. Default 10.                                                                                                                                                                                                                                               |
| `sort_by`   | string | No       | Ranking key. Default `visitors`. See below for which values are allowed.                                                                                                                                                                                         |

Plus [date range](/api/conventions#date-ranges) and [filters](/api/conventions#filters).

`sort_by` allows `visitors`, `revenue`, `recurring_revenue` — except: on the `event_name` dimension, or whenever an active `goal` filter puts the breakdown into **conversions mode** (every dimension except `entry_path`, `exit_path`, `channel`, `source`, `campaign`), only `visitors` is allowed. An invalid pairing returns `422`.

Note: this endpoint does not accept a `campaign_param`; the `campaign` dimension always unions every UTM/`ref` column (equivalent to `campaign_param=all` on the [Campaign details](#campaign-details) endpoint below).

**Response**

| Field  | Type   | Description                                                                                                                                                                           |
| ------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `kpi`  | object | `{ metric: "recurring_revenue", label: "Charges", currency }`. **Absent** in conversions mode (an active `goal` filter) — that mode's money is client-reported, not trusted payments. |
| `rows` | array  | Ranked rows, see below.                                                                                                                                                               |

Each row in `rows`:

| Field               | Type   | Description                                                                              |
| ------------------- | ------ | ---------------------------------------------------------------------------------------- |
| `label`             | string | The dimension value.                                                                     |
| `count`             | int    | Visitors (or pageviews, depending on dimension) — the ranking metric.                    |
| `percent`           | float  | Share of the dimension's total, computed against every value not just the returned page. |
| `conversion_rate`   | float  | **Present only in conversions mode.**                                                    |
| `revenue`           | int    | Minor units. Present when the row has at least one revenue-bearing event.                |
| `recurring_revenue` | int    | Minor units. Same presence rule as `revenue`.                                            |
| `country`           | string | Present on `region`/`city` rows.                                                         |
| `scroll_depth`      | int    | Present on `path` rows that have engagement data (average scroll depth %).               |

Status: `200 OK`.

<CodeGroup>
  ```bash title="curl" theme={null}
  curl "https://clickbase.so/api/sites/example.com/stats/breakdown?dimension=path&range=last_7_days" \
    -H "Authorization: Bearer {token}" \
    -H "Accept: application/json"
  ```

  ```javascript title="JavaScript" theme={null}
  await fetch('https://clickbase.so/api/sites/example.com/stats/breakdown?dimension=path&range=last_7_days', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
  ```

  ```python title="Python" theme={null}
  requests.get('https://clickbase.so/api/sites/example.com/stats/breakdown', params={'dimension': 'path', 'range': 'last_7_days'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
  ```
</CodeGroup>

### Goal breakdown

```http theme={null}
GET /api/sites/{siteKey}/stats/goals
```

Every one of the site's [goals](/api/goals)' conversions over the resolved range, in one pass.

**Path parameters**

| Parameter | Type   | Required | Description          |
| --------- | ------ | -------- | -------------------- |
| `siteKey` | string | Yes      | Site UUID or domain. |

**Query parameters** — [date range](/api/conventions#date-ranges) and [filters](/api/conventions#filters). The `goal` filter, if present, is ignored — this endpoint always lists every goal.

**Response** — flat JSON array of:

| Field             | Type          | Description                                                                          |
| ----------------- | ------------- | ------------------------------------------------------------------------------------ |
| `id`              | string (uuid) | Goal id.                                                                             |
| `display_name`    | string        | Goal label.                                                                          |
| `visitors`        | int           | Unique converting visitors.                                                          |
| `events`          | int           | Total conversion events.                                                             |
| `conversion_rate` | float         | `visitors` over total site visitors in range (capped at 100%).                       |
| `revenue`         | int           | Minor units. Present only when the goal has at least one revenue-bearing conversion. |

Status: `200 OK`.

<CodeGroup>
  ```bash title="curl" theme={null}
  curl "https://clickbase.so/api/sites/example.com/stats/goals?range=last_7_days" \
    -H "Authorization: Bearer {token}" \
    -H "Accept: application/json"
  ```

  ```javascript title="JavaScript" theme={null}
  await fetch('https://clickbase.so/api/sites/example.com/stats/goals?range=last_7_days', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
  ```

  ```python title="Python" theme={null}
  requests.get('https://clickbase.so/api/sites/example.com/stats/goals', params={'range': 'last_7_days'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
  ```
</CodeGroup>

### Performance overview

```http theme={null}
GET /api/sites/{siteKey}/stats/performance/overview
```

Site-wide Core Web Vitals percentiles for the resolved range.

**Path parameters**

| Parameter | Type   | Required | Description          |
| --------- | ------ | -------- | -------------------- |
| `siteKey` | string | Yes      | Site UUID or domain. |

**Query parameters** — [date range](/api/conventions#date-ranges) and [filters](/api/conventions#filters).

**Response** — a flat object with 4 percentiles (`p50`, `p75`, `p90`, `p99`) for each of 5 metrics (`lcp`, `cls`, `inp`, `fcp`, `ttfb`), plus a total count:

| Field                            | Type          | Description                                                                                      |
| -------------------------------- | ------------- | ------------------------------------------------------------------------------------------------ |
| `{metric}_p50`/`p75`/`p90`/`p99` | float \| null | e.g. `lcp_p75`, `cls_p90`, `inp_p50`, `fcp_p99`, `ttfb_p75`. `null` when no data. 20 keys total. |
| `total_performance_events`       | int           | Count of performance events in range.                                                            |

Status: `200 OK`.

<CodeGroup>
  ```bash title="curl" theme={null}
  curl "https://clickbase.so/api/sites/example.com/stats/performance/overview?range=last_7_days" \
    -H "Authorization: Bearer {token}" \
    -H "Accept: application/json"
  ```

  ```javascript title="JavaScript" theme={null}
  await fetch('https://clickbase.so/api/sites/example.com/stats/performance/overview?range=last_7_days', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
  ```

  ```python title="Python" theme={null}
  requests.get('https://clickbase.so/api/sites/example.com/stats/performance/overview', params={'range': 'last_7_days'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
  ```
</CodeGroup>

### Performance timeseries

```http theme={null}
GET /api/sites/{siteKey}/stats/performance/timeseries
```

Per-bucket Core Web Vitals percentiles for the Performance chart.

**Path parameters**

| Parameter | Type   | Required | Description          |
| --------- | ------ | -------- | -------------------- |
| `siteKey` | string | Yes      | Site UUID or domain. |

**Query parameters**

| Parameter | Type   | Required | Description                                                                                                                                                                                                           |
| --------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `group`   | string | No       | Bucket size override: `five_minutes`, `ten_minutes`, `fifteen_minutes`, `thirty_minutes`, `hour`, `day`, `week`, `month`. Ignored if it doesn't fit the resolved range; the range's default grouping is used instead. |

Plus [date range](/api/conventions#date-ranges) and [filters](/api/conventions#filters).

**Response**

| Field    | Type      | Description                                                                                                                                            |
| -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `labels` | string\[] | Bucket start instants, ISO 8601 UTC.                                                                                                                   |
| `group`  | string    | The bucket size actually used.                                                                                                                         |
| `points` | array     | One object per bucket: `event_count` (int) plus the same 20 `{metric}_p{pct}` keys as [Performance overview](#performance-overview) (`float \| null`). |

Status: `200 OK`.

<CodeGroup>
  ```bash title="curl" theme={null}
  curl "https://clickbase.so/api/sites/example.com/stats/performance/timeseries?range=last_7_days" \
    -H "Authorization: Bearer {token}" \
    -H "Accept: application/json"
  ```

  ```javascript title="JavaScript" theme={null}
  await fetch('https://clickbase.so/api/sites/example.com/stats/performance/timeseries?range=last_7_days', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
  ```

  ```python title="Python" theme={null}
  requests.get('https://clickbase.so/api/sites/example.com/stats/performance/timeseries', params={'range': 'last_7_days'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
  ```
</CodeGroup>

### Performance by dimension

```http theme={null}
GET /api/sites/{siteKey}/stats/performance/by-dimension
```

Core Web Vitals ranked by a single dimension.

**Path parameters**

| Parameter | Type   | Required | Description          |
| --------- | ------ | -------- | -------------------- |
| `siteKey` | string | Yes      | Site UUID or domain. |

**Query parameters**

| Parameter   | Type   | Required | Description                                                    |
| ----------- | ------ | -------- | -------------------------------------------------------------- |
| `dimension` | string | Yes      | One of `path`, `country`, `device`, `browser`, `os`, `region`. |
| `limit`     | int    | No       | 1–100. Default 100.                                            |

Plus [date range](/api/conventions#date-ranges) and [filters](/api/conventions#filters).

**Response** — flat JSON array, one entry per dimension value:

| Field                                      | Type          | Description                                                                                                      |
| ------------------------------------------ | ------------- | ---------------------------------------------------------------------------------------------------------------- |
| `dimension`                                | string        | The dimension value.                                                                                             |
| `event_count`                              | int           | Performance events for this value.                                                                               |
| `{metric}_avg`/`_p50`/`_p75`/`_p90`/`_p99` | float \| null | For each of `lcp`, `cls`, `inp`, `fcp`, `ttfb` — average plus 4 percentiles, 25 keys total. `null` when no data. |

Status: `200 OK`.

<CodeGroup>
  ```bash title="curl" theme={null}
  curl "https://clickbase.so/api/sites/example.com/stats/performance/by-dimension?dimension=path" \
    -H "Authorization: Bearer {token}" \
    -H "Accept: application/json"
  ```

  ```javascript title="JavaScript" theme={null}
  await fetch('https://clickbase.so/api/sites/example.com/stats/performance/by-dimension?dimension=path', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
  ```

  ```python title="Python" theme={null}
  requests.get('https://clickbase.so/api/sites/example.com/stats/performance/by-dimension', params={'dimension': 'path'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
  ```
</CodeGroup>

### Location details

```http theme={null}
GET /api/sites/{siteKey}/stats/location-details
```

On-demand session-entry DETAILS ranking, with bounce rate and average visit duration, for a location/device/acquisition dimension. Richer per-row metrics than the [Breakdown](#breakdown) endpoint's `country`/`region`/`city`/`browser`/`os`/`device`/`channel`/`source`/`referrer_domain` dimensions, fetched on demand rather than for the dashboard card.

**Path parameters**

| Parameter | Type   | Required | Description          |
| --------- | ------ | -------- | -------------------- |
| `siteKey` | string | Yes      | Site UUID or domain. |

**Query parameters**

| Parameter   | Type   | Required | Description                                                                                                               |
| ----------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `dimension` | string | No       | One of `country`, `region`, `city`, `browser`, `os`, `device`, `channel`, `source`, `referrer_domain`. Default `country`. |
| `limit`     | int    | No       | 1–500. Default 250.                                                                                                       |

Plus [date range](/api/conventions#date-ranges) and [filters](/api/conventions#filters). `channel`/`source`/`referrer_domain` ignore an active `goal` filter (they rank visit volume, not conversions).

**Response**

| Field  | Type  | Description             |
| ------ | ----- | ----------------------- |
| `rows` | array | Ranked rows, see below. |

Each row in `rows`:

| Field                 | Type   | Description                                                              |
| --------------------- | ------ | ------------------------------------------------------------------------ |
| `label`               | string | The dimension value.                                                     |
| `visitors`            | int    | Unique visitors entering a session on this value.                        |
| `bounce_rate`         | float  | Percentage of single-pageview sessions.                                  |
| `avg_session_seconds` | float  | Average session duration in seconds.                                     |
| `percent`             | float  | Share of total visitors across all values, not just the returned page.   |
| `country`             | string | Present on `region`/`city` rows.                                         |
| `domain`              | string | Present on `source` rows (representative referrer domain, for favicons). |

Status: `200 OK`.

<CodeGroup>
  ```bash title="curl" theme={null}
  curl "https://clickbase.so/api/sites/example.com/stats/location-details?dimension=country" \
    -H "Authorization: Bearer {token}" \
    -H "Accept: application/json"
  ```

  ```javascript title="JavaScript" theme={null}
  await fetch('https://clickbase.so/api/sites/example.com/stats/location-details?dimension=country', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
  ```

  ```python title="Python" theme={null}
  requests.get('https://clickbase.so/api/sites/example.com/stats/location-details', params={'dimension': 'country'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
  ```
</CodeGroup>

### Campaign details

```http theme={null}
GET /api/sites/{siteKey}/stats/campaign-details
```

On-demand campaign DETAILS: session-entry `param=value` rows unioned across every UTM/`ref` column (or one column when narrowed), with bounce rate and average visit duration.

**Path parameters**

| Parameter | Type   | Required | Description          |
| --------- | ------ | -------- | -------------------- |
| `siteKey` | string | Yes      | Site UUID or domain. |

**Query parameters**

| Parameter        | Type   | Required | Description                                                                                                                       |
| ---------------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `campaign_param` | string | No       | Narrow the union to one column: `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `ref`, or `all` (default). |
| `limit`          | int    | No       | 1–500. Default 250.                                                                                                               |

Plus [date range](/api/conventions#date-ranges) and [filters](/api/conventions#filters). An active `goal` filter is ignored (ranks visit volume, not conversions).

**Response**

| Field  | Type  | Description             |
| ------ | ----- | ----------------------- |
| `rows` | array | Ranked rows, see below. |

Each row in `rows`:

| Field                 | Type   | Description                                                            |
| --------------------- | ------ | ---------------------------------------------------------------------- |
| `label`               | string | The `param=value` pair, e.g. `utm_campaign=black-friday`.              |
| `visitors`            | int    | Unique visitors entering a session with this campaign value.           |
| `bounce_rate`         | float  | Percentage of single-pageview sessions.                                |
| `avg_session_seconds` | float  | Average session duration in seconds.                                   |
| `percent`             | float  | Share of total visitors across all values, not just the returned page. |

Status: `200 OK`.

<CodeGroup>
  ```bash title="curl" theme={null}
  curl "https://clickbase.so/api/sites/example.com/stats/campaign-details?campaign_param=utm_campaign" \
    -H "Authorization: Bearer {token}" \
    -H "Accept: application/json"
  ```

  ```javascript title="JavaScript" theme={null}
  await fetch('https://clickbase.so/api/sites/example.com/stats/campaign-details?campaign_param=utm_campaign', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
  ```

  ```python title="Python" theme={null}
  requests.get('https://clickbase.so/api/sites/example.com/stats/campaign-details', params={'campaign_param': 'utm_campaign'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
  ```
</CodeGroup>

### Page details

```http theme={null}
GET /api/sites/{siteKey}/stats/page-details
```

On-demand Top / Entry / Exit pages DETAILS, ranked with the richer per-kind metrics each drill-down needs.

**Path parameters**

| Parameter | Type   | Required | Description          |
| --------- | ------ | -------- | -------------------- |
| `siteKey` | string | Yes      | Site UUID or domain. |

**Query parameters**

| Parameter | Type   | Required | Description                                                                                  |
| --------- | ------ | -------- | -------------------------------------------------------------------------------------------- |
| `kind`    | string | No       | `path` (Top pages), `entry_path` (Entry pages), or `exit_path` (Exit pages). Default `path`. |
| `limit`   | int    | No       | 1–500. Default 250.                                                                          |

Plus [date range](/api/conventions#date-ranges) and [filters](/api/conventions#filters).

**Response**

| Field  | Type  | Description             |
| ------ | ----- | ----------------------- |
| `rows` | array | Ranked rows, see below. |

Each row in `rows` — fields depend on `kind`:

| Field                  | Type   | `kind`                    | Description                                                                    |
| ---------------------- | ------ | ------------------------- | ------------------------------------------------------------------------------ |
| `label`                | string | all                       | The page path.                                                                 |
| `visitors`             | int    | all                       | Unique visitors (`path`) or unique entrances/exits (`entry_path`/`exit_path`). |
| `percent`              | float  | all                       | Share of total visitors across all values, not just the returned page.         |
| `pageviews`            | int    | `path`                    | Total pageviews on this path.                                                  |
| `bounce_rate`          | float  | `path`, `entry_path`      | Percentage of single-pageview sessions.                                        |
| `time_on_page_seconds` | float  | `path`                    | Present only when engagement data exists for the path.                         |
| `scroll_depth`         | int    | `path`                    | Average scroll depth %. Present only when engagement data exists.              |
| `visits`               | int    | `entry_path`, `exit_path` | Total entrances/exits.                                                         |
| `avg_session_seconds`  | float  | `entry_path`              | Average session duration in seconds.                                           |
| `exit_rate`            | float  | `exit_path`               | Exits on this path divided by total pageviews on this path.                    |

Status: `200 OK`.

<CodeGroup>
  ```bash title="curl" theme={null}
  curl "https://clickbase.so/api/sites/example.com/stats/page-details?kind=entry_path" \
    -H "Authorization: Bearer {token}" \
    -H "Accept: application/json"
  ```

  ```javascript title="JavaScript" theme={null}
  await fetch('https://clickbase.so/api/sites/example.com/stats/page-details?kind=entry_path', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
  ```

  ```python title="Python" theme={null}
  requests.get('https://clickbase.so/api/sites/example.com/stats/page-details', params={'kind': 'entry_path'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
  ```
</CodeGroup>
