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

# Create dashboard

> Creates a dashboard, either from the cards in the request body or as a copy of a template (`templateId`). Every card gets its own widget row, so editing a card never changes the widget catalogue or another dashboard. See the [Dashboard overview](/api-reference/analytics/dashboard-overview) for the card and layout rules.



## OpenAPI

````yaml /openapi/public/openapi-analytics.json post /dynamic-dashboard
openapi: 3.0.0
info:
  title: API - Analytics
  version: 3.0.0
  description: API Documentation - RESTful API for field operations management.
servers:
  - url: https://apiweb.mile.app/api/v3
security:
  - bearerAuth: []
tags:
  - name: Dashboard
    description: >-
      Dashboard lets a user compose their own dashboard from any number of
      cards, start from a template, duplicate a dashboard, share it with roles,
      and save it back as an organization template. Each card owns its own
      widget row (a chart type plus a query spec), cloned from the widget
      catalogue (built-in widgets plus the organization's custom widgets), so
      renaming or editing a card never touches the catalogue or another
      dashboard. Dashboards are owned by their creator: roles they are shared
      with can view, duplicate and save as template, but only the owner can edit
      or delete. Every write reuses the dashboard permission family (view, add,
      edit and delete dashboard).


      The numbers behind each card come from one generic aggregation endpoint
      instead of one endpoint per chart: the client sends a batch of up to 12
      declarative query specs, the server injects the caller's organization, hub
      and soft-delete scope from the session, runs each spec read-only, and
      returns a flat columns and rows table per item. The catalog endpoints
      describe the data sources, fields and limits a client may use.
  - name: Report
    description: >-
      A report is a saved table definition over tasks of one flow or records of
      one data type: which fields to show, which hubs to include, and the
      default filters.
  - name: Insight Report
    description: >-
      Insight reports are written summaries of your operations, generated from
      your task and data records: findings, a summary and suggested actions. You
      set the context once per flow, then generate reports on demand or on a
      schedule.
paths:
  /dynamic-dashboard:
    post:
      tags:
        - Dashboard
      summary: Create dashboard
      description: >-
        Creates a dashboard, either from the cards in the request body or as a
        copy of a template (`templateId`). Every card gets its own widget row,
        so editing a card never changes the widget catalogue or another
        dashboard. See the [Dashboard
        overview](/api-reference/analytics/dashboard-overview) for the card and
        layout rules.
      operationId: createDynamicDashboard
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
                  maxLength: 200
                description:
                  type: string
                templateId:
                  type: string
                  maxLength: 200
                  description: >-
                    Template name (for example `dailyOperations`), not its
                    `_id`. Names are stable across environments; ObjectIds are
                    not.
                sharedRoleIds:
                  type: array
                  maxItems: 50
                  items:
                    type: string
                  description: >-
                    Role ids of the caller's organization, each distinct, at
                    least one. Absent = shared with the creator's own role. An
                    empty array is `400 dydsh-009`, a repeated id is `400
                    dydsh-002`, and a role of another organization or an unknown
                    id is `400 dydsh-011` ("Share the dashboard with at least
                    one role of your organization.").
                hubScope:
                  type: object
                  properties:
                    mode:
                      type: string
                      enum:
                        - all
                        - selected
                      description: Required whenever `hubScope` is sent
                    hubIds:
                      type: array
                      maxItems: 200
                      items:
                        type: string
                timeRange:
                  type: object
                  description: >-
                    Default time window for the dashboard, or `null`. Not
                    interpreted by the CRUD layer; the analytics endpoint
                    accepts `today`, `yesterday`, `last_7d`, `last_30d`.
                  properties:
                    preset:
                      type: string
                      maxLength: 50
                grid:
                  type: object
                  properties:
                    columns:
                      type: integer
                      minimum: 1
                      maximum: 48
                      description: Column count, default 12. Stored per document.
                    engine:
                      type: string
                      enum:
                        - flow
                        - absolute
                      description: Optional layout engine hint
                widgets:
                  type: array
                  items:
                    type: object
                    properties:
                      widgetId:
                        type: string
                        pattern: ^[0-9a-fA-F]{24}$
                      widgetName:
                        type: string
                        maxLength: 200
                      widget:
                        type: object
                        description: >-
                          A widget definition (a `dynamicWidgets` row without
                          identity and audit fields)
                        properties:
                          schemaVersion:
                            type: integer
                            example: 1
                          name:
                            type: string
                            maxLength: 200
                            description: Literal display name, never translated
                          description:
                            type: string
                          category:
                            type: string
                            enum:
                              - overview
                              - taskStatus
                              - productivity
                              - timeDuration
                              - team
                              - hub
                              - trend
                              - utility
                          viz:
                            type: string
                            description: >-
                              Visualization: kpi, bar, line, donut, table,
                              heatmap, text, banner
                          spec:
                            type: object
                            description: >-
                              Neutral analytics query spec executed by POST
                              /analytics/query. See Run analytics query for the
                              full grammar.
                            properties:
                              specVersion:
                                type: integer
                              dataSourceId:
                                type: string
                              timeField:
                                type: string
                              measures:
                                type: array
                                items:
                                  type: object
                                  additionalProperties: true
                              dimensions:
                                type: array
                                items:
                                  type: object
                                  additionalProperties: true
                              filters:
                                type: array
                                items:
                                  type: object
                                  additionalProperties: true
                          composite:
                            type: object
                            description: >-
                              Multi-query widget `{kind, queries: {key: spec}}`;
                              `null` for ordinary widgets
                            additionalProperties: true
                          content:
                            type: object
                            description: >-
                              `{body}` for text and banner widgets; `null`
                              otherwise
                            properties:
                              body:
                                type: string
                                maxLength: 2000
                          defaultLayout:
                            type: object
                            description: Card placement on the grid
                            properties:
                              w:
                                type: integer
                                minimum: 2
                                description: Width in grid columns, 2 to `grid.columns`
                              h:
                                type: integer
                                minimum: 3
                                maximum: 18
                                description: >-
                                  Height in rows, 3-18; `null` = as tall as its
                                  content
                              x:
                                type: integer
                                minimum: 0
                                maximum: 48
                                description: >-
                                  Optional column offset (free placement
                                  accepted, not required)
                              'y':
                                type: integer
                                minimum: 0
                                description: Optional row offset
                      layout:
                        type: object
                        description: Card placement on the grid
                        properties:
                          w:
                            type: integer
                            minimum: 2
                            description: Width in grid columns, 2 to `grid.columns`
                          h:
                            type: integer
                            minimum: 3
                            maximum: 18
                            description: >-
                              Height in rows, 3-18; `null` = as tall as its
                              content
                          x:
                            type: integer
                            minimum: 0
                            maximum: 48
                            description: >-
                              Optional column offset (free placement accepted,
                              not required)
                          'y':
                            type: integer
                            minimum: 0
                            description: Optional row offset
                      cardId:
                        type: string
                        maxLength: 64
                        description: Ignored on create; the server assigns fresh ids
              example:
                name: Jakarta Hub - Daily
                description: Morning stand-up view
                sharedRoleIds:
                  - 6650c2a1f3b9e4001c7d2b20
                hubScope:
                  mode: selected
                  hubIds:
                    - 6650c2a1f3b9e4001c7d2c30
                timeRange:
                  preset: last_7d
                grid:
                  columns: 12
                widgets:
                  - widgetName: Total Tasks
                    layout:
                      w: 3
                      h: null
                  - widgetId: 66e0b3f1c9a8d7e6f5a4b202
                    layout:
                      w: 6
                      h: 6
                      x: 3
                      'y': 0
                  - widget:
                      name: Shift notes
                      viz: text
                      category: utility
                      spec: null
                      content:
                        body: Check the Bekasi backlog first.
                      defaultLayout:
                        w: 3
                        h: null
                    layout:
                      w: 3
                      h: 3
        description: Dashboard to create
        required: true
      responses:
        '201':
          description: Created - the new dashboard, with widget definitions attached
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                    example: true
                  code:
                    type: integer
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      _id:
                        type: string
                      organizationId:
                        type: string
                        description: Stamped from the caller's session; immutable
                      schemaVersion:
                        type: integer
                        example: 1
                      name:
                        type: string
                      description:
                        type: string
                      sharedRoleIds:
                        type: array
                        items:
                          type: string
                        description: >-
                          The roles that can see the dashboard. Never empty:
                          there is no private dashboard. Rights to change it
                          follow each role's permission.
                      hubScope:
                        type: object
                        properties:
                          mode:
                            type: string
                            enum:
                              - all
                              - selected
                            description: Required whenever `hubScope` is sent
                          hubIds:
                            type: array
                            maxItems: 200
                            items:
                              type: string
                      timeRange:
                        type: object
                        description: >-
                          Default time window for the dashboard, or `null`. Not
                          interpreted by the CRUD layer; the analytics endpoint
                          accepts `today`, `yesterday`, `last_7d`, `last_30d`.
                        properties:
                          preset:
                            type: string
                            maxLength: 50
                      grid:
                        type: object
                        properties:
                          columns:
                            type: integer
                            minimum: 1
                            maximum: 48
                            description: Column count, default 12. Stored per document.
                          engine:
                            type: string
                            enum:
                              - flow
                              - absolute
                            description: Optional layout engine hint
                      widgets:
                        type: array
                        items:
                          type: object
                          description: >-
                            A card on a dashboard. Stored cards carry only the
                            reference; `widget` is attached on read.
                          properties:
                            cardId:
                              type: string
                              description: >-
                                Stable card id `crd_` followed by a ULID,
                                assigned by the server. Also the batch key of
                                the analytics request.
                            widgetId:
                              type: string
                              description: The `dynamicWidgets` row this card owns
                            widgetName:
                              type: string
                              description: Label that follows the row's name
                            layout:
                              type: object
                              description: Card placement on the grid
                              properties:
                                w:
                                  type: integer
                                  minimum: 2
                                  description: Width in grid columns, 2 to `grid.columns`
                                h:
                                  type: integer
                                  minimum: 3
                                  maximum: 18
                                  description: >-
                                    Height in rows, 3-18; `null` = as tall as
                                    its content
                                x:
                                  type: integer
                                  minimum: 0
                                  maximum: 48
                                  description: >-
                                    Optional column offset (free placement
                                    accepted, not required)
                                'y':
                                  type: integer
                                  minimum: 0
                                  description: Optional row offset
                            widget:
                              type: object
                              description: >-
                                A widget definition (a `dynamicWidgets` row
                                without identity and audit fields)
                              properties:
                                schemaVersion:
                                  type: integer
                                  example: 1
                                name:
                                  type: string
                                  maxLength: 200
                                  description: Literal display name, never translated
                                description:
                                  type: string
                                category:
                                  type: string
                                  enum:
                                    - overview
                                    - taskStatus
                                    - productivity
                                    - timeDuration
                                    - team
                                    - hub
                                    - trend
                                    - utility
                                viz:
                                  type: string
                                  description: >-
                                    Visualization: kpi, bar, line, donut, table,
                                    heatmap, text, banner
                                spec:
                                  type: object
                                  description: >-
                                    Neutral analytics query spec executed by
                                    POST /analytics/query. See Run analytics
                                    query for the full grammar.
                                  properties:
                                    specVersion:
                                      type: integer
                                    dataSourceId:
                                      type: string
                                    timeField:
                                      type: string
                                    measures:
                                      type: array
                                      items:
                                        type: object
                                        additionalProperties: true
                                    dimensions:
                                      type: array
                                      items:
                                        type: object
                                        additionalProperties: true
                                    filters:
                                      type: array
                                      items:
                                        type: object
                                        additionalProperties: true
                                composite:
                                  type: object
                                  description: >-
                                    Multi-query widget `{kind, queries: {key:
                                    spec}}`; `null` for ordinary widgets
                                  additionalProperties: true
                                content:
                                  type: object
                                  description: >-
                                    `{body}` for text and banner widgets; `null`
                                    otherwise
                                  properties:
                                    body:
                                      type: string
                                      maxLength: 2000
                                defaultLayout:
                                  type: object
                                  description: Card placement on the grid
                                  properties:
                                    w:
                                      type: integer
                                      minimum: 2
                                      description: >-
                                        Width in grid columns, 2 to
                                        `grid.columns`
                                    h:
                                      type: integer
                                      minimum: 3
                                      maximum: 18
                                      description: >-
                                        Height in rows, 3-18; `null` = as tall
                                        as its content
                                    x:
                                      type: integer
                                      minimum: 0
                                      maximum: 48
                                      description: >-
                                        Optional column offset (free placement
                                        accepted, not required)
                                    'y':
                                      type: integer
                                      minimum: 0
                                      description: Optional row offset
                      origin:
                        type: object
                        description: Provenance only; nothing dereferences `sourceId`
                        properties:
                          kind:
                            type: string
                            enum:
                              - blank
                              - template
                              - duplicate
                              - dashboard
                          sourceId:
                            type: string
                          sourceSchemaVersion:
                            type: integer
                          copiedAt:
                            type: string
                            format: date-time
                      createdBy:
                        type: string
                        description: >-
                          Creator's email. Audit trail only: it grants no
                          rights.
                      updatedBy:
                        type: string
                      createdTime:
                        type: string
                        format: date-time
                      updatedTime:
                        type: string
                        format: date-time
                        description: >-
                          Echo this back on PATCH as the lost-update
                          precondition
              examples:
                response:
                  value:
                    status: true
                    code: 201
                    message: Dashboard has been added successfully.
                    data:
                      _id: 66f9a1c2e4b0a7d3c1f20a11
                      organizationId: 6650c2a1f3b9e4001c7d2a10
                      schemaVersion: 1
                      name: Jakarta Hub - Daily
                      description: Morning stand-up view
                      sharedRoleIds:
                        - 6650c2a1f3b9e4001c7d2b20
                      hubScope:
                        mode: selected
                        hubIds:
                          - 6650c2a1f3b9e4001c7d2c30
                      timeRange:
                        preset: last_7d
                      grid:
                        columns: 12
                      widgets:
                        - cardId: crd_01J8ZQ4R5W6X7Y8Z9A0B1C2D3E
                          widgetId: 66f9a1c2e4b0a7d3c1f20b01
                          widgetName: Total Tasks
                          layout:
                            w: 3
                            h: null
                          widget:
                            schemaVersion: 1
                            name: Total Tasks
                            description: >-
                              Tasks whose start time falls in the selected
                              range, across every status.
                            category: overview
                            viz: kpi
                            spec:
                              specVersion: 1
                              dataSourceId: task
                              timeField: startTime
                              measures:
                                - id: m1
                                  fn: count
                              dimensions: []
                              filters: []
                            composite: null
                            content: null
                            defaultLayout:
                              w: 3
                              h: null
                        - cardId: crd_01J8ZQ4R5W6X7Y8Z9A0B1C2D3F
                          widgetId: 66f9a1c2e4b0a7d3c1f20b02
                          widgetName: Tasks by Status
                          layout:
                            w: 6
                            h: 6
                            x: 3
                            'y': 0
                          widget:
                            schemaVersion: 1
                            name: Tasks by Status
                            description: Task count per status in the selected range.
                            category: taskStatus
                            viz: donut
                            spec:
                              specVersion: 1
                              dataSourceId: task
                              timeField: startTime
                              measures:
                                - id: m1
                                  fn: count
                              dimensions:
                                - id: d1
                                  kind: terms
                                  field: status
                                  limit: 3
                              filters: []
                            composite: null
                            content: null
                            defaultLayout:
                              w: 6
                              h: 6
                        - cardId: crd_01J8ZQ4R5W6X7Y8Z9A0B1C2D3G
                          widgetId: 66f9a1c2e4b0a7d3c1f20b03
                          widgetName: Shift notes
                          layout:
                            w: 3
                            h: 3
                          widget:
                            schemaVersion: 1
                            name: Shift notes
                            description: null
                            category: utility
                            viz: text
                            spec: null
                            composite: null
                            content:
                              body: Check the Bekasi backlog first.
                            defaultLayout:
                              w: 3
                              h: null
                      origin:
                        kind: blank
                        sourceId: null
                        sourceSchemaVersion: null
                        copiedAt: '2026-09-30T08:10:44+07:00'
                      createdBy: ops.lead@example.com
                      updatedBy: ops.lead@example.com
                      createdTime: '2026-09-30T01:10:44.512000Z'
                      updatedTime: '2026-09-30T01:10:44.512000Z'
        '400':
          description: >-
            Bad Request - validation failed. `dydsh-001` missing/blank required
            field, `dydsh-002` repeated role id, `dydsh-003` bad `widgetId`
            format or `overrides` present, `dydsh-009` length/range or an empty
            `sharedRoleIds`, `dydsh-011` not an array, or `sharedRoleIds`
            holding a role of another organization or an unknown id, `dydsh-013`
            card with no reference or an ambiguous `widgetName`, `dydsh-014` an
            inline widget `viz` or `spec` is not valid, a custom card's `spec`
            has a new Flow (`flowId` filter, `eq` or `in`) outside the
            organization, `dydsh-037` unknown widget id or name. Time measures
            and dimensions follow the same rules as Run analytics query: an
            unknown duration pair, age field, bucket preset or dimension kind,
            `missing: "zero"` on `avgDuration`/`avgAge`/`doneShare`, a field on
            `doneShare`, a `granularity` on `ageBucket`/`hourOfDay`/`dayOfWeek`,
            two date groupings, or `cardinality`/`avg` under
            `hourOfDay`/`dayOfWeek` is `400 dydsh-014` with the message "The
            widget query is not valid: "; `<reason>` is English technical text
            and `error.code` names the rule (for example
            `duration_pair_unknown`, `bucket_preset_unknown`,
            `fold_measure_unsupported`). Data sources: a `spec.dataSourceId`
            that does not resolve for the organization (a `task:<flowId>` of
            another organization, a deleted or system flow, a
            `data:<dataTypeId>` that is unknown, of another organization,
            deleted or external) is `400 dydsh-014`; so is a spec on a Data
            source naming a field the data type does not offer (absent, not
            stored as keyword/number/date, or no record has a value yet), and an
            hourly grouping (`minute`/`hour` `dateHistogram` or `hourOfDay`) on
            a Data `dateTime` field without a `range` filter on it of at most 31
            days (`error.code` `time_grouping_needs_range`) or on a `date` field
            of any source (`error.code` `time_grouping_date_only`); a bare
            24-hex id is `400 dydsh-014` with `error.code`
            `data_source_id_invalid`. From / To follows Run analytics query
            (`duration_fields_same`, `duration_field_not_date`,
            `duration_pair_conflict`). A `spec` that names a retired Task field
            (`docId`, `organizationName`, `organizationEmail`, `hubCountry`,
            `hubLat`, `hubLng`, `year`) is `dydsh-014`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                    example: false
                  message:
                    type: string
                    description: Human-readable reason
                  failedCode:
                    type: string
                    description: Structured error code, see Status Codes
              examples:
                response:
                  value:
                    status: false
                    message: No widget definition is named Daily Volume.
                    failedCode: dydsh-037
        '401':
          description: Unauthorized - missing, invalid or expired access token
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                    example: false
                  message:
                    type: string
                    description: Human-readable reason
                  failedCode:
                    type: string
                    description: Structured error code, see Status Codes
              examples:
                response:
                  value:
                    status: false
                    message: Unauthenticated.
                    failedCode: auth-034
        '403':
          description: Forbidden - the caller's role lacks `add/dashboard`
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                    example: false
                  message:
                    type: string
                    description: Human-readable reason
                  failedCode:
                    type: string
                    description: Structured error code, see Status Codes
              examples:
                response:
                  value:
                    status: false
                    message: >-
                      Access denied. You do not have permission for add
                      dashboard. Please contact your admin to request access.
                    failedCode: sys-035
        '404':
          description: >-
            Not Found - no template with that `templateId` name is visible to
            the caller
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                    example: false
                  message:
                    type: string
                    description: Human-readable reason
                  failedCode:
                    type: string
                    description: Structured error code, see Status Codes
                  code:
                    type: integer
                    description: >-
                      HTTP status repeated in the body (repository failures
                      only)
                  data:
                    type: array
                    items:
                      type: object
                      additionalProperties: true
                    description: Empty on most failures
              examples:
                response:
                  value:
                    status: false
                    code: 404
                    message: Dashboard template not found.
                    failedCode: dydsh-038
        '422':
          description: >-
            Unprocessable - the document was written by a newer schema version
            than this API node understands (transient during a rolling deploy).
            Nothing was written.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                    example: false
                  message:
                    type: string
                    description: Human-readable reason
                  failedCode:
                    type: string
                    description: Structured error code, see Status Codes
                  code:
                    type: integer
                    description: >-
                      HTTP status repeated in the body (repository failures
                      only)
                  data:
                    type: array
                    items:
                      type: object
                      additionalProperties: true
                    description: Empty on most failures
              examples:
                response:
                  value:
                    status: false
                    code: 422
                    message: >-
                      This dashboard was saved by a newer version of the
                      platform and cannot be opened here. Please refresh the
                      page and try again.
                    data: []
                    failedCode: dydsh-040
        '500':
          description: Server Error - unexpected exception, logged server-side
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                    example: false
                  message:
                    type: string
                    description: Human-readable reason
                  failedCode:
                    type: string
                    description: Structured error code, see Status Codes
                  code:
                    type: integer
                    description: >-
                      HTTP status repeated in the body (repository failures
                      only)
                  data:
                    type: array
                    items:
                      type: object
                      additionalProperties: true
                    description: Empty on most failures
              examples:
                response:
                  value:
                    status: false
                    code: 500
                    message: something_wrong
                    failedCode: dydsh-045
      security:
        - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Use a valid Bearer token to authenticate.

````

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