> ## Documentation Index
> Fetch the complete documentation index at: https://docs.base44.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Aggregate analytics events by field

> <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>



## OpenAPI

````yaml /developers/references/app-management/app-management-openapi.json post /api/apps/{app_id}/analytics/grouped
openapi: 3.1.0
info:
  title: Base44 App Management API
  version: 1.0.0
servers:
  - url: https://app.base44.com
security:
  - ApiKeyAuth: []
paths:
  /api/apps/{app_id}/analytics/grouped:
    post:
      summary: Aggregate analytics events by field
      description: >-
        <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>
      operationId: grouped_api_apps__app_id__analytics_grouped_post
      parameters:
        - name: app_id
          in: path
          required: true
          schema:
            type: string
            description: ID of the app whose analytics to read.
            title: App Id
          description: ID of the app whose analytics to read.
          example: 6820f3a4e7b91d003c45a1f2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupedAggregationRequest'
      responses:
        '200':
          description: The grouped metrics.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupedAggregationResponse'
        '401':
          description: Missing or invalid credentials.
        '403':
          description: You don't have access to this app.
        '404':
          description: App not found.
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    GroupedAggregationRequest:
      properties:
        event_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Event Name
          description: >-
            Name of the event to aggregate. Omit to aggregate every event the
            app tracks.
          example: checkout_completed
        start_time:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Start Time
          description: Start of the time range. Defaults to 30 days ago.
          example: '2026-07-03T00:00:00Z'
        end_time:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: End Time
          description: End of the time range. Defaults to now.
          example: '2026-08-02T00:00:00Z'
        max_groups:
          type: integer
          maximum: 1000
          minimum: 1
          title: Max Groups
          description: >-
            Maximum number of groups to return per metric, between 1 and 1000.
            The largest groups are kept.
          default: 100
          example: 10
        metrics:
          items:
            $ref: '#/components/schemas/AggregationMetric'
          type: array
          maxItems: 10
          minItems: 1
          title: Metrics
          description: >-
            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`.
          example:
            - field: page_url
              function: count
              name: event_count
      type: object
      title: GroupedAggregationRequest
      description: Request for grouped event aggregation.
    GroupedAggregationResponse:
      properties:
        event_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Event Name
          description: >-
            The event name that was aggregated, or `null` when the request
            covered every event.
          example: checkout_completed
        group_count:
          type: integer
          title: Group Count
          description: Number of entries in `groups`, summed across every metric.
          default: 0
          example: 10
        totals:
          additionalProperties:
            anyOf:
              - type: number
              - type: integer
          type: object
          title: Totals
          description: >-
            Each metric computed over the whole range without grouping, keyed by
            metric name.
          example:
            event_count: 3840
        groups:
          items:
            $ref: '#/components/schemas/AggregationGroup'
          type: array
          title: Groups
          description: >-
            One entry per group value per metric, largest metric value first
            within each metric.
          example:
            - group: /checkout
              metrics:
                event_count: 842
            - group: /pricing
              metrics:
                event_count: 517
      type: object
      title: GroupedAggregationResponse
      description: Response for grouped event aggregation.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    AggregationMetric:
      properties:
        name:
          type: string
          maxLength: 64
          pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
          title: Name
          description: >-
            Name to report this metric under. It becomes a key in `metrics` and
            `totals` in the response.
          example: unique_users
        function:
          type: string
          enum:
            - count
            - count_unique
            - sum
            - avg
            - min
            - max
            - p50
            - p90
            - p95
            - p99
          title: Function
          description: >-
            How to aggregate the field. `count` counts events, `count_unique`
            counts distinct values, and the rest compute over the field's
            numeric values.
          example: count_unique
        field:
          anyOf:
            - type: string
              maxLength: 128
              pattern: >-
                ^(properties\.)?[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*$
            - type: 'null'
          title: Field
          description: >-
            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.
          example: user_id
      type: object
      required:
        - name
        - function
      title: AggregationMetric
      description: A single aggregation metric to compute.
    AggregationGroup:
      properties:
        group:
          anyOf:
            - type: string
            - type: 'null'
          title: Group
          description: >-
            Value of the grouped field, or `null` when the events in this group
            have no value for it.
          example: checkout_completed
        metrics:
          additionalProperties:
            anyOf:
              - type: number
              - type: integer
          type: object
          title: Metrics
          description: >-
            The single metric this entry reports, keyed by the `name` you gave
            it.
          example:
            event_count: 842
      type: object
      required:
        - group
      title: AggregationGroup
      description: A single group with its field value and computed metrics.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: api_key
      description: Personal API key.

````