---
title: "Change one or more preferences"
method: PATCH
path: "/internal/api/settings/preferences"
tags: ["SETTINGS"]
---

# Change one or more preferences

`PATCH /internal/api/settings/preferences`

## Request

- Base URL: `https://api.signalshq.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.signalshq.io/internal/api/settings/preferences`
- Auth: OAuth 2
  - Password
  - Token URL: `/auth/login`

Partial update — only the keys present in `values` are touched. Validation is all-or-nothing: one invalid value rejects the whole request rather than saving half of it. Returns the full refreshed set so the client never has to merge. An unknown key answers 400 `SETTING_UNKNOWN_KEY`; a value outside its definition answers 400 `SETTING_INVALID_VALUE`.

## Request body

- PreferencesUpdateRequest: A partial update: only the keys present are touched. Partial rather than whole-document so two admins editing two sections of the pane cannot clobber each other, and so a client running an older build cannot erase a preference it has never heard of by echoing back the map it was given.
  - `values` object, required: Preference key to new value. Only these keys are changed.

## Response `200`

Successful Response

- PreferencesResponse
  - `groups` PreferenceGroupResponse[], required
    - `id` string, required
    - `label` string, required
    - `description` string, required
    - `display_order` integer, required
  - `settings` PreferenceResponse[], required
    - `key` string, required
    - `type` 'BOOLEAN' | 'ENUM' | 'INTEGER' | 'STRING', required: Control type. The frontend renders purely from this — see the renderer registry in ``settings/panes/preferences/controls``. Adding a member here means the frontend will receive a type it has never seen until it ships. That is expected and safe: the renderer registry skips unknown types rather than crashing the pane, so the backend can deploy first. It is also tested, because "the API added a control we don't know about" is the single most likely cross-repo ordering in this design.
    - `group` string, required
    - `label` string, required
    - `description` string, required
    - `value` unknown, required
    - `default_value` unknown, required
    - `is_overridden` boolean, required
    - `impact` 'PRESENTATION' | 'WORKFLOW', required: What flipping this preference actually changes. Surfaced to the UI so an admin knows whether they are changing paperwork or changing behaviour. See the module docstring for why there is no calculation-altering member and why adding one is a deliberate act.
    - `display_order` integer, required
    - `options` PreferenceOptionResponse[]
      - `value` string, required
      - `label` string, required
      - `description` string, nullable
    - `min_value` integer, nullable
    - `max_value` integer, nullable
    - `max_length` integer, nullable
    - `effect_note` string, nullable
    - `requires_reevaluation` boolean
    - `editable` boolean, required
  - `meta` PreferencesMeta, required
    - `can_manage_preferences` boolean, required
    - `last_updated_at` string, date-time, nullable

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/signalshq/apis/signals-api.md) - [All operations](https://skmtc.dev/signalshq/apis/signals-api/llms.txt) - [OpenAPI document](https://skmtc.dev/signalshq/apis/signals-api/revisions/2c22af3b5576?raw)
