REST API
Events
The Events explorer: a raw, chronological log of custom events (clicks, downloads, forms, outbound links, copies, custom track() calls, and errors), a chart of counts over time, and a per-event property drill-down. A dedicated Page titles list and its own filter-value autocomplete live here too, since both power the same explorer UI.
A site is addressed by {siteKey} (UUID or domain). All endpoints require Authorization: Bearer {token} and accept the shared range/from/to and filter query parameters described in Conventions.
List events
GET /api/sites/{siteKey}/stats/events
A chronological log of individual events, newest first. Always excludes internal engagement beacons. Scroll-paginated with the standard data/meta/links envelope — see Conventions.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
range |
string | No | Preset date range. See Conventions. |
from |
string | No | Custom range start, Y-m-d. |
to |
string | No | Custom range end, Y-m-d. |
types |
string | No | Comma-separated list of event types to include, e.g. outbound,download. Unknown values are silently dropped. Omit to include every type. Allowed: pageview, event, outbound, download, button, form, copy, error. |
per_page |
int | No | Page size, 1–100. Default 50. |
Filter dimensions (path, country, browser, prop_key/prop_value, etc.) are also accepted — see Conventions.
Response — each item in data:
| Field | Type | Description |
|---|---|---|
event_type |
string | One of the types listed above. |
event_name |
string | Custom event name, autocapture kind, or error name. Empty for pageview. |
timestamp |
string (ISO 8601) | When the event was recorded. |
path |
string | Page path. |
url |
string | Full page URL. |
title |
string | Page title. |
hostname |
string | Page hostname. |
user_id |
string | Identified user id; empty for an anonymous visitor. |
visitor_id |
string (uuid) | Anonymous visitor id. |
display_name |
string | Generated display nickname for the visitor/user. |
avatar_url |
string | Generated avatar URL for the visitor/user. |
country |
string | Visitor's country. |
device |
string | Device type. |
browser |
string | Browser name. |
os |
string | Operating system. |
properties |
object | The event's custom properties, string ⇒ string. |
error_id |
string | null | The error's fingerprint id (same id a /stats/errors row carries) when event_type is error; null otherwise. Link this to GET /stats/errors/{error}. |
Status: 200 OK.
curl "https://clickbase.so/api/sites/example.com/stats/events?range=last_7_days&types=outbound,download" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/events?range=last_7_days&types=outbound,download', {
headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' },
});
requests.get(
'https://clickbase.so/api/sites/example.com/stats/events',
params={'range': 'last_7_days', 'types': 'outbound,download'},
headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'},
)
Events timeseries
GET /api/sites/{siteKey}/stats/events/timeseries
Per-bucket event counts, one series per event type present — the Events explorer chart. Always excludes engagement.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
range |
string | No | Preset date range. |
from |
string | No | Custom range start, Y-m-d. |
to |
string | No | Custom range end, Y-m-d. |
types |
string | No | Comma-separated subset of event types to chart (same allowlist as the list endpoint). Omit to chart every type. |
Filter dimensions are also accepted.
Response — flat object:
| Field | Type | Description |
|---|---|---|
labels |
string[] (ISO 8601) | Bucket start timestamps. |
types |
string[] | Event types present in series (the requested subset, or all list types). |
series |
object | Map of event type ⇒ int[] counts, index-aligned with labels. |
group |
string | Resolved bucket size: hour, day, week, or month. |
Status: 200 OK.
curl "https://clickbase.so/api/sites/example.com/stats/events/timeseries?range=last_7_days" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/events/timeseries?range=last_7_days', {
headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' },
});
requests.get(
'https://clickbase.so/api/sites/example.com/stats/events/timeseries',
params={'range': 'last_7_days'},
headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'},
)
Event property breakdown
GET /api/sites/{siteKey}/stats/events/property-breakdown
The per-event drill-down: the top custom-property key/value pairs recorded for one exact event_name within one event_type, ranked by unique visitors. There is no site-level property allow-list — any key the matching events actually carried is returned. Capped at 50 rows.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
range |
string | No | Preset date range. |
from |
string | No | Custom range start, Y-m-d. |
to |
string | No | Custom range end, Y-m-d. |
event_type |
string | Yes | One of event, outbound, download, button, form, copy, error. Note pageview is not breakdownable. |
event_name |
string | Yes | Exact event name to drill into. Max 255 chars. |
Filter dimensions are also accepted.
Response — flat object:
| Field | Type | Description |
|---|---|---|
rows |
object[] | Up to 50 ranked key/value pairs. |
rows[].key |
string | Property key. |
rows[].value |
string | Property value. |
rows[].visitors |
int | Unique visitors that carried this key/value pair. |
Status: 200 OK.
curl "https://clickbase.so/api/sites/example.com/stats/events/property-breakdown?event_type=button&event_name=Signup+Click&range=last_7_days" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
const params = new URLSearchParams({ event_type: 'button', event_name: 'Signup Click', range: 'last_7_days' });
await fetch(`https://clickbase.so/api/sites/example.com/stats/events/property-breakdown?${params}`, {
headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' },
});
requests.get(
'https://clickbase.so/api/sites/example.com/stats/events/property-breakdown',
params={'event_type': 'button', 'event_name': 'Signup Click', 'range': 'last_7_days'},
headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'},
)
List page titles
GET /api/sites/{siteKey}/stats/page-titles
Document titles ranked by sessions, with pageviews, bounce rate, dwell time, and the session-count change versus the previous period. Scroll-paginated with the standard data/meta/links envelope.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
range |
string | No | Preset date range. |
from |
string | No | Custom range start, Y-m-d. |
to |
string | No | Custom range end, Y-m-d. |
per_page |
int | No | Page size, 1–100. Default 25. |
Filter dimensions are also accepted.
Response — each item in data:
| Field | Type | Description |
|---|---|---|
title |
string | Document title. |
path |
string | The title's most recently seen page path. |
hostname |
string | The title's most recently seen hostname. |
pageviews |
int | Total pageviews for this title in range. |
sessions |
int | Unique sessions that viewed this title. |
bounce_rate |
float | Percentage (0–100) of those sessions that had exactly one pageview. |
time_on_page_seconds |
float | null | Average engaged time on the title, in seconds; null when no engagement data. |
sessions_previous |
int | Sessions for this title in the equivalent previous period. |
sessions_change_pct |
float | null | Percent change vs. sessions_previous; null when there is no previous baseline to compare against. |
Status: 200 OK.
curl "https://clickbase.so/api/sites/example.com/stats/page-titles?range=last_7_days" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/stats/page-titles?range=last_7_days', {
headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' },
});
requests.get(
'https://clickbase.so/api/sites/example.com/stats/page-titles',
params={'range': 'last_7_days'},
headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'},
)
Page title timeseries
GET /api/sites/{siteKey}/stats/page-titles/timeseries
Bucketed unique-session counts for one document title — the Pages table sparkline.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
title |
string | Yes | Exact document title. Max 2048 chars. |
range |
string | No | Preset date range. |
from |
string | No | Custom range start, Y-m-d. |
to |
string | No | Custom range end, Y-m-d. |
Filter dimensions are also accepted.
Response — flat object:
| Field | Type | Description |
|---|---|---|
labels |
string[] (ISO 8601) | Bucket start timestamps. |
values |
int[] | Unique sessions per bucket, index-aligned with labels. |
group |
string | Resolved bucket size: hour, day, week, or month. |
Status: 200 OK.
curl "https://clickbase.so/api/sites/example.com/stats/page-titles/timeseries?title=Pricing&range=last_7_days" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
const params = new URLSearchParams({ title: 'Pricing', range: 'last_7_days' });
await fetch(`https://clickbase.so/api/sites/example.com/stats/page-titles/timeseries?${params}`, {
headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' },
});
requests.get(
'https://clickbase.so/api/sites/example.com/stats/page-titles/timeseries',
params={'title': 'Pricing', 'range': 'last_7_days'},
headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'},
)
Filter value suggestions
GET /api/sites/{siteKey}/stats/filter-values
Autocomplete for the Filter popover: distinct values seen for one dimension over the resolved range/filters, ranked by count. The requested dimension's own active filter is stripped before suggesting (so alternatives still show); other active filters continue to narrow the suggestions.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
dimension |
string | Yes | One of path, entry_path, title, hostname, user_id, event_name, visit_count, referrer, channel, source, utm_source, utm_medium, utm_campaign, utm_content, utm_term, browser, os, size, country, region, city. Note campaign, goal, and prop_key/prop_value — filterable elsewhere — are not suggestible dimensions here. |
range |
string | No | Preset date range. |
from |
string | No | Custom range start, Y-m-d. |
to |
string | No | Custom range end, Y-m-d. |
limit |
int | No | Max suggestions, 1–1000. Default 1000. |
Other filter dimensions (besides dimension itself) are also accepted, to narrow suggestions.
Response — flat object:
| Field | Type | Description |
|---|---|---|
values |
object[] | Ranked distinct values for the dimension. |
values[].value |
string | The raw value. |
values[].label |
string | Display label (currently always equal to value). |
Status: 200 OK.
curl "https://clickbase.so/api/sites/example.com/stats/filter-values?dimension=country&range=last_7_days" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
const params = new URLSearchParams({ dimension: 'country', range: 'last_7_days' });
await fetch(`https://clickbase.so/api/sites/example.com/stats/filter-values?${params}`, {
headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' },
});
requests.get(
'https://clickbase.so/api/sites/example.com/stats/filter-values',
params={'dimension': 'country', 'range': 'last_7_days'},
headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'},
)