---
title: "Create or update one panel (upsert by id). With viewName the write lands on that saved view's own dashboard, forking a copy if it was still inheriting the object's"
method: PUT
path: "/crm/objects/{objectName}/analytics/panels/{panelId}"
tags: ["crm"]
---

# Create or update one panel (upsert by id). With viewName the write lands on that saved view's own dashboard, forking a copy if it was still inheriting the object's

`PUT /crm/objects/{objectName}/analytics/panels/{panelId}`

## Request

- Base URL: `https://www.dench.com/api/v1`
- URL: `https://www.dench.com/api/v1/crm/objects/{objectName}/analytics/panels/{panelId}`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Create or update one panel (upsert by id). With viewName the write lands on that saved view's own dashboard, forking a copy if it was still inheriting the object's.

## Path parameters

- `objectName` string, required
- `panelId` string, required: Panel id (path); becomes panel.id.

## Request body

- object
  - `panel` object, required: The panel definition to upsert.
    - `title` string, required
    - `type` 'stat' | 'bar' | 'line' | 'area' | 'donut' | 'funnel' | 'leaderboard' | 'forecast' | 'map', required
    - `metric` 'count' | 'sum' | 'avg' | 'min' | 'max', required
    - `metricField` string: Numeric field for sum/avg/min/max. Ignored for count.
    - `groupBy` string: Bucketing field (enum/user/relation/boolean/text, or $location). On a time-series panel it splits the series into one line per value.
    - `dateField` string: Date field for line/area/forecast bucketing (or $createdAt).
    - `dateBucket` 'day' | 'week' | 'month' | 'quarter'
    - `filters` object: Panel-scoped FilterGroup, same shape as saved-view filters.
    - `size` 'sm' | 'md' | 'lg': Deprecated; ignored for layout. Use `span`.
    - `span` union: Card width on the 6-track dashboard grid: 2 = a third, 3 = half, 4 = two thirds, 6 = full row. Defaults: funnel 4; map and leaderboard 2; bar/donut grouped by a user field 2, by anything else 4; trends 3.
      - 2
      - 3
      - 4
      - 6
    - `hidden` boolean: Hide from the strip above the table; still shown in the full analytics view.
    - `sortOrder` number, required
    - `derived` 'conversion_rate' | 'win_rate' | 'won_amount' | 'lost_amount' | 'open_pipeline' | 'pipeline_forecast' | 'mrr' | 'arr': Role-driven derived metric; when set the panel computes from fieldRoles instead of metric/groupBy.
    - `id` string
  - `viewName` string: Write the saved view's own dashboard (forks a copy if it was inheriting).

## Response `200`

Successful response

- object
  - `ok` boolean, required
  - `panelId` string, required

## Other responses

- `400`: Invalid request
- `401`: Missing or invalid authentication
- `404`: Operation or resource not found
- `500`: Server error

---

[API](https://skmtc.dev/dench/apis/dench-api.md) - [All operations](https://skmtc.dev/dench/apis/dench-api/llms.txt) - [OpenAPI document](https://skmtc.dev/dench/apis/dench-api/revisions/4a145b38f19c?raw)
