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

# Create a dashboard view

> Create a dashboard view from a full `DashboardViewConfiguration` body. For
the high-level builder that auto-lays-out widgets from a measure list, see
the `POST /api/dashboard/views/from-preset` endpoint.

**Required scope:** `dashboards:write`.

`createdBy` and `updatedBy` on the resulting record are empty strings —
api-key writes intentionally don't store a fake user id. Audit info
(`apiKeyPk`) is recorded in CloudWatch logs.




## OpenAPI

````yaml /api-reference/openapi.yaml post /accounts/api/dashboard/views
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:
  /accounts/api/dashboard/views:
    post:
      tags:
        - Dashboards
      summary: Create a dashboard view
      description: >
        Create a dashboard view from a full `DashboardViewConfiguration` body.
        For

        the high-level builder that auto-lays-out widgets from a measure list,
        see

        the `POST /api/dashboard/views/from-preset` endpoint.


        **Required scope:** `dashboards:write`.


        `createdBy` and `updatedBy` on the resulting record are empty strings —

        api-key writes intentionally don't store a fake user id. Audit info

        (`apiKeyPk`) is recorded in CloudWatch logs.
      operationId: createDashboardView
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - type
                - name
                - configuration
              properties:
                type:
                  $ref: '#/components/schemas/DashboardViewType'
                name:
                  type: string
                  minLength: 1
                  maxLength: 200
                configuration:
                  $ref: '#/components/schemas/DashboardViewConfiguration'
                order:
                  type: integer
      responses:
        '200':
          description: Created view.
          content:
            application/json:
              schema:
                type: object
                required:
                  - dashboardView
                properties:
                  dashboardView:
                    $ref: '#/components/schemas/DashboardView'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
components:
  schemas:
    DashboardViewType:
      type: string
      enum:
        - view
        - attribution_view
        - pnl_view
      description: |
        Type of dashboard view.
        - `view` — the regular KPI dashboard.
        - `attribution_view` — attribution-specific dashboard.
        - `pnl_view` — P&L dashboard.
    DashboardViewConfiguration:
      type: object
      required:
        - attributionModel
        - attributionWindow
        - granularity
        - dateRange
        - grid
        - widgets
      properties:
        attributionModel:
          $ref: '#/components/schemas/AttributionModel'
        attributionWindow:
          type: integer
          description: Attribution lookback window in days.
        granularity:
          $ref: '#/components/schemas/Granularity'
        dateRange:
          $ref: '#/components/schemas/DateRange'
        filters:
          type: object
          description: >
            Date-picker / compare state (e.g. `{ preset: "last30", isCompare:
            false }`).

            Free-form; the in-app dashboard editor owns the shape.
        grid:
          type: object
          required:
            - maxWidth
          properties:
            maxWidth:
              type: integer
              example: 1200
        widgets:
          type: array
          description: |
            Flat array of all widgets across all sections. Dual-written: when
            `sections` is present, this array is a flattened mirror of the
            widgets inside each section (in section render order). Older
            consumers that read the flat list stay correct; clients writing
            the configuration should set both fields in sync.
          items:
            $ref: '#/components/schemas/DashboardWidget'
        sections:
          type: array
          description: |
            Authoritative grouping of widgets into labelled sections. When
            present, the web app renders sections in ordinal order (Pinned
            first via `ordinal: -1`), and uses each section's `widgets` for
            its content. Optional for backwards compatibility with views
            created before sections existed — call `PATCH` with a `sections`
            array to migrate.
          items:
            $ref: '#/components/schemas/DashboardSection'
        defaultSettings:
          $ref: '#/components/schemas/DashboardSectionSettings'
          description: |
            View-level defaults inherited by sections that don't override a
            given setting.
    DashboardView:
      type: object
      required:
        - id
        - pixelId
        - type
        - name
        - configuration
        - createdAt
        - updatedAt
        - createdBy
        - updatedBy
      properties:
        id:
          type: string
        pixelId:
          type: string
        type:
          $ref: '#/components/schemas/DashboardViewType'
        name:
          type: string
        configuration:
          $ref: '#/components/schemas/DashboardViewConfiguration'
        order:
          type: integer
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        createdBy:
          type: string
          description: >-
            User id of the human creator. Empty string for views created via API
            key.
        updatedBy:
          type: string
    AttributionModel:
      type: string
      enum:
        - first_click
        - last_click
        - any_click
    Granularity:
      type: string
      enum:
        - none
        - second
        - minute
        - hour
        - day
        - week
        - month
        - quarter
        - year
    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'
    DashboardWidget:
      type: object
      required:
        - id
        - title
        - chartType
        - layout
        - dataConfig
      properties:
        id:
          type: string
        title:
          type: string
        chartType:
          $ref: '#/components/schemas/ChartType'
        layout:
          $ref: '#/components/schemas/WidgetLayout'
        dataConfig:
          type: object
          properties:
            measures:
              type: array
              items:
                type: string
              description: Canonical measure ids (e.g. `core.new_customer_roas`).
            dimensions:
              type: array
              items:
                type: string
            filters:
              type: array
              items:
                type: object
        sourceWidgetId:
          type: string
          description: |
            Present on widgets inside the Pinned section. Links the pinned copy
            back to the original widget id in the source section so unpin can
            resolve from either end.
    DashboardSection:
      type: object
      required:
        - id
        - title
        - ordinal
        - collapsed
        - hidden
        - layoutMode
        - widgets
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
          maxLength: 200
        ordinal:
          type: integer
          minimum: -1
          description: |
            Render order. The Pinned section uses `-1` (renders first);
            non-pinned sections use `0, 1, 2, …`. Clients should sort by
            ordinal and may renormalize to keep the sequence contiguous.
        collapsed:
          type: boolean
        hidden:
          type: boolean
        layoutMode:
          $ref: '#/components/schemas/SectionLayoutMode'
        sectionType:
          allOf:
            - $ref: '#/components/schemas/SectionType'
          description: Omit on normal sections; set to `PINNED` for the Pinned section.
        settings:
          $ref: '#/components/schemas/DashboardSectionSettings'
        widgets:
          type: array
          items:
            $ref: '#/components/schemas/DashboardWidget'
    DashboardSectionSettings:
      type: object
      description: |
        Per-section overrides. Any field left undefined falls back to the
        view-level `defaultSettings` (and ultimately to product defaults).
      properties:
        density:
          $ref: '#/components/schemas/DashboardDensity'
        pacing:
          type: boolean
          description: Show pacing indicators on KPI widgets in this section.
        theme:
          type: string
        backgroundColor:
          type: string
          maxLength: 50
        headerStyle:
          $ref: '#/components/schemas/SectionHeaderStyle'
        filters:
          $ref: '#/components/schemas/Filter'
          description: Per-section canonical filter (overlay on the view's `filters`).
    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
    ChartType:
      type: string
      enum:
        - bar
        - line
        - sparkline
        - pie
        - scatter
        - area
        - dimensionTable
        - table
        - attributionTable
        - kpi
        - gauge
        - heatmap
        - histogram
        - boxplot
        - treemap
    WidgetLayout:
      type: object
      required:
        - x
        - 'y'
        - rows
        - columns
        - minColumns
        - maxColumns
        - minRows
        - maxRows
        - static
      properties:
        x:
          type: integer
          minimum: 0
          maximum: 11
        'y':
          type: integer
          minimum: 0
        rows:
          type: integer
          minimum: 1
        columns:
          type: integer
          minimum: 1
          maximum: 12
        minColumns:
          type: integer
          minimum: 1
        maxColumns:
          type: integer
          maximum: 12
        minRows:
          type: integer
          minimum: 1
        maxRows:
          type: integer
        static:
          type: boolean
    SectionLayoutMode:
      type: string
      enum:
        - auto
        - 1_column
        - 2_columns
        - 3_columns
        - 4_columns
      description: |
        How widgets are laid out inside a section. `auto` packs by add order;
        the `N_columns` variants force a fixed-column grid.
    SectionType:
      type: string
      enum:
        - default
        - pinned
      description: |
        Identifies the kind of section. `default` is a normal section (also
        the omitted value); `pinned` marks the special Pinned section, which
        always renders first (it carries `ordinal: -1`).
    DashboardDensity:
      type: string
      enum:
        - compact
        - normal
    SectionHeaderStyle:
      type: string
      enum:
        - default
        - minimal
        - accent
    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" }
          ]
        }
        ```
    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'
    FilterNode:
      description: Either a `FilterCondition` leaf or a nested `FilterGroup`.
      oneOf:
        - $ref: '#/components/schemas/FilterCondition'
        - $ref: '#/components/schemas/FilterGroup'
    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'
    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.

````