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

# Save dashboard as template

> Saves a snapshot of a dashboard the caller can see as a template of the caller's organization. Later changes to the dashboard do not change the template.



## OpenAPI

````yaml /openapi/public/openapi-analytics.json post /dynamic-dashboard/{id}/save-as-template
openapi: 3.0.0
info:
  title: MileApp API - Analytics
  version: 3.0.0
  description: MileApp 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.
paths:
  /dynamic-dashboard/{id}/save-as-template:
    post:
      tags:
        - Dashboard
      summary: Save dashboard as template
      description: >-
        Saves a snapshot of a dashboard the caller can see as a template of the
        caller's organization. Later changes to the dashboard do not change the
        template.
      operationId: saveDynamicDashboardAsTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: Source dashboard `_id`
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
                  maxLength: 200
                description:
                  type: string
              example:
                name: Hub morning view
                description: Volume, completion and backlog for one hub.
        description: Template name and description
        required: true
      responses:
        '201':
          description: Created - the new template
          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: >-
                          `system` for built-in templates, otherwise the owning
                          organization
                      schemaVersion:
                        type: integer
                      name:
                        type: string
                        description: >-
                          System rows: machine identifier used as `templateId`
                          (e.g. `dailyOperations`). Organization rows: the name
                          the user typed.
                      title:
                        type: string
                        description: Display title; system rows only
                      description:
                        type: string
                      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
                        description: >-
                          Self-contained cards: `{widget: {full definition},
                          layout}`. No `cardId`, `widgetId` or `widgetName`.
                        items:
                          type: object
                          properties:
                            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
                      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
                      updatedBy:
                        type: string
                      createdTime:
                        type: string
                        format: date-time
                      updatedTime:
                        type: string
                        format: date-time
              examples:
                response:
                  value:
                    status: true
                    code: 201
                    message: Dashboard Template has been added successfully.
                    data:
                      _id: 66f9b0aa1d2e3f4a5b6c7d8e
                      organizationId: 6650c2a1f3b9e4001c7d2a10
                      schemaVersion: 1
                      name: Hub morning view
                      description: Volume, completion and backlog for one hub.
                      grid:
                        columns: 12
                      widgets:
                        - 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
                          layout:
                            w: 3
                            h: null
                        - 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
                          layout:
                            w: 6
                            h: 6
                            x: 3
                            'y': 0
                      origin:
                        kind: dashboard
                        sourceId: 66f9a1c2e4b0a7d3c1f20a11
                        sourceSchemaVersion: 1
                        copiedAt: '2026-09-30T10:02:11+07:00'
                      createdBy: ops.lead@example.com
                      updatedBy: ops.lead@example.com
                      createdTime: '2026-09-30T03:02:11.338000Z'
                      updatedTime: '2026-09-30T03:02:11.338000Z'
        '400':
          description: >-
            Bad Request - `dydsh-001` name missing, `dydsh-002` name already
            used by a template in this organization, `dydsh-009` too long,
            `dydsh-037` a card's widget row cannot be resolved
          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: >-
                      That dashboard template name is already in use. Please use
                      a different name.
                    failedCode: dydsh-002
        '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 - the dashboard does not exist, belongs to another
            organization, or is not visible to the caller. The three cases are
            indistinguishable on purpose.
          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: >-
                      Data not found. Please check the ID or reference number
                      and try again.
                    data: []
                    failedCode: dydsh-033
        '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 MileApp 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.