# Widgets

## Add Widget to Dashboard

**post** `/v5/evaluation-dashboards/{dashboard_id}/widgets`

Create a new widget, append it to the dashboard, and compute its result in one call.

The widget is persisted as its own entity, its ID is appended to the dashboard's
`widget_order`, and — unless it is a `markdown` or `heading` widget — its result is
computed synchronously against the dashboard's evaluation (or evaluation-group) data
before the response returns. Validation is type-specific: `markdown` requires
`config.content`, `bar`/`histogram`/`donut`/`scatter` require exactly one of
`config.x_column` or `config.x_column_group`, `table` configs with conditional
formatting are schema-validated, and all other chart types require a `query`. The
dashboard must exist and not be archived. A computation failure does not fail the
request: the widget is still created and returned with a result whose
`computation_status` is `failed` and an `error_message` set, while `markdown` and
`heading` widgets return a null result.

### Path Parameters

- `dashboard_id: string`

### Body Parameters

- `title: string`

  Widget title

- `type: EvaluationWidgetTypeEnum`

  Widget type

  - `"bar"`

  - `"histogram"`

  - `"donut"`

  - `"scatter"`

  - `"metric"`

  - `"table"`

  - `"markdown"`

  - `"heading"`

  - `"timeseries"`

- `config: optional map[unknown]`

  Chart-specific display configuration

- `query: optional SeriesQuery or MetricQuery`

  Structured query AST for metric computation (SeriesQuery or MetricQuery)

  - `SeriesQuery object { select, evaluation_ids, filter, 4 more }`

    Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

    Used for widget types: table, bar, histogram, donut, scatter.
    Returns: {"type": "series", "data": [...]}

    Example SQL equivalent:
    SELECT category, AVG(score) as avg_score, COUNT(*) as count
    FROM evaluation_items
    WHERE score > 0.5 AND category = 'test'
    GROUP BY category
    ORDER BY avg_score DESC
    LIMIT 100

    - `select: array of SelectItem`

      - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

        - `Column object { column, source, type }`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `column: string`

            Column name from evaluation_items.data

          - `source: optional string`

            Column source: 'data' or 'task_result_cache'

          - `type: optional "COLUMN"`

            - `"COLUMN"`

        - `Aggregation object { column, function, evaluation_ids, 3 more }`

          Aggregation function to apply

          Examples:
          {"type": "AGGREGATION", "function": "AVG", "column": "score"}
          {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
          {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

          - `column: string`

            Column to aggregate, or '*' for COUNT(*)

          - `function: "COUNT" or "SUM" or "AVG" or 7 more`

            Supported aggregation functions

            - `"COUNT"`

            - `"SUM"`

            - `"AVG"`

            - `"MIN"`

            - `"MAX"`

            - `"STDDEV"`

            - `"VARIANCE"`

            - `"PERCENTILE"`

            - `"COUNT_DISTINCT"`

            - `"PERCENTAGE"`

          - `evaluation_ids: optional array of string`

            Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

          - `params: optional map[unknown]`

            Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

          - `source: optional string`

            Column source: 'data' or 'task_result_cache'

          - `type: optional "AGGREGATION"`

            - `"AGGREGATION"`

      - `alias: optional string`

        Optional alias for the selected item

    - `evaluation_ids: optional array of string`

      Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

    - `filter: optional Filter`

      Filter conditions (WHERE clause)

      - `conditions: array of object { column, operator, source, value }`

        - `column: string`

          Column name to filter on

        - `operator: "=" or "!=" or ">" or 9 more`

          Comparison operator

          - `"="`

          - `"!="`

          - `">"`

          - `"<"`

          - `">="`

          - `"<="`

          - `"IN"`

          - `"NOT IN"`

          - `"LIKE"`

          - `"NOT LIKE"`

          - `"IS NULL"`

          - `"IS NOT NULL"`

        - `source: optional string`

          Column source: 'data' or 'task_result_cache'

        - `value: optional string or number or boolean or array of unknown`

          Value to compare against. Not required for IS NULL / IS NOT NULL operators.

          - `string`

          - `number`

          - `boolean`

          - `array of unknown`

      - `logicalOperators: optional array of "AND" or "OR"`

        Logical operators connecting conditions. Length must be len(conditions) - 1

        - `"AND"`

        - `"OR"`

    - `groupBy: optional array of string`

      Columns to group by

    - `latest_only: optional boolean`

      When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

    - `limit: optional number`

      Max rows to return

    - `orderBy: optional array of object { column, direction, source }`

      Sort order

      - `column: string`

        Column name to sort by

      - `direction: optional "ASC" or "DESC"`

        Sort direction

        - `"ASC"`

        - `"DESC"`

      - `source: optional string`

        Column source: 'data' or 'task_result_cache'

  - `MetricQuery object { select, evaluation_ids, filter, latest_only }`

    Query that returns a single metric value (used for metric widgets).

    Used for widget type: metric.
    Enforces exactly 1 aggregation in select.
    Returns: {"type": "metric", "data": ...}

    Example SQL equivalent:
    SELECT AVG(score) as average_score
    FROM evaluation_items

    - `select: array of SelectItem`

      - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

      - `alias: optional string`

        Optional alias for the selected item

    - `evaluation_ids: optional array of string`

      Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

    - `filter: optional Filter`

      Filter conditions (WHERE clause)

    - `latest_only: optional boolean`

      When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

### Returns

- `EvaluationDashboardWidgetWithResult object { id, account_id, created_at, 6 more }`

  Response model for widget creation - includes widget and computed result

  - `id: string`

    Unique identifier of the widget

  - `account_id: string`

    Account that owns this widget

  - `created_at: string`

    When the widget was created

  - `title: string`

    Widget title

  - `type: EvaluationWidgetTypeEnum`

    Widget type

    - `"bar"`

    - `"histogram"`

    - `"donut"`

    - `"scatter"`

    - `"metric"`

    - `"table"`

    - `"markdown"`

    - `"heading"`

    - `"timeseries"`

  - `config: optional map[unknown]`

    Display configuration

  - `object: optional "evaluation_widget"`

    - `"evaluation_widget"`

  - `query: optional SeriesQuery or MetricQuery`

    Structured query AST for computation (SeriesQuery or MetricQuery)

    - `SeriesQuery object { select, evaluation_ids, filter, 4 more }`

      Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

      Used for widget types: table, bar, histogram, donut, scatter.
      Returns: {"type": "series", "data": [...]}

      Example SQL equivalent:
      SELECT category, AVG(score) as avg_score, COUNT(*) as count
      FROM evaluation_items
      WHERE score > 0.5 AND category = 'test'
      GROUP BY category
      ORDER BY avg_score DESC
      LIMIT 100

      - `select: array of SelectItem`

        - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `Column object { column, source, type }`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

            - `column: string`

              Column name from evaluation_items.data

            - `source: optional string`

              Column source: 'data' or 'task_result_cache'

            - `type: optional "COLUMN"`

              - `"COLUMN"`

          - `Aggregation object { column, function, evaluation_ids, 3 more }`

            Aggregation function to apply

            Examples:
            {"type": "AGGREGATION", "function": "AVG", "column": "score"}
            {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
            {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

            - `column: string`

              Column to aggregate, or '*' for COUNT(*)

            - `function: "COUNT" or "SUM" or "AVG" or 7 more`

              Supported aggregation functions

              - `"COUNT"`

              - `"SUM"`

              - `"AVG"`

              - `"MIN"`

              - `"MAX"`

              - `"STDDEV"`

              - `"VARIANCE"`

              - `"PERCENTILE"`

              - `"COUNT_DISTINCT"`

              - `"PERCENTAGE"`

            - `evaluation_ids: optional array of string`

              Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

            - `params: optional map[unknown]`

              Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

            - `source: optional string`

              Column source: 'data' or 'task_result_cache'

            - `type: optional "AGGREGATION"`

              - `"AGGREGATION"`

        - `alias: optional string`

          Optional alias for the selected item

      - `evaluation_ids: optional array of string`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: optional Filter`

        Filter conditions (WHERE clause)

        - `conditions: array of object { column, operator, source, value }`

          - `column: string`

            Column name to filter on

          - `operator: "=" or "!=" or ">" or 9 more`

            Comparison operator

            - `"="`

            - `"!="`

            - `">"`

            - `"<"`

            - `">="`

            - `"<="`

            - `"IN"`

            - `"NOT IN"`

            - `"LIKE"`

            - `"NOT LIKE"`

            - `"IS NULL"`

            - `"IS NOT NULL"`

          - `source: optional string`

            Column source: 'data' or 'task_result_cache'

          - `value: optional string or number or boolean or array of unknown`

            Value to compare against. Not required for IS NULL / IS NOT NULL operators.

            - `string`

            - `number`

            - `boolean`

            - `array of unknown`

        - `logicalOperators: optional array of "AND" or "OR"`

          Logical operators connecting conditions. Length must be len(conditions) - 1

          - `"AND"`

          - `"OR"`

      - `groupBy: optional array of string`

        Columns to group by

      - `latest_only: optional boolean`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

      - `limit: optional number`

        Max rows to return

      - `orderBy: optional array of object { column, direction, source }`

        Sort order

        - `column: string`

          Column name to sort by

        - `direction: optional "ASC" or "DESC"`

          Sort direction

          - `"ASC"`

          - `"DESC"`

        - `source: optional string`

          Column source: 'data' or 'task_result_cache'

    - `MetricQuery object { select, evaluation_ids, filter, latest_only }`

      Query that returns a single metric value (used for metric widgets).

      Used for widget type: metric.
      Enforces exactly 1 aggregation in select.
      Returns: {"type": "metric", "data": ...}

      Example SQL equivalent:
      SELECT AVG(score) as average_score
      FROM evaluation_items

      - `select: array of SelectItem`

        - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

        - `alias: optional string`

          Optional alias for the selected item

      - `evaluation_ids: optional array of string`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: optional Filter`

        Filter conditions (WHERE clause)

      - `latest_only: optional boolean`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

  - `result: optional EvaluationDashboardWidgetResultResponse`

    Computed result for this widget

    - `id: string`

      Unique identifier of the widget result

    - `computation_status: string`

      Status: pending, completed, or failed

    - `widget_id: string`

      Widget ID this result belongs to

    - `computed_at: optional string`

      When computation completed

    - `computed_result: optional map[unknown]`

      Computed result data. Metric: {type: 'metric', data: 42}, Series: {type: 'series', data: [{x: 'A', y: 10}, ...]}

    - `error_message: optional string`

      Error message if computation failed

### Example

```http
curl https://api.egp.scale.com/v5/evaluation-dashboards/$DASHBOARD_ID/widgets \
    -H 'Content-Type: application/json' \
    -H "x-api-key: $SGP_API_KEY" \
    -d '{
          "title": "x",
          "type": "bar"
        }'
```

#### Response

```json
{
  "id": "id",
  "account_id": "account_id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "title": "title",
  "type": "bar",
  "config": {
    "foo": "bar"
  },
  "object": "evaluation_widget",
  "query": {
    "select": [
      {
        "expression": {
          "column": "column",
          "source": "source",
          "type": "COLUMN"
        },
        "alias": "alias"
      }
    ],
    "evaluation_ids": [
      "string"
    ],
    "filter": {
      "conditions": [
        {
          "column": "column",
          "operator": "=",
          "source": "source",
          "value": "string"
        }
      ],
      "logicalOperators": [
        "AND"
      ]
    },
    "groupBy": [
      "string"
    ],
    "latest_only": true,
    "limit": 1,
    "orderBy": [
      {
        "column": "column",
        "direction": "ASC",
        "source": "source"
      }
    ]
  },
  "result": {
    "id": "id",
    "computation_status": "computation_status",
    "widget_id": "widget_id",
    "computed_at": "2019-12-27T18:11:19.117Z",
    "computed_result": {
      "foo": "bar"
    },
    "error_message": "error_message"
  }
}
```

## Update Dashboard Widget

**patch** `/v5/evaluation-dashboards/{dashboard_id}/widgets/{widget_id}`

Update a widget's fields within this dashboard, using copy-on-write for shared widgets.

If the widget belongs only to this dashboard it is updated in place; if it is
referenced by more than one dashboard, a new widget is created with the updates
applied and swapped into this dashboard's `widget_order`, leaving the other
dashboards' copy untouched. The widget must already be in this dashboard's
`widget_order`, otherwise the call is rejected. The result is recomputed
synchronously when the `query` changes or when the widget was cloned; otherwise the
existing cached result is returned. For `table` widgets, conditional-formatting
column references are re-resolved against the (possibly updated) query on each save.
The dashboard must exist and not be archived.

### Path Parameters

- `dashboard_id: string`

- `widget_id: string`

### Body Parameters

- `config: optional map[unknown]`

  Chart-specific display configuration

- `query: optional SeriesQuery or MetricQuery`

  Structured query AST for metric computation (SeriesQuery or MetricQuery)

  - `SeriesQuery object { select, evaluation_ids, filter, 4 more }`

    Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

    Used for widget types: table, bar, histogram, donut, scatter.
    Returns: {"type": "series", "data": [...]}

    Example SQL equivalent:
    SELECT category, AVG(score) as avg_score, COUNT(*) as count
    FROM evaluation_items
    WHERE score > 0.5 AND category = 'test'
    GROUP BY category
    ORDER BY avg_score DESC
    LIMIT 100

    - `select: array of SelectItem`

      - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

        - `Column object { column, source, type }`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `column: string`

            Column name from evaluation_items.data

          - `source: optional string`

            Column source: 'data' or 'task_result_cache'

          - `type: optional "COLUMN"`

            - `"COLUMN"`

        - `Aggregation object { column, function, evaluation_ids, 3 more }`

          Aggregation function to apply

          Examples:
          {"type": "AGGREGATION", "function": "AVG", "column": "score"}
          {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
          {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

          - `column: string`

            Column to aggregate, or '*' for COUNT(*)

          - `function: "COUNT" or "SUM" or "AVG" or 7 more`

            Supported aggregation functions

            - `"COUNT"`

            - `"SUM"`

            - `"AVG"`

            - `"MIN"`

            - `"MAX"`

            - `"STDDEV"`

            - `"VARIANCE"`

            - `"PERCENTILE"`

            - `"COUNT_DISTINCT"`

            - `"PERCENTAGE"`

          - `evaluation_ids: optional array of string`

            Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

          - `params: optional map[unknown]`

            Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

          - `source: optional string`

            Column source: 'data' or 'task_result_cache'

          - `type: optional "AGGREGATION"`

            - `"AGGREGATION"`

      - `alias: optional string`

        Optional alias for the selected item

    - `evaluation_ids: optional array of string`

      Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

    - `filter: optional Filter`

      Filter conditions (WHERE clause)

      - `conditions: array of object { column, operator, source, value }`

        - `column: string`

          Column name to filter on

        - `operator: "=" or "!=" or ">" or 9 more`

          Comparison operator

          - `"="`

          - `"!="`

          - `">"`

          - `"<"`

          - `">="`

          - `"<="`

          - `"IN"`

          - `"NOT IN"`

          - `"LIKE"`

          - `"NOT LIKE"`

          - `"IS NULL"`

          - `"IS NOT NULL"`

        - `source: optional string`

          Column source: 'data' or 'task_result_cache'

        - `value: optional string or number or boolean or array of unknown`

          Value to compare against. Not required for IS NULL / IS NOT NULL operators.

          - `string`

          - `number`

          - `boolean`

          - `array of unknown`

      - `logicalOperators: optional array of "AND" or "OR"`

        Logical operators connecting conditions. Length must be len(conditions) - 1

        - `"AND"`

        - `"OR"`

    - `groupBy: optional array of string`

      Columns to group by

    - `latest_only: optional boolean`

      When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

    - `limit: optional number`

      Max rows to return

    - `orderBy: optional array of object { column, direction, source }`

      Sort order

      - `column: string`

        Column name to sort by

      - `direction: optional "ASC" or "DESC"`

        Sort direction

        - `"ASC"`

        - `"DESC"`

      - `source: optional string`

        Column source: 'data' or 'task_result_cache'

  - `MetricQuery object { select, evaluation_ids, filter, latest_only }`

    Query that returns a single metric value (used for metric widgets).

    Used for widget type: metric.
    Enforces exactly 1 aggregation in select.
    Returns: {"type": "metric", "data": ...}

    Example SQL equivalent:
    SELECT AVG(score) as average_score
    FROM evaluation_items

    - `select: array of SelectItem`

      - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

      - `alias: optional string`

        Optional alias for the selected item

    - `evaluation_ids: optional array of string`

      Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

    - `filter: optional Filter`

      Filter conditions (WHERE clause)

    - `latest_only: optional boolean`

      When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

- `title: optional string`

  Widget title

### Returns

- `EvaluationDashboardWidgetWithResult object { id, account_id, created_at, 6 more }`

  Response model for widget creation - includes widget and computed result

  - `id: string`

    Unique identifier of the widget

  - `account_id: string`

    Account that owns this widget

  - `created_at: string`

    When the widget was created

  - `title: string`

    Widget title

  - `type: EvaluationWidgetTypeEnum`

    Widget type

    - `"bar"`

    - `"histogram"`

    - `"donut"`

    - `"scatter"`

    - `"metric"`

    - `"table"`

    - `"markdown"`

    - `"heading"`

    - `"timeseries"`

  - `config: optional map[unknown]`

    Display configuration

  - `object: optional "evaluation_widget"`

    - `"evaluation_widget"`

  - `query: optional SeriesQuery or MetricQuery`

    Structured query AST for computation (SeriesQuery or MetricQuery)

    - `SeriesQuery object { select, evaluation_ids, filter, 4 more }`

      Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

      Used for widget types: table, bar, histogram, donut, scatter.
      Returns: {"type": "series", "data": [...]}

      Example SQL equivalent:
      SELECT category, AVG(score) as avg_score, COUNT(*) as count
      FROM evaluation_items
      WHERE score > 0.5 AND category = 'test'
      GROUP BY category
      ORDER BY avg_score DESC
      LIMIT 100

      - `select: array of SelectItem`

        - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `Column object { column, source, type }`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

            - `column: string`

              Column name from evaluation_items.data

            - `source: optional string`

              Column source: 'data' or 'task_result_cache'

            - `type: optional "COLUMN"`

              - `"COLUMN"`

          - `Aggregation object { column, function, evaluation_ids, 3 more }`

            Aggregation function to apply

            Examples:
            {"type": "AGGREGATION", "function": "AVG", "column": "score"}
            {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
            {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

            - `column: string`

              Column to aggregate, or '*' for COUNT(*)

            - `function: "COUNT" or "SUM" or "AVG" or 7 more`

              Supported aggregation functions

              - `"COUNT"`

              - `"SUM"`

              - `"AVG"`

              - `"MIN"`

              - `"MAX"`

              - `"STDDEV"`

              - `"VARIANCE"`

              - `"PERCENTILE"`

              - `"COUNT_DISTINCT"`

              - `"PERCENTAGE"`

            - `evaluation_ids: optional array of string`

              Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

            - `params: optional map[unknown]`

              Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

            - `source: optional string`

              Column source: 'data' or 'task_result_cache'

            - `type: optional "AGGREGATION"`

              - `"AGGREGATION"`

        - `alias: optional string`

          Optional alias for the selected item

      - `evaluation_ids: optional array of string`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: optional Filter`

        Filter conditions (WHERE clause)

        - `conditions: array of object { column, operator, source, value }`

          - `column: string`

            Column name to filter on

          - `operator: "=" or "!=" or ">" or 9 more`

            Comparison operator

            - `"="`

            - `"!="`

            - `">"`

            - `"<"`

            - `">="`

            - `"<="`

            - `"IN"`

            - `"NOT IN"`

            - `"LIKE"`

            - `"NOT LIKE"`

            - `"IS NULL"`

            - `"IS NOT NULL"`

          - `source: optional string`

            Column source: 'data' or 'task_result_cache'

          - `value: optional string or number or boolean or array of unknown`

            Value to compare against. Not required for IS NULL / IS NOT NULL operators.

            - `string`

            - `number`

            - `boolean`

            - `array of unknown`

        - `logicalOperators: optional array of "AND" or "OR"`

          Logical operators connecting conditions. Length must be len(conditions) - 1

          - `"AND"`

          - `"OR"`

      - `groupBy: optional array of string`

        Columns to group by

      - `latest_only: optional boolean`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

      - `limit: optional number`

        Max rows to return

      - `orderBy: optional array of object { column, direction, source }`

        Sort order

        - `column: string`

          Column name to sort by

        - `direction: optional "ASC" or "DESC"`

          Sort direction

          - `"ASC"`

          - `"DESC"`

        - `source: optional string`

          Column source: 'data' or 'task_result_cache'

    - `MetricQuery object { select, evaluation_ids, filter, latest_only }`

      Query that returns a single metric value (used for metric widgets).

      Used for widget type: metric.
      Enforces exactly 1 aggregation in select.
      Returns: {"type": "metric", "data": ...}

      Example SQL equivalent:
      SELECT AVG(score) as average_score
      FROM evaluation_items

      - `select: array of SelectItem`

        - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

        - `alias: optional string`

          Optional alias for the selected item

      - `evaluation_ids: optional array of string`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: optional Filter`

        Filter conditions (WHERE clause)

      - `latest_only: optional boolean`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

  - `result: optional EvaluationDashboardWidgetResultResponse`

    Computed result for this widget

    - `id: string`

      Unique identifier of the widget result

    - `computation_status: string`

      Status: pending, completed, or failed

    - `widget_id: string`

      Widget ID this result belongs to

    - `computed_at: optional string`

      When computation completed

    - `computed_result: optional map[unknown]`

      Computed result data. Metric: {type: 'metric', data: 42}, Series: {type: 'series', data: [{x: 'A', y: 10}, ...]}

    - `error_message: optional string`

      Error message if computation failed

### Example

```http
curl https://api.egp.scale.com/v5/evaluation-dashboards/$DASHBOARD_ID/widgets/$WIDGET_ID \
    -X PATCH \
    -H 'Content-Type: application/json' \
    -H "x-api-key: $SGP_API_KEY" \
    -d '{}'
```

#### Response

```json
{
  "id": "id",
  "account_id": "account_id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "title": "title",
  "type": "bar",
  "config": {
    "foo": "bar"
  },
  "object": "evaluation_widget",
  "query": {
    "select": [
      {
        "expression": {
          "column": "column",
          "source": "source",
          "type": "COLUMN"
        },
        "alias": "alias"
      }
    ],
    "evaluation_ids": [
      "string"
    ],
    "filter": {
      "conditions": [
        {
          "column": "column",
          "operator": "=",
          "source": "source",
          "value": "string"
        }
      ],
      "logicalOperators": [
        "AND"
      ]
    },
    "groupBy": [
      "string"
    ],
    "latest_only": true,
    "limit": 1,
    "orderBy": [
      {
        "column": "column",
        "direction": "ASC",
        "source": "source"
      }
    ]
  },
  "result": {
    "id": "id",
    "computation_status": "computation_status",
    "widget_id": "widget_id",
    "computed_at": "2019-12-27T18:11:19.117Z",
    "computed_result": {
      "foo": "bar"
    },
    "error_message": "error_message"
  }
}
```

## Remove Widget from Dashboard

**delete** `/v5/evaluation-dashboards/{dashboard_id}/widgets/{widget_id}`

Detach a widget from this dashboard without deleting the widget itself.

This removes the widget's ID from the dashboard's `widget_order` only; the
underlying widget entity and any computed widget results are left intact, so a widget
shared with other dashboards continues to work there. The widget must currently be in
this dashboard's `widget_order`, otherwise a not-found error is returned. Responds
with 204 No Content on success.

### Path Parameters

- `dashboard_id: string`

- `widget_id: string`

### Example

```http
curl https://api.egp.scale.com/v5/evaluation-dashboards/$DASHBOARD_ID/widgets/$WIDGET_ID \
    -X DELETE \
    -H "x-api-key: $SGP_API_KEY"
```

## Domain Types

### Evaluation Dashboard Widget

- `EvaluationDashboardWidget object { id, account_id, created_at, 6 more }`

  - `id: string`

    Unique identifier of the widget

  - `account_id: string`

    Account that owns this widget

  - `created_at: string`

    When the widget was created

  - `title: string`

    Widget title

  - `type: EvaluationWidgetTypeEnum`

    Widget type

    - `"bar"`

    - `"histogram"`

    - `"donut"`

    - `"scatter"`

    - `"metric"`

    - `"table"`

    - `"markdown"`

    - `"heading"`

    - `"timeseries"`

  - `archived_at: optional string`

    When the widget was archived (soft-deleted)

  - `config: optional map[unknown]`

    Chart-specific display configuration

  - `object: optional "evaluation_dashboard_widget"`

    - `"evaluation_dashboard_widget"`

  - `query: optional SeriesQuery or MetricQuery`

    Structured query AST for metric computation (SeriesQuery or MetricQuery)

    - `SeriesQuery object { select, evaluation_ids, filter, 4 more }`

      Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

      Used for widget types: table, bar, histogram, donut, scatter.
      Returns: {"type": "series", "data": [...]}

      Example SQL equivalent:
      SELECT category, AVG(score) as avg_score, COUNT(*) as count
      FROM evaluation_items
      WHERE score > 0.5 AND category = 'test'
      GROUP BY category
      ORDER BY avg_score DESC
      LIMIT 100

      - `select: array of SelectItem`

        - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `Column object { column, source, type }`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

            - `column: string`

              Column name from evaluation_items.data

            - `source: optional string`

              Column source: 'data' or 'task_result_cache'

            - `type: optional "COLUMN"`

              - `"COLUMN"`

          - `Aggregation object { column, function, evaluation_ids, 3 more }`

            Aggregation function to apply

            Examples:
            {"type": "AGGREGATION", "function": "AVG", "column": "score"}
            {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
            {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

            - `column: string`

              Column to aggregate, or '*' for COUNT(*)

            - `function: "COUNT" or "SUM" or "AVG" or 7 more`

              Supported aggregation functions

              - `"COUNT"`

              - `"SUM"`

              - `"AVG"`

              - `"MIN"`

              - `"MAX"`

              - `"STDDEV"`

              - `"VARIANCE"`

              - `"PERCENTILE"`

              - `"COUNT_DISTINCT"`

              - `"PERCENTAGE"`

            - `evaluation_ids: optional array of string`

              Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

            - `params: optional map[unknown]`

              Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

            - `source: optional string`

              Column source: 'data' or 'task_result_cache'

            - `type: optional "AGGREGATION"`

              - `"AGGREGATION"`

        - `alias: optional string`

          Optional alias for the selected item

      - `evaluation_ids: optional array of string`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: optional Filter`

        Filter conditions (WHERE clause)

        - `conditions: array of object { column, operator, source, value }`

          - `column: string`

            Column name to filter on

          - `operator: "=" or "!=" or ">" or 9 more`

            Comparison operator

            - `"="`

            - `"!="`

            - `">"`

            - `"<"`

            - `">="`

            - `"<="`

            - `"IN"`

            - `"NOT IN"`

            - `"LIKE"`

            - `"NOT LIKE"`

            - `"IS NULL"`

            - `"IS NOT NULL"`

          - `source: optional string`

            Column source: 'data' or 'task_result_cache'

          - `value: optional string or number or boolean or array of unknown`

            Value to compare against. Not required for IS NULL / IS NOT NULL operators.

            - `string`

            - `number`

            - `boolean`

            - `array of unknown`

        - `logicalOperators: optional array of "AND" or "OR"`

          Logical operators connecting conditions. Length must be len(conditions) - 1

          - `"AND"`

          - `"OR"`

      - `groupBy: optional array of string`

        Columns to group by

      - `latest_only: optional boolean`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

      - `limit: optional number`

        Max rows to return

      - `orderBy: optional array of object { column, direction, source }`

        Sort order

        - `column: string`

          Column name to sort by

        - `direction: optional "ASC" or "DESC"`

          Sort direction

          - `"ASC"`

          - `"DESC"`

        - `source: optional string`

          Column source: 'data' or 'task_result_cache'

    - `MetricQuery object { select, evaluation_ids, filter, latest_only }`

      Query that returns a single metric value (used for metric widgets).

      Used for widget type: metric.
      Enforces exactly 1 aggregation in select.
      Returns: {"type": "metric", "data": ...}

      Example SQL equivalent:
      SELECT AVG(score) as average_score
      FROM evaluation_items

      - `select: array of SelectItem`

        - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

        - `alias: optional string`

          Optional alias for the selected item

      - `evaluation_ids: optional array of string`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: optional Filter`

        Filter conditions (WHERE clause)

      - `latest_only: optional boolean`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

### Evaluation Dashboard Widget Result

- `EvaluationDashboardWidgetResult object { id, account_id, computation_status, 10 more }`

  - `id: string`

    Unique identifier of the widget result

  - `account_id: string`

    Account that owns this widget result

  - `computation_status: "pending" or "completed" or "failed"`

    Status of the computation

    - `"pending"`

    - `"completed"`

    - `"failed"`

  - `created_at: string`

    When the widget result was created

  - `widget_id: string`

    Unique identifier of the widget

  - `computation_job_id: optional string`

    Temporal workflow ID or job ID for async computation tracking

  - `computed_at: optional string`

    Timestamp when computation completed successfully

  - `computed_result: optional map[unknown]`

    Cached computation results

  - `error_message: optional string`

    Error message if computation failed

  - `evaluation_group_id: optional string`

    FK to evaluation_groups. Null if result is for a single evaluation.

  - `evaluation_id: optional string`

    FK to evaluations. Null if result is for an evaluation group.

  - `object: optional "evaluation_dashboard_widget_result"`

    - `"evaluation_dashboard_widget_result"`

  - `widget: optional EvaluationDashboardWidget`

    Widget that this result is for

    - `id: string`

      Unique identifier of the widget

    - `account_id: string`

      Account that owns this widget

    - `created_at: string`

      When the widget was created

    - `title: string`

      Widget title

    - `type: EvaluationWidgetTypeEnum`

      Widget type

      - `"bar"`

      - `"histogram"`

      - `"donut"`

      - `"scatter"`

      - `"metric"`

      - `"table"`

      - `"markdown"`

      - `"heading"`

      - `"timeseries"`

    - `archived_at: optional string`

      When the widget was archived (soft-deleted)

    - `config: optional map[unknown]`

      Chart-specific display configuration

    - `object: optional "evaluation_dashboard_widget"`

      - `"evaluation_dashboard_widget"`

    - `query: optional SeriesQuery or MetricQuery`

      Structured query AST for metric computation (SeriesQuery or MetricQuery)

      - `SeriesQuery object { select, evaluation_ids, filter, 4 more }`

        Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

        Used for widget types: table, bar, histogram, donut, scatter.
        Returns: {"type": "series", "data": [...]}

        Example SQL equivalent:
        SELECT category, AVG(score) as avg_score, COUNT(*) as count
        FROM evaluation_items
        WHERE score > 0.5 AND category = 'test'
        GROUP BY category
        ORDER BY avg_score DESC
        LIMIT 100

        - `select: array of SelectItem`

          - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

            - `Column object { column, source, type }`

              Reference to a column from evaluation_items.data

              Example:
              {"type": "COLUMN", "column": "category"}

              - `column: string`

                Column name from evaluation_items.data

              - `source: optional string`

                Column source: 'data' or 'task_result_cache'

              - `type: optional "COLUMN"`

                - `"COLUMN"`

            - `Aggregation object { column, function, evaluation_ids, 3 more }`

              Aggregation function to apply

              Examples:
              {"type": "AGGREGATION", "function": "AVG", "column": "score"}
              {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
              {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

              - `column: string`

                Column to aggregate, or '*' for COUNT(*)

              - `function: "COUNT" or "SUM" or "AVG" or 7 more`

                Supported aggregation functions

                - `"COUNT"`

                - `"SUM"`

                - `"AVG"`

                - `"MIN"`

                - `"MAX"`

                - `"STDDEV"`

                - `"VARIANCE"`

                - `"PERCENTILE"`

                - `"COUNT_DISTINCT"`

                - `"PERCENTAGE"`

              - `evaluation_ids: optional array of string`

                Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

              - `params: optional map[unknown]`

                Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

              - `source: optional string`

                Column source: 'data' or 'task_result_cache'

              - `type: optional "AGGREGATION"`

                - `"AGGREGATION"`

          - `alias: optional string`

            Optional alias for the selected item

        - `evaluation_ids: optional array of string`

          Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

        - `filter: optional Filter`

          Filter conditions (WHERE clause)

          - `conditions: array of object { column, operator, source, value }`

            - `column: string`

              Column name to filter on

            - `operator: "=" or "!=" or ">" or 9 more`

              Comparison operator

              - `"="`

              - `"!="`

              - `">"`

              - `"<"`

              - `">="`

              - `"<="`

              - `"IN"`

              - `"NOT IN"`

              - `"LIKE"`

              - `"NOT LIKE"`

              - `"IS NULL"`

              - `"IS NOT NULL"`

            - `source: optional string`

              Column source: 'data' or 'task_result_cache'

            - `value: optional string or number or boolean or array of unknown`

              Value to compare against. Not required for IS NULL / IS NOT NULL operators.

              - `string`

              - `number`

              - `boolean`

              - `array of unknown`

          - `logicalOperators: optional array of "AND" or "OR"`

            Logical operators connecting conditions. Length must be len(conditions) - 1

            - `"AND"`

            - `"OR"`

        - `groupBy: optional array of string`

          Columns to group by

        - `latest_only: optional boolean`

          When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

        - `limit: optional number`

          Max rows to return

        - `orderBy: optional array of object { column, direction, source }`

          Sort order

          - `column: string`

            Column name to sort by

          - `direction: optional "ASC" or "DESC"`

            Sort direction

            - `"ASC"`

            - `"DESC"`

          - `source: optional string`

            Column source: 'data' or 'task_result_cache'

      - `MetricQuery object { select, evaluation_ids, filter, latest_only }`

        Query that returns a single metric value (used for metric widgets).

        Used for widget type: metric.
        Enforces exactly 1 aggregation in select.
        Returns: {"type": "metric", "data": ...}

        Example SQL equivalent:
        SELECT AVG(score) as average_score
        FROM evaluation_items

        - `select: array of SelectItem`

          - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

          - `alias: optional string`

            Optional alias for the selected item

        - `evaluation_ids: optional array of string`

          Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

        - `filter: optional Filter`

          Filter conditions (WHERE clause)

        - `latest_only: optional boolean`

          When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

### Evaluation Dashboard Widget Result Response

- `EvaluationDashboardWidgetResultResponse object { id, computation_status, widget_id, 3 more }`

  Computed result for a widget - used in widget creation response

  - `id: string`

    Unique identifier of the widget result

  - `computation_status: string`

    Status: pending, completed, or failed

  - `widget_id: string`

    Widget ID this result belongs to

  - `computed_at: optional string`

    When computation completed

  - `computed_result: optional map[unknown]`

    Computed result data. Metric: {type: 'metric', data: 42}, Series: {type: 'series', data: [{x: 'A', y: 10}, ...]}

  - `error_message: optional string`

    Error message if computation failed

### Evaluation Dashboard Widget With Result

- `EvaluationDashboardWidgetWithResult object { id, account_id, created_at, 6 more }`

  Response model for widget creation - includes widget and computed result

  - `id: string`

    Unique identifier of the widget

  - `account_id: string`

    Account that owns this widget

  - `created_at: string`

    When the widget was created

  - `title: string`

    Widget title

  - `type: EvaluationWidgetTypeEnum`

    Widget type

    - `"bar"`

    - `"histogram"`

    - `"donut"`

    - `"scatter"`

    - `"metric"`

    - `"table"`

    - `"markdown"`

    - `"heading"`

    - `"timeseries"`

  - `config: optional map[unknown]`

    Display configuration

  - `object: optional "evaluation_widget"`

    - `"evaluation_widget"`

  - `query: optional SeriesQuery or MetricQuery`

    Structured query AST for computation (SeriesQuery or MetricQuery)

    - `SeriesQuery object { select, evaluation_ids, filter, 4 more }`

      Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

      Used for widget types: table, bar, histogram, donut, scatter.
      Returns: {"type": "series", "data": [...]}

      Example SQL equivalent:
      SELECT category, AVG(score) as avg_score, COUNT(*) as count
      FROM evaluation_items
      WHERE score > 0.5 AND category = 'test'
      GROUP BY category
      ORDER BY avg_score DESC
      LIMIT 100

      - `select: array of SelectItem`

        - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `Column object { column, source, type }`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

            - `column: string`

              Column name from evaluation_items.data

            - `source: optional string`

              Column source: 'data' or 'task_result_cache'

            - `type: optional "COLUMN"`

              - `"COLUMN"`

          - `Aggregation object { column, function, evaluation_ids, 3 more }`

            Aggregation function to apply

            Examples:
            {"type": "AGGREGATION", "function": "AVG", "column": "score"}
            {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
            {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

            - `column: string`

              Column to aggregate, or '*' for COUNT(*)

            - `function: "COUNT" or "SUM" or "AVG" or 7 more`

              Supported aggregation functions

              - `"COUNT"`

              - `"SUM"`

              - `"AVG"`

              - `"MIN"`

              - `"MAX"`

              - `"STDDEV"`

              - `"VARIANCE"`

              - `"PERCENTILE"`

              - `"COUNT_DISTINCT"`

              - `"PERCENTAGE"`

            - `evaluation_ids: optional array of string`

              Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

            - `params: optional map[unknown]`

              Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

            - `source: optional string`

              Column source: 'data' or 'task_result_cache'

            - `type: optional "AGGREGATION"`

              - `"AGGREGATION"`

        - `alias: optional string`

          Optional alias for the selected item

      - `evaluation_ids: optional array of string`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: optional Filter`

        Filter conditions (WHERE clause)

        - `conditions: array of object { column, operator, source, value }`

          - `column: string`

            Column name to filter on

          - `operator: "=" or "!=" or ">" or 9 more`

            Comparison operator

            - `"="`

            - `"!="`

            - `">"`

            - `"<"`

            - `">="`

            - `"<="`

            - `"IN"`

            - `"NOT IN"`

            - `"LIKE"`

            - `"NOT LIKE"`

            - `"IS NULL"`

            - `"IS NOT NULL"`

          - `source: optional string`

            Column source: 'data' or 'task_result_cache'

          - `value: optional string or number or boolean or array of unknown`

            Value to compare against. Not required for IS NULL / IS NOT NULL operators.

            - `string`

            - `number`

            - `boolean`

            - `array of unknown`

        - `logicalOperators: optional array of "AND" or "OR"`

          Logical operators connecting conditions. Length must be len(conditions) - 1

          - `"AND"`

          - `"OR"`

      - `groupBy: optional array of string`

        Columns to group by

      - `latest_only: optional boolean`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

      - `limit: optional number`

        Max rows to return

      - `orderBy: optional array of object { column, direction, source }`

        Sort order

        - `column: string`

          Column name to sort by

        - `direction: optional "ASC" or "DESC"`

          Sort direction

          - `"ASC"`

          - `"DESC"`

        - `source: optional string`

          Column source: 'data' or 'task_result_cache'

    - `MetricQuery object { select, evaluation_ids, filter, latest_only }`

      Query that returns a single metric value (used for metric widgets).

      Used for widget type: metric.
      Enforces exactly 1 aggregation in select.
      Returns: {"type": "metric", "data": ...}

      Example SQL equivalent:
      SELECT AVG(score) as average_score
      FROM evaluation_items

      - `select: array of SelectItem`

        - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

        - `alias: optional string`

          Optional alias for the selected item

      - `evaluation_ids: optional array of string`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: optional Filter`

        Filter conditions (WHERE clause)

      - `latest_only: optional boolean`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

  - `result: optional EvaluationDashboardWidgetResultResponse`

    Computed result for this widget

    - `id: string`

      Unique identifier of the widget result

    - `computation_status: string`

      Status: pending, completed, or failed

    - `widget_id: string`

      Widget ID this result belongs to

    - `computed_at: optional string`

      When computation completed

    - `computed_result: optional map[unknown]`

      Computed result data. Metric: {type: 'metric', data: 42}, Series: {type: 'series', data: [{x: 'A', y: 10}, ...]}

    - `error_message: optional string`

      Error message if computation failed

### Evaluation Widget Type Enum

- `EvaluationWidgetTypeEnum = "bar" or "histogram" or "donut" or 6 more`

  Widget types for dashboard visualizations

  - `"bar"`

  - `"histogram"`

  - `"donut"`

  - `"scatter"`

  - `"metric"`

  - `"table"`

  - `"markdown"`

  - `"heading"`

  - `"timeseries"`

### Filter

- `Filter object { conditions, logicalOperators }`

  Filter clause with conditions connected by logical operators.

  Conditions are evaluated left-to-right without precedence (no nesting/parentheses).
  Example: condition1 AND condition2 OR condition3 evaluates as ((condition1 AND condition2) OR condition3)

  Example:
  {
  "conditions": [
  {"column": "score", "operator": ">", "value": 0.5},
  {"column": "category", "operator": "=", "value": "test"}
  ],
  "logicalOperators": ["AND"]
  }

  - `conditions: array of object { column, operator, source, value }`

    - `column: string`

      Column name to filter on

    - `operator: "=" or "!=" or ">" or 9 more`

      Comparison operator

      - `"="`

      - `"!="`

      - `">"`

      - `"<"`

      - `">="`

      - `"<="`

      - `"IN"`

      - `"NOT IN"`

      - `"LIKE"`

      - `"NOT LIKE"`

      - `"IS NULL"`

      - `"IS NOT NULL"`

    - `source: optional string`

      Column source: 'data' or 'task_result_cache'

    - `value: optional string or number or boolean or array of unknown`

      Value to compare against. Not required for IS NULL / IS NOT NULL operators.

      - `string`

      - `number`

      - `boolean`

      - `array of unknown`

  - `logicalOperators: optional array of "AND" or "OR"`

    Logical operators connecting conditions. Length must be len(conditions) - 1

    - `"AND"`

    - `"OR"`

### Metric Query

- `MetricQuery object { select, evaluation_ids, filter, latest_only }`

  Query that returns a single metric value (used for metric widgets).

  Used for widget type: metric.
  Enforces exactly 1 aggregation in select.
  Returns: {"type": "metric", "data": ...}

  Example SQL equivalent:
  SELECT AVG(score) as average_score
  FROM evaluation_items

  - `select: array of SelectItem`

    - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

      Reference to a column from evaluation_items.data

      Example:
      {"type": "COLUMN", "column": "category"}

      - `Column object { column, source, type }`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

        - `column: string`

          Column name from evaluation_items.data

        - `source: optional string`

          Column source: 'data' or 'task_result_cache'

        - `type: optional "COLUMN"`

          - `"COLUMN"`

      - `Aggregation object { column, function, evaluation_ids, 3 more }`

        Aggregation function to apply

        Examples:
        {"type": "AGGREGATION", "function": "AVG", "column": "score"}
        {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
        {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

        - `column: string`

          Column to aggregate, or '*' for COUNT(*)

        - `function: "COUNT" or "SUM" or "AVG" or 7 more`

          Supported aggregation functions

          - `"COUNT"`

          - `"SUM"`

          - `"AVG"`

          - `"MIN"`

          - `"MAX"`

          - `"STDDEV"`

          - `"VARIANCE"`

          - `"PERCENTILE"`

          - `"COUNT_DISTINCT"`

          - `"PERCENTAGE"`

        - `evaluation_ids: optional array of string`

          Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

        - `params: optional map[unknown]`

          Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

        - `source: optional string`

          Column source: 'data' or 'task_result_cache'

        - `type: optional "AGGREGATION"`

          - `"AGGREGATION"`

    - `alias: optional string`

      Optional alias for the selected item

  - `evaluation_ids: optional array of string`

    Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

  - `filter: optional Filter`

    Filter conditions (WHERE clause)

    - `conditions: array of object { column, operator, source, value }`

      - `column: string`

        Column name to filter on

      - `operator: "=" or "!=" or ">" or 9 more`

        Comparison operator

        - `"="`

        - `"!="`

        - `">"`

        - `"<"`

        - `">="`

        - `"<="`

        - `"IN"`

        - `"NOT IN"`

        - `"LIKE"`

        - `"NOT LIKE"`

        - `"IS NULL"`

        - `"IS NOT NULL"`

      - `source: optional string`

        Column source: 'data' or 'task_result_cache'

      - `value: optional string or number or boolean or array of unknown`

        Value to compare against. Not required for IS NULL / IS NOT NULL operators.

        - `string`

        - `number`

        - `boolean`

        - `array of unknown`

    - `logicalOperators: optional array of "AND" or "OR"`

      Logical operators connecting conditions. Length must be len(conditions) - 1

      - `"AND"`

      - `"OR"`

  - `latest_only: optional boolean`

    When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

### Select Item

- `SelectItem object { expression, alias }`

  Column in SELECT clause

  - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

    Reference to a column from evaluation_items.data

    Example:
    {"type": "COLUMN", "column": "category"}

    - `Column object { column, source, type }`

      Reference to a column from evaluation_items.data

      Example:
      {"type": "COLUMN", "column": "category"}

      - `column: string`

        Column name from evaluation_items.data

      - `source: optional string`

        Column source: 'data' or 'task_result_cache'

      - `type: optional "COLUMN"`

        - `"COLUMN"`

    - `Aggregation object { column, function, evaluation_ids, 3 more }`

      Aggregation function to apply

      Examples:
      {"type": "AGGREGATION", "function": "AVG", "column": "score"}
      {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
      {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

      - `column: string`

        Column to aggregate, or '*' for COUNT(*)

      - `function: "COUNT" or "SUM" or "AVG" or 7 more`

        Supported aggregation functions

        - `"COUNT"`

        - `"SUM"`

        - `"AVG"`

        - `"MIN"`

        - `"MAX"`

        - `"STDDEV"`

        - `"VARIANCE"`

        - `"PERCENTILE"`

        - `"COUNT_DISTINCT"`

        - `"PERCENTAGE"`

      - `evaluation_ids: optional array of string`

        Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

      - `params: optional map[unknown]`

        Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

      - `source: optional string`

        Column source: 'data' or 'task_result_cache'

      - `type: optional "AGGREGATION"`

        - `"AGGREGATION"`

  - `alias: optional string`

    Optional alias for the selected item

### Series Query

- `SeriesQuery object { select, evaluation_ids, filter, 4 more }`

  Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

  Used for widget types: table, bar, histogram, donut, scatter.
  Returns: {"type": "series", "data": [...]}

  Example SQL equivalent:
  SELECT category, AVG(score) as avg_score, COUNT(*) as count
  FROM evaluation_items
  WHERE score > 0.5 AND category = 'test'
  GROUP BY category
  ORDER BY avg_score DESC
  LIMIT 100

  - `select: array of SelectItem`

    - `expression: object { column, source, type }  or object { column, function, evaluation_ids, 3 more }`

      Reference to a column from evaluation_items.data

      Example:
      {"type": "COLUMN", "column": "category"}

      - `Column object { column, source, type }`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

        - `column: string`

          Column name from evaluation_items.data

        - `source: optional string`

          Column source: 'data' or 'task_result_cache'

        - `type: optional "COLUMN"`

          - `"COLUMN"`

      - `Aggregation object { column, function, evaluation_ids, 3 more }`

        Aggregation function to apply

        Examples:
        {"type": "AGGREGATION", "function": "AVG", "column": "score"}
        {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
        {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

        - `column: string`

          Column to aggregate, or '*' for COUNT(*)

        - `function: "COUNT" or "SUM" or "AVG" or 7 more`

          Supported aggregation functions

          - `"COUNT"`

          - `"SUM"`

          - `"AVG"`

          - `"MIN"`

          - `"MAX"`

          - `"STDDEV"`

          - `"VARIANCE"`

          - `"PERCENTILE"`

          - `"COUNT_DISTINCT"`

          - `"PERCENTAGE"`

        - `evaluation_ids: optional array of string`

          Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

        - `params: optional map[unknown]`

          Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

        - `source: optional string`

          Column source: 'data' or 'task_result_cache'

        - `type: optional "AGGREGATION"`

          - `"AGGREGATION"`

    - `alias: optional string`

      Optional alias for the selected item

  - `evaluation_ids: optional array of string`

    Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

  - `filter: optional Filter`

    Filter conditions (WHERE clause)

    - `conditions: array of object { column, operator, source, value }`

      - `column: string`

        Column name to filter on

      - `operator: "=" or "!=" or ">" or 9 more`

        Comparison operator

        - `"="`

        - `"!="`

        - `">"`

        - `"<"`

        - `">="`

        - `"<="`

        - `"IN"`

        - `"NOT IN"`

        - `"LIKE"`

        - `"NOT LIKE"`

        - `"IS NULL"`

        - `"IS NOT NULL"`

      - `source: optional string`

        Column source: 'data' or 'task_result_cache'

      - `value: optional string or number or boolean or array of unknown`

        Value to compare against. Not required for IS NULL / IS NOT NULL operators.

        - `string`

        - `number`

        - `boolean`

        - `array of unknown`

    - `logicalOperators: optional array of "AND" or "OR"`

      Logical operators connecting conditions. Length must be len(conditions) - 1

      - `"AND"`

      - `"OR"`

  - `groupBy: optional array of string`

    Columns to group by

  - `latest_only: optional boolean`

    When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

  - `limit: optional number`

    Max rows to return

  - `orderBy: optional array of object { column, direction, source }`

    Sort order

    - `column: string`

      Column name to sort by

    - `direction: optional "ASC" or "DESC"`

      Sort direction

      - `"ASC"`

      - `"DESC"`

    - `source: optional string`

      Column source: 'data' or 'task_result_cache'
