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

# Aggregate records

> Counts the records matching every filter and measures numeric fields over them. With
`groupBy`, it does the same for each distinct value of that field and returns the results
in `groups`; without it, it returns one total in `count` and `metrics`.

A `call` aggregation counts only the calls the key's owner can open.


> [!NOTE]
>
> The Clearskies API is in beta and available on request. To turn it on for your workspace, email
> [support@clearskies.cc](mailto:support@clearskies.cc).


## OpenAPI

````yaml api-reference/openapi.yaml POST /v1/objects/{object}/aggregate
openapi: 3.1.0
info:
  title: Clearskies Public API
  version: '1'
  description: >
    Read the accounts, calls, contacts and deals in your Context Graph, and the
    transcripts of

    your calls, from your own code.


    Every response is a JSON envelope. A success carries `ok: true` and the
    result in `data`; a

    failure carries `ok: false` and an `error` whose `code` is the value to
    branch on. Both carry

    `requestId`, which support resolves a report against.


    The fields available can differ between workspaces, so read an object's
    schema with

    `GET /v1/objects/{object}` before you query it. The schema lists every field
    you can select,

    filter, sort, group or measure, and the filter operators each one accepts.
servers:
  - url: https://api.clearskies.cc
security:
  - apiKey: []
tags:
  - name: Objects
    description: The object types the API serves, and the fields each one carries.
  - name: Records
    description: Query and aggregate the records of one object type.
  - name: Calls
    description: Read what was said on a call.
paths:
  /v1/objects/{object}/aggregate:
    post:
      tags:
        - Records
      summary: Aggregate records
      description: >
        Counts the records matching every filter and measures numeric fields
        over them. With

        `groupBy`, it does the same for each distinct value of that field and
        returns the results

        in `groups`; without it, it returns one total in `count` and `metrics`.


        A `call` aggregation counts only the calls the key's owner can open.
      operationId: aggregateRecords
      parameters:
        - $ref: '#/components/parameters/object'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AggregateRequest'
            example:
              filters:
                - field: closeDate
                  op: after
                  value: '2026-01-01'
              groupBy: stage
              metrics:
                - field: amount
                  function: sum
                - field: amount
                  function: avg
      responses:
        '200':
          description: The aggregation.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessEnvelope'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/AggregateResult'
              example:
                ok: true
                data:
                  count: 15
                  metrics: null
                  groups:
                    - value: Negotiation
                      count: 12
                      metrics:
                        - field: amount
                          function: sum
                          value: 864000
                        - field: amount
                          function: avg
                          value: 72000
                    - value: null
                      count: 3
                      metrics:
                        - field: amount
                          function: sum
                          value: 0
                        - field: amount
                          function: avg
                          value: null
                requestId: 0199f2b0-7c41-7a3e-9d6c-2f5a1b8e4c07
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/TenantBlocked'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
        '504':
          $ref: '#/components/responses/GatewayTimeout'
components:
  parameters:
    object:
      name: object
      in: path
      required: true
      description: >-
        The object type. An unknown name is a `400`, and the message lists the
        valid ones.
      schema:
        $ref: '#/components/schemas/ObjectName'
  schemas:
    AggregateRequest:
      type: object
      additionalProperties: false
      description: >
        Every member is optional, and a member sent as null counts as omitted.
        An empty body

        counts every record.
      properties:
        filters:
          type:
            - array
            - 'null'
          maxItems: 100
          items:
            $ref: '#/components/schemas/FilterClause'
        groupBy:
          type:
            - string
            - 'null'
          description: >
            A field whose `groupable` is true. A field with too many distinct
            values among the

            matching records is a `400`; add filters to narrow them.
        metrics:
          type:
            - array
            - 'null'
          maxItems: 5
          items:
            $ref: '#/components/schemas/MetricClause'
          description: Each function of each field may appear once.
    SuccessEnvelope:
      type: object
      required:
        - ok
        - data
        - requestId
      properties:
        ok:
          type: boolean
          const: true
        data: {}
        requestId:
          type: string
          description: Identifies this call. Quote it when you contact support.
        traceId:
          type: string
          description: Present on a traced request.
    AggregateResult:
      type: object
      required:
        - count
        - metrics
        - groups
      properties:
        count:
          type: integer
          description: >-
            Every record the filters match. When the request grouped, the sum of
            the groups' counts.
        metrics:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Metric'
          description: >-
            The requested metrics over every matching record. Null when the
            request grouped or asked for none.
        groups:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/AggregateGroup'
          description: >-
            One entry per distinct `groupBy` value. Null when the request did
            not group.
    ObjectName:
      type: string
      enum:
        - account
        - call
        - contact
        - deal
    FilterClause:
      type: object
      required:
        - field
        - op
      additionalProperties: false
      description: One condition. A request's filters must all match.
      properties:
        field:
          type: string
          description: A field whose `filterable` is true.
        op:
          allOf:
            - $ref: '#/components/schemas/FilterOperator'
          description: One of the field's `operators`.
        value:
          description: >
            Depends on `op`:


            - `isEmpty`, `isNotEmpty`: omit it, or send null.

            - `isIn`, `isNotIn`: an array of values.

            - Anything else: a single value.


            On a `referenceArray` field, `isIn` matches a record that refers to
            any of the ids,

            and `isNotIn` one that refers to none of them.


            Each value must match the field's type: a number for `integer`,
            `currency` and

            `duration`; `true` or `false` for `boolean`; an RFC 3339 timestamp

            (`2026-01-31T09:00:00Z`) or a date (`2026-01-31`) for `date` and
            `timestamp`; and a

            non-empty string for everything else, including a reference field's
            record `id`.

            Text comparisons ignore case.
          oneOf:
            - type: 'null'
            - type: string
            - type: number
            - type: boolean
            - type: array
              minItems: 1
              maxItems: 200
              items:
                oneOf:
                  - type: string
                  - type: number
                  - type: boolean
    MetricClause:
      type: object
      required:
        - field
        - function
      additionalProperties: false
      properties:
        field:
          type: string
          description: A field whose `measurable` is true.
        function:
          $ref: '#/components/schemas/MetricFunction'
    Metric:
      type: object
      required:
        - field
        - function
        - value
      properties:
        field:
          type: string
        function:
          $ref: '#/components/schemas/MetricFunction'
        value:
          type:
            - number
            - 'null'
          description: >-
            Null when no record in scope has a value for the field, except for
            `sum`, which is 0.
    AggregateGroup:
      type: object
      required:
        - value
        - count
        - metrics
      properties:
        value:
          type:
            - string
            - number
            - boolean
            - 'null'
          description: >
            The `groupBy` value, written as the field's value is written in a
            record, so a group

            joins to the records it counts. A reference field's is the
            referenced record's `id`.

            Null groups the records with no value.
        count:
          type: integer
        metrics:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Metric'
          description: >-
            The requested metrics over this group. Null when the request asked
            for none.
    ErrorEnvelope:
      type: object
      required:
        - ok
        - error
        - requestId
      properties:
        ok:
          type: boolean
          const: false
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
              description: >
                A diagnosis for a person to read. Its wording changes over time,
                so branch on

                `code`, not on this text.
        requestId:
          type: string
          description: Identifies this call. Quote it when you contact support.
        traceId:
          type: string
          description: Present on a traced request.
    FilterOperator:
      type: string
      enum:
        - equal
        - notEqual
        - contains
        - greaterThan
        - greaterThanOrEqual
        - lessThan
        - lessThanOrEqual
        - before
        - after
        - isIn
        - isNotIn
        - isEmpty
        - isNotEmpty
    MetricFunction:
      type: string
      enum:
        - sum
        - avg
        - min
        - max
    ErrorCode:
      type: string
      description: The value to branch on when a request fails.
      enum:
        - BAD_REQUEST
        - UNAUTHORIZED
        - TENANT_BLOCKED
        - NOT_FOUND
        - RATE_LIMITED
        - INTERNAL_ERROR
        - SERVICE_UNAVAILABLE
        - GATEWAY_TIMEOUT
  headers:
    X-RateLimit-Limit:
      description: >
        Requests the key can make in a burst. The rate-limit headers are sent on
        the responses

        that list them, while the rate limiter is reachable.
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests left in the current budget.
      schema:
        type: integer
    X-RateLimit-Reset:
      description: Seconds until the budget is full again.
      schema:
        type: integer
    X-Request-ID:
      description: >-
        Identifies this call, as `requestId` in the body does. Quote either to
        support.
      schema:
        type: string
    Retry-After:
      description: Seconds to wait before retrying.
      schema:
        type: integer
  responses:
    BadRequest:
      description: >
        The API declined to run the request. The message names the member at
        fault by its JSON

        path and lists what that member accepts. Fix the request rather than
        retrying it.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            ok: false
            error:
              code: BAD_REQUEST
              message: >-
                filters[0].op "contains" is not an operator "createdAt" accepts.
                Valid operators: equal, notEqual, before, after, isEmpty,
                isNotEmpty.
            requestId: 0199f2b0-7c41-7a3e-9d6c-2f5a1b8e4c07
    Unauthorized:
      description: >
        The key was not accepted: it is missing, malformed, unknown or revoked;
        the person who

        created it has been deactivated or has left the workspace; or the
        workspace is inactive.

        Every case answers the same way, so check each when a key that worked
        starts failing.
      headers:
        WWW-Authenticate:
          schema:
            type: string
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    TenantBlocked:
      description: The key's workspace is blocked.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    RateLimited:
      description: >
        The key has spent its request budget, or has too many requests in
        flight. Wait for

        `Retry-After` seconds, then retry.
      headers:
        Retry-After:
          $ref: '#/components/headers/Retry-After'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    InternalError:
      description: The request failed on our side. Quote `requestId` to support.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    ServiceUnavailable:
      description: >-
        The key could not be verified because a service it depends on did not
        answer. Retry.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    GatewayTimeout:
      description: >-
        The request ran past its deadline. Narrow the query with filters and
        retry.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >
        An API key created under Context Graph → API keys in the app sidebar,
        sent as `Authorization: Bearer csk_…`.

        The key is checked on every request, so a revoked key fails on its next
        call.

````

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