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

# Run an analytics query

> Execute a measures-and-dimensions query against your event stream. Mirrors
the in-app query builder.

**Required scope:** `analytics:read`.

See [Querying Data](/analytics/query-guide) for a guided walkthrough.




## OpenAPI

````yaml /api-reference/openapi.yaml post /db-mgmt/api/query
openapi: 3.1.0
info:
  title: Upstack Data API
  version: '1.0'
  description: >
    Programmatic access to your Upstack Data pixel — analytics queries, the

    measures/dimensions catalog, and dashboard view management.


    All requests authenticate with two headers:


    - `x-api-key`: your Upstack API key (mint one at **Settings → API Keys** in
    the dashboard).

    - `x-pixel-id`: the pixel id the request targets. One key is scoped to one
    pixel.
servers:
  - url: https://api.upstackdata.com
    description: Production
security:
  - apiKey: []
    pixelId: []
tags:
  - name: Analytics
    description: Query events, attribution, and cohort analyses.
  - name: Catalog
    description: List the measures available to your pixel.
  - name: Dashboards
    description: >-
      Manage dashboard views — create, update, copy, delete, and the high-level
      preset builder.
  - name: Account
    description: >-
      Read and update the account that owns this API key — display name, active
      owners and admins, and subscription summary.
  - name: Costs
    description: >-
      Read and update every cost surface — global product overrides, shipping
      method, per-variant handling fees and COGS history, and per-type cost
      lines (order / gateway / shipping profile / variable / fixed). Mutations
      trigger the same per-order COGS recalculation as web-UI changes.
  - name: Products
    description: Browse products + variants in the configured catalog.
  - name: Events
    description: Send server-side tracking events directly from your backend.
paths:
  /db-mgmt/api/query:
    post:
      tags:
        - Analytics
      summary: Run an analytics query
      description: >
        Execute a measures-and-dimensions query against your event stream.
        Mirrors

        the in-app query builder.


        **Required scope:** `analytics:read`.


        See [Querying Data](/analytics/query-guide) for a guided walkthrough.
      operationId: query
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - pixelId
                - granularity
                - measures
                - dateRange
              properties:
                pixelId:
                  type: string
                  description: Must match the `x-pixel-id` header (403 if it doesn't).
                granularity:
                  $ref: '#/components/schemas/Granularity'
                measures:
                  type: array
                  minItems: 1
                  maxItems: 30
                  items:
                    $ref: '#/components/schemas/MeasureConfig'
                dimensions:
                  type: array
                  maxItems: 5
                  items:
                    type: string
                    description: >-
                      Dimension id (see [Measures &
                      Dimensions](/data-dictionary/measures-and-dimensions)).
                filters:
                  $ref: '#/components/schemas/Filter'
                  description: |
                    Canonical filter applied to the query. Discover valid
                    fields with `GET /api/filters`.
                dateRange:
                  $ref: '#/components/schemas/DateRange'
                compareDateRange:
                  $ref: '#/components/schemas/DateRange'
                  description: >-
                    Optional comparison period. Must not overlap `dateRange`;
                    the server picks the preceding period if omitted (and
                    `granularity` ≠ `none`).
                timezone:
                  type: string
                  description: IANA timezone (e.g. `America/New_York`).
                orderSettings:
                  $ref: '#/components/schemas/OrderSettings'
            examples:
              minimal:
                summary: Gross revenue and purchases by day, last 30 days
                value:
                  pixelId: 5f1e6a4f-...
                  granularity: day
                  measures:
                    - measure: orders.gross_revenue
                    - measure: tracked.purchases
                  dateRange:
                    start: '2026-04-01'
                    end: '2026-04-30'
              withFilter:
                summary: Scope to web/POS orders from new customers
                value:
                  pixelId: 5f1e6a4f-...
                  granularity: day
                  measures:
                    - measure: orders.gross_revenue
                  dateRange:
                    start: '2026-04-01'
                    end: '2026-04-30'
                  filters:
                    and:
                      - field: orders.source_name
                        op: in
                        value:
                          - web
                          - pos
                      - field: orders.customer_type
                        op: equals
                        value: new_customer
      responses:
        '200':
          description: Query results.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
components:
  schemas:
    Granularity:
      type: string
      enum:
        - none
        - second
        - minute
        - hour
        - day
        - week
        - month
        - quarter
        - year
    MeasureConfig:
      type: object
      required:
        - measure
      description: |
        A measure entry in a query request. Pass the canonical measure id and an
        optional `pacing` flag.
      properties:
        measure:
          type: string
          description: >-
            Canonical measure id (e.g. `orders.gross_revenue`). Use the `GET
            /api/measures` endpoint to discover valid ids.
          example: orders.gross_revenue
        pacing:
          type: boolean
          default: false
          description: When `true`, include pacing data for this measure.
    Filter:
      $ref: '#/components/schemas/FilterGroup'
      description: |
        Top-level canonical filter. Alias of `FilterGroup` — every request that
        carries a `filters` field at the body level uses this shape. Example:

        ```json
        {
          "and": [
            { "field": "orders.source_name", "op": "in", "value": ["web", "pos"] },
            { "field": "orders.customer_type", "op": "equals", "value": "new_customer" }
          ]
        }
        ```
    DateRange:
      type: object
      required:
        - start
        - end
      properties:
        start:
          type: string
          format: date
          example: '2026-04-01'
        end:
          type: string
          format: date
          example: '2026-04-30'
    OrderSettings:
      type: object
      description: Order-level query settings — exclusion filters, pending/voided handling.
      properties:
        countPendingOrders:
          type: boolean
        countVoidedOrders:
          type: boolean
        refundDateAttribution:
          type: string
          enum:
            - original_order_date
            - refund_date
        exclusionFilters:
          type: array
          items:
            type: object
            description: |
              Exclusion filter group. Free-form here; see the in-app
              **Order Settings** UI for the live shape.
    QueryResponse:
      type: object
      required:
        - results
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/QueryResult'
    FilterGroup:
      type: object
      description: |
        Group node — exactly one of `and` / `or` / `not` is set. `and` and `or`
        carry an array of child nodes (leaf or nested group); `not` carries a
        single child node. Nesting depth is capped at 3.
      oneOf:
        - type: object
          required:
            - and
          properties:
            and:
              type: array
              minItems: 1
              items:
                $ref: '#/components/schemas/FilterNode'
        - type: object
          required:
            - or
          properties:
            or:
              type: array
              minItems: 1
              items:
                $ref: '#/components/schemas/FilterNode'
        - type: object
          required:
            - not
          properties:
            not:
              $ref: '#/components/schemas/FilterNode'
    QueryResult:
      type: object
      properties:
        granularity:
          $ref: '#/components/schemas/Granularity'
        dimensions:
          type: array
          items:
            type: string
        dateRange:
          $ref: '#/components/schemas/DateRange'
        compareDateRange:
          $ref: '#/components/schemas/DateRange'
        measureDetails:
          type: array
          nullable: true
          items:
            $ref: '#/components/schemas/MeasureDetail'
        data:
          oneOf:
            - $ref: '#/components/schemas/QueryData'
            - type: 'null'
    Error:
      type: object
      required:
        - message
      properties:
        message:
          type: string
          description: Human-readable error message.
        errors:
          type: array
          description: Per-field validation errors (present on 400 responses).
          items:
            type: object
            properties:
              message:
                type: string
              key:
                type: string
              path:
                type: array
                items:
                  type: string
    FilterNode:
      description: Either a `FilterCondition` leaf or a nested `FilterGroup`.
      oneOf:
        - $ref: '#/components/schemas/FilterCondition'
        - $ref: '#/components/schemas/FilterGroup'
    MeasureDetail:
      type: object
      properties:
        measure:
          type: string
        isAverage:
          type: boolean
        isPercentage:
          type: boolean
        calculatedAverage:
          type: boolean
        success:
          type: boolean
        primaryAvg:
          type: number
        compareAvg:
          type: number
        primarySum:
          type: number
        compareSum:
          type: number
        percentDiff:
          type: number
        hasPacing:
          type: boolean
        preferredTrendDirection:
          type: string
          enum:
            - up
            - down
          description: Whether higher (`up`) or lower (`down`) values are favorable.
    QueryData:
      type: object
      properties:
        primary:
          type: array
          items:
            $ref: '#/components/schemas/MeasureDataRow'
        compare:
          type: array
          items:
            $ref: '#/components/schemas/MeasureDataRow'
    FilterCondition:
      type: object
      required:
        - field
        - op
        - value
      description: Leaf node of a canonical filter — a single `field op value` predicate.
      properties:
        field:
          $ref: '#/components/schemas/FilterFieldId'
        op:
          $ref: '#/components/schemas/FilterOperator'
        value:
          $ref: '#/components/schemas/FilterValue'
    MeasureDataRow:
      type: object
      description: |
        One row of query data. Always carries the requested dimension values and
        per-measure numeric values keyed by measure id. May include a `dt` field
        when granularity isn't `none`.
      additionalProperties: true
      properties:
        dt:
          type: string
          description: Bucket date for the row (when `granularity != none`).
        start:
          type: string
        end:
          type: string
    FilterFieldId:
      type: string
      description: |
        Canonical filter field id (`<scope>.<snake_case_id>`). Each id is only
        valid in certain endpoint contexts — discover the full set via
        `GET /api/filters`.
      enum:
        - orders.source_name
        - orders.customer_type
        - orders.order_type
        - orders.value
        - orders.payment_gateway
        - orders.tags
        - channel.resource_name
        - channel.resource_source
        - channel.resource_status
        - channel.resource_configured_status
        - channel.resource_effective_status
        - channel.account_id
        - channel.campaign_id
        - channel.adset_id
        - channel.ad_id
        - attribution.utm_source
        - attribution.utm_medium
        - attribution.utm_campaign
        - attribution.utm_adset
        - attribution.utm_term
        - attribution.utm_ad
        - attribution.utm_content
        - emq.dataset_id
        - emq.event_name
        - emq.diagnostic_name
    FilterOperator:
      type: string
      description: |
        Operator on a filter condition. Which operators are valid for a field
        depends on its `valueType` — discover with `GET /api/filters`.
      enum:
        - equals
        - not_equals
        - greater_than
        - less_than
        - greater_than_or_equals
        - less_than_or_equals
        - contains
        - in
        - not_in
        - array_includes
        - array_includes_all
        - array_includes_any
    FilterValue:
      description: |
        Scalar (`string` / `number` / `boolean`) for equality / comparison /
        `contains` operators. Array of scalars for `in`, `not_in`, and
        `array_includes_*` operators.
      oneOf:
        - type: string
        - type: number
        - type: boolean
        - type: array
          items:
            type: string
        - type: array
          items:
            type: number
        - type: array
          items:
            type: boolean
  responses:
    BadRequest:
      description: Validation error. Includes an `errors` array with per-field detail.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: >-
        Missing or invalid `x-api-key` / `x-pixel-id`, or key is
        revoked/expired.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: >-
        API key does not carry the required scope for this endpoint, or body
        `pixelId` does not match the `x-pixel-id` header.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: Your Upstack API key. Starts with `upstack_`.
    pixelId:
      type: apiKey
      in: header
      name: x-pixel-id
      description: The pixel id the request targets.

````