---
title: "Aggregate analytics events by field"
method: POST
path: "/api/apps/{app_id}/analytics/grouped"
---

# Aggregate analytics events by field

`POST /api/apps/{app_id}/analytics/grouped`

<Info>This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.</Info>

Breaks the app's analytics events down by the value of a field, so you can rank them: the busiest pages, the countries your users come from, the most tracked event names.

Every metric must set `field`, and that field is what the metric groups by. `user_id`, `session_id`, `event_id`, `event_name` and `page_url` group by those top-level fields, which is what the default metric does. A `metadata.` prefix groups by the device information Base44 captures itself: `metadata.country`, `metadata.device_type`, and `metadata.os`. Any other name groups by an event property. Groups come back largest first, capped at `max_groups` per metric. The range defaults to the last 30 days, and events are kept for 60 days.

Use `count` for the metric function. Because a metric's `field` is both the field it groups by and the field its function reads, the other functions return a value the grouping already implies: `count_unique` reports `1` for every group, and `sum`, `avg`, `min`, `max` and the percentiles report the group's own value.

Each entry in `groups` carries exactly one metric. When you send several metrics, the list holds one entry per group value per metric, so read the metric name off each entry's `metrics` key instead of assuming a single set of groups. `group_count` counts those entries across all metrics, not the number of distinct group values.

<Note>This endpoint takes no filter expression. To break down a filtered set of events, filter by event name here, or use [Aggregate analytics events over time](/api-reference/aggregate-analytics-events-over-time) with `q` and a single bucket.</Note>

## Path parameters

- `app_id` string, required — ID of the app whose analytics to read.

## Request body

- GroupedAggregationRequest — Request for grouped event aggregation.
  - `event_name` string, nullable — Name of the event to aggregate. Omit to aggregate every event the app tracks.
  - `start_time` string, date-time, nullable — Start of the time range. Defaults to 30 days ago.
  - `end_time` string, date-time, nullable — End of the time range. Defaults to now.
  - `max_groups` integer — Maximum number of groups to return per metric, between 1 and 1000. The largest groups are kept.
  - `metrics` AggregationMetric[] — Between 1 and 10 metrics to compute. Each one must set `field`, which is the field it groups by. Defaults to an event count per event name, named `event_count`.
    - `name` string, required — Name to report this metric under. It becomes a key in `metrics` and `totals` in the response.
    - `function` 'count' | 'count_unique' | 'sum' | 'avg' | 'min' | 'max' | 'p50' | 'p90' | 'p95' | 'p99', required — How to aggregate the field. `count` counts events, `count_unique` counts distinct values, and the rest compute over the field's numeric values.
    - `field` string, nullable — Field to aggregate. Required for every function except `count`. Top-level fields are `user_id`, `session_id`, `event_id`, `event_name`, and `page_url`. Prefix a key with `metadata.` for the device information Base44 captures itself: `metadata.device_type`, `metadata.os`, and `metadata.country`. Any other name reads as an event property, so `amount` and `properties.amount` mean the same thing.

## Response `200`

The grouped metrics.

- GroupedAggregationResponse — Response for grouped event aggregation.
  - `event_name` string, nullable — The event name that was aggregated, or `null` when the request covered every event.
  - `group_count` integer — Number of entries in `groups`, summed across every metric.
  - `totals` object — Each metric computed over the whole range without grouping, keyed by metric name.
  - `groups` AggregationGroup[] — One entry per group value per metric, largest metric value first within each metric.
    - `group` string, nullable, required — Value of the grouped field, or `null` when the events in this group have no value for it.
    - `metrics` object — The single metric this entry reports, keyed by the `name` you gave it.

## Other responses

- `401` — Missing or invalid credentials.
- `403` — You don't have access to this app.
- `404` — App not found.
- `422` — Validation Error

## Changes

- **2026-08-25** `8dfd9c46c0b9` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/idealspot/apis/base44-app-management-api/changes/api/apps/:app_id/analytics/grouped/post.md)

---

[API](https://skmtc.dev/idealspot/apis/base44-app-management-api.md) · [All operations](https://skmtc.dev/idealspot/apis/base44-app-management-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/idealspot/base44-app-management-api/revisions/31ef75eb64ab/schema)
