---
title: "Add a widget"
method: POST
path: "/v1/dashboard/{dashboardId}/widget"
tags: ["Dashboard"]
---

# Add a widget

`POST /v1/dashboard/{dashboardId}/widget`

## Request

- Base URL: `https://api.roark.ai`
- URL: `https://api.roark.ai/v1/dashboard/{dashboardId}/widget`
- Auth: HTTP bearer

Adds a widget to the top of a dashboard. Its name must be unique on the dashboard.

## Path parameters

- `dashboardId` string, uuid, required

## Request body

- DashboardWidgetInput: One widget: an analytics query plus its name (unique on the dashboard), chart type and size.
  - `measures` object[], required: What to aggregate: 1 to 10 measures.
    - `type` 'METRIC' | 'CONVERSATION' | 'UPTIME': METRIC (default): a metric's values. CONVERSATION: conversation counts. UPTIME: health-check outcomes.
    - `metric` string: The metric's slug (e.g. `task_completion`) or id. Required for METRIC.
    - `aggregation` 'COUNT' | 'AVG' | 'MIN' | 'MAX' | 'SUM' | 'MEDIAN' | 'PERCENTILE' | 'PASS_RATE': Defaults by output type: AVG for numeric metrics, COUNT (split by value) for classification and text, PASS_RATE for thresholds and uptime, COUNT for conversations.
    - `percentile` integer: Required with PERCENTILE, e.g. 95.
    - `distinctBy` 'NONE' | 'CALL': CALL (default for metrics) folds each conversation to one value first, so a long call does not outweigh a short one. NONE aggregates every value.
    - `nestedAggregation` 'COUNT' | 'AVG' | 'MIN' | 'MAX' | 'SUM' | 'MEDIAN' | 'PERCENTILE' | 'PASS_RATE': How each conversation is folded when distinctBy is CALL. Defaults to SUM under SUM, else AVG.
    - `nestedAggregationPercentile` integer
    - `passOperator` 'EQUALS' | 'NOT_EQUALS' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUAL_TO' | 'LESS_THAN' | 'LESS_THAN_OR_EQUAL_TO' | 'CONTAINS' | 'STARTS_WITH' | 'IS_SET' | 'IS_NOT_SET': PASS_RATE condition operator. Omit for a threshold metric: its own condition is used.
    - `passValue` union: PASS_RATE condition value, e.g. 4 or "resolved".
      - string
      - number
      - boolean
    - `breakdown` object: Split the measure into one series per value of this dimension (the largest 50 are returned). Ignored while comparisonGroups are set: each group is then one series.
      - `type` 'METRIC_PROPERTY' | 'CALL_PROPERTY' | 'AGENT_PROPERTY' | 'DATASET', required
      - `property` string: The property to split by. Required for CALL_PROPERTY and METRIC_PROPERTY.
    - `filters` object[]: Filters for this measure only, on top of the query's filters.
      - `type` 'METRIC_PROPERTY' | 'CALL_PROPERTY' | 'AGENT_PROPERTY' | 'CALL_ID' | 'MODALITY' | 'DATASET' | 'METRIC_VALUE', required: What the filter narrows on. GET /v1/analytics/schema lists each type.
      - `property` string: The property to compare. Required for CALL_PROPERTY and METRIC_PROPERTY; may be omitted for AGENT_PROPERTY, DATASET, MODALITY and CALL_ID.
      - `operator` 'EQUALS' | 'NOT_EQUALS' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUAL_TO' | 'LESS_THAN' | 'LESS_THAN_OR_EQUAL_TO' | 'CONTAINS' | 'STARTS_WITH' | 'IS_SET' | 'IS_NOT_SET': Defaults to EQUALS. IS_SET / IS_NOT_SET (CALL_PROPERTY only) keep conversations where the property is set, whatever the value, or missing (never sent, sent as null, or removed); they take no value.
      - `value` union: The value to compare against (an agent id, "call" / "chat", a property value). Required except with IS_SET / IS_NOT_SET.
        - string
        - number
        - boolean
    - `isBaseline` boolean: Mark one measure as the baseline: every series also reports its value as a percentage of it.
    - `color` 'GREEN' | 'RED' | 'ORANGE' | 'PURPLE' | 'GREY' | 'BLUE' | 'PEACH' | 'TEAL' | 'INDIGO' | 'AMBER' | 'ROSE' | 'CYAN': Chart color on a dashboard.
  - `filters` object[]: Applied to every measure, on top of each measure's own filters.
    - `type` 'METRIC_PROPERTY' | 'CALL_PROPERTY' | 'AGENT_PROPERTY' | 'CALL_ID' | 'MODALITY' | 'DATASET' | 'METRIC_VALUE', required: What the filter narrows on. GET /v1/analytics/schema lists each type.
    - `property` string: The property to compare. Required for CALL_PROPERTY and METRIC_PROPERTY; may be omitted for AGENT_PROPERTY, DATASET, MODALITY and CALL_ID.
    - `operator` 'EQUALS' | 'NOT_EQUALS' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUAL_TO' | 'LESS_THAN' | 'LESS_THAN_OR_EQUAL_TO' | 'CONTAINS' | 'STARTS_WITH' | 'IS_SET' | 'IS_NOT_SET': Defaults to EQUALS. IS_SET / IS_NOT_SET (CALL_PROPERTY only) keep conversations where the property is set, whatever the value, or missing (never sent, sent as null, or removed); they take no value.
    - `value` union: The value to compare against (an agent id, "call" / "chat", a property value). Required except with IS_SET / IS_NOT_SET.
      - string
      - number
      - boolean
  - `interval` 'HOUR' | 'DAY' | 'WEEK' | 'MONTH': Bucket size. Defaults from the window's length and steps coarser when the window would exceed 500 buckets.
  - `comparisonMode` 'NONE' | 'PREVIOUS_PERIOD': PREVIOUS_PERIOD adds the preceding window of the same length to every series.
  - `comparisonGroups` object[]: Run every measure once per named filter set, e.g. one group per agent.
    - `name` string, required: The series label; unique within the query.
    - `filters` object[], required
      - `type` 'METRIC_PROPERTY' | 'CALL_PROPERTY' | 'AGENT_PROPERTY' | 'CALL_ID' | 'MODALITY' | 'DATASET' | 'METRIC_VALUE', required: What the filter narrows on. GET /v1/analytics/schema lists each type.
      - `property` string: The property to compare. Required for CALL_PROPERTY and METRIC_PROPERTY; may be omitted for AGENT_PROPERTY, DATASET, MODALITY and CALL_ID.
      - `operator` 'EQUALS' | 'NOT_EQUALS' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUAL_TO' | 'LESS_THAN' | 'LESS_THAN_OR_EQUAL_TO' | 'CONTAINS' | 'STARTS_WITH' | 'IS_SET' | 'IS_NOT_SET': Defaults to EQUALS. IS_SET / IS_NOT_SET (CALL_PROPERTY only) keep conversations where the property is set, whatever the value, or missing (never sent, sent as null, or removed); they take no value.
      - `value` union: The value to compare against (an agent id, "call" / "chat", a property value). Required except with IS_SET / IS_NOT_SET.
        - string
        - number
        - boolean
    - `color` 'GREEN' | 'RED' | 'ORANGE' | 'PURPLE' | 'GREY' | 'BLUE' | 'PEACH' | 'TEAL' | 'INDIGO' | 'AMBER' | 'ROSE' | 'CYAN'
  - `name` string, required: Unique on the dashboard: how the widget is matched on update.
  - `description` string
  - `display` 'LINE' | 'NUMBER' | 'RADAR' | 'STACKED_BAR' | 'TABLE': Chart type. Defaults to LINE.
  - `size` 'SMALL' | 'MEDIUM' | 'LARGE' | 'EXTRA_LARGE': Grid width. Defaults to MEDIUM.

## Response `201`

The created widget

- object
  - `data` DashboardWidget, required
    - `measures` object[], required: What to aggregate: 1 to 10 measures.
      - `type` 'METRIC' | 'CONVERSATION' | 'UPTIME': METRIC (default): a metric's values. CONVERSATION: conversation counts. UPTIME: health-check outcomes.
      - `metric` string: The metric's slug (e.g. `task_completion`) or id. Required for METRIC.
      - `aggregation` 'COUNT' | 'AVG' | 'MIN' | 'MAX' | 'SUM' | 'MEDIAN' | 'PERCENTILE' | 'PASS_RATE': Defaults by output type: AVG for numeric metrics, COUNT (split by value) for classification and text, PASS_RATE for thresholds and uptime, COUNT for conversations.
      - `percentile` integer: Required with PERCENTILE, e.g. 95.
      - `distinctBy` 'NONE' | 'CALL': CALL (default for metrics) folds each conversation to one value first, so a long call does not outweigh a short one. NONE aggregates every value.
      - `nestedAggregation` 'COUNT' | 'AVG' | 'MIN' | 'MAX' | 'SUM' | 'MEDIAN' | 'PERCENTILE' | 'PASS_RATE': How each conversation is folded when distinctBy is CALL. Defaults to SUM under SUM, else AVG.
      - `nestedAggregationPercentile` integer
      - `passOperator` 'EQUALS' | 'NOT_EQUALS' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUAL_TO' | 'LESS_THAN' | 'LESS_THAN_OR_EQUAL_TO' | 'CONTAINS' | 'STARTS_WITH' | 'IS_SET' | 'IS_NOT_SET': PASS_RATE condition operator. Omit for a threshold metric: its own condition is used.
      - `passValue` union: PASS_RATE condition value, e.g. 4 or "resolved".
        - string
        - number
        - boolean
      - `breakdown` object: Split the measure into one series per value of this dimension (the largest 50 are returned). Ignored while comparisonGroups are set: each group is then one series.
        - `type` 'METRIC_PROPERTY' | 'CALL_PROPERTY' | 'AGENT_PROPERTY' | 'DATASET', required
        - `property` string: The property to split by. Required for CALL_PROPERTY and METRIC_PROPERTY.
      - `filters` object[]: Filters for this measure only, on top of the query's filters.
        - `type` 'METRIC_PROPERTY' | 'CALL_PROPERTY' | 'AGENT_PROPERTY' | 'CALL_ID' | 'MODALITY' | 'DATASET' | 'METRIC_VALUE', required: What the filter narrows on. GET /v1/analytics/schema lists each type.
        - `property` string: The property to compare. Required for CALL_PROPERTY and METRIC_PROPERTY; may be omitted for AGENT_PROPERTY, DATASET, MODALITY and CALL_ID.
        - `operator` 'EQUALS' | 'NOT_EQUALS' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUAL_TO' | 'LESS_THAN' | 'LESS_THAN_OR_EQUAL_TO' | 'CONTAINS' | 'STARTS_WITH' | 'IS_SET' | 'IS_NOT_SET': Defaults to EQUALS. IS_SET / IS_NOT_SET (CALL_PROPERTY only) keep conversations where the property is set, whatever the value, or missing (never sent, sent as null, or removed); they take no value.
        - `value` union: The value to compare against (an agent id, "call" / "chat", a property value). Required except with IS_SET / IS_NOT_SET.
          - string
          - number
          - boolean
      - `isBaseline` boolean: Mark one measure as the baseline: every series also reports its value as a percentage of it.
      - `color` 'GREEN' | 'RED' | 'ORANGE' | 'PURPLE' | 'GREY' | 'BLUE' | 'PEACH' | 'TEAL' | 'INDIGO' | 'AMBER' | 'ROSE' | 'CYAN': Chart color on a dashboard.
    - `filters` object[]: Applied to every measure, on top of each measure's own filters.
      - `type` 'METRIC_PROPERTY' | 'CALL_PROPERTY' | 'AGENT_PROPERTY' | 'CALL_ID' | 'MODALITY' | 'DATASET' | 'METRIC_VALUE', required: What the filter narrows on. GET /v1/analytics/schema lists each type.
      - `property` string: The property to compare. Required for CALL_PROPERTY and METRIC_PROPERTY; may be omitted for AGENT_PROPERTY, DATASET, MODALITY and CALL_ID.
      - `operator` 'EQUALS' | 'NOT_EQUALS' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUAL_TO' | 'LESS_THAN' | 'LESS_THAN_OR_EQUAL_TO' | 'CONTAINS' | 'STARTS_WITH' | 'IS_SET' | 'IS_NOT_SET': Defaults to EQUALS. IS_SET / IS_NOT_SET (CALL_PROPERTY only) keep conversations where the property is set, whatever the value, or missing (never sent, sent as null, or removed); they take no value.
      - `value` union: The value to compare against (an agent id, "call" / "chat", a property value). Required except with IS_SET / IS_NOT_SET.
        - string
        - number
        - boolean
    - `interval` 'HOUR' | 'DAY' | 'WEEK' | 'MONTH': Bucket size. Defaults from the window's length and steps coarser when the window would exceed 500 buckets.
    - `comparisonMode` 'NONE' | 'PREVIOUS_PERIOD': PREVIOUS_PERIOD adds the preceding window of the same length to every series.
    - `comparisonGroups` object[]: Run every measure once per named filter set, e.g. one group per agent.
      - `name` string, required: The series label; unique within the query.
      - `filters` object[], required
        - `type` 'METRIC_PROPERTY' | 'CALL_PROPERTY' | 'AGENT_PROPERTY' | 'CALL_ID' | 'MODALITY' | 'DATASET' | 'METRIC_VALUE', required: What the filter narrows on. GET /v1/analytics/schema lists each type.
        - `property` string: The property to compare. Required for CALL_PROPERTY and METRIC_PROPERTY; may be omitted for AGENT_PROPERTY, DATASET, MODALITY and CALL_ID.
        - `operator` 'EQUALS' | 'NOT_EQUALS' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUAL_TO' | 'LESS_THAN' | 'LESS_THAN_OR_EQUAL_TO' | 'CONTAINS' | 'STARTS_WITH' | 'IS_SET' | 'IS_NOT_SET': Defaults to EQUALS. IS_SET / IS_NOT_SET (CALL_PROPERTY only) keep conversations where the property is set, whatever the value, or missing (never sent, sent as null, or removed); they take no value.
        - `value` union: The value to compare against (an agent id, "call" / "chat", a property value). Required except with IS_SET / IS_NOT_SET.
          - string
          - number
          - boolean
      - `color` 'GREEN' | 'RED' | 'ORANGE' | 'PURPLE' | 'GREY' | 'BLUE' | 'PEACH' | 'TEAL' | 'INDIGO' | 'AMBER' | 'ROSE' | 'CYAN'
    - `name` string, required: Unique on the dashboard: how the widget is matched on update.
    - `description` string
    - `display` 'LINE' | 'NUMBER' | 'RADAR' | 'STACKED_BAR' | 'TABLE': Chart type. Defaults to LINE.
    - `size` 'SMALL' | 'MEDIUM' | 'LARGE' | 'EXTRA_LARGE': Grid width. Defaults to MEDIUM.
    - `id` string, uuid, required

## Other responses

- `400`: Invalid dashboard, or a widget the analytics store cannot answer
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Dashboard, widget or a referenced metric not found
- `409`: The dashboard is managed by config as code
- `429`: Too Many Requests
- `500`: Internal Server Error

## Changes

> 188 revisions in range; 1 not diffed.

- **2026-10-21** `8913d3b08c7b`: 3 breaking, 8 warning, 11 info
  - the response property `data/comparisonGroups/items/filters/items/value` became optional for the status `201`
  - the response property `data/filters/items/value` became optional for the status `201`
  - the response property `data/measures/items/filters/items/value` became optional for the status `201`
  - added the new `IS_NOT_SET` enum value to the `data/comparisonGroups/items/filters/items/operator` response property for the response status `201`
  - …18 more
- **2026-10-21** `2e403107d6ec`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/roarkhq/apis/roark-analytics-api/changes/v1/dashboard/:dashboardId/widget/post.md)

---

[API](https://skmtc.dev/roarkhq/apis/roark-analytics-api.md) - [All operations](https://skmtc.dev/roarkhq/apis/roark-analytics-api/llms.txt) - [OpenAPI document](https://skmtc.dev/roarkhq/apis/roark-analytics-api/revisions/efc3377249d1?raw)
