Analytics API
Query your analytics data programmatically via the REST API.
Authentication
All API requests require a Bearer token and an organization header. Create API keys from your profile settings.
| Header | Value |
|---|---|
Authorization | Bearer bc_live_... |
x-organization | Your organization ID |
Content-Type | application/json |
API keys inherit your role permissions. Fields you cannot access in the dashboard are also restricted via the API.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v1/analytics/run-query | Execute a table or chart query |
GET | /api/v1/analytics/get-fields | List available dimensions and measures for your role |
Get Fields
Returns the dimensions and measures available to your role. Use this to discover which fields you can query.
curl /api/v1/analytics/get-fields \
-H "Authorization: Bearer bc_live_..." \
-H "x-organization: <organization-id>"
Response
{
"dimensions": [
{ "field": "DATE", "label": "Date", "category": "Time", "dataType": "date", "canFilter": true, "description": "..." },
{ "field": "COUNTRY", "label": "Country", "category": "Geo", "dataType": "string", "canFilter": true, "description": "..." }
],
"measures": [
{ "field": "PAGEVIEWS", "label": "Pageviews", "category": "Traffic", "dataType": "number", "description": "..." },
{ "field": "TOTAL_REVENUE", "label": "Revenue", "category": "Revenue", "dataType": "number", "description": "..." }
]
}
Table Queries
Table queries return dimensional/aggregate data — the same data that powers the Explore table in the dashboard.
curl -X POST /api/v1/analytics/run-query \
-H "Authorization: Bearer bc_live_..." \
-H "x-organization: <organization-id>" \
-H "Content-Type: application/json" \
-d '{
"type": "table",
"dimensions": ["DATE", "COUNTRY"],
"measures": ["PAGEVIEWS", "TOTAL_REVENUE"],
"startDate": "2026-03-01",
"endDate": "2026-03-09",
"filters": [
{ "field": "COUNTRY", "operator": "is any of", "values": ["US", "GB"] }
],
"rowLimit": 100
}'
Parameters
| Field | Type | Description |
|---|---|---|
type | "table" | Required |
dimensions | string[] | Group-by fields (e.g. DATE, COUNTRY) |
measures | string[] | Aggregate metrics (e.g. PAGEVIEWS, TOTAL_REVENUE) |
startDate | string | Start date (YYYY-MM-DD or full datetime) |
endDate | string | End date (YYYY-MM-DD or full datetime) |
filters | Filter[] | Optional. Array of filter objects (see Filters below) |
sortArray | Sort[] | Optional. [{ field, order: "ASC"|"DESC" }] |
rowLimit | number | Max rows returned (default 500, max 1000) |
forExport | boolean | Return CSV string instead of JSON rows |
enableGrouping | boolean | Include rollup subtotals (WITH ROLLUP) |
relativeDateRange | string | Real-time range: last5Minutes, last30Minutes, last1Hour, last2Hours, last24Hours |
excludeIncompleteCurrentInterval | boolean | Exclude the current incomplete time interval from results |
forceGranularity | string | Override time granularity: minute or hour |
timezone | string | IANA timezone (defaults to your profile setting) |
Response (JSON)
{
"success": true,
"data": [
{ "DATE": "2026-03-01", "COUNTRY": "US", "PAGEVIEWS": 12345, "TOTAL_REVENUE": 98.76 },
{ "DATE": "2026-03-01", "COUNTRY": "GB", "PAGEVIEWS": 6789, "TOTAL_REVENUE": 45.23 }
],
"count": 2
}
Response (CSV export)
{
"success": true,
"csv": "DATE,COUNTRY,PAGEVIEWS,TOTAL_REVENUE\n2026-03-01,US,12345,98.76\n...",
"filename": "data_export_2026-03-01_to_2026-03-09_2026-03-09T12-00-00.csv"
}
Chart Queries
Chart queries return time-series data with optional pivot dimensions and comparison ranges — the same data that powers dashboard charts.
curl -X POST /api/v1/analytics/run-query \
-H "Authorization: Bearer bc_live_..." \
-H "x-organization: <organization-id>" \
-H "Content-Type: application/json" \
-d '{
"type": "chart",
"primaryRange": { "startDate": "2026-03-01", "endDate": "2026-03-09" },
"timeDimension": "DATE",
"measures": ["PAGEVIEWS"],
"pivotDimension": "DEVICE",
"maxPivotSeries": 5
}'
Parameters
| Field | Type | Description |
|---|---|---|
type | "chart" | Required |
primaryRange | { startDate, endDate } | Date range for the primary series |
comparisonRange | { startDate, endDate } | Optional. Date range for comparison overlay |
timeDimension | string | Time granularity (DATE, DATE_1HOUR, WEEK_YEAR, etc.) |
measures | string | string[] | One or more metrics |
pivotDimension | string | Optional. Break down by dimension (e.g. DEVICE, COUNTRY) |
maxPivotSeries | number | Max pivot values shown (default 10). Top N by first measure |
rowLimit | number | Max rows (default 500, max 1000) |
filters | Filter[] | Optional. Same filter format as table queries |
relativeDateRange | string | Optional. Real-time range (same values as table queries) |
excludeIncompleteInterval | boolean | Exclude the current incomplete time interval from results |
timezone | string | IANA timezone (defaults to your profile setting) |
Filters
Filters narrow your query results. Each filter has a field, operator, and values array.
{ "field": "COUNTRY", "operator": "is any of", "values": ["US", "GB", "DE"] }
{ "field": "PAGEVIEWS", "operator": ">", "values": [1000] }
{ "field": "PAGE_PATH", "operator": "contains", "values": ["/blog"] }
Operators
| Operator | Description |
|---|---|
= | Equals |
!= | Not equals |
<, <=, >, >= | Numeric comparison |
is any of | Value in list (OR) |
is none of | Value not in list |
contains | Substring match (case-insensitive) |
does not contain | Negated substring match |
is between | Range (requires 2 values: [start, end]) |
is before | Datetime before value |
is on or after | Datetime on or after value |
Errors
Error responses include an HTTP status code and a JSON body.
| Status | Meaning |
|---|---|
400 | Invalid request body, unknown fields, or incompatible dimensions |
401 | Missing, invalid, or expired API key |
403 | No properties found for the organization |
500 | Server error during query execution |
Error response format
{ "success": false, "error": "Unknown fields: INVALID_FIELD" }
Tips
- Use
GET /api/v1/analytics/get-fieldsto discover which dimensions and measures are available for your role before building queries. - Prefer specific date ranges over
relativeDateRangefor reproducible results. Relative ranges are best for dashboards and monitoring. - When using
pivotDimensionin chart queries, keepmaxPivotSerieslow (5-10) to avoid large result sets. - CSV export (
forExport: true) removes the row limit, so use date filters to bound your data. - Custom dimensions (e.g. key-value fields) can only be combined with a subset of standard dimensions. If you get a compatibility error, remove conflicting dimensions.