# Stats API endpoints

> Query the aggregate, timeseries, breakdown and overview stats API endpoints (also MCP tools) with periods, comparisons and filters, and read example responses.

All four accept the [period, comparison and filter inputs](/docs/api/filters)
and need the `analytics.read` permission.

## Aggregate

`GET /sites/{site_id}/stats/aggregate.json` · MCP `stats_aggregate`

```sh
curl "https://privatusanalytics.com/sites/pa_7Q2K9XH3AB/stats/aggregate.json?period=30d&compare=previous_period" \
  -H "Authorization: Bearer $PRIVATUS_TOKEN"
```

```json
{
  "data": {
    "period": { "from": "2026-08-31T00:00:00+02:00", "to": "2026-09-30T00:00:00+02:00" },
    "metrics": { "visitors": 8120, "visits": 10433, "pageviews": 24871, "views_per_visit": 2.38,
                 "bounce_rate": 38.9, "visit_duration": 52000, "revenue": 1254300 },
    "comparison_period": { "from": "2026-08-01T00:00:00+02:00", "to": "2026-08-31T00:00:00+02:00" },
    "comparison": { "visitors": 7410, "…": "…" },
    "change": { "visitors": 9.6, "visits": 7.1, "…": "…" }
  }
}
```

- `visit_duration` is the median engaged time in milliseconds.
- `bounce_rate` is a percentage.
- `revenue` is in minor units of the site currency.
- `change` is the percentage change, or `null` when the previous value is
  zero.

## Timeseries

`GET /sites/{site_id}/stats/timeseries.json` · MCP `stats_timeseries`

Extra input: `interval` = `auto` (default), `minute`, `hour`, `day`,
`week`, `month`, `quarter`, `year`.

```json
{
  "data": {
    "period": { "from": "…", "to": "…" },
    "interval": "day",
    "series": [
      { "date": "2026-09-28T00:00:00Z", "visitors": 301, "visits": 377, "pageviews": 902,
        "views_per_visit": 2.39, "bounce_rate": 37.1, "visit_duration": 51000, "revenue": 0 }
    ],
    "comparison_series": [ … ]
  }
}
```

`date` is the start of each bucket as wall-clock time in the site's
timezone (written with a `Z` suffix), so `2026-09-28T00:00:00Z` means
"September 28" in the site's timezone. Empty buckets are included with
zeros.

## Breakdown

`GET /sites/{site_id}/breakdown/{dimension}.json` · MCP `stats_breakdown`

Extra inputs: `limit` (default 10, max 1,000), `page`, `sort`
(`visitors`, `visits`, `pageviews`, `revenue`). `dimension` is any key from
[Filters › Dimensions](/docs/api/filters#dimensions), including
`prop:<key>`.

```sh
curl "https://privatusanalytics.com/sites/pa_7Q2K9XH3AB/breakdown/channel.json?period=7d" \
  -H "Authorization: Bearer $PRIVATUS_TOKEN"
```

```json
{
  "data": {
    "period": { "…": "…" }, "dimension": "channel", "label": "Channel",
    "page": 1, "limit": 10,
    "rows": [
      { "value": "organic_search", "visitors": 912, "visits": 1104, "pageviews": 2710, "share": 41.2, "…": "…" },
      { "value": "direct", "visitors": 603, "…": "…", "share": 27.3 }
    ]
  }
}
```

The columns depend on the dimension: visit dimensions return visit
metrics, `page` returns pageviews, visits, time on page and scroll depth,
and `event` and `goal` return completions, conversions, conversion rate and
revenue. The [reference](/docs/api) has the exact schema. Swap `.json`
for `.csv` to download rows as CSV.

## Overview

`GET /sites/{site_id}/overview.json` · MCP `stats_overview`

Everything the Overview page shows (metrics, the chart series and the top
rows of each panel) in one request.
