# Update tenant settings

Canonical page: https://docs.ovok.com/signals/standalone/api/tenants/update-tenant-settings

{/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */}


# Update tenant settings [#update-tenant-settings]

| Method | Path |
| --- | --- |
| `PATCH` | `/v1/signals/api/tenant` |

<Availability route="PATCH /v1/signals/api/tenant" />

`settings` is merged, so a switch left out is left alone. Takes effect on the next request — except `throttleLimit`, which each replica caches for up to a minute.

`episodicAlerts` gates episode recording and the notification feed. `synchronousMode` makes ingest return before evaluating. `throttleLimit` overrides THROTTLE_LIMIT for this tenant; `0` exempts it.

`informationalCodes`, `historyCategories` and `feedCodes` (lists of strings, none by default): the codes the tenant's triggers consume and never judge (no no-verdict, and the `*` trigger skips them), the reading categories stored and never judged, and the codes the notification feed lists by default (none: every code). A new tenant is given the default pack's lists.

`ruleSet` is deprecated and ignored: readings are judged by the triggers in the rule settings, the tenant's (`orgSettings`) and each patient's own (`/api/patient/{id}/settings`).

`orgSettings` is the tenant's rule settings, which replace `/api/settings/org`: what the triggers judge by, the triggers themselves included. It is merged key by key: a key sent replaces the stored one whole, `null` removes it, and a key left out is kept. Its first write is given the default pack when it sends no `triggers`. Audited as `UPDATE_ORG_SETTINGS`, and a band it changes ends the episodes judged under the old one. A tenant whose only org settings are one project's, with no patient stamped with another project, has them made the tenant's first, so the write reaches the patients they served.

`resolvedAt` (ISO 8601) is when the caller resolved `orgSettings`: it lands only over a write resolved earlier, or stored without one, and is otherwise refused 409 `STALE_SETTINGS` with nothing written. With `ifAbsent=true` each key of `orgSettings` is written only where the stored settings lack it, so a default seeded at enrolment cannot overwrite a concurrent save.

### Through ovok [#through-ovok]

- **Who can call it:** Manager apps, and users whose access policy grants the capabilities.
- **Capabilities, all required:** `signals_config:update`, `signals_silence:update`. Project admins have every capability; client applications get no admin bypass.
- Only `orgSettings`, `resolvedAt` and `settings.episodicAlerts` are written through ovok. Turning `episodicAlerts` off stops Signals recording episodes, which empties episode feeds.
- It can reach any patient of your project without naming one, so it is for callers that reach every patient: project admins, manager or submitter apps, and anyone whose Patient access has no criteria.

## Request [#request]

### Query parameters [#query-parameters]

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `ifAbsent` | boolean | No | Write each key of `orgSettings` only where the stored settings lack it. |

### Body [#body]

Required.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `settings` | object | No | — |
| `settings.episodicAlerts` | boolean | No | Group firing observations into AlertEpisode rows and expose the episode routes. |
| `orgSettings` | object | No | The tenant's rule settings, merged key by key: a key sent replaces the stored one, `null` removes it. |
| `resolvedAt` | string | No | When the caller resolved `orgSettings`: it lands only over a write resolved earlier. |

## Responses [#responses]

| Status | Meaning |
| --- | --- |
| `200` | The tenant as it now stands. |
| `400` | The query carries a raw `#`, or more than 200 parameters. |
| `401` | Your ovok access token, or your client id and secret, are missing or invalid. |
| `403` | ovok refused the call: you lack a capability this route needs, or your session has no project, or the body sets a field other than `orgSettings`, `resolvedAt` or `settings.episodicAlerts`, or your access covers only some patients. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. |
| `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. From Signals: A newer write of `orgSettings` is already stored (`STALE_SETTINGS`); nothing was written. |
| `415` | The body is not JSON. |
| `422` | `settings.episodicAlerts` is not true or false, or `resolvedAt` is more than 5 minutes ahead of now. From Signals: The payload failed validation. |
| `429` | Too many requests. Retry after the seconds in `Retry-After`. |
| `500` | ovok hit an unexpected fault, such as your project having no Signals submitter. |
| `502` | Signals answered with something ovok couldn't use, or refused ovok's own credential. |
| `503` | Signals is unavailable. Retry after the seconds in `Retry-After`. |
| `504` | Signals did not answer in time. |

## Example [#example]

```bash
curl --request PATCH 'https://api.sandbox.ovok.com/v1/signals/api/tenant' \
  --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \
  --header 'Content-Type: application/json' \
  --data @body.json
```
