---
title: "Update a dashboard"
method: PUT
path: "/dashboards/{dashboardId}"
tags: ["Dashboards"]
---

# Update a dashboard

`PUT /dashboards/{dashboardId}`

## Request

- Base URL: `https://api.speakai.co/v1`
- URL: `https://api.speakai.co/v1/dashboards/{dashboardId}`
- Auth: API key in header `x-speakai-key` and API key in header `x-access-token`

Update a dashboard. Send only the keys you want to change. To change the dashboard itself, send the full `spec` with the `revision` you read: the write is accepted only while it still matches, and returns 409 otherwise. Settings, icon, sharing, filters and the default flag can be changed without a `spec`.

#### Viewer settings

`settings` controls what viewers of the dashboard's share link see on each media page. Each section (`fields`, `feedback`, `labels`, `comments`, `profiles`) is saved on its own: the section you send replaces the stored one in full, and a section you leave out keeps its stored value. Read the dashboard first and resend every key of the section you change.

Labels and comments are off until you turn them on. With `labels.mode` set to `apply` or `comments.mode` set to `reply`, a viewer picks one of the dashboard's feedback submitter names (`feedback.submitters`, even while feedback itself is off), or types another name when `feedback.allowOtherSubmitter` is on, and writes under that name. With no names and other names off, nobody can write. The link has no sign-in, so these writes are not authenticated: the link holder chooses the name and Speak AI records the entry under it without checking who sent it, the same as feedback. Only the dashboard's feedback names are accepted, plus any other name when `feedback.allowOtherSubmitter` is on. Speak AI accepts this risk by design and limits it: every entry written through the link is shown as made via the dashboard, a name can change or delete only the entries written under it from that dashboard, a name that is not allowed is refused on every write, and revoking the link stops every write at once. List only the names you are happy for link holders to write as.

#### Errors

- `400` when a field fails validation, the spec is invalid, the payload is too large, or a label group is not an active group of your company ("Choose active label groups from this workspace."). Nothing is saved.
- `404` when the dashboard does not exist or you cannot edit it.
- `409` when the spec `revision` is stale: "Dashboard was modified by another update. Reload and try again."

## Path parameters

- `dashboardId` string, required

## Request body

- object
  - `spec` object: The dashboard itself: `title` (1 to 60 characters), `description` (up to 280), `source` (`{"type": "workspace"}`, `{"type": "team"}` or `{"type": "folders", "folderIds": [...]}`), `dateRange` (`{"preset": "last30days"}`), `sections` and `widgets`. It is checked against the dashboard spec schema, and unknown keys return 400. When sent it must be the full spec, with `revision`.
  - `revision` number: The dashboard's current revision, a whole number. Required when you send `settings.profiles` without a `spec`; a stale one returns 409.
  - `icon` string: Icon identifier. Optional. An empty string is allowed.
  - `assignTo` string[]: User ids, or group ids written as `<groupId> (G)`, that can view the dashboard. Optional.
  - `filters` object: Saved filters for the dashboard. Optional. Up to 100 keys; `filterList` holds up to 20 filters.
  - `settings` object: What viewers of the dashboard's share link see on each media page. Optional. Every section is saved on its own: a section you send replaces that whole section, and a section you leave out keeps its stored value. Unknown keys return 400.
    - `fields` object: Which custom fields the media page shows, and how its Fields tab groups them.
      - `includeIds` string[], required: Field ids shown, in this order, private fields included. Empty shows the company's public fields. Required in the section. Ids that are not fields of your company are dropped and listed in `droppedFieldIds`.
      - `orderIds` string[]: Used only when `includeIds` is empty: these fields show first, in this order. Optional.
      - `groups` object[], required: Pills on the Fields tab. Unique by `key`. Required in the section; send an empty array for none.
        - `key` string, required: Stable key of the group, unique in the list.
        - `label` string, required: Name shown on the pill.
        - `fieldIds` string[], required: Field ids in the group, in order. At least one.
    - `feedback` object: The Feedback button on the media page.
      - `isEnabled` boolean, required: Show the Feedback button.
      - `fieldIds` string[], required: Fields a reviewer scores. Empty means every field the page shows.
      - `submitters` string[], required: Names a reviewer picks from. Empty lets them type their own.
      - `removeReasons` string[], required: Reasons for removing a call from scoring. Empty hides that option.
      - `reviewScope` 'dashboard' | 'company': `dashboard` (the default) or `company`. Optional.
      - `allowOtherSubmitter` boolean: Lets a reviewer type a name that is not in `submitters`. Optional.
      - `groups` object[]: Pills in the Feedback dialog. Optional.
        - `key` string, required: Stable key of the group, unique in the list.
        - `label` string, required: Name shown on the pill.
        - `fieldIds` string[], required: Field ids in the group, in order. At least one.
      - `fieldRules` object: Per field id: an optional row `label` and the allowed `min` and `max` score. Optional.
      - `sheetWebhookUrl` string: Google Apps Script web app URL that receives one row per submission. Never shown to viewers. Optional.
    - `labels` object: Labels on the shared media pages. Off unless you turn it on.
      - `isEnabled` boolean, required: Show labels on media pages opened from the share link.
      - `mode` 'view' | 'apply', required: `view` shows labels read-only. `apply` also lets a viewer add and remove labels under one of the reviewer names.
      - `labelGroupIds` string[], required: Label groups the link shows and offers. Up to 100 group ids, no repeats. Empty means every active label. Each must be an active label group of your company, or the whole save returns 400 "Choose active label groups from this workspace." Groups are refused rather than dropped, because dropping them all would widen the link to every label. If every chosen group is archived later, the link shows no labels.
    - `comments` object: Comments on the shared media pages. Off unless you turn it on.
      - `isEnabled` boolean, required: Show comments on media pages opened from the share link.
      - `mode` 'view' | 'reply', required: `view` shows comments read-only. `reply` also lets a viewer comment and reply under one of the reviewer names.
    - `profiles` object[]: Profiles: an image, a description and a link for values of a custom field, such as speakers, events or sponsors. Up to 5 groups, one per field (a field may appear only once). Sending `profiles` replaces the whole list. On an update it also needs the dashboard's current `revision` at the top level of the body: without it the request returns 400, and a stale one returns 409. Saving only `profiles` does not change which fields media pages show. Names, images, descriptions and links are visible to anyone with the dashboard link. Optional.
      - `fieldId` string, required: Id of the custom field the profiles are for. Required.
      - `label` string, required: Name of the group, such as `Speakers`. 1 to 40 characters. Required.
      - `imageShape` 'round' | 'square': How images are cropped. Optional; round when left out.
      - `entries` object[], required: Up to 60 profiles. Required; send an empty array for none.
        - `id` string: Stable id of the entry: lowercase letters, digits and hyphens, up to 64 characters. Optional.
        - `name` string, required: The field value this profile is for, up to 80 characters. It matches the value ignoring case and extra spaces, and a name may appear only once in a group. Required.
        - `imageKey` string: The `imageKey` returned by `POST /dashboards/{dashboardId}/profile-image`, or one read back from the dashboard unchanged. Optional.
        - `description` string: Plain text shown with the profile, up to 600 characters. Optional.
        - `link` string: An `http` or `https` link, up to 2048 characters. Optional.
  - `isDefault` boolean: Make this your default dashboard. Setting it clears the flag on your other dashboards. Optional.

## Response `200`

Success

- object
  - `status` 'success': `success` on every 2xx response.
  - `data` object
    - `dashboardId` string: Id of the dashboard.
    - `revision` integer: The dashboard's revision after the update.
    - `droppedFieldIds` string[]: Field ids removed from `settings` because they are not fields of your company. Present only when some were removed.
    - `message` string: Confirmation text.

## Other responses

- `400`: Validation failed
- `404`: The dashboard does not exist or you cannot edit it
- `409`: The spec revision is stale

---

[API](https://skmtc.dev/speakai/apis/speak-ai-api.md) · [All operations](https://skmtc.dev/speakai/apis/speak-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/speakai/apis/speak-ai-api/revisions/52d777e6d46e?raw)
