API Reference

Custom Queries

The Custom Query API lets you build queries with custom aggregations, filters, and groupings when the standard query types don't meet your needs.

Endpoint

http
POST /v1/query/custom?website_id={id}

Request Format

json
{
"query": {
  "table": "events",
  "selects": [
    {
      "field": "path",
      "aggregate": "count",
      "alias": "pageviews"
    },
    {
      "field": "anonymous_id",
      "aggregate": "uniq",
      "alias": "unique_visitors"
    }
  ],
  "filters": [
    {
      "field": "country",
      "operator": "eq",
      "value": "US"
    }
  ],
  "groupBy": ["path"]
},
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"timezone": "America/New_York",
"limit": 100
}

Request Fields

Root Fields

FieldTypeRequiredDescription
queryobjectYesQuery configuration
startDatestringYesStart date (YYYY-MM-DD)
endDatestringYesEnd date (YYYY-MM-DD)
timezonestringNoTimezone (default: UTC)
granularitystringNo"hourly" or "daily"
limitnumberNoMax rows (default: 1000, max: 10000)

Query Object

FieldTypeRequiredDescription
tablestringYesTable to query
selectsarrayYesAggregations to compute (1-10)
filtersarrayNoFilter conditions (max 20)
groupByarrayNoGroup by columns (max 5)

Select Object

FieldTypeRequiredDescription
fieldstringYesColumn name or "*" for count
aggregatestringYesAggregation function
aliasstringNoOutput column name

Aggregate Functions

FunctionDescriptionField Requirements
countCount rowsAny field or "*"
uniqCount unique valuesAny field
sumSum valuesNumeric fields only
avgAverage valueNumeric fields only
maxMaximum valueNumeric fields only
minMinimum valueNumeric fields only

Filter Operators

OperatorDescription
eqEquals
neNot equals
gtGreater than
ltLess than
gteGreater than or equal
lteLess than or equal
containsContains substring
not_containsDoes not contain
starts_withStarts with prefix
inValue in array
not_inValue not in array

Available Tables

TableDescription
eventsPage views and custom events
sessionsSession-level data
profilesUser profile data
errorsJavaScript errors
performanceWeb vitals and performance metrics

Example Queries

Top Pages by Unique Visitors

json
{
"query": {
  "table": "events",
  "selects": [
    {"field": "path", "aggregate": "count", "alias": "views"},
    {"field": "anonymous_id", "aggregate": "uniq", "alias": "visitors"}
  ],
  "groupBy": ["path"]
},
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"limit": 20
}

Average Session Duration by Country

json
{
"query": {
  "table": "sessions",
  "selects": [
    {"field": "duration", "aggregate": "avg", "alias": "avg_duration"},
    {"field": "*", "aggregate": "count", "alias": "session_count"}
  ],
  "groupBy": ["country"]
},
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"limit": 50
}

Error Count by Browser

json
{
"query": {
  "table": "errors",
  "selects": [
    {"field": "*", "aggregate": "count", "alias": "error_count"},
    {"field": "message", "aggregate": "uniq", "alias": "unique_errors"}
  ],
  "filters": [
    {"field": "level", "operator": "eq", "value": "error"}
  ],
  "groupBy": ["browser_name"]
},
"startDate": "2024-01-01",
"endDate": "2024-01-31"
}

Response Format

json
{
"success": true,
"data": [
  {
    "path": "/",
    "views": 1250,
    "visitors": 890
  },
  {
    "path": "/pricing",
    "views": 450,
    "visitors": 380
  }
],
"meta": {
  "rowCount": 2,
  "executionTime": 45
}
}

Validation Errors

Custom queries are validated against the schema. Common errors:

json
{
"success": false,
"error": "Invalid column \"invalid_field\" for table \"events\""
}
ErrorCause
Invalid tableTable name not in allowed list
Invalid columnColumn doesn't exist on table
Column not filterableColumn can't be used in filters
Column not aggregatableColumn can't use that aggregate function
Too many selectsMore than 10 select expressions
Too many filtersMore than 20 filters
Too many groupByMore than 5 group by fields

Rate Limits

Custom queries have stricter rate limits due to their computational cost:

  • 30 requests per minute (vs 200+ for standard queries)

Use standard query types when possible for better performance and higher rate limits.

How is this guide?