> ## 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 attribution query

> Attribute conversions across marketing touchpoints. Supports first-click,
last-click, and any-click models with a fixed-set lookback window.

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




## OpenAPI

````yaml /api-reference/openapi.yaml post /db-mgmt/api/query-attribution
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-attribution:
    post:
      tags:
        - Analytics
      summary: Run an attribution query
      description: >
        Attribute conversions across marketing touchpoints. Supports
        first-click,

        last-click, and any-click models with a fixed-set lookback window.


        **Required scope:** `analytics:read`.
      operationId: queryAttribution
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - pixelId
                - dimension
                - dateRange
                - attributionModel
                - attributionWindow
              properties:
                pixelId:
                  type: string
                  description: Must match the `x-pixel-id` header.
                dimension:
                  type: string
                  description: Dimension to attribute by (e.g. `utm_source`).
                filters:
                  $ref: '#/components/schemas/Filter'
                  description: |
                    Canonical filter applied to the attribution result set.
                    `attribution.utm_*` fields and `orders.*` fields are valid
                    in this context — discover the full set via
                    `GET /api/filters`.
                dateRange:
                  $ref: '#/components/schemas/DateRange'
                attributionModel:
                  $ref: '#/components/schemas/AttributionModel'
                attributionWindow:
                  type: integer
                  enum:
                    - 1
                    - 7
                    - 14
                    - 30
                    - 60
                    - 90
                    - -1
                  description: Attribution window in days. `-1` means unlimited.
                timezone:
                  type: string
                valueSource:
                  type: string
                  enum:
                    - orders
                    - events
                  default: orders
                  description: Source of truth for conversion data.
                conversionEvent:
                  type: string
                  default: purchase
                  description: >
                    Required when `valueSource` = `events`. Defaults to
                    `purchase`

                    when `valueSource` = `orders`.
                orderSettings:
                  $ref: '#/components/schemas/OrderSettings'
            examples:
              firstClickByUtmSource:
                summary: First-click attribution by UTM source
                value:
                  pixelId: 5f1e6a4f-...
                  dimension: utm_source
                  dateRange:
                    start: '2026-04-01'
                    end: '2026-04-30'
                  attributionModel: first_click
                  attributionWindow: 30
              scopedToGoogle:
                summary: Attribution scoped to one UTM source via canonical filter
                value:
                  pixelId: 5f1e6a4f-...
                  dimension: utm_campaign
                  dateRange:
                    start: '2026-04-01'
                    end: '2026-04-30'
                  attributionModel: last_click
                  attributionWindow: 30
                  filters:
                    and:
                      - field: attribution.utm_source
                        op: equals
                        value: google
      responses:
        '200':
          description: Attribution results.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AttributionQueryResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
components:
  schemas:
    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'
    AttributionModel:
      type: string
      enum:
        - first_click
        - last_click
        - any_click
    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.
    AttributionQueryResponse:
      type: object
      required:
        - results
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/AttributionQueryResult'
    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'
    AttributionQueryResult:
      type: object
      properties:
        dateRange:
          $ref: '#/components/schemas/DateRange'
        dimension:
          type: string
        data:
          $ref: '#/components/schemas/QueryData'
        measureDetails:
          type: array
          items:
            $ref: '#/components/schemas/MeasureDetail'
    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'
    QueryData:
      type: object
      properties:
        primary:
          type: array
          items:
            $ref: '#/components/schemas/MeasureDataRow'
        compare:
          type: array
          items:
            $ref: '#/components/schemas/MeasureDataRow'
    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.
    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.

````