---
title: Query API
description: POST /v1/query - Query your analytics data programmatically
url: https://www.supalytics.co/docs/api/query
---



Query your analytics data programmatically. Get pageviews, visitors, revenue and other metrics with flexible filtering, sorting, and grouping.

## Endpoint

```
POST https://api.supalytics.co/v1/query
```

## Authentication

Requires an API key or Personal Access Token with `analytics:read` scope.

```
Authorization: Bearer sly_xxx...
```

When using a PAT, you must include the `domain` parameter in your request.

## Request

### Body

| Field             | Type                         | Required | Description                                                                                           |
| ----------------- | ---------------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `domain`          | string                       | PAT only | Site domain to query. Required when using a Personal Access Token.                                    |
| `metrics`         | string\[]                    | No       | Metrics to return. Default: `["visitors", "pageviews"]`. See [Available Metrics](#available-metrics). |
| `date_range`      | string or \[string, string]  | No       | Time period. Default: `"30d"`.                                                                        |
| `dimensions`      | string\[]                    | No       | Group results by dimension. Max 2. See [Available Dimensions](#available-dimensions).                 |
| `filters`         | \[field, operator, value]\[] | No       | Filter data. See [Filters](#filters).                                                                 |
| `sort`            | object                       | No       | Sort results. See [Sorting](#sorting).                                                                |
| `timezone`        | string                       | No       | IANA timezone for date grouping. Default: `"UTC"`.                                                    |
| `limit`           | number                       | No       | Max results (1-1000). Default: 100.                                                                   |
| `offset`          | number                       | No       | Skip results for pagination. Default: 0.                                                              |
| `include_revenue` | boolean                      | No       | Include revenue metrics. Default: false.                                                              |

### Example

```bash
curl -X POST https://api.supalytics.co/v1/query \
  -H "Authorization: Bearer sly_xxx..." \
  -H "Content-Type: application/json" \
  -d '{
    "metrics": ["pageviews", "visitors", "revenue"],
    "date_range": "30d",
    "dimensions": ["page"],
    "filters": [
      ["page", "contains", "/blog"]
    ],
    "sort": {
      "field": "revenue",
      "order": "desc"
    },
    "timezone": "America/New_York",
    "limit": 10,
    "include_revenue": true
  }'
```

## Response

```json
{
  "data": [
    {
      "dimensions": { "page": "/blog/getting-started" },
      "metrics": { "pageviews": 1234, "visitors": 567, "revenue": 45000 }
    },
    {
      "dimensions": { "page": "/blog/advanced-tips" },
      "metrics": { "pageviews": 890, "visitors": 432, "revenue": 23000 }
    }
  ],
  "meta": {
    "domain": "example.com",
    "date_range": ["2024-11-22", "2024-12-22"],
    "timezone": "America/New_York",
    "query_ms": 23
  },
  "pagination": {
    "limit": 10,
    "offset": 0,
    "has_more": true
  },
  "query": {
    "metrics": ["pageviews", "visitors", "revenue"],
    "dimensions": ["page"],
    "date_range": "30d",
    "filters": [["page", "contains", "/blog"]],
    "sort": { "field": "revenue", "order": "desc" },
    "timezone": "America/New_York"
  }
}
```

### Response Fields

| Field                 | Description                                          |
| --------------------- | ---------------------------------------------------- |
| `data`                | Array of result objects with dimensions and metrics  |
| `meta.domain`         | The website domain associated with this API key      |
| `meta.date_range`     | Array of \[start\_date, end\_date] for the query     |
| `meta.timezone`       | Timezone used for date grouping                      |
| `meta.query_ms`       | Query execution time in milliseconds                 |
| `pagination.limit`    | Number of results requested                          |
| `pagination.offset`   | Number of results skipped                            |
| `pagination.has_more` | Whether more results exist beyond this page          |
| `query`               | Echo of the interpreted query (useful for debugging) |

## Available Metrics

### Core Metrics

| Metric                 | Description                         |
| ---------------------- | ----------------------------------- |
| `pageviews`            | Total page views                    |
| `visitors`             | Unique visitors                     |
| `bounce_rate`          | Bounce rate (0-100)                 |
| `avg_session_duration` | Average session duration in seconds |

### Revenue Metrics

Requires `include_revenue: true`.

| Metric            | Description                   |
| ----------------- | ----------------------------- |
| `revenue`         | Total revenue in cents        |
| `conversions`     | Number of converting visitors |
| `conversion_rate` | Conversion rate (0-100)       |

## Available Dimensions

Group your results by one or more dimensions (max 2).

### Content

| Dimension | Description |
| --------- | ----------- |
| `page`    | URL path    |

### Traffic Sources

| Dimension      | Description                   |
| -------------- | ----------------------------- |
| `referrer`     | Referrer domain (or "direct") |
| `utm_source`   | UTM source parameter          |
| `utm_medium`   | UTM medium parameter          |
| `utm_campaign` | UTM campaign parameter        |
| `utm_content`  | UTM content parameter         |
| `utm_term`     | UTM term parameter            |

### Geography

| Dimension | Description                         |
| --------- | ----------------------------------- |
| `country` | ISO country code (US, GB, DE, etc.) |
| `region`  | Region/state name                   |
| `city`    | City name                           |

### Technology

| Dimension | Description                                  |
| --------- | -------------------------------------------- |
| `browser` | Browser name (Chrome, Firefox, Safari, etc.) |
| `os`      | Operating system (Windows, macOS, iOS, etc.) |
| `device`  | Device type (desktop, mobile, tablet)        |

### Time

| Dimension | Description                       |
| --------- | --------------------------------- |
| `date`    | Date bucket (returns daily data)  |
| `hour`    | Hour bucket (returns hourly data) |

### Events

| Dimension | Description                                                  |
| --------- | ------------------------------------------------------------ |
| `event`   | Custom event name (cannot be combined with other dimensions) |

## Date Range

### Predefined Ranges

| Value  | Description            |
| ------ | ---------------------- |
| `7d`   | Last 7 days            |
| `14d`  | Last 14 days           |
| `30d`  | Last 30 days (default) |
| `90d`  | Last 90 days           |
| `12mo` | Last 12 months         |
| `all`  | All time               |

### Custom Range

Pass an array of two ISO dates:

```json
{
  "date_range": ["2024-01-01", "2024-01-31"]
}
```

## Filters

Filter your data using `[field, operator, value]` tuples.

### Operators

| Operator       | Description                                   |
| -------------- | --------------------------------------------- |
| `is`           | Exact match (supports comma-separated values) |
| `is_not`       | Exclude exact match                           |
| `contains`     | Substring match                               |
| `not_contains` | Exclude substring match                       |
| `starts_with`  | Prefix match                                  |

### Filterable Fields

#### Standard Fields

`page`, `country`, `region`, `city`, `browser`, `os`, `device`, `referrer`, `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`

#### Event Filters

| Field            | Description                                       |
| ---------------- | ------------------------------------------------- |
| `event`          | Filter by visitors who triggered a specific event |
| `event_property` | Filter by event property in `key:value` format    |
| `exit_link`      | Filter by exit link URL                           |

### Examples

```json
// Pages containing "/blog"
["page", "contains", "/blog"]

// Visitors from US or UK
["country", "is", "US,UK"]

// Exclude mobile devices
["device", "is_not", "mobile"]

// Traffic from Google
["referrer", "is", "google.com"]

// Visitors who triggered "signup" event
["event", "is", "signup"]

// Visitors with premium plan (event property)
["event_property", "is", "plan:premium"]

// Visitors who clicked a specific exit link
["exit_link", "is", "https://example.com"]
```

## Sorting

Sort results by a metric field.

### Sort Object

```json
{
  "sort": {
    "field": "revenue",
    "order": "desc"
  }
}
```

### Sortable Fields

| Field         | Description             |
| ------------- | ----------------------- |
| `visitors`    | Sort by unique visitors |
| `pageviews`   | Sort by page views      |
| `revenue`     | Sort by revenue         |
| `bounce_rate` | Sort by bounce rate     |

### Sort Order

| Value  | Description                          |
| ------ | ------------------------------------ |
| `desc` | Descending (highest first) - default |
| `asc`  | Ascending (lowest first)             |

## Timezone

Specify a timezone for date/hour dimension grouping. Uses [IANA timezone names](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).

```json
{
  "timezone": "America/New_York"
}
```

Common timezones:

* `UTC` (default)
* `America/New_York`
* `America/Los_Angeles`
* `Europe/London`
* `Europe/Berlin`
* `Asia/Tokyo`

## Pagination

Results are paginated. Use `limit` and `offset` to navigate.

```json
{
  "limit": 100,
  "offset": 0
}
```

Check `pagination.has_more` in the response to know if more results exist:

```json
{
  "pagination": {
    "limit": 100,
    "offset": 0,
    "has_more": true
  }
}
```

To get the next page:

```json
{
  "limit": 100,
  "offset": 100
}
```

## Rate Limits

* **100 requests per minute** per API key
* Rate limit headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`

## Usage Limits

API calls count toward your plan's event limit. If you exceed your limit, you'll receive a `403` response:

```json
{
  "error": "Usage limit exceeded",
  "message": "Your team has exceeded the event limit for this billing period."
}
```

## Examples

### Get overview stats

```json
{
  "metrics": ["pageviews", "visitors", "bounce_rate"]
}
```

### Top pages by revenue

```json
{
  "metrics": ["visitors", "revenue"],
  "dimensions": ["page"],
  "sort": { "field": "revenue", "order": "desc" },
  "include_revenue": true,
  "limit": 10
}
```

### Daily pageview trend

```json
{
  "metrics": ["pageviews", "visitors"],
  "dimensions": ["date"],
  "date_range": "30d",
  "timezone": "America/New_York"
}
```

### Traffic by country with revenue

```json
{
  "metrics": ["visitors", "revenue", "conversion_rate"],
  "dimensions": ["country"],
  "include_revenue": true,
  "limit": 20
}
```

### Filter by referrer and country

```json
{
  "metrics": ["pageviews", "visitors"],
  "dimensions": ["page"],
  "filters": [
    ["referrer", "is", "twitter.com"],
    ["country", "is", "US"]
  ]
}
```

### Mobile traffic from blog pages

```json
{
  "metrics": ["visitors", "bounce_rate"],
  "dimensions": ["page"],
  "filters": [
    ["page", "contains", "/blog"],
    ["device", "is", "mobile"]
  ],
  "sort": { "field": "visitors", "order": "desc" }
}
```

### Custom events breakdown

```json
{
  "dimensions": ["event"]
}
```

### Top countries for visitors who signed up

```json
{
  "dimensions": ["country"],
  "filters": [
    ["event", "is", "signup"]
  ]
}
```

### Pages visited by premium users

```json
{
  "dimensions": ["page"],
  "filters": [
    ["event_property", "is", "plan:premium"]
  ],
  "sort": { "field": "visitors", "order": "desc" }
}
```


---

## Other Documentation

- [Autocapture](https://www.supalytics.co/llms/docs/autocapture)
- [Backfill Existing Subscriptions](https://www.supalytics.co/llms/docs/backfill-existing-subscriptions)
- [Block Your Own Traffic](https://www.supalytics.co/llms/docs/block-your-traffic)
- [CLI](https://www.supalytics.co/llms/docs/cli)
- [Custom Events](https://www.supalytics.co/llms/docs/custom-events)
- [Features](https://www.supalytics.co/llms/docs/features)
- [Conversion Funnels](https://www.supalytics.co/llms/docs/funnels)
- [Introduction](https://www.supalytics.co/llms/docs)
- [Install Script](https://www.supalytics.co/llms/docs/install-script)
- [MRR Tracking](https://www.supalytics.co/llms/docs/mrr-tracking)
- [Revenue Attribution](https://www.supalytics.co/llms/docs/revenue-attribution)
- [Agent Skills](https://www.supalytics.co/llms/docs/skills)
- [Tracking Modes](https://www.supalytics.co/llms/docs/tracking-modes)
- [Visitor Journey](https://www.supalytics.co/llms/docs/visitor-journey)
- [Annotations](https://www.supalytics.co/llms/docs/api/annotations)
- [Error Codes](https://www.supalytics.co/llms/docs/api/errors)
- [Events (Read)](https://www.supalytics.co/llms/docs/api/events)
- [API Reference](https://www.supalytics.co/llms/docs/api)
- [Journeys](https://www.supalytics.co/llms/docs/api/journeys)
- [Realtime API](https://www.supalytics.co/llms/docs/api/realtime)
- [Revenue Attribution API](https://www.supalytics.co/llms/docs/api/revenue-attribution)
- [Events (Write)](https://www.supalytics.co/llms/docs/api/server-side-events)