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

> ## Agent Instructions
> Internal links on these pages omit the .md extension. Append .md to a docs page URL, or send an Accept: text/markdown header, to get that page as markdown.

# Aggregate entity records

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

Computes counts, totals, averages, minimums, maximums and distinct counts over one of the app's entities, grouped by the fields you choose, without returning the records.

Pick the records with `query`, group them with `group_by`, `date_bucket`, or both, and name the values to compute. For example, `{"group_by": "status", "sum": "amount"}` returns one row per status with its record count and the total of `amount`. Leave out `group_by` and `date_bucket` to get one row over every matching record. That row is returned even when no record matches, with `0` for counts and totals and `null` for averages, minimums and maximums, unless `having` rules it out.

Fields can be any field the entity's schema declares, or one every record carries, such as `created_date` or `created_by`. `sum` and `avg` need fields the schema declares as numbers, and `min`, `max` and `count_distinct` need fields it declares as a string, number, integer or boolean. A stored value of another type is skipped. A `date_bucket` on `created_date` or `updated_date` returns the start of each period as a timestamp. On a date field from the schema it returns the matching part of the stored text, such as `2026-06` for a month, and a stored value that isn't a date is grouped under `null`.

Deleted records are left out, and row-level security applies, so the values cover only the records the entity's `rls` read rule lets your credential see. An aggregate reads every matching record and must finish within 30 seconds, with a response under 256 KB. Narrow `query` when it doesn't. The `User` entity and entities with field-level read rules aren't supported.

The camelCase spellings `groupBy`, `dateBucket` and `countDistinct` are accepted too.

<Note>This endpoint accepts a personal API key belonging to a user with access to the app, including a read-only key. Workspace API keys are not accepted.</Note>



## OpenAPI

````yaml /developers/references/app-management/app-management-openapi.json post /api/apps/{app_id}/entities/{entity_name}/aggregate
openapi: 3.1.0
info:
  title: Base44 App Management API
  version: 1.0.0
servers:
  - url: https://app.base44.com
security:
  - PersonalAccessTokenAuth: []
paths:
  /api/apps/{app_id}/entities/{entity_name}/aggregate:
    post:
      summary: Aggregate entity records
      description: >-
        <Info>This API is in beta. Endpoints, fields, and behavior may still
        change, so avoid depending on it in production.</Info>


        Computes counts, totals, averages, minimums, maximums and distinct
        counts over one of the app's entities, grouped by the fields you choose,
        without returning the records.


        Pick the records with `query`, group them with `group_by`,
        `date_bucket`, or both, and name the values to compute. For example,
        `{"group_by": "status", "sum": "amount"}` returns one row per status
        with its record count and the total of `amount`. Leave out `group_by`
        and `date_bucket` to get one row over every matching record. That row is
        returned even when no record matches, with `0` for counts and totals and
        `null` for averages, minimums and maximums, unless `having` rules it
        out.


        Fields can be any field the entity's schema declares, or one every
        record carries, such as `created_date` or `created_by`. `sum` and `avg`
        need fields the schema declares as numbers, and `min`, `max` and
        `count_distinct` need fields it declares as a string, number, integer or
        boolean. A stored value of another type is skipped. A `date_bucket` on
        `created_date` or `updated_date` returns the start of each period as a
        timestamp. On a date field from the schema it returns the matching part
        of the stored text, such as `2026-06` for a month, and a stored value
        that isn't a date is grouped under `null`.


        Deleted records are left out, and row-level security applies, so the
        values cover only the records the entity's `rls` read rule lets your
        credential see. An aggregate reads every matching record and must finish
        within 30 seconds, with a response under 256 KB. Narrow `query` when it
        doesn't. The `User` entity and entities with field-level read rules
        aren't supported.


        The camelCase spellings `groupBy`, `dateBucket` and `countDistinct` are
        accepted too.


        <Note>This endpoint accepts a personal API key belonging to a user with
        access to the app, including a read-only key. Workspace API keys are not
        accepted.</Note>
      operationId: >-
        aggregate_entities_api_apps__app_id__entities__entity_name__aggregate_post
      parameters:
        - name: app_id
          in: path
          required: true
          schema:
            type: string
            description: ID of the app that owns the entity.
            title: App Id
          description: ID of the app that owns the entity.
          example: 6820f3a4e7b91d003c45a1f2
        - name: entity_name
          in: path
          required: true
          schema:
            type: string
            description: >-
              Name of the entity, exactly as [List entity
              schemas](/api-reference/list-entity-schemas) reports it. Don't
              pass `User` here. It doesn't fail, but it reads and writes a
              separate, disconnected set of records stored under that name, not
              the app's real user accounts, which are managed through their own
              endpoints.
            title: Entity Name
          description: >-
            Name of the entity, exactly as [List entity
            schemas](/api-reference/list-entity-schemas) reports it. Don't pass
            `User` here. It doesn't fail, but it reads and writes a separate,
            disconnected set of records stored under that name, not the app's
            real user accounts, which are managed through their own endpoints.
          example: Invoice
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AggregateSpec'
      responses:
        '200':
          description: The computed values.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
                title: EntityAggregateResponse
                description: The computed values, one row per group.
                properties:
                  rows:
                    description: >-
                      One row per group. A row holds each group field and the
                      `date_bucket` field under its own name, then `count` and
                      the `sum_<field>`, `avg_<field>`, `min_<field>`,
                      `max_<field>` and `count_distinct_<field>` values you
                      asked for. In those computed names, a dot in the field
                      name becomes `_`. Date values, such as a `date_bucket` or
                      a `min_created_date`, are UTC timestamps in ISO 8601
                      format with an offset.
                    example:
                      - count: 128
                        status: paid
                        sum_amount: 20480.5
                    items:
                      additionalProperties: true
                      type: object
                    title: Rows
                    type: array
                  truncated:
                    description: >-
                      `true` when more groups matched than `limit`, so some were
                      left out.
                    example: false
                    title: Truncated
                    type: boolean
                required:
                  - rows
                  - truncated
        '400':
          description: >-
            A field isn't declared in the entity's schema or has the wrong type
            for what you asked, `group_by` names more than 4 fields, nothing is
            left to compute, `having` or `sort` names a field the request
            doesn't compute or group by, two names collide, `query` isn't a
            filter Base44 can run, the aggregate ran past 30 seconds or 256 KB,
            or the entity is `User` or has field-level read rules.
        '401':
          description: Missing or invalid credentials.
        '403':
          description: You don't have access to this app.
        '404':
          description: App not found, or the app has no entity with this name.
        '422':
          description: >-
            The body has a field not documented here, or `limit` is outside 1 to
            1000.
        '429':
          description: >-
            Rate limit exceeded. The base limit is 15 requests per minute: an
            aggregate reads every matching record, so its limit is separate from
            list and lower. Pages of [List entity
            records](/api-reference/list-entity-records) with `distinct` count
            against it too. See [Rate
            limits](/developers/references/apps-api/get-started/rate-limits) for
            the multiplier your plan gets.
components:
  schemas:
    AggregateSpec:
      properties:
        query:
          additionalProperties: true
          type: object
          title: Query
          description: >-
            Filter selecting the records to aggregate, in the same form as `q`
            on [List entity records](/api-reference/list-entity-records). Leave
            it out to aggregate every record you can read.
          example:
            status: paid
        group_by:
          items:
            type: string
          type: array
          title: Group By
          description: >-
            Up to 4 fields to group by, as a list or a single field name. Each
            row holds one combination of their values. Leave it out, along with
            `date_bucket`, for one row over all matching records.
          example:
            - status
        date_bucket:
          anyOf:
            - $ref: '#/components/schemas/DateBucket'
            - type: 'null'
          description: >-
            Also groups by the period a date falls in, such as the day or month
            a record was created.
        count:
          type: boolean
          title: Count
          description: >-
            Whether each row includes `count`, the number of records in the
            group.
          default: true
          example: true
        sum:
          items:
            type: string
          type: array
          title: Sum
          description: >-
            Number fields to total, as a list or a single field name. Each adds
            `sum_<field>` to the rows.
          example:
            - amount
        avg:
          items:
            type: string
          type: array
          title: Avg
          description: >-
            Number fields to average, as a list or a single field name. Each
            adds `avg_<field>` to the rows.
          example:
            - amount
        min:
          items:
            type: string
          type: array
          title: Min
          description: >-
            Fields whose smallest value to return, as a list or a single field
            name. Each adds `min_<field>` to the rows.
          example:
            - created_date
        max:
          items:
            type: string
          type: array
          title: Max
          description: >-
            Fields whose largest value to return, as a list or a single field
            name. Each adds `max_<field>` to the rows.
          example:
            - amount
        count_distinct:
          anyOf:
            - type: string
            - type: 'null'
          title: Count Distinct
          description: >-
            One field whose distinct values to count, leaving out `null`. Adds
            `count_distinct_<field>` to the rows.
          example: customer_email
        having:
          additionalProperties: true
          type: object
          title: Having
          description: >-
            Filter on the computed values, applied after grouping. Name `count`
            or a computed field such as `sum_amount`, with a value to match or
            with `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in` or `$nin`.
          example:
            count:
              $gt: 1
        sort:
          anyOf:
            - type: string
            - type: 'null'
          title: Sort
          description: >-
            Group field or computed field to sort the rows by, prefixed with `-`
            for descending. Without it, the order of the rows isn't defined.
          example: '-sum_amount'
        limit:
          type: integer
          maximum: 1000
          minimum: 1
          title: Limit
          description: Maximum number of rows to return, from 1 to 1000.
          default: 1000
          example: 100
      additionalProperties: false
      type: object
      title: AggregateSpec
      description: >-
        The wire body of POST /{entity}/aggregate. Keys are camelCase on the
        wire (the SDK's vocabulary).
    DateBucket:
      properties:
        field:
          type: string
          title: Field
          description: >-
            Date field to bucket by: `created_date`, `updated_date`, or a field
            the entity's schema declares as a string with format `date` or
            `date-time`.
          example: created_date
        unit:
          type: string
          enum:
            - day
            - week
            - month
            - year
          title: Unit
          description: >-
            Length of each period. `week` works only on `created_date` and
            `updated_date`, where weeks start on Sunday.
          default: day
          example: month
      additionalProperties: false
      type: object
      required:
        - field
      title: DateBucket
      description: Groups records by the period a date falls in.
  securitySchemes:
    PersonalAccessTokenAuth:
      type: http
      scheme: bearer
      description: 'Personal access token, sent as `Authorization: Bearer <token>`.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.