REST API
Analytics
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 parameters (range, or from/to) and, unless noted otherwise, the shared dashboard filters as query parameters. Money fields (revenue, recurring_revenue, and their _new/_renewal/_refunds splits) follow the Conventions money contract — integers in minor units, never floats. The site's Overview endpoint (topline metrics + previous-period delta) is documented in Sites — this page covers the deeper reads.
Timeseries
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 and 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.
curl "https://clickbase.so/api/sites/example.com/stats/timeseries?range=last_7_days" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/timeseries?range=last_7_days', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
requests.get('https://clickbase.so/api/sites/example.com/stats/timeseries', params={'range': 'last_7_days'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
Breakdown
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 and 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 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.
curl "https://clickbase.so/api/sites/example.com/stats/breakdown?dimension=path&range=last_7_days" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/breakdown?dimension=path&range=last_7_days', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
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'})
Goal breakdown
GET /api/sites/{siteKey}/stats/goals
Every one of the site's 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 and 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.
curl "https://clickbase.so/api/sites/example.com/stats/goals?range=last_7_days" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/goals?range=last_7_days', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
requests.get('https://clickbase.so/api/sites/example.com/stats/goals', params={'range': 'last_7_days'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
Performance overview
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 and 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.
curl "https://clickbase.so/api/sites/example.com/stats/performance/overview?range=last_7_days" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/performance/overview?range=last_7_days', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
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'})
Performance timeseries
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 and 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 (float | null). |
Status: 200 OK.
curl "https://clickbase.so/api/sites/example.com/stats/performance/timeseries?range=last_7_days" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/performance/timeseries?range=last_7_days', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
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'})
Performance by dimension
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 and 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.
curl "https://clickbase.so/api/sites/example.com/stats/performance/by-dimension?dimension=path" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/performance/by-dimension?dimension=path', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
requests.get('https://clickbase.so/api/sites/example.com/stats/performance/by-dimension', params={'dimension': 'path'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
Location details
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 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 and 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.
curl "https://clickbase.so/api/sites/example.com/stats/location-details?dimension=country" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/location-details?dimension=country', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
requests.get('https://clickbase.so/api/sites/example.com/stats/location-details', params={'dimension': 'country'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})
Campaign details
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 and 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.
curl "https://clickbase.so/api/sites/example.com/stats/campaign-details?campaign_param=utm_campaign" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/campaign-details?campaign_param=utm_campaign', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
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'})
Page details
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 and 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.
curl "https://clickbase.so/api/sites/example.com/stats/page-details?kind=entry_path" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/page-details?kind=entry_path', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
requests.get('https://clickbase.so/api/sites/example.com/stats/page-details', params={'kind': 'entry_path'}, headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'})