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

# Run an analytics query

> Runs a query against a versioned analytics catalog model and returns a columnar table. Totals queries (no dimensions) return exactly one row. Grouped, dimension-ordered queries may paginate with an opaque `cursor`.



## OpenAPI

````yaml /openapi.json post /api/v1/analytics/query
openapi: 3.0.3
info:
  title: Burt Analytics API
  version: 1.0.0
  description: >-
    Organization-scoped analytics over agent runs and the attribution records
    that connect people to those runs. Authenticate with an organization API key
    (`Authorization: Bearer burt_sk_...`) that includes the `analytics:read`
    scope.
servers:
  - url: https://api.burthq.com
security:
  - bearerAuth: []
paths:
  /api/v1/analytics/query:
    post:
      summary: Run an analytics query
      description: >-
        Runs a query against a versioned analytics catalog model and returns a
        columnar table. Totals queries (no dimensions) return exactly one row.
        Grouped, dimension-ordered queries may paginate with an opaque `cursor`.
      operationId: runAnalyticsQuery
      parameters:
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnalyticsQueryRequest'
            example:
              model: agent_runs
              metrics:
                - run_count
                - completed_run_count
                - failed_run_count
              dimensions: []
              filters: []
              range:
                start: '2026-08-01'
                end: '2026-08-14'
                timezone: UTC
              order: []
              limit: 100
      responses:
        '200':
          description: Columnar query results.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnalyticsQueryResponse'
              example:
                queryId: 550e8400-e29b-41d4-a716-446655440000
                catalogVersion: 2026-08-24.2
                asOf: '2026-08-21T00:00:00.000Z'
                range:
                  start: '2026-08-01'
                  end: '2026-08-14'
                  timezone: UTC
                  startUtc: '2026-08-01T00:00:00.000Z'
                  endUtc: '2026-08-15T00:00:00.000Z'
                columns:
                  - name: run_count
                    type: number
                    member: run_count
                  - name: completed_run_count
                    type: number
                    member: completed_run_count
                  - name: failed_run_count
                    type: number
                    member: failed_run_count
                rows:
                  - - 25
                    - 17
                    - 4
                cursor: null
                warnings: []
        '400':
          description: >-
            Invalid request. `error.code` is one of `invalid_query`,
            `unknown_member`, `range_too_large`, or `invalid_cursor`.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryErrorEnvelope'
              examples:
                invalidQuery:
                  summary: Invalid query grammar
                  value:
                    error:
                      code: invalid_query
                      message: Invalid analytics query.
                      request_id: req_01J5Y7E9K2M4P6Q8R0S1T3V5W7
                unknownMember:
                  summary: Unknown catalog member
                  value:
                    error:
                      code: unknown_member
                      message: Unknown analytics member.
                      param: not_a_member
                      request_id: req_01J5Y7E9K2M4P6Q8R0S1T3V5W7
                rangeTooLarge:
                  summary: Date range exceeds 366 days
                  value:
                    error:
                      code: range_too_large
                      message: Analytics date range is too large.
                      request_id: req_01J5Y7E9K2M4P6Q8R0S1T3V5W7
                invalidCursor:
                  summary: Invalid or mismatched cursor
                  value:
                    error:
                      code: invalid_cursor
                      message: Invalid analytics cursor.
                      request_id: req_01J5Y7E9K2M4P6Q8R0S1T3V5W7
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/InsufficientScope'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  parameters:
    RequestId:
      name: x-request-id
      in: header
      required: false
      description: >-
        Optional caller-supplied request ID. Values must contain 1–64 ASCII
        letters, digits, or `._:/=-`; invalid values are replaced with a
        generated UUID.
      schema:
        type: string
        minLength: 1
        maxLength: 64
        pattern: ^[A-Za-z0-9._:/=-]+$
  schemas:
    AnalyticsQueryRequest:
      type: object
      required:
        - model
        - metrics
        - range
      additionalProperties: false
      properties:
        model:
          type: string
          minLength: 1
          maxLength: 64
          enum:
            - agent_runs
            - agent_user_activity
          description: >-
            Catalog model name. The current catalog supports `agent_runs` and
            `agent_user_activity`.
        metrics:
          type: array
          minItems: 1
          maxItems: 16
          uniqueItems: true
          items:
            type: string
            minLength: 1
            maxLength: 64
          description: Unique catalog metric names to select.
        dimensions:
          type: array
          maxItems: 8
          default: []
          uniqueItems: true
          items:
            type: string
            minLength: 1
            maxLength: 64
          description: Unique catalog dimensions to group by.
        filters:
          type: array
          maxItems: 8
          default: []
          items:
            $ref: '#/components/schemas/QueryFilter'
          description: >-
            Dimension filters: `eq` with one `value`, or `in` with 1–50
            `values`.
        range:
          $ref: '#/components/schemas/QueryRange'
        order:
          type: array
          maxItems: 8
          default: []
          uniqueItems: true
          x-unique-by: member
          items:
            $ref: '#/components/schemas/QueryOrderTerm'
          description: >-
            Up to eight unique order terms. Members must be selected metrics or
            dimensions. Totals queries cannot specify order terms.
        limit:
          type: integer
          minimum: 1
          maximum: 500
          default: 100
          description: Maximum rows returned per page.
        cursor:
          type: string
          minLength: 1
          maxLength: 2048
          description: >-
            Opaque continuation cursor from a previous grouped response. Not
            accepted on totals or metric-ordered queries.
    AnalyticsQueryResponse:
      type: object
      additionalProperties: false
      required:
        - queryId
        - catalogVersion
        - asOf
        - range
        - columns
        - rows
        - cursor
        - warnings
      properties:
        queryId:
          type: string
          format: uuid
          description: Unique identifier for this execution.
        catalogVersion:
          type: string
          description: Catalog version used to produce this response.
        asOf:
          type: string
          format: date-time
          description: >-
            Inclusion boundary used for this response and any cursor
            continuation.
        range:
          type: object
          additionalProperties: false
          required:
            - start
            - end
            - timezone
            - startUtc
            - endUtc
          properties:
            start:
              type: string
              format: date
            end:
              type: string
              format: date
            timezone:
              type: string
            startUtc:
              type: string
              format: date-time
              description: Inclusive UTC instant the range resolves to.
            endUtc:
              type: string
              format: date-time
              description: Exclusive UTC instant the range resolves to.
        columns:
          type: array
          items:
            $ref: '#/components/schemas/Column'
          description: >-
            Ordered column descriptors; a selected dimension is followed by its
            companions, then metrics.
        rows:
          type: array
          items:
            type: array
            items:
              oneOf:
                - type: string
                - type: number
                - type: string
                  nullable: true
                  enum:
                    - null
          description: Values in the same order as `columns`.
        cursor:
          type: string
          nullable: true
          description: >-
            Continuation cursor for the next page, or `null` when there is no
            next page.
        warnings:
          type: array
          items:
            $ref: '#/components/schemas/Warning'
          description: Non-fatal semantic notices.
    QueryErrorEnvelope:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              enum:
                - invalid_query
                - unknown_member
                - range_too_large
                - invalid_cursor
            message:
              type: string
            param:
              type: string
              description: Request field or member that caused the error, when applicable.
            request_id:
              type: string
              description: Matches the `x-request-id` response header.
    QueryFilter:
      oneOf:
        - type: object
          required:
            - member
            - op
            - value
          additionalProperties: false
          properties:
            member:
              type: string
              minLength: 1
              maxLength: 64
            op:
              type: string
              enum:
                - eq
            value:
              type: string
              minLength: 1
              maxLength: 200
        - type: object
          required:
            - member
            - op
            - values
          additionalProperties: false
          properties:
            member:
              type: string
              minLength: 1
              maxLength: 64
            op:
              type: string
              enum:
                - in
            values:
              type: array
              minItems: 1
              maxItems: 50
              items:
                type: string
                minLength: 1
                maxLength: 200
    QueryRange:
      type: object
      required:
        - start
        - end
        - timezone
      additionalProperties: false
      properties:
        start:
          type: string
          format: date
          description: >-
            Inclusive, valid calendar date (`YYYY-MM-DD`) in the requested
            timezone. Must be on or before `end`.
        end:
          type: string
          format: date
          description: >-
            Inclusive, valid calendar date (`YYYY-MM-DD`). The range may cover
            at most 366 days.
        timezone:
          type: string
          description: >-
            Canonical IANA timezone identifier, for example `America/Chicago` or
            `UTC`. Numeric offsets and legacy aliases are rejected.
    QueryOrderTerm:
      type: object
      required:
        - member
        - direction
      additionalProperties: false
      properties:
        member:
          type: string
          minLength: 1
          maxLength: 64
          description: A selected metric or dimension name.
        direction:
          type: string
          enum:
            - asc
            - desc
    Column:
      type: object
      additionalProperties: false
      required:
        - name
        - type
        - member
      properties:
        name:
          type: string
          description: Output column name.
        type:
          type: string
          enum:
            - string
            - number
            - date
          description: Value type of the column.
        member:
          type: string
          description: >-
            Catalog member this column belongs to; companion columns share their
            dimension's member name.
    Warning:
      type: object
      additionalProperties: false
      required:
        - code
        - member
        - message
      properties:
        code:
          type: string
          enum:
            - non_additive_metric
        member:
          type: string
        message:
          type: string
    UnauthorizedErrorEnvelope:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              enum:
                - unauthorized
            message:
              type: string
              enum:
                - Invalid API key
            request_id:
              type: string
    InsufficientScopeErrorEnvelope:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              enum:
                - insufficient_scope
            message:
              type: string
              enum:
                - API key does not have the required scope
            request_id:
              type: string
    RateLimitedErrorEnvelope:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              enum:
                - rate_limited
            message:
              type: string
            request_id:
              type: string
    InternalErrorEnvelope:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              enum:
                - internal_error
            message:
              type: string
              enum:
                - An internal error occurred
            request_id:
              type: string
  headers:
    RequestId:
      description: Request identifier. On errors this matches `error.request_id`.
      schema:
        type: string
    RetryAfter:
      description: Seconds to wait before retrying.
      schema:
        type: integer
        minimum: 1
        maximum: 60
  responses:
    Unauthorized:
      description: >-
        A missing or malformed key returns this response without spending an
        admission limit. A well-formed unknown or revoked key normally returns
        the same response, but can return 429 while the global
        credential-verification budget is exhausted.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/UnauthorizedErrorEnvelope'
          examples:
            unauthorized:
              summary: Invalid API key
              value:
                error:
                  code: unauthorized
                  message: Invalid API key
                  request_id: 550e8400-e29b-41d4-a716-446655440000
    InsufficientScope:
      description: The key is valid but does not include `analytics:read`.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/InsufficientScopeErrorEnvelope'
          examples:
            insufficientScope:
              summary: Missing analytics scope
              value:
                error:
                  code: insufficient_scope
                  message: API key does not have the required scope
                  request_id: 550e8400-e29b-41d4-a716-446655440000
    RateLimited:
      description: >-
        A per-key rate limit, the global unknown-credential verification budget,
        or an analytics concurrency limit was exceeded. Read `Retry-After`.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RateLimitedErrorEnvelope'
          examples:
            rateLimited:
              summary: Rate limit exceeded
              value:
                error:
                  code: rate_limited
                  message: Too many requests
                  request_id: 550e8400-e29b-41d4-a716-446655440000
            concurrencyLimited:
              summary: Analytics concurrency limit exceeded
              value:
                error:
                  code: rate_limited
                  message: Too many concurrent requests
                  request_id: 550e8400-e29b-41d4-a716-446655440000
    InternalError:
      description: An unexpected application or infrastructure failure occurred.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/InternalErrorEnvelope'
          examples:
            internalError:
              summary: Unexpected server failure
              value:
                error:
                  code: internal_error
                  message: An internal error occurred
                  request_id: 550e8400-e29b-41d4-a716-446655440000
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Organization API key with the `analytics:read` scope.

````