Projects

Update a project setting

  • Sandbox: available
  • Staging: available
  • Production: unknown
PUT
/v1/project/settings/{key}

Turns one on/off setting of your current project on or off, for example PRACTITIONER_INVITATION_ENABLED.

Auth: bearer token of a project admin. The caller must also be a Practitioner, an admin or hold the System Owner access policy. Scope: the caller's project (from the token).

Behaviour

  • :key must be one of the on/off keys returned in settings by GET /v1/project/settings. It may be URL-encoded.
  • Writes the entry into Project.setting[], adding it when missing. Every other entry is kept as it is.
  • The write only succeeds if the project did not change since the server read it; otherwise it answers 409.
  • The response is the full settings envelope after the write, as GET /v1/project/settings returns it.
  • An unknown :key returns 400 UNKNOWN_SETTING with the accepted keys.
  • SIGNALS_SEND_AUTO and SIGNALS_ANNOTATE_OBSERVATIONS also switch their wiring before the setting is saved: Medplum's Subscription for send-auto, Signals' ovok-annotations subscriber for annotations. Nothing is saved if that fails (502 SETTING_WIRING_FAILED). Turning either on for a project without its own Signals tenant answers 409 SETTING_NOT_AVAILABLE; a concurrent change of the same switch answers 409 too. While SIGNALS_ANNOTATE_OBSERVATIONS has no saved value it follows SIGNALS_SEND_AUTO, so switching send-auto also switches annotations' wiring.
  • Read the project again and retry on 409.

Example

curl -X PUT 'https://api.sandbox.ovok.com/v1/project/settings/PRACTITIONER_INVITATION_ENABLED' \  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \  -H 'Content-Type: application/json' \  -d '{ "enabled": true }'

Authorization

bearer
headerAuthorizationBearer <JWT>

Path Parameters

key*string

The setting key.

Request Body

application/json
  1. body
enabled*boolean

Response Body

The full settings envelope after the write.

application/json
  1. response
projectId*string
settings*
overrides*

The saved value of each switch, or null when the project has none saved.

effectiveSettings*

What ovok applies: the saved value, else the default, and off while a needed access policy is missing, or, for SIGNALS_SEND_AUTO and SIGNALS_ANNOTATE_OBSERVATIONS, while the project has no Signals tenant of its own. SIGNALS_ANNOTATE_OBSERVATIONS with no saved value follows SIGNALS_SEND_AUTO.

values*
Example Request
curl -X PUT 'https://api.sandbox.ovok.com/v1/project/settings/string' \  -H 'Content-Type: application/json' \  -d '{  "enabled": true}'
Example Response
{  "projectId": "string",  "settings": {    "CONTENT_ENABLED": true,    "MAILING_ENABLED": true,    "PATIENT_INVITATION_ENABLED": true,    "PATIENT_REGISTRATION_ENABLED": true,    "PATIENT_LOGIN_ENABLED": true,    "PRACTITIONER_INVITATION_ENABLED": true,    "PRACTITIONER_REGISTRATION_ENABLED": true,    "PRACTITIONER_LOGIN_ENABLED": true,    "RELATED_PERSON_INVITATION_ENABLED": true,    "RELATED_PERSON_LOGIN_ENABLED": true,    "CLINICIAN_INVITE_ON_BUSINESS_EMAIL": true,    "SIGNALS_SEND_AUTO": true,    "SIGNALS_ANNOTATE_OBSERVATIONS": true  },  "overrides": {    "CONTENT_ENABLED": true,    "MAILING_ENABLED": true,    "PATIENT_INVITATION_ENABLED": true,    "PATIENT_REGISTRATION_ENABLED": true,    "PATIENT_LOGIN_ENABLED": true,    "PRACTITIONER_INVITATION_ENABLED": true,    "PRACTITIONER_REGISTRATION_ENABLED": true,    "PRACTITIONER_LOGIN_ENABLED": true,    "RELATED_PERSON_INVITATION_ENABLED": true,    "RELATED_PERSON_LOGIN_ENABLED": true,    "CLINICIAN_INVITE_ON_BUSINESS_EMAIL": true,    "SIGNALS_SEND_AUTO": true,    "SIGNALS_ANNOTATE_OBSERVATIONS": true  },  "effectiveSettings": {    "CONTENT_ENABLED": true,    "MAILING_ENABLED": true,    "PATIENT_INVITATION_ENABLED": true,    "PATIENT_REGISTRATION_ENABLED": true,    "PATIENT_LOGIN_ENABLED": true,    "PRACTITIONER_INVITATION_ENABLED": true,    "PRACTITIONER_REGISTRATION_ENABLED": true,    "PRACTITIONER_LOGIN_ENABLED": true,    "RELATED_PERSON_INVITATION_ENABLED": true,    "RELATED_PERSON_LOGIN_ENABLED": true,    "CLINICIAN_INVITE_ON_BUSINESS_EMAIL": true,    "SIGNALS_SEND_AUTO": true,    "SIGNALS_ANNOTATE_OBSERVATIONS": true  },  "values": {    "PATIENT_APP_URL": "string",    "PRACTITIONER_APP_URL": "string",    "PATIENT_SIGNUP_URL": "string",    "CLINICIAN_DASHBOARD_URL": "string",    "DEFAULT_PATIENT_ACCESS_POLICY": "string",    "DEFAULT_PRACTITIONER_ACCESS_POLICY": "string",    "CLINICIAN_INVITE_ACCESS_POLICY": "string"  }}

Get current project settings GET

Returns the settings of your current project: the on/off settings and the text settings such as app URLs and default access policies. **Auth:** bearer token. The caller must be a Practitioner, a project admin, or hold the System Owner access policy. **Scope:** the caller's project (from the token). ## Behaviour - Settings are read from `Project.setting[]` by name. - `settings` always has every on/off key. A key that is not stored, or not stored as a boolean, is `false`. - `values` always has every text key. A key that is not stored, or is blank, is `null`. - `DEFAULT_PATIENT_ACCESS_POLICY` is read from `Project.defaultPatientAccessPolicy`, as `AccessPolicy/<id>`: the policy patient registration and patient invites give a new patient. - Entries of `Project.setting[]` with other names are not returned. ## Saved and effective values `settings` cannot tell a switch turned off from one never saved. Two records, with every on/off key, can: - `overrides`: the saved value, `true` or `false`, or `null` when none is saved (or it is not stored as a boolean). - `effectiveSettings`: what Ovok applies. The saved value, else the default below, and off while the feature lacks what it needs (the column on the right). | Key | Default | Also needs | | --- | --- | --- | | `PATIENT_LOGIN_ENABLED`, `PRACTITIONER_LOGIN_ENABLED`, `RELATED_PERSON_LOGIN_ENABLED` | on | | | `PATIENT_INVITATION_ENABLED` | on | `DEFAULT_PATIENT_ACCESS_POLICY`. | | `PRACTITIONER_INVITATION_ENABLED`, `RELATED_PERSON_INVITATION_ENABLED` | on | | | `PATIENT_REGISTRATION_ENABLED` | on | `DEFAULT_PATIENT_ACCESS_POLICY`, naming a policy that can be read. | | `PRACTITIONER_REGISTRATION_ENABLED` | off | `DEFAULT_PRACTITIONER_ACCESS_POLICY` (or `CLINICIAN_INVITE_ACCESS_POLICY`): an AccessPolicy of this project. | | `CLINICIAN_INVITE_ON_BUSINESS_EMAIL` | off | Effective `PATIENT_REGISTRATION_ENABLED`, and the default practitioner access policy as above. | | `CONTENT_ENABLED`, `MAILING_ENABLED` | off | Markers the Console sets; Ovok does not act on them. | | `SIGNALS_SEND_AUTO` | off | A Signals tenant of the project's own. Observations created through FHIR go to it, and a resident's first one enrols the resident in Signals; ingest readings go there on their own. | | `SIGNALS_ANNOTATE_OBSERVATIONS` | as `SIGNALS_SEND_AUTO` | A Signals tenant of the project's own. Signals' alerts and episodes are written into the project as `DetectedIssue` and `Flag`, and an alert's reading gets its `interpretation`. Project roles need read on `DetectedIssue` and `Flag` to see them. | - App URLs are not folded in: they are in `values`, and a flow that needs a missing one reports it, for example an invite answers 409 `app_url_not_configured`. - Some routes need more. The sharing invites (`/v1/invites`) also need practitioner sharing on, set through the patient-sharing settings. - With `PRACTITIONER_LOGIN_ENABLED` off, a practitioner who is a project admin keeps refreshing an open session, so they can turn it back on. - A default access policy that cannot be read at that moment counts as missing, as it does for the flows themselves. - Every key is read from the first `Project.setting[]` entry of its name. ## App URLs `PATIENT_APP_URL` and `PRACTITIONER_APP_URL` are the app roots that links in emails are built on: `https://app.example.com` gives `https://app.example.com/setpassword/<id>/<secret>`. - Resolution order, per audience: the project's setting, then the parent project's, then the legacy setting (`PATIENT_SIGNUP_URL` or `CLINICIAN_DASHBOARD_URL`, on the project then its parent), then the request `Origin` for flows that allow it, then the deployment default. - For set-password and invite links, only the origin of `PATIENT_SIGNUP_URL` is used: `https://app.example.com/register` gives `https://app.example.com`, and `vitalwise://register` gives `vitalwise://`. Set `PATIENT_APP_URL` if the patient app lives under a path. - The continue-as-patient link (a business-address sign-up turned into a clinician invite) uses `PATIENT_SIGNUP_URL` in full whenever it is set, ahead of `PATIENT_APP_URL`. - An app URL is an https URL on any host (http only on localhost), or an app deep link `scheme://[host][/path]`: `vitalwise://` gives `vitalwise:///setpassword/<id>/<secret>`. A web URL on this API's own host is refused, and a stored one is skipped when an email is sent. - Only the canonical form is stored and used, without a trailing slash. Userinfo, a query, a fragment, an opaque `scheme:path`, and web, script or local schemes used as a deep link (`javascript:`, `data:`, `file:` and others) are refused on write and skipped on send. - An invite with no app URL for its audience answers 409 `app_url_not_configured` and creates nothing. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/project/settings' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ```

Update a project text setting PUT

Sets one text setting of your current project, such as an app URL or a default access policy, or removes it with `null`. **Auth:** bearer token of a project admin. The caller must also be a Practitioner, an admin or hold the System Owner access policy. **Scope:** the caller's project (from the token). ## Behaviour - `:key` must be one of the text keys returned in `values` by `GET /v1/project/settings`. It may be URL-encoded. - `value` is trimmed and checked for the key's kind: - App URL keys (`PATIENT_APP_URL`, `PRACTITIONER_APP_URL`, `PATIENT_SIGNUP_URL`, `CLINICIAN_DASHBOARD_URL`): see App URLs below. The canonical form is stored. - Access policy keys (`DEFAULT_PATIENT_ACCESS_POLICY`, `DEFAULT_PRACTITIONER_ACCESS_POLICY`, `CLINICIAN_INVITE_ACCESS_POLICY`): `AccessPolicy/<id>` of an AccessPolicy in this project. - `null` removes the entry. Every other entry of `Project.setting[]` is kept as it is. - `DEFAULT_PATIENT_ACCESS_POLICY` is written to `Project.defaultPatientAccessPolicy`, not to `Project.setting[]`. Removing it turns patient registration and patient invitations off: see `effectiveSettings` in `GET /v1/project/settings`. - The write only succeeds if the project did not change since the server read it; otherwise it answers 409. - The response is the full settings envelope after the write, as `GET /v1/project/settings` returns it. ## App URLs `PATIENT_APP_URL` and `PRACTITIONER_APP_URL` are the app roots that links in emails are built on: `https://app.example.com` gives `https://app.example.com/setpassword/<id>/<secret>`. - Resolution order, per audience: the project's setting, then the parent project's, then the legacy setting (`PATIENT_SIGNUP_URL` or `CLINICIAN_DASHBOARD_URL`, on the project then its parent), then the request `Origin` for flows that allow it, then the deployment default. - For set-password and invite links, only the origin of `PATIENT_SIGNUP_URL` is used: `https://app.example.com/register` gives `https://app.example.com`, and `vitalwise://register` gives `vitalwise://`. Set `PATIENT_APP_URL` if the patient app lives under a path. - The continue-as-patient link (a business-address sign-up turned into a clinician invite) uses `PATIENT_SIGNUP_URL` in full whenever it is set, ahead of `PATIENT_APP_URL`. - An app URL is an https URL on any host (http only on localhost), or an app deep link `scheme://[host][/path]`: `vitalwise://` gives `vitalwise:///setpassword/<id>/<secret>`. A web URL on this API's own host is refused, and a stored one is skipped when an email is sent. - Only the canonical form is stored and used, without a trailing slash. Userinfo, a query, a fragment, an opaque `scheme:path`, and web, script or local schemes used as a deep link (`javascript:`, `data:`, `file:` and others) are refused on write and skipped on send. - An invite with no app URL for its audience answers 409 `app_url_not_configured` and creates nothing. - An unknown `:key` returns 400 `UNKNOWN_SETTING` with the accepted keys. A web app URL on this API's own host returns 400 `APP_URL_NOT_ALLOWED`. A value that is not valid for the key returns 422 `INVALID_SETTING_VALUE`. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/project/settings/values/PRACTITIONER_APP_URL' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "value": "https://app.example.com" }' ```