# FHIR API Canonical page: https://docs.ovok.com/api/fhir Ovok's FHIR R4 API is your door to the FHIR store behind Ovok. It speaks standard FHIR R4: resources, search, history, batches and transactions. On top of that, Ovok adds a few operations of its own. - **Every request is scoped to your project.** The bearer token names one project, and every read, search and write runs inside it. The token's project decides this, never a `meta.project` in the request body. - **Ovok is the only door.** There is no direct access to the FHIR store. Every FHIR call goes through the Ovok API, which applies project scoping and serves Ovok's own operations. Only FHIR R4 is available. ## Base URL [#base-url] | Purpose | URL | | --- | --- | | FHIR R4 base | `https://api.sandbox.ovok.com/fhir/R4` | | Default version | `https://api.sandbox.ovok.com/fhir`, which serves R4 | | CapabilityStatement | `https://api.sandbox.ovok.com/fhir/R4/metadata` | Resource paths follow the FHIR pattern: `/fhir/R4/Patient`, `/fhir/R4/Patient/[id]`, `/fhir/R4/Observation?patient=Patient/[id]`. Use `Content-Type: application/fhir+json` for request bodies. `GET /fhir/R4/metadata` needs no token. It returns Ovok's own CapabilityStatement: every resource and search parameter the store supports, plus the operations Ovok adds (`$lastn`, `$populate`, `$extract` and `$enable-signals`). Read it when a client must decide at runtime what it may call. The other unauthenticated discovery routes are listed under [Health and discovery](/primitives/health-and-discovery). ## Authentication [#authentication] Send an access token on every call except `metadata`: ```http Authorization: Bearer ``` Patients and practitioners get a token by signing in to a tenant; see [Authentication](/authentication), [Patient sign-in](/authentication/patient-login) and [Practitioner sign-in](/authentication/practitioner-login). A missing or expired token answers `401`. What a call can read or change depends on two things: 1. **The project.** A token is issued for one project. Resources of other projects do not exist for it: a read answers `404` and a search leaves them out. 2. **The member's AccessPolicy.** The policy decides which resource types and interactions the member may use, and can narrow them with criteria, for example to one patient's own records. A call the policy does not grant is refused, and a search returns only what the policy lets the member read. A membership without a policy is not restricted by one; see [AccessPolicy model and membership](/access-policies/policy-model) and [Default policies](/access-policies/defaults). Ovok's Signals operations check named Signals capabilities as well as Patient access; see [Signals route policies](/access-policies/signals). ## Supported interactions [#supported-interactions] All standard FHIR R4 REST interactions are available, subject to your AccessPolicy: | Interaction | Method | Path | | --- | --- | --- | | Read | `GET` | `/fhir/R4/[type]/[id]` | | Vread | `GET` | `/fhir/R4/[type]/[id]/_history/[vid]` | | Search | `GET` | `/fhir/R4/[type]?[parameters]` | | Create | `POST` | `/fhir/R4/[type]` | | Update | `PUT` | `/fhir/R4/[type]/[id]` | | Patch | `PATCH` | `/fhir/R4/[type]/[id]`, with a JSON Patch body (`application/json-patch+json`) | | Delete | `DELETE` | `/fhir/R4/[type]/[id]` | | History | `GET` | `/fhir/R4/[type]/[id]/_history` | | Batch or transaction | `POST` | `/fhir/R4`, with a `Bundle` of type `batch` or `transaction` | A `transaction` Bundle is all or nothing when the project has the [`transaction-bundles`](/settings-and-features/features/transaction-bundles) feature, which new projects have. Without it, a transaction runs as a batch. Each resource's structure, interaction paths and search parameters are in the [FHIR R4 resource reference](/api/fhir/r4), for example [Patient](/api/fhir/r4/patient), [Observation](/api/fhir/r4/observation) and [Device](/api/fhir/r4/device). Data types are in [FHIR Elements](/fhir-elements). New to FHIR? Start with [FHIR Basics](/fhir-basics). ## Ovok's own operations [#ovoks-own-operations] Ovok serves these routes itself, under the same base URL and with the same token: | Operation | Method and path | What it does | | --- | --- | --- | | [Last observations](/primitives/last-observations) | `GET /fhir/R4/Observation/$lastn` | The newest Observations per code, for example the last heart rate and blood pressure of a patient. | | [Populate a Questionnaire](/primitives/populate-questionnaire) | `POST /fhir/R4/Questionnaire/[id]/$populate` | Pre-fills a QuestionnaireResponse for the signed-in patient. The caller must be a patient. | | [Extract observations](/primitives/extract-observations) | `POST /fhir/R4/QuestionnaireResponse/[id]/$extract` | Builds Observations from a saved QuestionnaireResponse. | | [Enable Signals](/primitives/enable-signals-patient) | `POST /fhir/R4/Patient/[id]/$enable-signals` | Enrols an existing Patient in Signals. Idempotent. | | Create a Patient | `POST /fhir/R4/Patient` | A standard create. With `?withSignals=true`, the Patient is also enrolled in Signals, all or nothing. | | Patient's Signals status | `GET /fhir/R4/Patient/[id]/signals` | Whether the Patient is enrolled in Signals, its reading and alert counts, and its newest alerts. Needs `signals_alerts:read`. | ## Errors [#errors] FHIR routes answer errors as a FHIR [`OperationOutcome`](/api/fhir/r4/operation-outcome), not as Ovok Problem Details. Read its `issue` entries: `severity`, `code`, `details` and `expression`. The HTTP status carries the same meaning as on every Ovok route. See [Error responses](/errors#protocol-specific-errors) for how FHIR errors differ from the rest of the API. ## Examples [#examples] Set `OVOK_TOKEN` to an access token and `PATIENT_ID` to a Patient in your project. **Read** a Patient: ```bash curl "https://api.sandbox.ovok.com/fhir/R4/Patient/${PATIENT_ID}" \ --header "Authorization: Bearer ${OVOK_TOKEN}" ``` **Search** a patient's heart rates, newest first: ```bash curl --get 'https://api.sandbox.ovok.com/fhir/R4/Observation' \ --header "Authorization: Bearer ${OVOK_TOKEN}" \ --data-urlencode "patient=Patient/${PATIENT_ID}" \ --data-urlencode 'code=http://loinc.org|8867-4' \ --data-urlencode '_sort=-date' \ --data-urlencode '_count=10' ``` The answer is a `searchset` [Bundle](/api/fhir/r4/bundle). Follow its `link` with `relation: next` for the next page. **Create** a Patient: ```bash curl --request POST 'https://api.sandbox.ovok.com/fhir/R4/Patient' \ --header "Authorization: Bearer ${OVOK_TOKEN}" \ --header 'Content-Type: application/fhir+json' \ --data '{ "resourceType": "Patient", "name": [{ "given": ["Jane"], "family": "Example" }], "birthDate": "1960-04-12" }' ``` The answer is `201 Created` with the stored Patient, including its server-assigned `id`. **`$lastn`**: the last heart rate and respiratory rate of a patient: ```bash curl --get 'https://api.sandbox.ovok.com/fhir/R4/Observation/$lastn' \ --header "Authorization: Bearer ${OVOK_TOKEN}" \ --data-urlencode "patient=Patient/${PATIENT_ID}" \ --data-urlencode 'max=1' \ --data-urlencode 'code=8867-4,9279-1' ``` ## Caveats [#caveats] - **Wearable and device Observations sit together.** A heart rate from a connected wearable uses the same LOINC code as one from a device, so `$lastn` and `Observation` searches return both. Wearable Observations carry a source tag in `meta.tag`, system `https://api.ovok.com/fhir/CodeSystem/wearables-source`. Filter with `_tag` or `_tag:not` to keep them apart; see [Keep wearable and device readings apart](/wearables/sync-and-read-data#keep-wearable-and-device-readings-apart) and [Cloud wearables](/wearables). - **Your project's capabilities decide.** The resource reference documents the FHIR R4 standard. Read `/fhir/R4/metadata` before relying on a less common interaction or search parameter. # Account Canonical page: https://docs.ovok.com/api/fhir/r4/account A financial tool for tracking value accrued for a particular purpose. In the healthcare field, used to track charges for a patient, cost centers, etc. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Account/[id]` | | Vread | `GET` | `/fhir/R4/Account/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Account/[id]` | | Patch | `PATCH` | `/fhir/R4/Account/[id]` | | Delete | `DELETE` | `/fhir/R4/Account/[id]` | | Create | `POST` | `/fhir/R4/Account` | | Search | `GET` | `/fhir/R4/Account` | | History | `GET` | `/fhir/R4/Account/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Account number | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| inactive \| entered-in-error \| on-hold \| unknown | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | E.g. patient, expense, depreciation | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Human-readable label | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..*` | The entity that caused the expenses | | `servicePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | Transaction window | | `coverage` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The party(s) that are responsible for covering the payment of this account, and what order should they be applied to the account | | `owner` | [Reference](/fhir-elements/complex/reference) | `0..1` | Entity managing the Account | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Explanation of purpose/use | | `guarantor` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The parties ultimately responsible for balancing the Account | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..1` | Reference to a parent Account | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `identifier` | token | Account number | | `name` | string | Human-readable label | | `owner` | reference | Entity managing the Account | | `patient` | reference | The entity that caused the expenses | | `period` | date | Transaction window | | `status` | token | active \| inactive \| entered-in-error \| on-hold \| unknown | | `subject` | reference | The entity that caused the expenses | | `type` | token | E.g. patient, expense, depreciation | ## Reference [#reference] Official FHIR R4 spec: [Account](https://hl7.org/fhir/R4/account.html). Maturity: Trial Use 2 (FMM 2). # ActivityDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/activity-definition This resource allows for the definition of some activity to be performed, independent of a particular patient, practitioner, or other performance context. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ActivityDefinition/[id]` | | Vread | `GET` | `/fhir/R4/ActivityDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ActivityDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/ActivityDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/ActivityDefinition/[id]` | | Create | `POST` | `/fhir/R4/ActivityDefinition` | | Search | `GET` | `/fhir/R4/ActivityDefinition` | | History | `GET` | `/fhir/R4/ActivityDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this activity definition, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the activity definition | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the activity definition | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this activity definition (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this activity definition (human friendly) | | `subtitle` | [string](/fhir-elements/primitive/string) | `0..1` | Subordinate title of the activity definition | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `subject[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `0..1` | Type of individual the activity definition is intended for | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the activity definition | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for activity definition (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this activity definition is defined | | `usage` | [string](/fhir-elements/primitive/string) | `0..1` | Describes the clinical usage of the activity definition | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the activity definition was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the activity definition was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the activity definition is expected to be used | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | E.g. Education, Treatment, Assessment, etc. | | `author` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who authored the content | | `editor` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who edited the content | | `reviewer` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who reviewed the content | | `endorser` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who endorsed the content | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | Additional documentation, citations, etc. | | `library` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Logic used by the activity definition | | `kind` | [code](/fhir-elements/primitive/code) | `0..1` | Kind of resource | | `profile` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | What profile the resource needs to conform to | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Detail type of activity | | `intent` | [code](/fhir-elements/primitive/code) | `0..1` | proposal \| plan \| directive \| order \| original-order \| reflex-order \| filler-order \| instance-order \| option | | `priority` | [code](/fhir-elements/primitive/code) | `0..1` | routine \| urgent \| asap \| stat | | `doNotPerform` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | True if the activity should not be performed | | `timing[x]` | [Timing](/fhir-elements/complex/timing), [dateTime](/fhir-elements/primitive/date-time), [Age](/fhir-elements/complex/age), [Period](/fhir-elements/complex/period), [Range](/fhir-elements/complex/range), [Duration](/fhir-elements/complex/duration) | `0..1` | When activity is to occur | | `location` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where it should happen | | `participant` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Who should participate in the action | | `product[x]` | [Reference](/fhir-elements/complex/reference), [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | What's administered/supplied | | `quantity` | [Quantity](/fhir-elements/complex/quantity) | `0..1` | How much is administered/consumed/supplied | | `dosage` | [Dosage](/fhir-elements/complex/dosage) | `0..*` | Detailed dosage instructions | | `bodySite` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | What part of body to perform on | | `specimenRequirement` | [Reference](/fhir-elements/complex/reference) | `0..*` | What specimens are required to perform this action | | `observationRequirement` | [Reference](/fhir-elements/complex/reference) | `0..*` | What observations are required to perform this action | | `observationResultRequirement` | [Reference](/fhir-elements/complex/reference) | `0..*` | What observations must be produced by this action | | `transform` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Transform to apply the template | | `dynamicValue` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Dynamic aspects of the definition | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `composed-of` | reference | What resource is being referenced | | `context` | token | A use context assigned to the activity definition | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the activity definition | | `context-type` | token | A type of use context assigned to the activity definition | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the activity definition | | `context-type-value` | composite | A use context type and value assigned to the activity definition | | `date` | date | The activity definition publication date | | `depends-on` | reference | What resource is being referenced | | `derived-from` | reference | What resource is being referenced | | `description` | string | The description of the activity definition | | `effective` | date | The time during which the activity definition is intended to be in use | | `identifier` | token | External identifier for the activity definition | | `jurisdiction` | token | Intended jurisdiction for the activity definition | | `name` | string | Computationally friendly name of the activity definition | | `predecessor` | reference | What resource is being referenced | | `publisher` | string | Name of the publisher of the activity definition | | `status` | token | The current status of the activity definition | | `successor` | reference | What resource is being referenced | | `title` | string | The human-friendly name of the activity definition | | `topic` | token | Topics associated with the module | | `url` | uri | The uri that identifies the activity definition | | `version` | token | The business version of the activity definition | ## Reference [#reference] Official FHIR R4 spec: [ActivityDefinition](https://hl7.org/fhir/R4/activitydefinition.html). Maturity: Trial Use 2 (FMM 2). # AdverseEvent Canonical page: https://docs.ovok.com/api/fhir/r4/adverse-event Actual or potential/avoided event causing unintended physical injury resulting from or contributed to by medical care, a research study or other healthcare setting factors that requires additional monitoring, treatment, or hospitalization, or that results in death. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/AdverseEvent/[id]` | | Vread | `GET` | `/fhir/R4/AdverseEvent/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/AdverseEvent/[id]` | | Patch | `PATCH` | `/fhir/R4/AdverseEvent/[id]` | | Delete | `DELETE` | `/fhir/R4/AdverseEvent/[id]` | | Create | `POST` | `/fhir/R4/AdverseEvent` | | Search | `GET` | `/fhir/R4/AdverseEvent` | | History | `GET` | `/fhir/R4/AdverseEvent/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Business identifier for the event | | `actuality` | [code](/fhir-elements/primitive/code) | `1..1` | actual \| potential | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | product-problem \| product-quality \| product-use-error \| wrong-dose \| incorrect-prescribing-information \| wrong-technique \| wrong-route-of-administration \| wrong-rate \| wrong-duration \| wrong-time \| expired-drug \| medical-device-use-error \| problem-different-manufacturer \| unsafe-physical-environment | | `event` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Type of the event itself in relation to the subject | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Subject impacted by event | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter created as part of | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the event occurred | | `detected` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the event was detected | | `recordedDate` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the event was recorded | | `resultingCondition` | [Reference](/fhir-elements/complex/reference) | `0..*` | Effect on the subject due to this event | | `location` | [Reference](/fhir-elements/complex/reference) | `0..1` | Location where adverse event occurred | | `seriousness` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Seriousness of the event | | `severity` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | mild \| moderate \| severe | | `outcome` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | resolved \| recovering \| ongoing \| resolvedWithSequelae \| fatal \| unknown | | `recorder` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who recorded the adverse event | | `contributor` | [Reference](/fhir-elements/complex/reference) | `0..*` | Who was involved in the adverse event or the potential adverse event | | `suspectEntity` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The suspected agent causing the adverse event | | `subjectMedicalHistory` | [Reference](/fhir-elements/complex/reference) | `0..*` | AdverseEvent.subjectMedicalHistory | | `referenceDocument` | [Reference](/fhir-elements/complex/reference) | `0..*` | AdverseEvent.referenceDocument | | `study` | [Reference](/fhir-elements/complex/reference) | `0..*` | AdverseEvent.study | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `actuality` | token | actual \| potential | | `category` | token | product-problem \| product-quality \| product-use-error \| wrong-dose \| incorrect-prescribing-information \| wrong-technique \| wrong-route-of-administration \| wrong-rate \| wrong-duration \| wrong-time \| expired-drug \| medical-device-use-error \| problem-different-manufacturer \| unsafe-physical-environment | | `date` | date | When the event occurred | | `event` | token | Type of the event itself in relation to the subject | | `location` | reference | Location where adverse event occurred | | `recorder` | reference | Who recorded the adverse event | | `resultingcondition` | reference | Effect on the subject due to this event | | `seriousness` | token | Seriousness of the event | | `severity` | token | mild \| moderate \| severe | | `study` | reference | AdverseEvent.study | | `subject` | reference | Subject impacted by event | | `substance` | reference | Refers to the specific entity that caused the adverse event | ## Reference [#reference] Official FHIR R4 spec: [AdverseEvent](https://hl7.org/fhir/R4/adverseevent.html). Maturity: Draft (FMM 0). # AllergyIntolerance Canonical page: https://docs.ovok.com/api/fhir/r4/allergy-intolerance Risk of harmful or undesirable, physiological response which is unique to an individual and associated with exposure to a substance. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/AllergyIntolerance/[id]` | | Vread | `GET` | `/fhir/R4/AllergyIntolerance/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/AllergyIntolerance/[id]` | | Patch | `PATCH` | `/fhir/R4/AllergyIntolerance/[id]` | | Delete | `DELETE` | `/fhir/R4/AllergyIntolerance/[id]` | | Create | `POST` | `/fhir/R4/AllergyIntolerance` | | Search | `GET` | `/fhir/R4/AllergyIntolerance` | | History | `GET` | `/fhir/R4/AllergyIntolerance/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External ids for this item | | `clinicalStatus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | active \| inactive \| resolved | | `verificationStatus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | unconfirmed \| confirmed \| refuted \| entered-in-error | | `type` | [code](/fhir-elements/primitive/code) | `0..1` | allergy \| intolerance - Underlying mechanism (if known) | | `category` | [code](/fhir-elements/primitive/code) | `0..*` | food \| medication \| environment \| biologic | | `criticality` | [code](/fhir-elements/primitive/code) | `0..1` | low \| high \| unable-to-assess | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Code that identifies the allergy or intolerance | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who the sensitivity is for | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter when the allergy or intolerance was asserted | | `onset[x]` | [dateTime](/fhir-elements/primitive/date-time), [Age](/fhir-elements/complex/age), [Period](/fhir-elements/complex/period), [Range](/fhir-elements/complex/range), [string](/fhir-elements/primitive/string) | `0..1` | When allergy or intolerance was identified | | `recordedDate` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date first version of the resource instance was recorded | | `recorder` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who recorded the sensitivity | | `asserter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Source of the information about the allergy | | `lastOccurrence` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date(/time) of last known occurrence of a reaction | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Additional text not captured in other fields | | `reaction` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Adverse Reaction Events linked to exposure to substance | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `asserter` | reference | Source of the information about the allergy | | `category` | token | food \| medication \| environment \| biologic | | `clinical-status` | token | active \| inactive \| resolved | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `criticality` | token | low \| high \| unable-to-assess | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `last-date` | date | Date(/time) of last known occurrence of a reaction | | `manifestation` | token | Clinical symptoms/signs associated with the Event | | `onset` | date | Date(/time) when manifestations showed | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `recorder` | reference | Who recorded the sensitivity | | `route` | token | How the subject was exposed to the substance | | `severity` | token | mild \| moderate \| severe (of event as a whole) | | `type` | token | Multiple Resources: AllergyIntolerance: allergy \| intolerance - Underlying mechanism (if known) ; Composition: Kind of composition (LOINC if possible) ; DocumentManifest: Kind of document set ; DocumentReference: Kind of document (LOINC if possible) ; Encounter: Specific type of encounter ; EpisodeOfCare: Type/class - e.g. specialist referral, disease management | | `verification-status` | token | unconfirmed \| confirmed \| refuted \| entered-in-error | ## Reference [#reference] Official FHIR R4 spec: [AllergyIntolerance](https://hl7.org/fhir/R4/allergyintolerance.html). Maturity: Trial Use 3 (FMM 3). # AppointmentResponse Canonical page: https://docs.ovok.com/api/fhir/r4/appointment-response A reply to an appointment request for a patient and/or practitioner(s), such as a confirmation or rejection. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/AppointmentResponse/[id]` | | Vread | `GET` | `/fhir/R4/AppointmentResponse/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/AppointmentResponse/[id]` | | Patch | `PATCH` | `/fhir/R4/AppointmentResponse/[id]` | | Delete | `DELETE` | `/fhir/R4/AppointmentResponse/[id]` | | Create | `POST` | `/fhir/R4/AppointmentResponse` | | Search | `GET` | `/fhir/R4/AppointmentResponse` | | History | `GET` | `/fhir/R4/AppointmentResponse/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Ids for this item | | `appointment` | [Reference](/fhir-elements/complex/reference) | `1..1` | Appointment this response relates to | | `start` | [instant](/fhir-elements/primitive/instant) | `0..1` | Time from appointment, or requested new start time | | `end` | [instant](/fhir-elements/primitive/instant) | `0..1` | Time from appointment, or requested new end time | | `participantType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Role of participant in the appointment | | `actor` | [Reference](/fhir-elements/complex/reference) | `0..1` | Person, Location, HealthcareService, or Device | | `participantStatus` | [code](/fhir-elements/primitive/code) | `1..1` | accepted \| declined \| tentative \| needs-action | | `comment` | [string](/fhir-elements/primitive/string) | `0..1` | Additional comments | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `actor` | reference | The Person, Location/HealthcareService or Device that this appointment response replies for | | `appointment` | reference | The appointment that the response is attached to | | `identifier` | token | An Identifier in this appointment response | | `location` | reference | This Response is for this Location | | `part-status` | token | The participants acceptance status for this appointment | | `patient` | reference | This Response is for this Patient | | `practitioner` | reference | This Response is for this Practitioner | ## Reference [#reference] Official FHIR R4 spec: [AppointmentResponse](https://hl7.org/fhir/R4/appointmentresponse.html). Maturity: Trial Use 3 (FMM 3). # Appointment Canonical page: https://docs.ovok.com/api/fhir/r4/appointment A booking of a healthcare event among patient(s), practitioner(s), related person(s) and/or device(s) for a specific date/time. This may result in one or more Encounter(s). These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Appointment/[id]` | | Vread | `GET` | `/fhir/R4/Appointment/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Appointment/[id]` | | Patch | `PATCH` | `/fhir/R4/Appointment/[id]` | | Delete | `DELETE` | `/fhir/R4/Appointment/[id]` | | Create | `POST` | `/fhir/R4/Appointment` | | Search | `GET` | `/fhir/R4/Appointment` | | History | `GET` | `/fhir/R4/Appointment/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Ids for this item | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | proposed \| pending \| booked \| arrived \| fulfilled \| cancelled \| noshow \| entered-in-error \| checked-in \| waitlist | | `cancelationReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The coded reason for the appointment being cancelled | | `serviceCategory` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | A broad categorization of the service that is to be performed during this appointment | | `serviceType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The specific service that is to be performed during this appointment | | `specialty` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The specialty of a practitioner that would be required to perform the service requested in this appointment | | `appointmentType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The style of appointment or patient that has been booked in the slot (not service type) | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Coded reason this appointment is scheduled | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Reason the appointment is to take place (resource) | | `priority` | [unsignedInt](/fhir-elements/primitive/unsigned-int) | `0..1` | Used to make informed decisions if needing to re-prioritize | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Shown on a subject line in a meeting request, or appointment list | | `supportingInformation` | [Reference](/fhir-elements/complex/reference) | `0..*` | Additional information to support the appointment | | `start` | [instant](/fhir-elements/primitive/instant) | `0..1` | When appointment is to take place | | `end` | [instant](/fhir-elements/primitive/instant) | `0..1` | When appointment is to conclude | | `minutesDuration` | [positiveInt](/fhir-elements/primitive/positive-int) | `0..1` | Can be less than start/end (e.g. estimate) | | `slot` | [Reference](/fhir-elements/complex/reference) | `0..*` | The slots that this appointment is filling | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | The date that this appointment was initially created | | `comment` | [string](/fhir-elements/primitive/string) | `0..1` | Additional comments | | `patientInstruction` | [string](/fhir-elements/primitive/string) | `0..1` | Detailed information and instructions for the patient | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | The service request this appointment is allocated to assess | | `participant` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | Participants involved in appointment | | `requestedPeriod` | [Period](/fhir-elements/complex/period) | `0..*` | Potential date/time interval(s) requested to allocate the appointment within | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `actor` | reference | Any one of the individuals participating in the appointment | | `appointment-type` | token | The style of appointment or patient that has been booked in the slot (not service type) | | `based-on` | reference | The service request this appointment is allocated to assess | | `date` | date | Appointment date/time. | | `identifier` | token | An Identifier of the Appointment | | `location` | reference | This location is listed in the participants of the appointment | | `part-status` | token | The Participation status of the subject, or other participant on the appointment. Can be used to locate participants that have not responded to meeting requests. | | `patient` | reference | One of the individuals of the appointment is this patient | | `practitioner` | reference | One of the individuals of the appointment is this practitioner | | `reason-code` | token | Coded reason this appointment is scheduled | | `reason-reference` | reference | Reason the appointment is to take place (resource) | | `service-category` | token | A broad categorization of the service that is to be performed during this appointment | | `service-type` | token | The specific service that is to be performed during this appointment | | `slot` | reference | The slots that this appointment is filling | | `specialty` | token | The specialty of a practitioner that would be required to perform the service requested in this appointment | | `status` | token | The overall status of the appointment | | `supporting-info` | reference | Additional information to support the appointment | ## Reference [#reference] Official FHIR R4 spec: [Appointment](https://hl7.org/fhir/R4/appointment.html). Maturity: Trial Use 3 (FMM 3). # AuditEvent Canonical page: https://docs.ovok.com/api/fhir/r4/audit-event A record of an event made for purposes of maintaining a security log. Typical uses include detection of intrusion attempts and monitoring for inappropriate usage. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/AuditEvent/[id]` | | Vread | `GET` | `/fhir/R4/AuditEvent/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/AuditEvent/[id]` | | Patch | `PATCH` | `/fhir/R4/AuditEvent/[id]` | | Delete | `DELETE` | `/fhir/R4/AuditEvent/[id]` | | Create | `POST` | `/fhir/R4/AuditEvent` | | Search | `GET` | `/fhir/R4/AuditEvent` | | History | `GET` | `/fhir/R4/AuditEvent/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `type` | [Coding](/fhir-elements/complex/coding) | `1..1` | Type/identifier of event | | `subtype` | [Coding](/fhir-elements/complex/coding) | `0..*` | More specific type/id for the event | | `action` | [code](/fhir-elements/primitive/code) | `0..1` | Type of action performed during the event | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | When the activity occurred | | `recorded` | [instant](/fhir-elements/primitive/instant) | `1..1` | Time when the event was recorded | | `outcome` | [code](/fhir-elements/primitive/code) | `0..1` | Whether the event succeeded or failed | | `outcomeDesc` | [string](/fhir-elements/primitive/string) | `0..1` | Description of the event outcome | | `purposeOfEvent` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The purposeOfUse of the event | | `agent` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | Actor involved in the event | | `source` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..1` | Audit Event Reporter | | `entity` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Data or objects used | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `action` | token | Type of action performed during the event | | `address` | string | Identifier for the network access point of the user device | | `agent` | reference | Identifier of who | | `agent-name` | string | Human friendly name for the agent | | `agent-role` | token | Agent role in the event | | `altid` | token | Alternative User identity | | `date` | date | Time when the event was recorded | | `entity` | reference | Specific instance of resource | | `entity-name` | string | Descriptor for entity | | `entity-role` | token | What role the entity played | | `entity-type` | token | Type of entity involved | | `outcome` | token | Whether the event succeeded or failed | | `patient` | reference | Identifier of who | | `policy` | uri | Policy that authorized event | | `site` | token | Logical source location within the enterprise | | `source` | reference | The identity of source detecting the event | | `subtype` | token | More specific type/id for the event | | `type` | token | Type/identifier of event | ## Reference [#reference] Official FHIR R4 spec: [AuditEvent](https://hl7.org/fhir/R4/auditevent.html). Maturity: Trial Use 3 (FMM 3). # Basic Canonical page: https://docs.ovok.com/api/fhir/r4/basic Basic is used for handling concepts not yet defined in FHIR, narrative-only resources that don't map to an existing resource, and custom resources not appropriate for inclusion in the FHIR specification. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Basic/[id]` | | Vread | `GET` | `/fhir/R4/Basic/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Basic/[id]` | | Patch | `PATCH` | `/fhir/R4/Basic/[id]` | | Delete | `DELETE` | `/fhir/R4/Basic/[id]` | | Create | `POST` | `/fhir/R4/Basic` | | Search | `GET` | `/fhir/R4/Basic` | | History | `GET` | `/fhir/R4/Basic/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Kind of Resource | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Identifies the focus of this resource | | `created` | [date](/fhir-elements/primitive/date) | `0..1` | When created | | `author` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who created | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `author` | reference | Who created | | `code` | token | Kind of Resource | | `created` | date | When created | | `identifier` | token | Business identifier | | `patient` | reference | Identifies the focus of this resource | | `subject` | reference | Identifies the focus of this resource | ## Reference [#reference] Official FHIR R4 spec: [Basic](https://hl7.org/fhir/R4/basic.html). Maturity: Trial Use 1 (FMM 1). # Binary Canonical page: https://docs.ovok.com/api/fhir/r4/binary A resource that represents the data of a single raw artifact as digital content accessible in its native format. A Binary resource can contain any content, whether text, image, pdf, zip archive, etc. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Binary/[id]` | | Vread | `GET` | `/fhir/R4/Binary/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Binary/[id]` | | Patch | `PATCH` | `/fhir/R4/Binary/[id]` | | Delete | `DELETE` | `/fhir/R4/Binary/[id]` | | Create | `POST` | `/fhir/R4/Binary` | | Search | `GET` | `/fhir/R4/Binary` | | History | `GET` | `/fhir/R4/Binary/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `contentType` | [code](/fhir-elements/primitive/code) | `1..1` | MimeType of the binary content | | `securityContext` | [Reference](/fhir-elements/complex/reference) | `0..1` | Identifies another resource to use as proxy when enforcing access control | | `data` | [base64Binary](/fhir-elements/primitive/base64-binary) | `0..1` | The actual content | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [Binary](https://hl7.org/fhir/R4/binary.html). Maturity: Trial Use 5 (FMM 5). # BiologicallyDerivedProduct Canonical page: https://docs.ovok.com/api/fhir/r4/biologically-derived-product A material substance originating from a biological entity intended to be transplanted or infused into another (possibly the same) biological entity. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/BiologicallyDerivedProduct/[id]` | | Vread | `GET` | `/fhir/R4/BiologicallyDerivedProduct/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/BiologicallyDerivedProduct/[id]` | | Patch | `PATCH` | `/fhir/R4/BiologicallyDerivedProduct/[id]` | | Delete | `DELETE` | `/fhir/R4/BiologicallyDerivedProduct/[id]` | | Create | `POST` | `/fhir/R4/BiologicallyDerivedProduct` | | Search | `GET` | `/fhir/R4/BiologicallyDerivedProduct` | | History | `GET` | `/fhir/R4/BiologicallyDerivedProduct/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External ids for this item | | `productCategory` | [code](/fhir-elements/primitive/code) | `0..1` | organ \| tissue \| fluid \| cells \| biologicalAgent | | `productCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | What this biologically derived product is | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | available \| unavailable | | `request` | [Reference](/fhir-elements/complex/reference) | `0..*` | Procedure request | | `quantity` | [integer](/fhir-elements/primitive/integer) | `0..1` | The amount of this biologically derived product | | `parent` | [Reference](/fhir-elements/complex/reference) | `0..*` | BiologicallyDerivedProduct parent | | `collection` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | How this product was collected | | `processing` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Any processing of the product during collection | | `manipulation` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Any manipulation of product post-collection | | `storage` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Product storage | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [BiologicallyDerivedProduct](https://hl7.org/fhir/R4/biologicallyderivedproduct.html). Maturity: Draft (FMM 0). # BodyStructure Canonical page: https://docs.ovok.com/api/fhir/r4/body-structure Record details about an anatomical structure. This resource may be used when a coded concept does not provide the necessary detail needed for the use case. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/BodyStructure/[id]` | | Vread | `GET` | `/fhir/R4/BodyStructure/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/BodyStructure/[id]` | | Patch | `PATCH` | `/fhir/R4/BodyStructure/[id]` | | Delete | `DELETE` | `/fhir/R4/BodyStructure/[id]` | | Create | `POST` | `/fhir/R4/BodyStructure` | | Search | `GET` | `/fhir/R4/BodyStructure` | | History | `GET` | `/fhir/R4/BodyStructure/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Bodystructure identifier | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether this record is in active use | | `morphology` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Kind of Structure | | `location` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Body site | | `locationQualifier` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Body site modifier | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Text description | | `image` | [Attachment](/fhir-elements/complex/attachment) | `0..*` | Attached images | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who this is about | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `identifier` | token | Bodystructure identifier | | `location` | token | Body site | | `morphology` | token | Kind of Structure | | `patient` | reference | Who this is about | ## Reference [#reference] Official FHIR R4 spec: [BodyStructure](https://hl7.org/fhir/R4/bodystructure.html). Maturity: Trial Use 1 (FMM 1). # Bundle Canonical page: https://docs.ovok.com/api/fhir/r4/bundle A container for a collection of resources. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Bundle/[id]` | | Vread | `GET` | `/fhir/R4/Bundle/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Bundle/[id]` | | Patch | `PATCH` | `/fhir/R4/Bundle/[id]` | | Delete | `DELETE` | `/fhir/R4/Bundle/[id]` | | Create | `POST` | `/fhir/R4/Bundle` | | Search | `GET` | `/fhir/R4/Bundle` | | History | `GET` | `/fhir/R4/Bundle/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Persistent identifier for the bundle | | `type` | [code](/fhir-elements/primitive/code) | `1..1` | document \| message \| transaction \| transaction-response \| batch \| batch-response \| history \| searchset \| collection | | `timestamp` | [instant](/fhir-elements/primitive/instant) | `0..1` | When the bundle was assembled | | `total` | [unsignedInt](/fhir-elements/primitive/unsigned-int) | `0..1` | If search, the total number of matches | | `link` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Links related to this Bundle | | `entry` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Entry in the bundle - will have a resource or information | | `signature` | [Signature](/fhir-elements/complex/signature) | `0..1` | Digital Signature | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `composition` | reference | The first resource in the bundle, if the bundle type is "document" - this is a composition, and this parameter provides access to search its contents | | `identifier` | token | Persistent identifier for the bundle | | `message` | reference | The first resource in the bundle, if the bundle type is "message" - this is a message header, and this parameter provides access to search its contents | | `timestamp` | date | When the bundle was assembled | | `type` | token | document \| message \| transaction \| transaction-response \| batch \| batch-response \| history \| searchset \| collection | ## Reference [#reference] Official FHIR R4 spec: [Bundle](https://hl7.org/fhir/R4/bundle.html). Maturity: Trial Use 5 (FMM 5). # CapabilityStatement Canonical page: https://docs.ovok.com/api/fhir/r4/capability-statement A Capability Statement documents a set of capabilities (behaviors) of a FHIR Server for a particular version of FHIR that may be used as a statement of actual server functionality or a statement of required or desired server implementation. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/CapabilityStatement/[id]` | | Vread | `GET` | `/fhir/R4/CapabilityStatement/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/CapabilityStatement/[id]` | | Patch | `PATCH` | `/fhir/R4/CapabilityStatement/[id]` | | Delete | `DELETE` | `/fhir/R4/CapabilityStatement/[id]` | | Create | `POST` | `/fhir/R4/CapabilityStatement` | | Search | `GET` | `/fhir/R4/CapabilityStatement` | | History | `GET` | `/fhir/R4/CapabilityStatement/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this capability statement, represented as a URI (globally unique) | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the capability statement | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this capability statement (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this capability statement (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the capability statement | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for capability statement (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this capability statement is defined | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `kind` | [code](/fhir-elements/primitive/code) | `1..1` | instance \| capability \| requirements | | `instantiates` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Canonical URL of another capability statement this implements | | `imports` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Canonical URL of another capability statement this adds to | | `software` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Software that is covered by this capability statement | | `implementation` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | If this describes a specific instance | | `fhirVersion` | [code](/fhir-elements/primitive/code) | `1..1` | FHIR Version the system supports | | `format` | [code](/fhir-elements/primitive/code) | `1..*` | formats supported (xml \| json \| ttl \| mime type) | | `patchFormat` | [code](/fhir-elements/primitive/code) | `0..*` | Patch formats supported | | `implementationGuide` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Implementation guides supported | | `rest` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | If the endpoint is a RESTful one | | `messaging` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | If messaging is supported | | `document` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Document definition | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `fhirversion` | token | The version of FHIR | | `format` | token | formats supported (xml \| json \| ttl \| mime type) | | `guide` | reference | Implementation guides supported | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `mode` | token | Mode - restful (server/client) or messaging (sender/receiver) | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `resource` | token | Name of a resource mentioned in a capability statement | | `resource-profile` | reference | A profile id invoked in a capability statement | | `security-service` | token | OAuth \| SMART-on-FHIR \| NTLM \| Basic \| Kerberos \| Certificates | | `software` | string | Part of the name of a software application | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `supported-profile` | reference | Profiles for use cases supported | | `title` | string | Multiple Resources: CapabilityStatement: The human-friendly name of the capability statement ; CodeSystem: The human-friendly name of the code system ; ConceptMap: The human-friendly name of the concept map ; ImplementationGuide: The human-friendly name of the implementation guide ; MessageDefinition: The human-friendly name of the message definition ; OperationDefinition: The human-friendly name of the operation definition ; StructureDefinition: The human-friendly name of the structure definition ; StructureMap: The human-friendly name of the structure map ; TerminologyCapabilities: The human-friendly name of the terminology capabilities ; ValueSet: The human-friendly name of the value set | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [CapabilityStatement](https://hl7.org/fhir/R4/capabilitystatement.html). Maturity: Trial Use 5 (FMM 5). # CarePlan Canonical page: https://docs.ovok.com/api/fhir/r4/care-plan Describes the intention of how one or more practitioners intend to deliver care for a particular patient, group or community for a period of time, possibly limited to care for a specific condition or set of conditions. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/CarePlan/[id]` | | Vread | `GET` | `/fhir/R4/CarePlan/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/CarePlan/[id]` | | Patch | `PATCH` | `/fhir/R4/CarePlan/[id]` | | Delete | `DELETE` | `/fhir/R4/CarePlan/[id]` | | Create | `POST` | `/fhir/R4/CarePlan` | | Search | `GET` | `/fhir/R4/CarePlan` | | History | `GET` | `/fhir/R4/CarePlan/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Ids for this plan | | `instantiatesCanonical` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Instantiates FHIR protocol or definition | | `instantiatesUri` | [uri](/fhir-elements/primitive/uri) | `0..*` | Instantiates external protocol or definition | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Fulfills CarePlan | | `replaces` | [Reference](/fhir-elements/complex/reference) | `0..*` | CarePlan replaced by this CarePlan | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Part of referenced CarePlan | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| on-hold \| revoked \| completed \| entered-in-error \| unknown | | `intent` | [code](/fhir-elements/primitive/code) | `1..1` | proposal \| plan \| order \| option | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Type of plan | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Human-friendly name for the care plan | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Summary of nature of plan | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who the care plan is for | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter created as part of | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | Time period plan covers | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date record was first recorded | | `author` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who is the designated responsible party | | `contributor` | [Reference](/fhir-elements/complex/reference) | `0..*` | Who provided the content of the care plan | | `careTeam` | [Reference](/fhir-elements/complex/reference) | `0..*` | Who's involved in plan? | | `addresses` | [Reference](/fhir-elements/complex/reference) | `0..*` | Health issues this plan addresses | | `supportingInfo` | [Reference](/fhir-elements/complex/reference) | `0..*` | Information considered as part of plan | | `goal` | [Reference](/fhir-elements/complex/reference) | `0..*` | Desired outcome of plan | | `activity` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Action to occur as part of plan | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments about the plan | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `activity-code` | token | Detail type of activity | | `activity-date` | date | Specified date occurs within period specified by CarePlan.activity.detail.scheduled[x] | | `activity-reference` | reference | Activity details defined in specific resource | | `based-on` | reference | Fulfills CarePlan | | `care-team` | reference | Who's involved in plan? | | `category` | token | Type of plan | | `condition` | reference | Health issues this plan addresses | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `encounter` | reference | Encounter created as part of | | `goal` | reference | Desired outcome of plan | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `instantiates-canonical` | reference | Instantiates FHIR protocol or definition | | `instantiates-uri` | uri | Instantiates external protocol or definition | | `intent` | token | proposal \| plan \| order \| option | | `part-of` | reference | Part of referenced CarePlan | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `performer` | reference | Matches if the practitioner is listed as a performer in any of the "simple" activities. (For performers of the detailed activities, chain through the activitydetail search parameter.) | | `replaces` | reference | CarePlan replaced by this CarePlan | | `status` | token | draft \| active \| on-hold \| revoked \| completed \| entered-in-error \| unknown | | `subject` | reference | Who the care plan is for | ## Reference [#reference] Official FHIR R4 spec: [CarePlan](https://hl7.org/fhir/R4/careplan.html). Maturity: Trial Use 2 (FMM 2). # CareTeam Canonical page: https://docs.ovok.com/api/fhir/r4/care-team The Care Team includes all the people and organizations who plan to participate in the coordination and delivery of care for a patient. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/CareTeam/[id]` | | Vread | `GET` | `/fhir/R4/CareTeam/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/CareTeam/[id]` | | Patch | `PATCH` | `/fhir/R4/CareTeam/[id]` | | Delete | `DELETE` | `/fhir/R4/CareTeam/[id]` | | Create | `POST` | `/fhir/R4/CareTeam` | | Search | `GET` | `/fhir/R4/CareTeam` | | History | `GET` | `/fhir/R4/CareTeam/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Ids for this team | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | proposed \| active \| suspended \| inactive \| entered-in-error | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Type of team | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the team, such as crisis assessment team | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who care team is for | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter created as part of | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | Time period team covers | | `participant` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Members of the team | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Why the care team exists | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Why the care team exists | | `managingOrganization` | [Reference](/fhir-elements/complex/reference) | `0..*` | Organization responsible for the care team | | `telecom` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | A contact detail for the care team (that applies to all members) | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments made about the CareTeam | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `category` | token | Type of team | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `encounter` | reference | Encounter created as part of | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `participant` | reference | Who is involved | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `status` | token | proposed \| active \| suspended \| inactive \| entered-in-error | | `subject` | reference | Who care team is for | ## Reference [#reference] Official FHIR R4 spec: [CareTeam](https://hl7.org/fhir/R4/careteam.html). Maturity: Trial Use 2 (FMM 2). # CatalogEntry Canonical page: https://docs.ovok.com/api/fhir/r4/catalog-entry Catalog entries are wrappers that contextualize items included in a catalog. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/CatalogEntry/[id]` | | Vread | `GET` | `/fhir/R4/CatalogEntry/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/CatalogEntry/[id]` | | Patch | `PATCH` | `/fhir/R4/CatalogEntry/[id]` | | Delete | `DELETE` | `/fhir/R4/CatalogEntry/[id]` | | Create | `POST` | `/fhir/R4/CatalogEntry` | | Search | `GET` | `/fhir/R4/CatalogEntry` | | History | `GET` | `/fhir/R4/CatalogEntry/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Unique identifier of the catalog item | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The type of item - medication, device, service, protocol or other | | `orderable` | [boolean](/fhir-elements/primitive/boolean) | `1..1` | Whether the entry represents an orderable item | | `referencedItem` | [Reference](/fhir-elements/complex/reference) | `1..1` | The item that is being defined | | `additionalIdentifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Any additional identifier(s) for the catalog item, in the same granularity or concept | | `classification` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Classification (category or class) of the item entry | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | draft \| active \| retired \| unknown | | `validityPeriod` | [Period](/fhir-elements/complex/period) | `0..1` | The time period in which this catalog entry is expected to be active | | `validTo` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | The date until which this catalog entry is expected to be active | | `lastUpdated` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When was this catalog last updated | | `additionalCharacteristic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Additional characteristics of the catalog entry | | `additionalClassification` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Additional classification of the catalog entry | | `relatedEntry` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | An item that this catalog entry is related to | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [CatalogEntry](https://hl7.org/fhir/R4/catalogentry.html). Maturity: Draft (FMM 0). # ChargeItemDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/charge-item-definition The ChargeItemDefinition resource provides the properties that apply to the (billing) codes necessary to calculate costs and prices. The properties may differ largely depending on type and realm, therefore this resource gives only a rough structure and requires profiling for each type of billing code system. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ChargeItemDefinition/[id]` | | Vread | `GET` | `/fhir/R4/ChargeItemDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ChargeItemDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/ChargeItemDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/ChargeItemDefinition/[id]` | | Create | `POST` | `/fhir/R4/ChargeItemDefinition` | | Search | `GET` | `/fhir/R4/ChargeItemDefinition` | | History | `GET` | `/fhir/R4/ChargeItemDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `1..1` | Canonical identifier for this charge item definition, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the charge item definition | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the charge item definition | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this charge item definition (human friendly) | | `derivedFromUri` | [uri](/fhir-elements/primitive/uri) | `0..*` | Underlying externally-defined charge item definition | | `partOf` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | A larger definition of which this particular definition is a component or step | | `replaces` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Completed or terminated request(s) whose function is taken by this new request | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the charge item definition | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for charge item definition (if applicable) | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the charge item definition was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the charge item definition was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the charge item definition is expected to be used | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Billing codes or product types this definition applies to | | `instance` | [Reference](/fhir-elements/complex/reference) | `0..*` | Instances this definition applies to | | `applicability` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Whether or not the billing code is applicable | | `propertyGroup` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Group of properties which are applicable under the same conditions | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `context` | token | A use context assigned to the charge item definition | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the charge item definition | | `context-type` | token | A type of use context assigned to the charge item definition | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the charge item definition | | `context-type-value` | composite | A use context type and value assigned to the charge item definition | | `date` | date | The charge item definition publication date | | `description` | string | The description of the charge item definition | | `effective` | date | The time during which the charge item definition is intended to be in use | | `identifier` | token | External identifier for the charge item definition | | `jurisdiction` | token | Intended jurisdiction for the charge item definition | | `publisher` | string | Name of the publisher of the charge item definition | | `status` | token | The current status of the charge item definition | | `title` | string | The human-friendly name of the charge item definition | | `url` | uri | The uri that identifies the charge item definition | | `version` | token | The business version of the charge item definition | ## Reference [#reference] Official FHIR R4 spec: [ChargeItemDefinition](https://hl7.org/fhir/R4/chargeitemdefinition.html). Maturity: Draft (FMM 0). # ChargeItem Canonical page: https://docs.ovok.com/api/fhir/r4/charge-item The resource ChargeItem describes the provision of healthcare provider products for a certain patient, therefore referring not only to the product, but containing in addition details of the provision, like date, time, amounts and participating organizations and persons. Main Usage of the ChargeItem is to enable the billing process and internal cost allocation. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ChargeItem/[id]` | | Vread | `GET` | `/fhir/R4/ChargeItem/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ChargeItem/[id]` | | Patch | `PATCH` | `/fhir/R4/ChargeItem/[id]` | | Delete | `DELETE` | `/fhir/R4/ChargeItem/[id]` | | Create | `POST` | `/fhir/R4/ChargeItem` | | Search | `GET` | `/fhir/R4/ChargeItem` | | History | `GET` | `/fhir/R4/ChargeItem/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for item | | `definitionUri` | [uri](/fhir-elements/primitive/uri) | `0..*` | Defining information about the code of this charge item | | `definitionCanonical` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Resource defining the code of this ChargeItem | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | planned \| billable \| not-billable \| aborted \| billed \| entered-in-error \| unknown | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Part of referenced ChargeItem | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | A code that identifies the charge, like a billing code | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Individual service was done for/to | | `context` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter / Episode associated with event | | `occurrence[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period), [Timing](/fhir-elements/complex/timing) | `0..1` | When the charged service was applied | | `performer` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Who performed charged service | | `performingOrganization` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization providing the charged service | | `requestingOrganization` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization requesting the charged service | | `costCenter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization that has ownership of the (potential, future) revenue | | `quantity` | [Quantity](/fhir-elements/complex/quantity) | `0..1` | Quantity of which the charge item has been serviced | | `bodysite` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Anatomical location, if relevant | | `factorOverride` | [decimal](/fhir-elements/primitive/decimal) | `0..1` | Factor overriding the associated rules | | `priceOverride` | [Money](/fhir-elements/complex/money) | `0..1` | Price overriding the associated rules | | `overrideReason` | [string](/fhir-elements/primitive/string) | `0..1` | Reason for overriding the list price/factor | | `enterer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Individual who was entering | | `enteredDate` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date the charge item was entered | | `reason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Why was the charged service rendered? | | `service` | [Reference](/fhir-elements/complex/reference) | `0..*` | Which rendered service is being charged? | | `product[x]` | [Reference](/fhir-elements/complex/reference), [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Product charged | | `account` | [Reference](/fhir-elements/complex/reference) | `0..*` | Account to place this charge | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments made about the ChargeItem | | `supportingInformation` | [Reference](/fhir-elements/complex/reference) | `0..*` | Further information supporting this charge | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `account` | reference | Account to place this charge | | `code` | token | A code that identifies the charge, like a billing code | | `context` | reference | Encounter / Episode associated with event | | `entered-date` | date | Date the charge item was entered | | `enterer` | reference | Individual who was entering | | `factor-override` | number | Factor overriding the associated rules | | `identifier` | token | Business Identifier for item | | `occurrence` | date | When the charged service was applied | | `patient` | reference | Individual service was done for/to | | `performer-actor` | reference | Individual who was performing | | `performer-function` | token | What type of performance was done | | `performing-organization` | reference | Organization providing the charged service | | `price-override` | quantity | Price overriding the associated rules | | `quantity` | quantity | Quantity of which the charge item has been serviced | | `requesting-organization` | reference | Organization requesting the charged service | | `service` | reference | Which rendered service is being charged? | | `subject` | reference | Individual service was done for/to | ## Reference [#reference] Official FHIR R4 spec: [ChargeItem](https://hl7.org/fhir/R4/chargeitem.html). Maturity: Draft (FMM 0). # ClaimResponse Canonical page: https://docs.ovok.com/api/fhir/r4/claim-response This resource provides the adjudication details from the processing of a Claim resource. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ClaimResponse/[id]` | | Vread | `GET` | `/fhir/R4/ClaimResponse/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ClaimResponse/[id]` | | Patch | `PATCH` | `/fhir/R4/ClaimResponse/[id]` | | Delete | `DELETE` | `/fhir/R4/ClaimResponse/[id]` | | Create | `POST` | `/fhir/R4/ClaimResponse` | | Search | `GET` | `/fhir/R4/ClaimResponse` | | History | `GET` | `/fhir/R4/ClaimResponse/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for a claim response | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| cancelled \| draft \| entered-in-error | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | More granular claim type | | `subType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | More granular claim type | | `use` | [code](/fhir-elements/primitive/code) | `1..1` | claim \| preauthorization \| predetermination | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | The recipient of the products and services | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Response creation date | | `insurer` | [Reference](/fhir-elements/complex/reference) | `1..1` | Party responsible for reimbursement | | `requestor` | [Reference](/fhir-elements/complex/reference) | `0..1` | Party responsible for the claim | | `request` | [Reference](/fhir-elements/complex/reference) | `0..1` | Id of resource triggering adjudication | | `outcome` | [code](/fhir-elements/primitive/code) | `1..1` | queued \| complete \| error \| partial | | `disposition` | [string](/fhir-elements/primitive/string) | `0..1` | Disposition Message | | `preAuthRef` | [string](/fhir-elements/primitive/string) | `0..1` | Preauthorization reference | | `preAuthPeriod` | [Period](/fhir-elements/complex/period) | `0..1` | Preauthorization reference effective period | | `payeeType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Party to be paid any benefits payable | | `item` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Adjudication for claim line items | | `addItem` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Insurer added line items | | `adjudication` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Header-level adjudication | | `total` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Adjudication totals | | `payment` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Payment Details | | `fundsReserve` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Funds reserved status | | `formCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Printed form identifier | | `form` | [Attachment](/fhir-elements/complex/attachment) | `0..1` | Printed reference or actual form | | `processNote` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Note concerning adjudication | | `communicationRequest` | [Reference](/fhir-elements/complex/reference) | `0..*` | Request for additional information | | `insurance` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Patient insurance information | | `error` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Processing errors | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `created` | date | The creation date | | `disposition` | string | The contents of the disposition message | | `identifier` | token | The identity of the ClaimResponse | | `insurer` | reference | The organization which generated this resource | | `outcome` | token | The processing outcome | | `patient` | reference | The subject of care | | `payment-date` | date | The expected payment date | | `request` | reference | The claim reference | | `requestor` | reference | The Provider of the claim | | `status` | token | The status of the ClaimResponse | | `use` | token | The type of claim | ## Reference [#reference] Official FHIR R4 spec: [ClaimResponse](https://hl7.org/fhir/R4/claimresponse.html). Maturity: Trial Use 2 (FMM 2). # Claim Canonical page: https://docs.ovok.com/api/fhir/r4/claim A provider issued list of professional services and products which have been provided, or are to be provided, to a patient which is sent to an insurer for reimbursement. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Claim/[id]` | | Vread | `GET` | `/fhir/R4/Claim/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Claim/[id]` | | Patch | `PATCH` | `/fhir/R4/Claim/[id]` | | Delete | `DELETE` | `/fhir/R4/Claim/[id]` | | Create | `POST` | `/fhir/R4/Claim` | | Search | `GET` | `/fhir/R4/Claim` | | History | `GET` | `/fhir/R4/Claim/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for claim | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| cancelled \| draft \| entered-in-error | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Category or discipline | | `subType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | More granular claim type | | `use` | [code](/fhir-elements/primitive/code) | `1..1` | claim \| preauthorization \| predetermination | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | The recipient of the products and services | | `billablePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | Relevant time frame for the claim | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Resource creation date | | `enterer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Author of the claim | | `insurer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Target | | `provider` | [Reference](/fhir-elements/complex/reference) | `1..1` | Party responsible for the claim | | `priority` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Desired processing ugency | | `fundsReserve` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | For whom to reserve funds | | `related` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Prior or corollary claims | | `prescription` | [Reference](/fhir-elements/complex/reference) | `0..1` | Prescription authorizing services and products | | `originalPrescription` | [Reference](/fhir-elements/complex/reference) | `0..1` | Original prescription if superseded by fulfiller | | `payee` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Recipient of benefits payable | | `referral` | [Reference](/fhir-elements/complex/reference) | `0..1` | Treatment referral | | `facility` | [Reference](/fhir-elements/complex/reference) | `0..1` | Servicing facility | | `careTeam` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Members of the care team | | `supportingInfo` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Supporting information | | `diagnosis` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Pertinent diagnosis information | | `procedure` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Clinical procedures performed | | `insurance` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | Patient insurance information | | `accident` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Details of the event | | `item` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Product or service provided | | `total` | [Money](/fhir-elements/complex/money) | `0..1` | Total claim cost | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `care-team` | reference | Member of the CareTeam | | `created` | date | The creation date for the Claim | | `detail-udi` | reference | UDI associated with a line item, detail product or service | | `encounter` | reference | Encounters associated with a billed line item | | `enterer` | reference | The party responsible for the entry of the Claim | | `facility` | reference | Facility where the products or services have been or will be provided | | `identifier` | token | The primary identifier of the financial resource | | `insurer` | reference | The target payor/insurer for the Claim | | `item-udi` | reference | UDI associated with a line item product or service | | `patient` | reference | Patient receiving the products or services | | `payee` | reference | The party receiving any payment for the Claim | | `priority` | token | Processing priority requested | | `procedure-udi` | reference | UDI associated with a procedure | | `provider` | reference | Provider responsible for the Claim | | `status` | token | The status of the Claim instance. | | `subdetail-udi` | reference | UDI associated with a line item, detail, subdetail product or service | | `use` | token | The kind of financial resource | ## Reference [#reference] Official FHIR R4 spec: [Claim](https://hl7.org/fhir/R4/claim.html). Maturity: Trial Use 2 (FMM 2). # ClinicalImpression Canonical page: https://docs.ovok.com/api/fhir/r4/clinical-impression A record of a clinical assessment performed to determine what problem(s) may affect the patient and before planning the treatments or management strategies that are best to manage a patient's condition. Assessments are often 1:1 with a clinical consultation / encounter, but this varies greatly depending on the clinical workflow. This resource is called "ClinicalImpression" rather than "ClinicalAssessment" to avoid confusion with the recording of assessment tools such as Apgar score. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ClinicalImpression/[id]` | | Vread | `GET` | `/fhir/R4/ClinicalImpression/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ClinicalImpression/[id]` | | Patch | `PATCH` | `/fhir/R4/ClinicalImpression/[id]` | | Delete | `DELETE` | `/fhir/R4/ClinicalImpression/[id]` | | Create | `POST` | `/fhir/R4/ClinicalImpression` | | Search | `GET` | `/fhir/R4/ClinicalImpression` | | History | `GET` | `/fhir/R4/ClinicalImpression/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | in-progress \| completed \| entered-in-error | | `statusReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Reason for current status | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Kind of assessment performed | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Why/how the assessment was performed | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Patient or group assessed | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter created as part of | | `effective[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period) | `0..1` | Time of assessment | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the assessment was documented | | `assessor` | [Reference](/fhir-elements/complex/reference) | `0..1` | The clinician performing the assessment | | `previous` | [Reference](/fhir-elements/complex/reference) | `0..1` | Reference to last assessment | | `problem` | [Reference](/fhir-elements/complex/reference) | `0..*` | Relevant impressions of patient state | | `investigation` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | One or more sets of investigations (signs, symptoms, etc.) | | `protocol` | [uri](/fhir-elements/primitive/uri) | `0..*` | Clinical Protocol followed | | `summary` | [string](/fhir-elements/primitive/string) | `0..1` | Summary of the assessment | | `finding` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Possible or likely findings and diagnoses | | `prognosisCodeableConcept` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Estimate of likely outcome | | `prognosisReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | RiskAssessment expressing likely outcome | | `supportingInfo` | [Reference](/fhir-elements/complex/reference) | `0..*` | Information supporting the clinical impression | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments made about the ClinicalImpression | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `assessor` | reference | The clinician performing the assessment | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `encounter` | reference | Encounter created as part of | | `finding-code` | token | What was found | | `finding-ref` | reference | What was found | | `identifier` | token | Business identifier | | `investigation` | reference | Record of a specific investigation | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `previous` | reference | Reference to last assessment | | `problem` | reference | Relevant impressions of patient state | | `status` | token | in-progress \| completed \| entered-in-error | | `subject` | reference | Patient or group assessed | | `supporting-info` | reference | Information supporting the clinical impression | ## Reference [#reference] Official FHIR R4 spec: [ClinicalImpression](https://hl7.org/fhir/R4/clinicalimpression.html). Maturity: Draft (FMM 0). # CodeSystem Canonical page: https://docs.ovok.com/api/fhir/r4/code-system The CodeSystem resource is used to declare the existence of and describe a code system or code system supplement and its key properties, and optionally define a part or all of its content. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/CodeSystem/[id]` | | Vread | `GET` | `/fhir/R4/CodeSystem/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/CodeSystem/[id]` | | Patch | `PATCH` | `/fhir/R4/CodeSystem/[id]` | | Delete | `DELETE` | `/fhir/R4/CodeSystem/[id]` | | Create | `POST` | `/fhir/R4/CodeSystem` | | Search | `GET` | `/fhir/R4/CodeSystem` | | History | `GET` | `/fhir/R4/CodeSystem/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this code system, represented as a URI (globally unique) (Coding.system) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the code system (business identifier) | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the code system (Coding.version) | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this code system (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this code system (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the code system | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for code system (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this code system is defined | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `caseSensitive` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | If code comparison is case sensitive | | `valueSet` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Canonical reference to the value set with entire code system | | `hierarchyMeaning` | [code](/fhir-elements/primitive/code) | `0..1` | grouped-by \| is-a \| part-of \| classified-with | | `compositional` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | If code system defines a compositional grammar | | `versionNeeded` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | If definitions are not stable | | `content` | [code](/fhir-elements/primitive/code) | `1..1` | not-present \| example \| fragment \| complete \| supplement | | `supplements` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Canonical URL of Code System this adds designations and properties to | | `count` | [unsignedInt](/fhir-elements/primitive/unsigned-int) | `0..1` | Total concepts in the code system | | `filter` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Filter that can be used in a value set | | `property` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Additional information supplied about each concept | | `concept` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Concepts in the code system | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `code` | token | A code defined in the code system | | `content-mode` | token | not-present \| example \| fragment \| complete \| supplement | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `identifier` | token | Multiple Resources: CodeSystem: External identifier for the code system ; ConceptMap: External identifier for the concept map ; MessageDefinition: External identifier for the message definition ; StructureDefinition: External identifier for the structure definition ; StructureMap: External identifier for the structure map ; ValueSet: External identifier for the value set | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `language` | token | A language in which a designation is provided | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `supplements` | reference | Find code system supplements for the referenced code system | | `system` | uri | The system for any codes defined by this code system (same as 'url') | | `title` | string | Multiple Resources: CapabilityStatement: The human-friendly name of the capability statement ; CodeSystem: The human-friendly name of the code system ; ConceptMap: The human-friendly name of the concept map ; ImplementationGuide: The human-friendly name of the implementation guide ; MessageDefinition: The human-friendly name of the message definition ; OperationDefinition: The human-friendly name of the operation definition ; StructureDefinition: The human-friendly name of the structure definition ; StructureMap: The human-friendly name of the structure map ; TerminologyCapabilities: The human-friendly name of the terminology capabilities ; ValueSet: The human-friendly name of the value set | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [CodeSystem](https://hl7.org/fhir/R4/codesystem.html). Maturity: Trial Use 5 (FMM 5). # CommunicationRequest Canonical page: https://docs.ovok.com/api/fhir/r4/communication-request A request to convey information; e.g. the CDS system proposes that an alert be sent to a responsible provider, the CDS system proposes that the public health agency be notified about a reportable condition. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/CommunicationRequest/[id]` | | Vread | `GET` | `/fhir/R4/CommunicationRequest/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/CommunicationRequest/[id]` | | Patch | `PATCH` | `/fhir/R4/CommunicationRequest/[id]` | | Delete | `DELETE` | `/fhir/R4/CommunicationRequest/[id]` | | Create | `POST` | `/fhir/R4/CommunicationRequest` | | Search | `GET` | `/fhir/R4/CommunicationRequest` | | History | `GET` | `/fhir/R4/CommunicationRequest/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Unique identifier | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Fulfills plan or proposal | | `replaces` | [Reference](/fhir-elements/complex/reference) | `0..*` | Request(s) replaced by this request | | `groupIdentifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Composite request this is part of | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| on-hold \| revoked \| completed \| entered-in-error \| unknown | | `statusReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Reason for current status | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Message category | | `priority` | [code](/fhir-elements/primitive/code) | `0..1` | routine \| urgent \| asap \| stat | | `doNotPerform` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | True if request is prohibiting action | | `medium` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | A channel of communication | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Focus of message | | `about` | [Reference](/fhir-elements/complex/reference) | `0..*` | Resources that pertain to this communication request | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter created as part of | | `payload` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Message payload | | `occurrence[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period) | `0..1` | When scheduled | | `authoredOn` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When request transitioned to being actionable | | `requester` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who/what is requesting service | | `recipient` | [Reference](/fhir-elements/complex/reference) | `0..*` | Message recipient | | `sender` | [Reference](/fhir-elements/complex/reference) | `0..1` | Message sender | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Why is communication needed? | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Why is communication needed? | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments made about communication request | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `authored` | date | When request transitioned to being actionable | | `based-on` | reference | Fulfills plan or proposal | | `category` | token | Message category | | `encounter` | reference | Encounter created as part of | | `group-identifier` | token | Composite request this is part of | | `identifier` | token | Unique identifier | | `medium` | token | A channel of communication | | `occurrence` | date | When scheduled | | `patient` | reference | Focus of message | | `priority` | token | routine \| urgent \| asap \| stat | | `recipient` | reference | Message recipient | | `replaces` | reference | Request(s) replaced by this request | | `requester` | reference | Who/what is requesting service | | `sender` | reference | Message sender | | `status` | token | draft \| active \| on-hold \| revoked \| completed \| entered-in-error \| unknown | | `subject` | reference | Focus of message | ## Reference [#reference] Official FHIR R4 spec: [CommunicationRequest](https://hl7.org/fhir/R4/communicationrequest.html). Maturity: Trial Use 2 (FMM 2). # Communication Canonical page: https://docs.ovok.com/api/fhir/r4/communication An occurrence of information being transmitted; e.g. an alert that was sent to a responsible provider, a public health agency that was notified about a reportable condition. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Communication/[id]` | | Vread | `GET` | `/fhir/R4/Communication/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Communication/[id]` | | Patch | `PATCH` | `/fhir/R4/Communication/[id]` | | Delete | `DELETE` | `/fhir/R4/Communication/[id]` | | Create | `POST` | `/fhir/R4/Communication` | | Search | `GET` | `/fhir/R4/Communication` | | History | `GET` | `/fhir/R4/Communication/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Unique identifier | | `instantiatesCanonical` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Instantiates FHIR protocol or definition | | `instantiatesUri` | [uri](/fhir-elements/primitive/uri) | `0..*` | Instantiates external protocol or definition | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Request fulfilled by this communication | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Part of this action | | `inResponseTo` | [Reference](/fhir-elements/complex/reference) | `0..*` | Reply to | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | preparation \| in-progress \| not-done \| on-hold \| stopped \| completed \| entered-in-error \| unknown | | `statusReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Reason for current status | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Message category | | `priority` | [code](/fhir-elements/primitive/code) | `0..1` | routine \| urgent \| asap \| stat | | `medium` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | A channel of communication | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Focus of message | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Description of the purpose/content | | `about` | [Reference](/fhir-elements/complex/reference) | `0..*` | Resources that pertain to this communication | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter created as part of | | `sent` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When sent | | `received` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When received | | `recipient` | [Reference](/fhir-elements/complex/reference) | `0..*` | Message recipient | | `sender` | [Reference](/fhir-elements/complex/reference) | `0..1` | Message sender | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Indication for message | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Why was communication done? | | `payload` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Message payload | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments made about the communication | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `based-on` | reference | Request fulfilled by this communication | | `category` | token | Message category | | `encounter` | reference | Encounter created as part of | | `identifier` | token | Unique identifier | | `instantiates-canonical` | reference | Instantiates FHIR protocol or definition | | `instantiates-uri` | uri | Instantiates external protocol or definition | | `medium` | token | A channel of communication | | `part-of` | reference | Part of this action | | `patient` | reference | Focus of message | | `received` | date | When received | | `recipient` | reference | Message recipient | | `sender` | reference | Message sender | | `sent` | date | When sent | | `status` | token | preparation \| in-progress \| not-done \| on-hold \| stopped \| completed \| entered-in-error \| unknown | | `subject` | reference | Focus of message | ## Reference [#reference] Official FHIR R4 spec: [Communication](https://hl7.org/fhir/R4/communication.html). Maturity: Trial Use 2 (FMM 2). # CompartmentDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/compartment-definition A compartment definition that defines how resources are accessed on a server. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/CompartmentDefinition/[id]` | | Vread | `GET` | `/fhir/R4/CompartmentDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/CompartmentDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/CompartmentDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/CompartmentDefinition/[id]` | | Create | `POST` | `/fhir/R4/CompartmentDefinition` | | Search | `GET` | `/fhir/R4/CompartmentDefinition` | | History | `GET` | `/fhir/R4/CompartmentDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `1..1` | Canonical identifier for this compartment definition, represented as a URI (globally unique) | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the compartment definition | | `name` | [string](/fhir-elements/primitive/string) | `1..1` | Name for this compartment definition (computer friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the compartment definition | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this compartment definition is defined | | `code` | [code](/fhir-elements/primitive/code) | `1..1` | Patient \| Encounter \| RelatedPerson \| Practitioner \| Device | | `search` | [boolean](/fhir-elements/primitive/boolean) | `1..1` | Whether the search syntax is supported | | `resource` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | How a resource is related to the compartment | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `code` | token | Patient \| Encounter \| RelatedPerson \| Practitioner \| Device | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `resource` | token | Name of resource type | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [CompartmentDefinition](https://hl7.org/fhir/R4/compartmentdefinition.html). Maturity: Trial Use 1 (FMM 1). # Composition Canonical page: https://docs.ovok.com/api/fhir/r4/composition A set of healthcare-related information that is assembled together into a single logical package that provides a single coherent statement of meaning, establishes its own context and that has clinical attestation with regard to who is making the statement. A Composition defines the structure and narrative content necessary for a document. However, a Composition alone does not constitute a document. Rather, the Composition must be the first entry in a Bundle where Bundle.type=document, and any other resources referenced from Composition must be included as subsequent entries in the Bundle (for example Patient, Practitioner, Encounter, etc.). These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Composition/[id]` | | Vread | `GET` | `/fhir/R4/Composition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Composition/[id]` | | Patch | `PATCH` | `/fhir/R4/Composition/[id]` | | Delete | `DELETE` | `/fhir/R4/Composition/[id]` | | Create | `POST` | `/fhir/R4/Composition` | | Search | `GET` | `/fhir/R4/Composition` | | History | `GET` | `/fhir/R4/Composition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Version-independent identifier for the Composition | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | preliminary \| final \| amended \| entered-in-error | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Kind of composition (LOINC if possible) | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Categorization of Composition | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who and/or what the composition is about | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Context of the Composition | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Composition editing time | | `author` | [Reference](/fhir-elements/complex/reference) | `1..*` | Who and/or what authored the composition | | `title` | [string](/fhir-elements/primitive/string) | `1..1` | Human Readable name/title | | `confidentiality` | [code](/fhir-elements/primitive/code) | `0..1` | As defined by affinity domain | | `attester` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Attests to accuracy of composition | | `custodian` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization which maintains the composition | | `relatesTo` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Relationships to other compositions/documents | | `event` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The clinical service(s) being documented | | `section` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Composition is broken into sections | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `attester` | reference | Who attested the composition | | `author` | reference | Who and/or what authored the composition | | `category` | token | Categorization of Composition | | `confidentiality` | token | As defined by affinity domain | | `context` | token | Code(s) that apply to the event being documented | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `entry` | reference | A reference to data that supports this section | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `period` | date | The period covered by the documentation | | `related-id` | token | Target of the relationship | | `related-ref` | reference | Target of the relationship | | `section` | token | Classification of section (recommended) | | `status` | token | preliminary \| final \| amended \| entered-in-error | | `subject` | reference | Who and/or what the composition is about | | `title` | string | Human Readable name/title | | `type` | token | Multiple Resources: AllergyIntolerance: allergy \| intolerance - Underlying mechanism (if known) ; Composition: Kind of composition (LOINC if possible) ; DocumentManifest: Kind of document set ; DocumentReference: Kind of document (LOINC if possible) ; Encounter: Specific type of encounter ; EpisodeOfCare: Type/class - e.g. specialist referral, disease management | ## Reference [#reference] Official FHIR R4 spec: [Composition](https://hl7.org/fhir/R4/composition.html). Maturity: Trial Use 2 (FMM 2). # ConceptMap Canonical page: https://docs.ovok.com/api/fhir/r4/concept-map A statement of relationships from one set of concepts to one or more other concepts - either concepts in code systems, or data element/data element concepts, or classes in class models. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ConceptMap/[id]` | | Vread | `GET` | `/fhir/R4/ConceptMap/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ConceptMap/[id]` | | Patch | `PATCH` | `/fhir/R4/ConceptMap/[id]` | | Delete | `DELETE` | `/fhir/R4/ConceptMap/[id]` | | Create | `POST` | `/fhir/R4/ConceptMap` | | Search | `GET` | `/fhir/R4/ConceptMap` | | History | `GET` | `/fhir/R4/ConceptMap/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this concept map, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Additional identifier for the concept map | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the concept map | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this concept map (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this concept map (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the concept map | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for concept map (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this concept map is defined | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `source[x]` | [uri](/fhir-elements/primitive/uri), [canonical](/fhir-elements/primitive/canonical) | `0..1` | The source value set that contains the concepts that are being mapped | | `target[x]` | [uri](/fhir-elements/primitive/uri), [canonical](/fhir-elements/primitive/canonical) | `0..1` | The target value set which provides context for the mappings | | `group` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Same source and target systems | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `dependson` | uri | Reference to property mapping depends on | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `identifier` | token | Multiple Resources: CodeSystem: External identifier for the code system ; ConceptMap: External identifier for the concept map ; MessageDefinition: External identifier for the message definition ; StructureDefinition: External identifier for the structure definition ; StructureMap: External identifier for the structure map ; ValueSet: External identifier for the value set | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `other` | reference | canonical reference to an additional ConceptMap to use for mapping if the source concept is unmapped | | `product` | uri | Reference to property mapping depends on | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `source` | reference | The source value set that contains the concepts that are being mapped | | `source-code` | token | Identifies element being mapped | | `source-system` | uri | Source system where concepts to be mapped are defined | | `source-uri` | reference | The source value set that contains the concepts that are being mapped | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `target` | reference | The target value set which provides context for the mappings | | `target-code` | token | Code that identifies the target element | | `target-system` | uri | Target system that the concepts are to be mapped to | | `target-uri` | reference | The target value set which provides context for the mappings | | `title` | string | Multiple Resources: CapabilityStatement: The human-friendly name of the capability statement ; CodeSystem: The human-friendly name of the code system ; ConceptMap: The human-friendly name of the concept map ; ImplementationGuide: The human-friendly name of the implementation guide ; MessageDefinition: The human-friendly name of the message definition ; OperationDefinition: The human-friendly name of the operation definition ; StructureDefinition: The human-friendly name of the structure definition ; StructureMap: The human-friendly name of the structure map ; TerminologyCapabilities: The human-friendly name of the terminology capabilities ; ValueSet: The human-friendly name of the value set | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [ConceptMap](https://hl7.org/fhir/R4/conceptmap.html). Maturity: Trial Use 3 (FMM 3). # Condition Canonical page: https://docs.ovok.com/api/fhir/r4/condition A clinical condition, problem, diagnosis, or other event, situation, issue, or clinical concept that has risen to a level of concern. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Condition/[id]` | | Vread | `GET` | `/fhir/R4/Condition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Condition/[id]` | | Patch | `PATCH` | `/fhir/R4/Condition/[id]` | | Delete | `DELETE` | `/fhir/R4/Condition/[id]` | | Create | `POST` | `/fhir/R4/Condition` | | Search | `GET` | `/fhir/R4/Condition` | | History | `GET` | `/fhir/R4/Condition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Ids for this condition | | `clinicalStatus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | active \| recurrence \| relapse \| inactive \| remission \| resolved | | `verificationStatus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | unconfirmed \| provisional \| differential \| confirmed \| refuted \| entered-in-error | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | problem-list-item \| encounter-diagnosis | | `severity` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Subjective severity of condition | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Identification of the condition, problem or diagnosis | | `bodySite` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Anatomical location, if relevant | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who has the condition? | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter created as part of | | `onset[x]` | [dateTime](/fhir-elements/primitive/date-time), [Age](/fhir-elements/complex/age), [Period](/fhir-elements/complex/period), [Range](/fhir-elements/complex/range), [string](/fhir-elements/primitive/string) | `0..1` | Estimated or actual date, date-time, or age | | `abatement[x]` | [dateTime](/fhir-elements/primitive/date-time), [Age](/fhir-elements/complex/age), [Period](/fhir-elements/complex/period), [Range](/fhir-elements/complex/range), [string](/fhir-elements/primitive/string) | `0..1` | When in resolution/remission | | `recordedDate` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date record was first recorded | | `recorder` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who recorded the condition | | `asserter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Person who asserts this condition | | `stage` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Stage/grade, usually assessed formally | | `evidence` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Supporting evidence | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Additional information about the Condition | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `abatement-age` | quantity | Abatement as age or age range | | `abatement-date` | date | Date-related abatements (dateTime and period) | | `abatement-string` | string | Abatement as a string | | `asserter` | reference | Person who asserts this condition | | `body-site` | token | Anatomical location, if relevant | | `category` | token | The category of the condition | | `clinical-status` | token | The clinical status of the condition | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `encounter` | reference | Encounter created as part of | | `evidence` | token | Manifestation/symptom | | `evidence-detail` | reference | Supporting information found elsewhere | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `onset-age` | quantity | Onsets as age or age range | | `onset-date` | date | Date related onsets (dateTime and Period) | | `onset-info` | string | Onsets as a string | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `recorded-date` | date | Date record was first recorded | | `severity` | token | The severity of the condition | | `stage` | token | Simple summary (disease specific) | | `subject` | reference | Who has the condition? | | `subject` | reference | Search by condition subject | | `verification-status` | token | unconfirmed \| provisional \| differential \| confirmed \| refuted \| entered-in-error | ## Reference [#reference] Official FHIR R4 spec: [Condition](https://hl7.org/fhir/R4/condition.html). Maturity: Trial Use 3 (FMM 3). # Consent Canonical page: https://docs.ovok.com/api/fhir/r4/consent A record of a healthcare consumer’s choices, which permits or denies identified recipient(s) or recipient role(s) to perform one or more actions within a given policy context, for specific purposes and periods of time. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Consent/[id]` | | Vread | `GET` | `/fhir/R4/Consent/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Consent/[id]` | | Patch | `PATCH` | `/fhir/R4/Consent/[id]` | | Delete | `DELETE` | `/fhir/R4/Consent/[id]` | | Create | `POST` | `/fhir/R4/Consent` | | Search | `GET` | `/fhir/R4/Consent` | | History | `GET` | `/fhir/R4/Consent/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Identifier for this record (external references) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| proposed \| active \| rejected \| inactive \| entered-in-error | | `scope` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Which of the four areas this resource covers (extensible) | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..*` | Classification of the consent statement - for indexing/retrieval | | `patient` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who the consent applies to | | `dateTime` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When this Consent was created or indexed | | `performer` | [Reference](/fhir-elements/complex/reference) | `0..*` | Who is agreeing to the policy and rules | | `organization` | [Reference](/fhir-elements/complex/reference) | `0..*` | Custodian of the consent | | `source[x]` | [Attachment](/fhir-elements/complex/attachment), [Reference](/fhir-elements/complex/reference) | `0..1` | Source from which this consent is taken | | `policy` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Policies covered by this consent | | `policyRule` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Regulation that this consents to | | `verification` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Consent Verified by patient or family | | `provision` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Constraints to the base Consent.policyRule | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `action` | token | Actions controlled by this rule | | `actor` | reference | Resource for the actor (or group, by role) | | `category` | token | Classification of the consent statement - for indexing/retrieval | | `consentor` | reference | Who is agreeing to the policy and rules | | `data` | reference | The actual data reference | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `organization` | reference | Custodian of the consent | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `period` | date | Timeframe for this rule | | `purpose` | token | Context of activities covered by this rule | | `scope` | token | Which of the four areas this resource covers (extensible) | | `security-label` | token | Security Labels that define affected resources | | `source-reference` | reference | Search by reference to a Consent, DocumentReference, Contract or QuestionnaireResponse | | `status` | token | draft \| proposed \| active \| rejected \| inactive \| entered-in-error | ## Reference [#reference] Official FHIR R4 spec: [Consent](https://hl7.org/fhir/R4/consent.html). Maturity: Trial Use 2 (FMM 2). # Contract Canonical page: https://docs.ovok.com/api/fhir/r4/contract Legally enforceable, formally recorded unilateral or bilateral directive i.e., a policy or agreement. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Contract/[id]` | | Vread | `GET` | `/fhir/R4/Contract/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Contract/[id]` | | Patch | `PATCH` | `/fhir/R4/Contract/[id]` | | Delete | `DELETE` | `/fhir/R4/Contract/[id]` | | Create | `POST` | `/fhir/R4/Contract` | | Search | `GET` | `/fhir/R4/Contract` | | History | `GET` | `/fhir/R4/Contract/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Contract number | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Basal definition | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business edition | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | amended \| appended \| cancelled \| disputed \| entered-in-error \| executable \| executed \| negotiable \| offered \| policy \| rejected \| renewed \| revoked \| resolved \| terminated | | `legalState` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Negotiation status | | `instantiatesCanonical` | [Reference](/fhir-elements/complex/reference) | `0..1` | Source Contract Definition | | `instantiatesUri` | [uri](/fhir-elements/primitive/uri) | `0..1` | External Contract Definition | | `contentDerivative` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Content derived from the basal information | | `issued` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When this Contract was issued | | `applies` | [Period](/fhir-elements/complex/period) | `0..1` | Effective time | | `expirationType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Contract cessation cause | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..*` | Contract Target Entity | | `authority` | [Reference](/fhir-elements/complex/reference) | `0..*` | Authority under which this Contract has standing | | `domain` | [Reference](/fhir-elements/complex/reference) | `0..*` | A sphere of control governed by an authoritative jurisdiction, organization, or person | | `site` | [Reference](/fhir-elements/complex/reference) | `0..*` | Specific Location | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Computer friendly designation | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Human Friendly name | | `subtitle` | [string](/fhir-elements/primitive/string) | `0..1` | Subordinate Friendly name | | `alias` | [string](/fhir-elements/primitive/string) | `0..*` | Acronym or short name | | `author` | [Reference](/fhir-elements/complex/reference) | `0..1` | Source of Contract | | `scope` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Range of Legal Concerns | | `topic[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `0..1` | Focus of contract interest | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Legal instrument category | | `subType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Subtype within the context of type | | `contentDefinition` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Contract precursor content | | `term` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Contract Term List | | `supportingInfo` | [Reference](/fhir-elements/complex/reference) | `0..*` | Extra Information | | `relevantHistory` | [Reference](/fhir-elements/complex/reference) | `0..*` | Key event in Contract History | | `signer` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Contract Signatory | | `friendly` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Contract Friendly Language | | `legal` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Contract Legal Language | | `rule` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Computable Contract Language | | `legallyBinding[x]` | [Attachment](/fhir-elements/complex/attachment), [Reference](/fhir-elements/complex/reference) | `0..1` | Binding Contract | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `authority` | reference | The authority of the contract | | `domain` | reference | The domain of the contract | | `identifier` | token | The identity of the contract | | `instantiates` | uri | A source definition of the contract | | `issued` | date | The date/time the contract was issued | | `patient` | reference | The identity of the subject of the contract (if a patient) | | `signer` | reference | Contract Signatory Party | | `status` | token | The status of the contract | | `subject` | reference | The identity of the subject of the contract | | `url` | uri | The basal contract definition | ## Reference [#reference] Official FHIR R4 spec: [Contract](https://hl7.org/fhir/R4/contract.html). Maturity: Trial Use 1 (FMM 1). # CoverageEligibilityRequest Canonical page: https://docs.ovok.com/api/fhir/r4/coverage-eligibility-request The CoverageEligibilityRequest provides patient and insurance coverage information to an insurer for them to respond, in the form of an CoverageEligibilityResponse, with information regarding whether the stated coverage is valid and in-force and optionally to provide the insurance details of the policy. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/CoverageEligibilityRequest/[id]` | | Vread | `GET` | `/fhir/R4/CoverageEligibilityRequest/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/CoverageEligibilityRequest/[id]` | | Patch | `PATCH` | `/fhir/R4/CoverageEligibilityRequest/[id]` | | Delete | `DELETE` | `/fhir/R4/CoverageEligibilityRequest/[id]` | | Create | `POST` | `/fhir/R4/CoverageEligibilityRequest` | | Search | `GET` | `/fhir/R4/CoverageEligibilityRequest` | | History | `GET` | `/fhir/R4/CoverageEligibilityRequest/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for coverage eligiblity request | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| cancelled \| draft \| entered-in-error | | `priority` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Desired processing priority | | `purpose` | [code](/fhir-elements/primitive/code) | `1..*` | auth-requirements \| benefits \| discovery \| validation | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | Intended recipient of products and services | | `serviced[x]` | [date](/fhir-elements/primitive/date), [Period](/fhir-elements/complex/period) | `0..1` | Estimated date or dates of service | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Creation date | | `enterer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Author | | `provider` | [Reference](/fhir-elements/complex/reference) | `0..1` | Party responsible for the request | | `insurer` | [Reference](/fhir-elements/complex/reference) | `1..1` | Coverage issuer | | `facility` | [Reference](/fhir-elements/complex/reference) | `0..1` | Servicing facility | | `supportingInfo` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Supporting information | | `insurance` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Patient insurance information | | `item` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Item to be evaluated for eligibiity | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `created` | date | The creation date for the EOB | | `enterer` | reference | The party who is responsible for the request | | `facility` | reference | Facility responsible for the goods and services | | `identifier` | token | The business identifier of the Eligibility | | `patient` | reference | The reference to the patient | | `provider` | reference | The reference to the provider | | `status` | token | The status of the EligibilityRequest | ## Reference [#reference] Official FHIR R4 spec: [CoverageEligibilityRequest](https://hl7.org/fhir/R4/coverageeligibilityrequest.html). Maturity: Trial Use 2 (FMM 2). # CoverageEligibilityResponse Canonical page: https://docs.ovok.com/api/fhir/r4/coverage-eligibility-response This resource provides eligibility and plan details from the processing of an CoverageEligibilityRequest resource. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/CoverageEligibilityResponse/[id]` | | Vread | `GET` | `/fhir/R4/CoverageEligibilityResponse/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/CoverageEligibilityResponse/[id]` | | Patch | `PATCH` | `/fhir/R4/CoverageEligibilityResponse/[id]` | | Delete | `DELETE` | `/fhir/R4/CoverageEligibilityResponse/[id]` | | Create | `POST` | `/fhir/R4/CoverageEligibilityResponse` | | Search | `GET` | `/fhir/R4/CoverageEligibilityResponse` | | History | `GET` | `/fhir/R4/CoverageEligibilityResponse/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for coverage eligiblity request | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| cancelled \| draft \| entered-in-error | | `purpose` | [code](/fhir-elements/primitive/code) | `1..*` | auth-requirements \| benefits \| discovery \| validation | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | Intended recipient of products and services | | `serviced[x]` | [date](/fhir-elements/primitive/date), [Period](/fhir-elements/complex/period) | `0..1` | Estimated date or dates of service | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Response creation date | | `requestor` | [Reference](/fhir-elements/complex/reference) | `0..1` | Party responsible for the request | | `request` | [Reference](/fhir-elements/complex/reference) | `1..1` | Eligibility request reference | | `outcome` | [code](/fhir-elements/primitive/code) | `1..1` | queued \| complete \| error \| partial | | `disposition` | [string](/fhir-elements/primitive/string) | `0..1` | Disposition Message | | `insurer` | [Reference](/fhir-elements/complex/reference) | `1..1` | Coverage issuer | | `insurance` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Patient insurance information | | `preAuthRef` | [string](/fhir-elements/primitive/string) | `0..1` | Preauthorization reference | | `form` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Printed form identifier | | `error` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Processing errors | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `created` | date | The creation date | | `disposition` | string | The contents of the disposition message | | `identifier` | token | The business identifier | | `insurer` | reference | The organization which generated this resource | | `outcome` | token | The processing outcome | | `patient` | reference | The reference to the patient | | `request` | reference | The EligibilityRequest reference | | `requestor` | reference | The EligibilityRequest provider | | `status` | token | The EligibilityRequest status | ## Reference [#reference] Official FHIR R4 spec: [CoverageEligibilityResponse](https://hl7.org/fhir/R4/coverageeligibilityresponse.html). Maturity: Trial Use 2 (FMM 2). # Coverage Canonical page: https://docs.ovok.com/api/fhir/r4/coverage Financial instrument which may be used to reimburse or pay for health care products and services. Includes both insurance and self-payment. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Coverage/[id]` | | Vread | `GET` | `/fhir/R4/Coverage/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Coverage/[id]` | | Patch | `PATCH` | `/fhir/R4/Coverage/[id]` | | Delete | `DELETE` | `/fhir/R4/Coverage/[id]` | | Create | `POST` | `/fhir/R4/Coverage` | | Search | `GET` | `/fhir/R4/Coverage` | | History | `GET` | `/fhir/R4/Coverage/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for the coverage | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| cancelled \| draft \| entered-in-error | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Coverage category such as medical or accident | | `policyHolder` | [Reference](/fhir-elements/complex/reference) | `0..1` | Owner of the policy | | `subscriber` | [Reference](/fhir-elements/complex/reference) | `0..1` | Subscriber to the policy | | `subscriberId` | [string](/fhir-elements/primitive/string) | `0..1` | ID assigned to the subscriber | | `beneficiary` | [Reference](/fhir-elements/complex/reference) | `1..1` | Plan beneficiary | | `dependent` | [string](/fhir-elements/primitive/string) | `0..1` | Dependent number | | `relationship` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Beneficiary relationship to the subscriber | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | Coverage start and end dates | | `payor` | [Reference](/fhir-elements/complex/reference) | `1..*` | Issuer of the policy | | `class` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Additional coverage classifications | | `order` | [positiveInt](/fhir-elements/primitive/positive-int) | `0..1` | Relative order of the coverage | | `network` | [string](/fhir-elements/primitive/string) | `0..1` | Insurer network | | `costToBeneficiary` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Patient payments for services/products | | `subrogation` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Reimbursement to insurer | | `contract` | [Reference](/fhir-elements/complex/reference) | `0..*` | Contract details | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `beneficiary` | reference | Covered party | | `class-type` | token | Coverage class (eg. plan, group) | | `class-value` | string | Value of the class (eg. Plan number, group number) | | `dependent` | string | Dependent number | | `identifier` | token | The primary identifier of the insured and the coverage | | `patient` | reference | Retrieve coverages for a patient | | `payor` | reference | The identity of the insurer or party paying for services | | `policy-holder` | reference | Reference to the policyholder | | `status` | token | The status of the Coverage | | `subscriber` | reference | Reference to the subscriber | | `type` | token | The kind of coverage (health plan, auto, Workers Compensation) | ## Reference [#reference] Official FHIR R4 spec: [Coverage](https://hl7.org/fhir/R4/coverage.html). Maturity: Trial Use 2 (FMM 2). # DetectedIssue Canonical page: https://docs.ovok.com/api/fhir/r4/detected-issue Indicates an actual or potential clinical issue with or between one or more active or proposed clinical actions for a patient; e.g. Drug-drug interaction, Ineffective treatment frequency, Procedure-condition conflict, etc. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/DetectedIssue/[id]` | | Vread | `GET` | `/fhir/R4/DetectedIssue/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/DetectedIssue/[id]` | | Patch | `PATCH` | `/fhir/R4/DetectedIssue/[id]` | | Delete | `DELETE` | `/fhir/R4/DetectedIssue/[id]` | | Create | `POST` | `/fhir/R4/DetectedIssue` | | Search | `GET` | `/fhir/R4/DetectedIssue` | | History | `GET` | `/fhir/R4/DetectedIssue/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Unique id for the detected issue | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | registered \| preliminary \| final \| amended + | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Issue Category, e.g. drug-drug, duplicate therapy, etc. | | `severity` | [code](/fhir-elements/primitive/code) | `0..1` | high \| moderate \| low | | `patient` | [Reference](/fhir-elements/complex/reference) | `0..1` | Associated patient | | `identified[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period) | `0..1` | When identified | | `author` | [Reference](/fhir-elements/complex/reference) | `0..1` | The provider or device that identified the issue | | `implicated` | [Reference](/fhir-elements/complex/reference) | `0..*` | Problem resource | | `evidence` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Supporting evidence | | `detail` | [string](/fhir-elements/primitive/string) | `0..1` | Description and context | | `reference` | [uri](/fhir-elements/primitive/uri) | `0..1` | Authority for issue | | `mitigation` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Step taken to address | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `author` | reference | The provider or device that identified the issue | | `code` | token | Issue Category, e.g. drug-drug, duplicate therapy, etc. | | `identified` | date | When identified | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `implicated` | reference | Problem resource | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | ## Reference [#reference] Official FHIR R4 spec: [DetectedIssue](https://hl7.org/fhir/R4/detectedissue.html). Maturity: Trial Use 1 (FMM 1). # DeviceDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/device-definition The characteristics, operational status and capabilities of a medical-related component of a medical device. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/DeviceDefinition/[id]` | | Vread | `GET` | `/fhir/R4/DeviceDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/DeviceDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/DeviceDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/DeviceDefinition/[id]` | | Create | `POST` | `/fhir/R4/DeviceDefinition` | | Search | `GET` | `/fhir/R4/DeviceDefinition` | | History | `GET` | `/fhir/R4/DeviceDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Instance identifier | | `udiDeviceIdentifier` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Unique Device Identifier (UDI) Barcode string | | `manufacturer[x]` | [string](/fhir-elements/primitive/string), [Reference](/fhir-elements/complex/reference) | `0..1` | Name of device manufacturer | | `deviceName` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A name given to the device to identify it | | `modelNumber` | [string](/fhir-elements/primitive/string) | `0..1` | The model number for the device | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | What kind of device or device system this is | | `specialization` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The capabilities supported on a device, the standards to which the device conforms for a particular purpose, and used for the communication | | `version` | [string](/fhir-elements/primitive/string) | `0..*` | Available versions | | `safety` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Safety characteristics of the device | | `shelfLifeStorage` | [ProductShelfLife](/fhir-elements/complex/product-shelf-life) | `0..*` | Shelf Life and storage information | | `physicalCharacteristics` | [ProdCharacteristic](/fhir-elements/complex/prod-characteristic) | `0..1` | Dimensions, color etc. | | `languageCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Language code for the human-readable text strings produced by the device (all supported) | | `capability` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Device capabilities | | `property` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The actual configuration settings of a device as it actually operates, e.g., regulation status, time properties | | `owner` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization responsible for device | | `contact` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | Details for human/organization for support | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Network address to contact device | | `onlineInformation` | [uri](/fhir-elements/primitive/uri) | `0..1` | Access to on-line information | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Device notes and comments | | `quantity` | [Quantity](/fhir-elements/complex/quantity) | `0..1` | The quantity of the device present in the packaging (e.g. the number of devices present in a pack, or the number of devices in the same package of the medicinal product) | | `parentDevice` | [Reference](/fhir-elements/complex/reference) | `0..1` | The parent device it can be part of | | `material` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A substance used to create the material(s) of which the device is made | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `identifier` | token | The identifier of the component | | `parent` | reference | The parent DeviceDefinition resource | | `type` | token | The device component type | ## Reference [#reference] Official FHIR R4 spec: [DeviceDefinition](https://hl7.org/fhir/R4/devicedefinition.html). Maturity: Draft (FMM 0). # DeviceMetric Canonical page: https://docs.ovok.com/api/fhir/r4/device-metric Describes a measurement, calculation or setting capability of a medical device. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/DeviceMetric/[id]` | | Vread | `GET` | `/fhir/R4/DeviceMetric/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/DeviceMetric/[id]` | | Patch | `PATCH` | `/fhir/R4/DeviceMetric/[id]` | | Delete | `DELETE` | `/fhir/R4/DeviceMetric/[id]` | | Create | `POST` | `/fhir/R4/DeviceMetric` | | Search | `GET` | `/fhir/R4/DeviceMetric` | | History | `GET` | `/fhir/R4/DeviceMetric/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Instance identifier | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Identity of metric, for example Heart Rate or PEEP Setting | | `unit` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Unit of Measure for the Metric | | `source` | [Reference](/fhir-elements/complex/reference) | `0..1` | Describes the link to the source Device | | `parent` | [Reference](/fhir-elements/complex/reference) | `0..1` | Describes the link to the parent Device | | `operationalStatus` | [code](/fhir-elements/primitive/code) | `0..1` | on \| off \| standby \| entered-in-error | | `color` | [code](/fhir-elements/primitive/code) | `0..1` | black \| red \| green \| yellow \| blue \| magenta \| cyan \| white | | `category` | [code](/fhir-elements/primitive/code) | `1..1` | measurement \| setting \| calculation \| unspecified | | `measurementPeriod` | [Timing](/fhir-elements/complex/timing) | `0..1` | Describes the measurement repetition time | | `calibration` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Describes the calibrations that have been performed or that are required to be performed | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `category` | token | The category of the metric | | `identifier` | token | The identifier of the metric | | `parent` | reference | The parent DeviceMetric resource | | `source` | reference | The device resource | | `type` | token | The component type | ## Reference [#reference] Official FHIR R4 spec: [DeviceMetric](https://hl7.org/fhir/R4/devicemetric.html). Maturity: Trial Use 1 (FMM 1). # DeviceRequest Canonical page: https://docs.ovok.com/api/fhir/r4/device-request Represents a request for a patient to employ a medical device. The device may be an implantable device, or an external assistive device, such as a walker. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/DeviceRequest/[id]` | | Vread | `GET` | `/fhir/R4/DeviceRequest/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/DeviceRequest/[id]` | | Patch | `PATCH` | `/fhir/R4/DeviceRequest/[id]` | | Delete | `DELETE` | `/fhir/R4/DeviceRequest/[id]` | | Create | `POST` | `/fhir/R4/DeviceRequest` | | Search | `GET` | `/fhir/R4/DeviceRequest` | | History | `GET` | `/fhir/R4/DeviceRequest/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Request identifier | | `instantiatesCanonical` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Instantiates FHIR protocol or definition | | `instantiatesUri` | [uri](/fhir-elements/primitive/uri) | `0..*` | Instantiates external protocol or definition | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | What request fulfills | | `priorRequest` | [Reference](/fhir-elements/complex/reference) | `0..*` | What request replaces | | `groupIdentifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Identifier of composite request | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | draft \| active \| on-hold \| revoked \| completed \| entered-in-error \| unknown | | `intent` | [code](/fhir-elements/primitive/code) | `1..1` | proposal \| plan \| directive \| order \| original-order \| reflex-order \| filler-order \| instance-order \| option | | `priority` | [code](/fhir-elements/primitive/code) | `0..1` | routine \| urgent \| asap \| stat | | `code[x]` | [Reference](/fhir-elements/complex/reference), [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Device requested | | `parameter` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Device details | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Focus of request | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter motivating request | | `occurrence[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period), [Timing](/fhir-elements/complex/timing) | `0..1` | Desired time or schedule for use | | `authoredOn` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When recorded | | `requester` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who/what is requesting diagnostics | | `performerType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Filler role | | `performer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Requested Filler | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Coded Reason for request | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Linked Reason for request | | `insurance` | [Reference](/fhir-elements/complex/reference) | `0..*` | Associated insurance coverage | | `supportingInfo` | [Reference](/fhir-elements/complex/reference) | `0..*` | Additional clinical information | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Notes or comments | | `relevantHistory` | [Reference](/fhir-elements/complex/reference) | `0..*` | Request provenance | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `authored-on` | date | When the request transitioned to being actionable | | `based-on` | reference | Plan/proposal/order fulfilled by this request | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `device` | reference | Reference to resource that is being requested/ordered | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `event-date` | date | When service should occur | | `group-identifier` | token | Composite request this is part of | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `instantiates-canonical` | reference | Instantiates FHIR protocol or definition | | `instantiates-uri` | uri | Instantiates external protocol or definition | | `insurance` | reference | Associated insurance coverage | | `intent` | token | proposal \| plan \| original-order \|reflex-order | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `performer` | reference | Desired performer for service | | `prior-request` | reference | Request takes the place of referenced completed or terminated requests | | `requester` | reference | Who/what is requesting service | | `status` | token | entered-in-error \| draft \| active \|suspended \| completed | | `subject` | reference | Individual the service is ordered for | ## Reference [#reference] Official FHIR R4 spec: [DeviceRequest](https://hl7.org/fhir/R4/devicerequest.html). Maturity: Trial Use 1 (FMM 1). # DeviceUseStatement Canonical page: https://docs.ovok.com/api/fhir/r4/device-use-statement A record of a device being used by a patient where the record is the result of a report from the patient or another clinician. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/DeviceUseStatement/[id]` | | Vread | `GET` | `/fhir/R4/DeviceUseStatement/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/DeviceUseStatement/[id]` | | Patch | `PATCH` | `/fhir/R4/DeviceUseStatement/[id]` | | Delete | `DELETE` | `/fhir/R4/DeviceUseStatement/[id]` | | Create | `POST` | `/fhir/R4/DeviceUseStatement` | | Search | `GET` | `/fhir/R4/DeviceUseStatement` | | History | `GET` | `/fhir/R4/DeviceUseStatement/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External identifier for this record | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Fulfills plan, proposal or order | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| completed \| entered-in-error + | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Patient using device | | `derivedFrom` | [Reference](/fhir-elements/complex/reference) | `0..*` | Supporting information | | `timing[x]` | [Timing](/fhir-elements/complex/timing), [Period](/fhir-elements/complex/period), [dateTime](/fhir-elements/primitive/date-time) | `0..1` | How often the device was used | | `recordedOn` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When statement was recorded | | `source` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who made the statement | | `device` | [Reference](/fhir-elements/complex/reference) | `1..1` | Reference to device used | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Why device was used | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Why was DeviceUseStatement performed? | | `bodySite` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Target body site | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Addition details (comments, instructions) | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `device` | reference | Search by device | | `identifier` | token | Search by identifier | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `subject` | reference | Search by subject | ## Reference [#reference] Official FHIR R4 spec: [DeviceUseStatement](https://hl7.org/fhir/R4/deviceusestatement.html). Maturity: Draft (FMM 0). # Device Canonical page: https://docs.ovok.com/api/fhir/r4/device A type of a manufactured item that is used in the provision of healthcare without being substantially changed through that activity. The device may be a medical or non-medical device. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Device/[id]` | | Vread | `GET` | `/fhir/R4/Device/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Device/[id]` | | Patch | `PATCH` | `/fhir/R4/Device/[id]` | | Delete | `DELETE` | `/fhir/R4/Device/[id]` | | Create | `POST` | `/fhir/R4/Device` | | Search | `GET` | `/fhir/R4/Device` | | History | `GET` | `/fhir/R4/Device/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Instance identifier | | `definition` | [Reference](/fhir-elements/complex/reference) | `0..1` | The reference to the definition for the device | | `udiCarrier` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Unique Device Identifier (UDI) Barcode string | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | active \| inactive \| entered-in-error \| unknown | | `statusReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | online \| paused \| standby \| offline \| not-ready \| transduc-discon \| hw-discon \| off | | `distinctIdentifier` | [string](/fhir-elements/primitive/string) | `0..1` | The distinct identification string | | `manufacturer` | [string](/fhir-elements/primitive/string) | `0..1` | Name of device manufacturer | | `manufactureDate` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date when the device was made | | `expirationDate` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date and time of expiry of this device (if applicable) | | `lotNumber` | [string](/fhir-elements/primitive/string) | `0..1` | Lot number of manufacture | | `serialNumber` | [string](/fhir-elements/primitive/string) | `0..1` | Serial number assigned by the manufacturer | | `deviceName` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The name of the device as given by the manufacturer | | `modelNumber` | [string](/fhir-elements/primitive/string) | `0..1` | The model number for the device | | `partNumber` | [string](/fhir-elements/primitive/string) | `0..1` | The part number of the device | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The kind or type of device | | `specialization` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The capabilities supported on a device, the standards to which the device conforms for a particular purpose, and used for the communication | | `version` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The actual design of the device or software version running on the device | | `property` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The actual configuration settings of a device as it actually operates, e.g., regulation status, time properties | | `patient` | [Reference](/fhir-elements/complex/reference) | `0..1` | Patient to whom Device is affixed | | `owner` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization responsible for device | | `contact` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | Details for human/organization for support | | `location` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where the device is found | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Network address to contact device | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Device notes and comments | | `safety` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Safety Characteristics of Device | | `parent` | [Reference](/fhir-elements/complex/reference) | `0..1` | The parent device | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `device-name` | string | A server defined search that may match any of the string fields in Device.deviceName or Device.type. | | `din` | token | The donation identification number (DIN) | | `identifier` | token | Instance id from manufacturer, owner, and others | | `location` | reference | A location, where the resource is found | | `manufacturer` | string | The manufacturer of the device | | `model` | string | The model of the device | | `organization` | reference | The organization responsible for the device | | `patient` | reference | Patient information, if the resource is affixed to a person | | `status` | token | active \| inactive \| entered-in-error \| unknown | | `type` | token | The type of the device | | `udi-carrier` | string | UDI Barcode (RFID or other technology) string in *HRF; format. | | `udi-di` | string | The udi Device Identifier (DI) | | `url` | uri | Network address to contact device | ## Reference [#reference] Official FHIR R4 spec: [Device](https://hl7.org/fhir/R4/device.html). Maturity: Trial Use 2 (FMM 2). # DiagnosticReport Canonical page: https://docs.ovok.com/api/fhir/r4/diagnostic-report The findings and interpretation of diagnostic tests performed on patients, groups of patients, devices, and locations, and/or specimens derived from these. The report includes clinical context such as requesting and provider information, and some mix of atomic results, images, textual and coded interpretations, and formatted representation of diagnostic reports. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/DiagnosticReport/[id]` | | Vread | `GET` | `/fhir/R4/DiagnosticReport/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/DiagnosticReport/[id]` | | Patch | `PATCH` | `/fhir/R4/DiagnosticReport/[id]` | | Delete | `DELETE` | `/fhir/R4/DiagnosticReport/[id]` | | Create | `POST` | `/fhir/R4/DiagnosticReport` | | Search | `GET` | `/fhir/R4/DiagnosticReport` | | History | `GET` | `/fhir/R4/DiagnosticReport/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier for report | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | What was requested | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | registered \| partial \| preliminary \| final + | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Service category | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Name/Code for this diagnostic report | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | The subject of the report - usually, but not always, the patient | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Health care event when test ordered | | `effective[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period) | `0..1` | Clinically relevant time/time-period for report | | `issued` | [instant](/fhir-elements/primitive/instant) | `0..1` | DateTime this version was made | | `performer` | [Reference](/fhir-elements/complex/reference) | `0..*` | Responsible Diagnostic Service | | `resultsInterpreter` | [Reference](/fhir-elements/complex/reference) | `0..*` | Primary result interpreter | | `specimen` | [Reference](/fhir-elements/complex/reference) | `0..*` | Specimens this report is based on | | `result` | [Reference](/fhir-elements/complex/reference) | `0..*` | Observations | | `imagingStudy` | [Reference](/fhir-elements/complex/reference) | `0..*` | Reference to full details of imaging associated with the diagnostic report | | `media` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Key images associated with this report | | `conclusion` | [string](/fhir-elements/primitive/string) | `0..1` | Clinical conclusion (interpretation) of test results | | `conclusionCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Codes for the clinical conclusion of test results | | `presentedForm` | [Attachment](/fhir-elements/complex/attachment) | `0..*` | Entire report as issued | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `assessed-condition` | reference | Condition assessed by genetic test | | `based-on` | reference | Reference to the service request. | | `category` | token | Which diagnostic discipline/department created the report | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `conclusion` | token | A coded conclusion (interpretation/impression) on the report | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `issued` | date | When the report was issued | | `media` | reference | A reference to the image source. | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `performer` | reference | Who is responsible for the report | | `result` | reference | Link to an atomic result (observation resource) | | `results-interpreter` | reference | Who was the source of the report | | `specimen` | reference | The specimen details | | `status` | token | The status of the report | | `subject` | reference | The subject of the report | ## Reference [#reference] Official FHIR R4 spec: [DiagnosticReport](https://hl7.org/fhir/R4/diagnosticreport.html). Maturity: Trial Use 3 (FMM 3). # DocumentManifest Canonical page: https://docs.ovok.com/api/fhir/r4/document-manifest A collection of documents compiled for a purpose together with metadata that applies to the collection. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/DocumentManifest/[id]` | | Vread | `GET` | `/fhir/R4/DocumentManifest/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/DocumentManifest/[id]` | | Patch | `PATCH` | `/fhir/R4/DocumentManifest/[id]` | | Delete | `DELETE` | `/fhir/R4/DocumentManifest/[id]` | | Create | `POST` | `/fhir/R4/DocumentManifest` | | Search | `GET` | `/fhir/R4/DocumentManifest` | | History | `GET` | `/fhir/R4/DocumentManifest/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `masterIdentifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Unique Identifier for the set of documents | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Other identifiers for the manifest | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | current \| superseded \| entered-in-error | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Kind of document set | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | The subject of the set of documents | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When this document manifest created | | `author` | [Reference](/fhir-elements/complex/reference) | `0..*` | Who and/or what authored the DocumentManifest | | `recipient` | [Reference](/fhir-elements/complex/reference) | `0..*` | Intended to get notified about this set of documents | | `source` | [uri](/fhir-elements/primitive/uri) | `0..1` | The source system/application/software | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Human-readable description (title) | | `content` | [Reference](/fhir-elements/complex/reference) | `1..*` | Items in manifest | | `related` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Related things | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `author` | reference | Who and/or what authored the DocumentManifest | | `created` | date | When this document manifest created | | `description` | string | Human-readable description (title) | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `item` | reference | Items in manifest | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `recipient` | reference | Intended to get notified about this set of documents | | `related-id` | token | Identifiers of things that are related | | `related-ref` | reference | Related Resource | | `source` | uri | The source system/application/software | | `status` | token | current \| superseded \| entered-in-error | | `subject` | reference | The subject of the set of documents | | `type` | token | Multiple Resources: AllergyIntolerance: allergy \| intolerance - Underlying mechanism (if known) ; Composition: Kind of composition (LOINC if possible) ; DocumentManifest: Kind of document set ; DocumentReference: Kind of document (LOINC if possible) ; Encounter: Specific type of encounter ; EpisodeOfCare: Type/class - e.g. specialist referral, disease management | ## Reference [#reference] Official FHIR R4 spec: [DocumentManifest](https://hl7.org/fhir/R4/documentmanifest.html). Maturity: Trial Use 2 (FMM 2). # DocumentReference Canonical page: https://docs.ovok.com/api/fhir/r4/document-reference A reference to a document of any kind for any purpose. Provides metadata about the document so that the document can be discovered and managed. The scope of a document is any seralized object with a mime-type, so includes formal patient centric documents (CDA), cliical notes, scanned paper, and non-patient specific documents like policy text. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/DocumentReference/[id]` | | Vread | `GET` | `/fhir/R4/DocumentReference/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/DocumentReference/[id]` | | Patch | `PATCH` | `/fhir/R4/DocumentReference/[id]` | | Delete | `DELETE` | `/fhir/R4/DocumentReference/[id]` | | Create | `POST` | `/fhir/R4/DocumentReference` | | Search | `GET` | `/fhir/R4/DocumentReference` | | History | `GET` | `/fhir/R4/DocumentReference/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `masterIdentifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Master Version Specific Identifier | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Other identifiers for the document | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | current \| superseded \| entered-in-error | | `docStatus` | [code](/fhir-elements/primitive/code) | `0..1` | preliminary \| final \| amended \| entered-in-error | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Kind of document (LOINC if possible) | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Categorization of document | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who/what is the subject of the document | | `date` | [instant](/fhir-elements/primitive/instant) | `0..1` | When this document reference was created | | `author` | [Reference](/fhir-elements/complex/reference) | `0..*` | Who and/or what authored the document | | `authenticator` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who/what authenticated the document | | `custodian` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization which maintains the document | | `relatesTo` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Relationships to other documents | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Human-readable description | | `securityLabel` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Document security-tags | | `content` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | Document referenced | | `context` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Clinical context of document | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `authenticator` | reference | Who/what authenticated the document | | `author` | reference | Who and/or what authored the document | | `category` | token | Categorization of document | | `contenttype` | token | Mime type of the content, with charset etc. | | `custodian` | reference | Organization which maintains the document | | `date` | date | When this document reference was created | | `description` | string | Human-readable description | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `event` | token | Main clinical acts documented | | `facility` | token | Kind of facility where patient was seen | | `format` | token | Format/content rules for the document | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `language` | token | Human language of the content (BCP-47) | | `location` | uri | Uri where the data can be found | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `period` | date | Time of service that is being documented | | `related` | reference | Related identifiers or resources | | `relatesto` | reference | Target of the relationship | | `relation` | token | replaces \| transforms \| signs \| appends | | `relationship` | composite | Combination of relation and relatesTo | | `security-label` | token | Document security-tags | | `setting` | token | Additional details about where the content was created (e.g. clinical specialty) | | `status` | token | current \| superseded \| entered-in-error | | `subject` | reference | Who/what is the subject of the document | | `type` | token | Multiple Resources: AllergyIntolerance: allergy \| intolerance - Underlying mechanism (if known) ; Composition: Kind of composition (LOINC if possible) ; DocumentManifest: Kind of document set ; DocumentReference: Kind of document (LOINC if possible) ; Encounter: Specific type of encounter ; EpisodeOfCare: Type/class - e.g. specialist referral, disease management | ## Reference [#reference] Official FHIR R4 spec: [DocumentReference](https://hl7.org/fhir/R4/documentreference.html). Maturity: Trial Use 3 (FMM 3). # EffectEvidenceSynthesis Canonical page: https://docs.ovok.com/api/fhir/r4/effect-evidence-synthesis The EffectEvidenceSynthesis resource describes the difference in an outcome between exposures states in a population where the effect estimate is derived from a combination of research studies. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/EffectEvidenceSynthesis/[id]` | | Vread | `GET` | `/fhir/R4/EffectEvidenceSynthesis/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/EffectEvidenceSynthesis/[id]` | | Patch | `PATCH` | `/fhir/R4/EffectEvidenceSynthesis/[id]` | | Delete | `DELETE` | `/fhir/R4/EffectEvidenceSynthesis/[id]` | | Create | `POST` | `/fhir/R4/EffectEvidenceSynthesis` | | Search | `GET` | `/fhir/R4/EffectEvidenceSynthesis` | | History | `GET` | `/fhir/R4/EffectEvidenceSynthesis/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this effect evidence synthesis, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the effect evidence synthesis | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the effect evidence synthesis | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this effect evidence synthesis (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this effect evidence synthesis (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the effect evidence synthesis | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Used for footnotes or explanatory notes | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for effect evidence synthesis (if applicable) | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the effect evidence synthesis was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the effect evidence synthesis was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the effect evidence synthesis is expected to be used | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The category of the EffectEvidenceSynthesis, such as Education, Treatment, Assessment, etc. | | `author` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who authored the content | | `editor` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who edited the content | | `reviewer` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who reviewed the content | | `endorser` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who endorsed the content | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | Additional documentation, citations, etc. | | `synthesisType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Type of synthesis | | `studyType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Type of study | | `population` | [Reference](/fhir-elements/complex/reference) | `1..1` | What population? | | `exposure` | [Reference](/fhir-elements/complex/reference) | `1..1` | What exposure? | | `exposureAlternative` | [Reference](/fhir-elements/complex/reference) | `1..1` | What comparison exposure? | | `outcome` | [Reference](/fhir-elements/complex/reference) | `1..1` | What outcome? | | `sampleSize` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | What sample size was involved? | | `resultsByExposure` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | What was the result per exposure? | | `effectEstimate` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | What was the estimated effect | | `certainty` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | How certain is the effect | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `context` | token | A use context assigned to the effect evidence synthesis | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the effect evidence synthesis | | `context-type` | token | A type of use context assigned to the effect evidence synthesis | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the effect evidence synthesis | | `context-type-value` | composite | A use context type and value assigned to the effect evidence synthesis | | `date` | date | The effect evidence synthesis publication date | | `description` | string | The description of the effect evidence synthesis | | `effective` | date | The time during which the effect evidence synthesis is intended to be in use | | `identifier` | token | External identifier for the effect evidence synthesis | | `jurisdiction` | token | Intended jurisdiction for the effect evidence synthesis | | `name` | string | Computationally friendly name of the effect evidence synthesis | | `publisher` | string | Name of the publisher of the effect evidence synthesis | | `status` | token | The current status of the effect evidence synthesis | | `title` | string | The human-friendly name of the effect evidence synthesis | | `url` | uri | The uri that identifies the effect evidence synthesis | | `version` | token | The business version of the effect evidence synthesis | ## Reference [#reference] Official FHIR R4 spec: [EffectEvidenceSynthesis](https://hl7.org/fhir/R4/effectevidencesynthesis.html). Maturity: Draft (FMM 0). # Encounter Canonical page: https://docs.ovok.com/api/fhir/r4/encounter An interaction between a patient and healthcare provider(s) for the purpose of providing healthcare service(s) or assessing the health status of a patient. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Encounter/[id]` | | Vread | `GET` | `/fhir/R4/Encounter/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Encounter/[id]` | | Patch | `PATCH` | `/fhir/R4/Encounter/[id]` | | Delete | `DELETE` | `/fhir/R4/Encounter/[id]` | | Create | `POST` | `/fhir/R4/Encounter` | | Search | `GET` | `/fhir/R4/Encounter` | | History | `GET` | `/fhir/R4/Encounter/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Identifier(s) by which this encounter is known | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | planned \| arrived \| triaged \| in-progress \| onleave \| finished \| cancelled + | | `statusHistory` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | List of past encounter statuses | | `class` | [Coding](/fhir-elements/complex/coding) | `1..1` | Classification of patient encounter | | `classHistory` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | List of past encounter classes | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Specific type of encounter | | `serviceType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Specific type of service | | `priority` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Indicates the urgency of the encounter | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | The patient or group present at the encounter | | `episodeOfCare` | [Reference](/fhir-elements/complex/reference) | `0..*` | Episode(s) of care that this encounter should be recorded against | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | The ServiceRequest that initiated this encounter | | `participant` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | List of participants involved in the encounter | | `appointment` | [Reference](/fhir-elements/complex/reference) | `0..*` | The appointment that scheduled this encounter | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | The start and end time of the encounter | | `length` | [Duration](/fhir-elements/complex/duration) | `0..1` | Quantity of time the encounter lasted (less time absent) | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Coded reason the encounter takes place | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Reason the encounter takes place (reference) | | `diagnosis` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The list of diagnosis relevant to this encounter | | `account` | [Reference](/fhir-elements/complex/reference) | `0..*` | The set of accounts that may be used for billing for this Encounter | | `hospitalization` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Details about the admission to a healthcare service | | `location` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | List of locations where the patient has been | | `serviceProvider` | [Reference](/fhir-elements/complex/reference) | `0..1` | The organization (facility) responsible for this encounter | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..1` | Another Encounter this encounter is part of | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `account` | reference | The set of accounts that may be used for billing for this Encounter | | `appointment` | reference | The appointment that scheduled this encounter | | `based-on` | reference | The ServiceRequest that initiated this encounter | | `class` | token | Classification of patient encounter | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `diagnosis` | reference | The diagnosis or procedure relevant to the encounter | | `episode-of-care` | reference | Episode(s) of care that this encounter should be recorded against | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `length` | quantity | Length of encounter in days | | `location` | reference | Location the encounter takes place | | `location-period` | date | Time period during which the patient was present at the location | | `part-of` | reference | Another Encounter this encounter is part of | | `participant` | reference | Persons involved in the encounter other than the patient | | `participant-type` | token | Role of participant in encounter | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `practitioner` | reference | Persons involved in the encounter other than the patient | | `reason-code` | token | Coded reason the encounter takes place | | `reason-reference` | reference | Reason the encounter takes place (reference) | | `service-provider` | reference | The organization (facility) responsible for this encounter | | `special-arrangement` | token | Wheelchair, translator, stretcher, etc. | | `status` | token | planned \| arrived \| triaged \| in-progress \| onleave \| finished \| cancelled + | | `subject` | reference | The patient or group present at the encounter | | `type` | token | Multiple Resources: AllergyIntolerance: allergy \| intolerance - Underlying mechanism (if known) ; Composition: Kind of composition (LOINC if possible) ; DocumentManifest: Kind of document set ; DocumentReference: Kind of document (LOINC if possible) ; Encounter: Specific type of encounter ; EpisodeOfCare: Type/class - e.g. specialist referral, disease management | ## Reference [#reference] Official FHIR R4 spec: [Encounter](https://hl7.org/fhir/R4/encounter.html). Maturity: Trial Use 2 (FMM 2). # Endpoint Canonical page: https://docs.ovok.com/api/fhir/r4/endpoint The technical details of an endpoint that can be used for electronic services, such as for web services providing XDS.b or a REST endpoint for another FHIR server. This may include any security context information. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Endpoint/[id]` | | Vread | `GET` | `/fhir/R4/Endpoint/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Endpoint/[id]` | | Patch | `PATCH` | `/fhir/R4/Endpoint/[id]` | | Delete | `DELETE` | `/fhir/R4/Endpoint/[id]` | | Create | `POST` | `/fhir/R4/Endpoint` | | Search | `GET` | `/fhir/R4/Endpoint` | | History | `GET` | `/fhir/R4/Endpoint/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Identifies this endpoint across multiple systems | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| suspended \| error \| off \| entered-in-error \| test | | `connectionType` | [Coding](/fhir-elements/complex/coding) | `1..1` | Protocol/Profile/Standard to be used with this endpoint connection | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | A name that this endpoint can be identified by | | `managingOrganization` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization that manages this endpoint (might not be the organization that exposes the endpoint) | | `contact` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | Contact details for source (e.g. troubleshooting) | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | Interval the endpoint is expected to be operational | | `payloadType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..*` | The type of content that may be used at this endpoint (e.g. XDS Discharge summaries) | | `payloadMimeType` | [code](/fhir-elements/primitive/code) | `0..*` | Mimetype to send. If not specified, the content could be anything (including no payload, if the connectionType defined this) | | `address` | [url](/fhir-elements/primitive/url) | `1..1` | The technical base address for connecting to this endpoint | | `header` | [string](/fhir-elements/primitive/string) | `0..*` | Usage depends on the channel type | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `connection-type` | token | Protocol/Profile/Standard to be used with this endpoint connection | | `identifier` | token | Identifies this endpoint across multiple systems | | `name` | string | A name that this endpoint can be identified by | | `organization` | reference | The organization that is managing the endpoint | | `payload-type` | token | The type of content that may be used at this endpoint (e.g. XDS Discharge summaries) | | `status` | token | The current status of the Endpoint (usually expected to be active) | ## Reference [#reference] Official FHIR R4 spec: [Endpoint](https://hl7.org/fhir/R4/endpoint.html). Maturity: Trial Use 2 (FMM 2). # EnrollmentRequest Canonical page: https://docs.ovok.com/api/fhir/r4/enrollment-request This resource provides the insurance enrollment details to the insurer regarding a specified coverage. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/EnrollmentRequest/[id]` | | Vread | `GET` | `/fhir/R4/EnrollmentRequest/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/EnrollmentRequest/[id]` | | Patch | `PATCH` | `/fhir/R4/EnrollmentRequest/[id]` | | Delete | `DELETE` | `/fhir/R4/EnrollmentRequest/[id]` | | Create | `POST` | `/fhir/R4/EnrollmentRequest` | | Search | `GET` | `/fhir/R4/EnrollmentRequest` | | History | `GET` | `/fhir/R4/EnrollmentRequest/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | active \| cancelled \| draft \| entered-in-error | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Creation date | | `insurer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Target | | `provider` | [Reference](/fhir-elements/complex/reference) | `0..1` | Responsible practitioner | | `candidate` | [Reference](/fhir-elements/complex/reference) | `0..1` | The subject to be enrolled | | `coverage` | [Reference](/fhir-elements/complex/reference) | `0..1` | Insurance information | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `identifier` | token | The business identifier of the Enrollment | | `patient` | reference | The party to be enrolled | | `status` | token | The status of the enrollment | | `subject` | reference | The party to be enrolled | ## Reference [#reference] Official FHIR R4 spec: [EnrollmentRequest](https://hl7.org/fhir/R4/enrollmentrequest.html). Maturity: Draft (FMM 0). # EnrollmentResponse Canonical page: https://docs.ovok.com/api/fhir/r4/enrollment-response This resource provides enrollment and plan details from the processing of an EnrollmentRequest resource. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/EnrollmentResponse/[id]` | | Vread | `GET` | `/fhir/R4/EnrollmentResponse/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/EnrollmentResponse/[id]` | | Patch | `PATCH` | `/fhir/R4/EnrollmentResponse/[id]` | | Delete | `DELETE` | `/fhir/R4/EnrollmentResponse/[id]` | | Create | `POST` | `/fhir/R4/EnrollmentResponse` | | Search | `GET` | `/fhir/R4/EnrollmentResponse` | | History | `GET` | `/fhir/R4/EnrollmentResponse/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | active \| cancelled \| draft \| entered-in-error | | `request` | [Reference](/fhir-elements/complex/reference) | `0..1` | Claim reference | | `outcome` | [code](/fhir-elements/primitive/code) | `0..1` | queued \| complete \| error \| partial | | `disposition` | [string](/fhir-elements/primitive/string) | `0..1` | Disposition Message | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Creation date | | `organization` | [Reference](/fhir-elements/complex/reference) | `0..1` | Insurer | | `requestProvider` | [Reference](/fhir-elements/complex/reference) | `0..1` | Responsible practitioner | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `identifier` | token | The business identifier of the EnrollmentResponse | | `request` | reference | The reference to the claim | | `status` | token | The status of the enrollment response | ## Reference [#reference] Official FHIR R4 spec: [EnrollmentResponse](https://hl7.org/fhir/R4/enrollmentresponse.html). Maturity: Draft (FMM 0). # EpisodeOfCare Canonical page: https://docs.ovok.com/api/fhir/r4/episode-of-care An association between a patient and an organization / healthcare provider(s) during which time encounters may occur. The managing organization assumes a level of responsibility for the patient during this time. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/EpisodeOfCare/[id]` | | Vread | `GET` | `/fhir/R4/EpisodeOfCare/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/EpisodeOfCare/[id]` | | Patch | `PATCH` | `/fhir/R4/EpisodeOfCare/[id]` | | Delete | `DELETE` | `/fhir/R4/EpisodeOfCare/[id]` | | Create | `POST` | `/fhir/R4/EpisodeOfCare` | | Search | `GET` | `/fhir/R4/EpisodeOfCare` | | History | `GET` | `/fhir/R4/EpisodeOfCare/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier(s) relevant for this EpisodeOfCare | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | planned \| waitlist \| active \| onhold \| finished \| cancelled \| entered-in-error | | `statusHistory` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Past list of status codes (the current status may be included to cover the start date of the status) | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Type/class - e.g. specialist referral, disease management | | `diagnosis` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The list of diagnosis relevant to this episode of care | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | The patient who is the focus of this episode of care | | `managingOrganization` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization that assumes care | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | Interval during responsibility is assumed | | `referralRequest` | [Reference](/fhir-elements/complex/reference) | `0..*` | Originating Referral Request(s) | | `careManager` | [Reference](/fhir-elements/complex/reference) | `0..1` | Care manager/care coordinator for the patient | | `team` | [Reference](/fhir-elements/complex/reference) | `0..*` | Other practitioners facilitating this episode of care | | `account` | [Reference](/fhir-elements/complex/reference) | `0..*` | The set of accounts that may be used for billing for this EpisodeOfCare | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `care-manager` | reference | Care manager/care coordinator for the patient | | `condition` | reference | Conditions/problems/diagnoses this episode of care is for | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `incoming-referral` | reference | Incoming Referral Request | | `organization` | reference | The organization that has assumed the specific responsibilities of this EpisodeOfCare | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `status` | token | The current status of the Episode of Care as provided (does not check the status history collection) | | `type` | token | Multiple Resources: AllergyIntolerance: allergy \| intolerance - Underlying mechanism (if known) ; Composition: Kind of composition (LOINC if possible) ; DocumentManifest: Kind of document set ; DocumentReference: Kind of document (LOINC if possible) ; Encounter: Specific type of encounter ; EpisodeOfCare: Type/class - e.g. specialist referral, disease management | ## Reference [#reference] Official FHIR R4 spec: [EpisodeOfCare](https://hl7.org/fhir/R4/episodeofcare.html). Maturity: Trial Use 2 (FMM 2). # EventDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/event-definition The EventDefinition resource provides a reusable description of when a particular event can occur. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/EventDefinition/[id]` | | Vread | `GET` | `/fhir/R4/EventDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/EventDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/EventDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/EventDefinition/[id]` | | Create | `POST` | `/fhir/R4/EventDefinition` | | Search | `GET` | `/fhir/R4/EventDefinition` | | History | `GET` | `/fhir/R4/EventDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this event definition, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the event definition | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the event definition | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this event definition (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this event definition (human friendly) | | `subtitle` | [string](/fhir-elements/primitive/string) | `0..1` | Subordinate title of the event definition | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `subject[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `0..1` | Type of individual the event definition is focused on | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the event definition | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for event definition (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this event definition is defined | | `usage` | [string](/fhir-elements/primitive/string) | `0..1` | Describes the clinical usage of the event definition | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the event definition was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the event definition was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the event definition is expected to be used | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | E.g. Education, Treatment, Assessment, etc. | | `author` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who authored the content | | `editor` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who edited the content | | `reviewer` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who reviewed the content | | `endorser` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who endorsed the content | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | Additional documentation, citations, etc. | | `trigger` | [TriggerDefinition](/fhir-elements/complex/trigger-definition) | `1..*` | "when" the event occurs (multiple = 'or') | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `composed-of` | reference | What resource is being referenced | | `context` | token | A use context assigned to the event definition | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the event definition | | `context-type` | token | A type of use context assigned to the event definition | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the event definition | | `context-type-value` | composite | A use context type and value assigned to the event definition | | `date` | date | The event definition publication date | | `depends-on` | reference | What resource is being referenced | | `derived-from` | reference | What resource is being referenced | | `description` | string | The description of the event definition | | `effective` | date | The time during which the event definition is intended to be in use | | `identifier` | token | External identifier for the event definition | | `jurisdiction` | token | Intended jurisdiction for the event definition | | `name` | string | Computationally friendly name of the event definition | | `predecessor` | reference | What resource is being referenced | | `publisher` | string | Name of the publisher of the event definition | | `status` | token | The current status of the event definition | | `successor` | reference | What resource is being referenced | | `title` | string | The human-friendly name of the event definition | | `topic` | token | Topics associated with the module | | `url` | uri | The uri that identifies the event definition | | `version` | token | The business version of the event definition | ## Reference [#reference] Official FHIR R4 spec: [EventDefinition](https://hl7.org/fhir/R4/eventdefinition.html). Maturity: Draft (FMM 0). # EvidenceVariable Canonical page: https://docs.ovok.com/api/fhir/r4/evidence-variable The EvidenceVariable resource describes a "PICO" element that knowledge (evidence, assertion, recommendation) is about. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/EvidenceVariable/[id]` | | Vread | `GET` | `/fhir/R4/EvidenceVariable/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/EvidenceVariable/[id]` | | Patch | `PATCH` | `/fhir/R4/EvidenceVariable/[id]` | | Delete | `DELETE` | `/fhir/R4/EvidenceVariable/[id]` | | Create | `POST` | `/fhir/R4/EvidenceVariable` | | Search | `GET` | `/fhir/R4/EvidenceVariable` | | History | `GET` | `/fhir/R4/EvidenceVariable/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this evidence variable, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the evidence variable | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the evidence variable | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this evidence variable (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this evidence variable (human friendly) | | `shortTitle` | [string](/fhir-elements/primitive/string) | `0..1` | Title for use in informal contexts | | `subtitle` | [string](/fhir-elements/primitive/string) | `0..1` | Subordinate title of the EvidenceVariable | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the evidence variable | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Used for footnotes or explanatory notes | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for evidence variable (if applicable) | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the evidence variable was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the evidence variable was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the evidence variable is expected to be used | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The category of the EvidenceVariable, such as Education, Treatment, Assessment, etc. | | `author` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who authored the content | | `editor` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who edited the content | | `reviewer` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who reviewed the content | | `endorser` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who endorsed the content | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | Additional documentation, citations, etc. | | `type` | [code](/fhir-elements/primitive/code) | `0..1` | dichotomous \| continuous \| descriptive | | `characteristic` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | What defines the members of the evidence element | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `composed-of` | reference | What resource is being referenced | | `context` | token | A use context assigned to the evidence variable | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the evidence variable | | `context-type` | token | A type of use context assigned to the evidence variable | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the evidence variable | | `context-type-value` | composite | A use context type and value assigned to the evidence variable | | `date` | date | The evidence variable publication date | | `depends-on` | reference | What resource is being referenced | | `derived-from` | reference | What resource is being referenced | | `description` | string | The description of the evidence variable | | `effective` | date | The time during which the evidence variable is intended to be in use | | `identifier` | token | External identifier for the evidence variable | | `jurisdiction` | token | Intended jurisdiction for the evidence variable | | `name` | string | Computationally friendly name of the evidence variable | | `predecessor` | reference | What resource is being referenced | | `publisher` | string | Name of the publisher of the evidence variable | | `status` | token | The current status of the evidence variable | | `successor` | reference | What resource is being referenced | | `title` | string | The human-friendly name of the evidence variable | | `topic` | token | Topics associated with the EvidenceVariable | | `url` | uri | The uri that identifies the evidence variable | | `version` | token | The business version of the evidence variable | ## Reference [#reference] Official FHIR R4 spec: [EvidenceVariable](https://hl7.org/fhir/R4/evidencevariable.html). Maturity: Draft (FMM 0). # Evidence Canonical page: https://docs.ovok.com/api/fhir/r4/evidence The Evidence resource describes the conditional state (population and any exposures being compared within the population) and outcome (if specified) that the knowledge (evidence, assertion, recommendation) is about. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Evidence/[id]` | | Vread | `GET` | `/fhir/R4/Evidence/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Evidence/[id]` | | Patch | `PATCH` | `/fhir/R4/Evidence/[id]` | | Delete | `DELETE` | `/fhir/R4/Evidence/[id]` | | Create | `POST` | `/fhir/R4/Evidence` | | Search | `GET` | `/fhir/R4/Evidence` | | History | `GET` | `/fhir/R4/Evidence/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this evidence, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the evidence | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the evidence | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this evidence (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this evidence (human friendly) | | `shortTitle` | [string](/fhir-elements/primitive/string) | `0..1` | Title for use in informal contexts | | `subtitle` | [string](/fhir-elements/primitive/string) | `0..1` | Subordinate title of the Evidence | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the evidence | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Used for footnotes or explanatory notes | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for evidence (if applicable) | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the evidence was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the evidence was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the evidence is expected to be used | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The category of the Evidence, such as Education, Treatment, Assessment, etc. | | `author` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who authored the content | | `editor` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who edited the content | | `reviewer` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who reviewed the content | | `endorser` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who endorsed the content | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | Additional documentation, citations, etc. | | `exposureBackground` | [Reference](/fhir-elements/complex/reference) | `1..1` | What population? | | `exposureVariant` | [Reference](/fhir-elements/complex/reference) | `0..*` | What exposure? | | `outcome` | [Reference](/fhir-elements/complex/reference) | `0..*` | What outcome? | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `composed-of` | reference | What resource is being referenced | | `context` | token | A use context assigned to the evidence | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the evidence | | `context-type` | token | A type of use context assigned to the evidence | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the evidence | | `context-type-value` | composite | A use context type and value assigned to the evidence | | `date` | date | The evidence publication date | | `depends-on` | reference | What resource is being referenced | | `derived-from` | reference | What resource is being referenced | | `description` | string | The description of the evidence | | `effective` | date | The time during which the evidence is intended to be in use | | `identifier` | token | External identifier for the evidence | | `jurisdiction` | token | Intended jurisdiction for the evidence | | `name` | string | Computationally friendly name of the evidence | | `predecessor` | reference | What resource is being referenced | | `publisher` | string | Name of the publisher of the evidence | | `status` | token | The current status of the evidence | | `successor` | reference | What resource is being referenced | | `title` | string | The human-friendly name of the evidence | | `topic` | token | Topics associated with the Evidence | | `url` | uri | The uri that identifies the evidence | | `version` | token | The business version of the evidence | ## Reference [#reference] Official FHIR R4 spec: [Evidence](https://hl7.org/fhir/R4/evidence.html). Maturity: Draft (FMM 0). # ExampleScenario Canonical page: https://docs.ovok.com/api/fhir/r4/example-scenario Example of workflow instance. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ExampleScenario/[id]` | | Vread | `GET` | `/fhir/R4/ExampleScenario/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ExampleScenario/[id]` | | Patch | `PATCH` | `/fhir/R4/ExampleScenario/[id]` | | Delete | `DELETE` | `/fhir/R4/ExampleScenario/[id]` | | Create | `POST` | `/fhir/R4/ExampleScenario` | | Search | `GET` | `/fhir/R4/ExampleScenario` | | History | `GET` | `/fhir/R4/ExampleScenario/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this example scenario, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the example scenario | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the example scenario | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this example scenario (computer friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for example scenario (if applicable) | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | The purpose of the example, e.g. to illustrate a scenario | | `actor` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Actor participating in the resource | | `instance` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Each resource and each version that is present in the workflow | | `process` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Each major process - a group of operations | | `workflow` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Another nested workflow | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `context` | token | A use context assigned to the example scenario | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the example scenario | | `context-type` | token | A type of use context assigned to the example scenario | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the example scenario | | `context-type-value` | composite | A use context type and value assigned to the example scenario | | `date` | date | The example scenario publication date | | `identifier` | token | External identifier for the example scenario | | `jurisdiction` | token | Intended jurisdiction for the example scenario | | `name` | string | Computationally friendly name of the example scenario | | `publisher` | string | Name of the publisher of the example scenario | | `status` | token | The current status of the example scenario | | `url` | uri | The uri that identifies the example scenario | | `version` | token | The business version of the example scenario | ## Reference [#reference] Official FHIR R4 spec: [ExampleScenario](https://hl7.org/fhir/R4/examplescenario.html). Maturity: Draft (FMM 0). # ExplanationOfBenefit Canonical page: https://docs.ovok.com/api/fhir/r4/explanation-of-benefit This resource provides: the claim details; adjudication details from the processing of a Claim; and optionally account balance information, for informing the subscriber of the benefits provided. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ExplanationOfBenefit/[id]` | | Vread | `GET` | `/fhir/R4/ExplanationOfBenefit/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ExplanationOfBenefit/[id]` | | Patch | `PATCH` | `/fhir/R4/ExplanationOfBenefit/[id]` | | Delete | `DELETE` | `/fhir/R4/ExplanationOfBenefit/[id]` | | Create | `POST` | `/fhir/R4/ExplanationOfBenefit` | | Search | `GET` | `/fhir/R4/ExplanationOfBenefit` | | History | `GET` | `/fhir/R4/ExplanationOfBenefit/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for the resource | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| cancelled \| draft \| entered-in-error | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Category or discipline | | `subType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | More granular claim type | | `use` | [code](/fhir-elements/primitive/code) | `1..1` | claim \| preauthorization \| predetermination | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | The recipient of the products and services | | `billablePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | Relevant time frame for the claim | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Response creation date | | `enterer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Author of the claim | | `insurer` | [Reference](/fhir-elements/complex/reference) | `1..1` | Party responsible for reimbursement | | `provider` | [Reference](/fhir-elements/complex/reference) | `1..1` | Party responsible for the claim | | `priority` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Desired processing urgency | | `fundsReserveRequested` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | For whom to reserve funds | | `fundsReserve` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Funds reserved status | | `related` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Prior or corollary claims | | `prescription` | [Reference](/fhir-elements/complex/reference) | `0..1` | Prescription authorizing services or products | | `originalPrescription` | [Reference](/fhir-elements/complex/reference) | `0..1` | Original prescription if superceded by fulfiller | | `payee` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Recipient of benefits payable | | `referral` | [Reference](/fhir-elements/complex/reference) | `0..1` | Treatment Referral | | `facility` | [Reference](/fhir-elements/complex/reference) | `0..1` | Servicing Facility | | `claim` | [Reference](/fhir-elements/complex/reference) | `0..1` | Claim reference | | `claimResponse` | [Reference](/fhir-elements/complex/reference) | `0..1` | Claim response reference | | `outcome` | [code](/fhir-elements/primitive/code) | `1..1` | queued \| complete \| error \| partial | | `disposition` | [string](/fhir-elements/primitive/string) | `0..1` | Disposition Message | | `preAuthRef` | [string](/fhir-elements/primitive/string) | `0..*` | Preauthorization reference | | `preAuthRefPeriod` | [Period](/fhir-elements/complex/period) | `0..*` | Preauthorization in-effect period | | `careTeam` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Care Team members | | `supportingInfo` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Supporting information | | `diagnosis` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Pertinent diagnosis information | | `procedure` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Clinical procedures performed | | `precedence` | [positiveInt](/fhir-elements/primitive/positive-int) | `0..1` | Precedence (primary, secondary, etc.) | | `insurance` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | Patient insurance information | | `accident` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Details of the event | | `item` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Product or service provided | | `addItem` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Insurer added line items | | `adjudication` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Header-level adjudication | | `total` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Adjudication totals | | `payment` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Payment Details | | `formCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Printed form identifier | | `form` | [Attachment](/fhir-elements/complex/attachment) | `0..1` | Printed reference or actual form | | `processNote` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Note concerning adjudication | | `benefitPeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the benefits are applicable | | `benefitBalance` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Balance by Benefit Category | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `care-team` | reference | Member of the CareTeam | | `claim` | reference | The reference to the claim | | `coverage` | reference | The plan under which the claim was adjudicated | | `created` | date | The creation date for the EOB | | `detail-udi` | reference | UDI associated with a line item detail product or service | | `disposition` | string | The contents of the disposition message | | `encounter` | reference | Encounters associated with a billed line item | | `enterer` | reference | The party responsible for the entry of the Claim | | `facility` | reference | Facility responsible for the goods and services | | `identifier` | token | The business identifier of the Explanation of Benefit | | `item-udi` | reference | UDI associated with a line item product or service | | `patient` | reference | The reference to the patient | | `payee` | reference | The party receiving any payment for the Claim | | `procedure-udi` | reference | UDI associated with a procedure | | `provider` | reference | The reference to the provider | | `status` | token | Status of the instance | | `subdetail-udi` | reference | UDI associated with a line item detail subdetail product or service | ## Reference [#reference] Official FHIR R4 spec: [ExplanationOfBenefit](https://hl7.org/fhir/R4/explanationofbenefit.html). Maturity: Trial Use 2 (FMM 2). # FamilyMemberHistory Canonical page: https://docs.ovok.com/api/fhir/r4/family-member-history Significant health conditions for a person related to the patient relevant in the context of care for the patient. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/FamilyMemberHistory/[id]` | | Vread | `GET` | `/fhir/R4/FamilyMemberHistory/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/FamilyMemberHistory/[id]` | | Patch | `PATCH` | `/fhir/R4/FamilyMemberHistory/[id]` | | Delete | `DELETE` | `/fhir/R4/FamilyMemberHistory/[id]` | | Create | `POST` | `/fhir/R4/FamilyMemberHistory` | | Search | `GET` | `/fhir/R4/FamilyMemberHistory` | | History | `GET` | `/fhir/R4/FamilyMemberHistory/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Id(s) for this record | | `instantiatesCanonical` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Instantiates FHIR protocol or definition | | `instantiatesUri` | [uri](/fhir-elements/primitive/uri) | `0..*` | Instantiates external protocol or definition | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | partial \| completed \| entered-in-error \| health-unknown | | `dataAbsentReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | subject-unknown \| withheld \| unable-to-obtain \| deferred | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | Patient history is about | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When history was recorded or last updated | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | The family member described | | `relationship` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Relationship to the subject | | `sex` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | male \| female \| other \| unknown | | `born[x]` | [Period](/fhir-elements/complex/period), [date](/fhir-elements/primitive/date), [string](/fhir-elements/primitive/string) | `0..1` | (approximate) date of birth | | `age[x]` | [Age](/fhir-elements/complex/age), [Range](/fhir-elements/complex/range), [string](/fhir-elements/primitive/string) | `0..1` | (approximate) age | | `estimatedAge` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Age is estimated? | | `deceased[x]` | [boolean](/fhir-elements/primitive/boolean), [Age](/fhir-elements/complex/age), [Range](/fhir-elements/complex/range), [date](/fhir-elements/primitive/date), [string](/fhir-elements/primitive/string) | `0..1` | Dead? How old/when? | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Why was family member history performed? | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Why was family member history performed? | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | General note about related person | | `condition` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Condition that the related person had | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `instantiates-canonical` | reference | Instantiates FHIR protocol or definition | | `instantiates-uri` | uri | Instantiates external protocol or definition | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `relationship` | token | A search by a relationship type | | `sex` | token | A search by a sex code of a family member | | `status` | token | partial \| completed \| entered-in-error \| health-unknown | ## Reference [#reference] Official FHIR R4 spec: [FamilyMemberHistory](https://hl7.org/fhir/R4/familymemberhistory.html). Maturity: Trial Use 2 (FMM 2). # Flag Canonical page: https://docs.ovok.com/api/fhir/r4/flag Prospective warnings of potential issues when providing care to the patient. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Flag/[id]` | | Vread | `GET` | `/fhir/R4/Flag/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Flag/[id]` | | Patch | `PATCH` | `/fhir/R4/Flag/[id]` | | Delete | `DELETE` | `/fhir/R4/Flag/[id]` | | Create | `POST` | `/fhir/R4/Flag` | | Search | `GET` | `/fhir/R4/Flag` | | History | `GET` | `/fhir/R4/Flag/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| inactive \| entered-in-error | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Clinical, administrative, etc. | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Coded or textual message to display to user | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who/What is flag about? | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | Time period when flag is active | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Alert relevant during encounter | | `author` | [Reference](/fhir-elements/complex/reference) | `0..1` | Flag creator | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `author` | reference | Flag creator | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `identifier` | token | Business identifier | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `subject` | reference | The identity of a subject to list flags for | ## Reference [#reference] Official FHIR R4 spec: [Flag](https://hl7.org/fhir/R4/flag.html). Maturity: Trial Use 1 (FMM 1). # Goal Canonical page: https://docs.ovok.com/api/fhir/r4/goal Describes the intended objective(s) for a patient, group or organization care, for example, weight loss, restoring an activity of daily living, obtaining herd immunity via immunization, meeting a process improvement objective, etc. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Goal/[id]` | | Vread | `GET` | `/fhir/R4/Goal/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Goal/[id]` | | Patch | `PATCH` | `/fhir/R4/Goal/[id]` | | Delete | `DELETE` | `/fhir/R4/Goal/[id]` | | Create | `POST` | `/fhir/R4/Goal` | | Search | `GET` | `/fhir/R4/Goal` | | History | `GET` | `/fhir/R4/Goal/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Ids for this goal | | `lifecycleStatus` | [code](/fhir-elements/primitive/code) | `1..1` | proposed \| planned \| accepted \| active \| on-hold \| completed \| cancelled \| entered-in-error \| rejected | | `achievementStatus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | in-progress \| improving \| worsening \| no-change \| achieved \| sustaining \| not-achieved \| no-progress \| not-attainable | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | E.g. Treatment, dietary, behavioral, etc. | | `priority` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | high-priority \| medium-priority \| low-priority | | `description` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Code or text describing goal | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who this goal is intended for | | `start[x]` | [date](/fhir-elements/primitive/date), [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | When goal pursuit begins | | `target` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Target outcome for the goal | | `statusDate` | [date](/fhir-elements/primitive/date) | `0..1` | When goal status took effect | | `statusReason` | [string](/fhir-elements/primitive/string) | `0..1` | Reason for current status | | `expressedBy` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who's responsible for creating Goal? | | `addresses` | [Reference](/fhir-elements/complex/reference) | `0..*` | Issues addressed by this goal | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments about the goal | | `outcomeCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | What result was achieved regarding the goal? | | `outcomeReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Observation that resulted from goal | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `achievement-status` | token | in-progress \| improving \| worsening \| no-change \| achieved \| sustaining \| not-achieved \| no-progress \| not-attainable | | `category` | token | E.g. Treatment, dietary, behavioral, etc. | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `lifecycle-status` | token | proposed \| planned \| accepted \| active \| on-hold \| completed \| cancelled \| entered-in-error \| rejected | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `start-date` | date | When goal pursuit begins | | `subject` | reference | Who this goal is intended for | | `target-date` | date | Reach goal on or before | ## Reference [#reference] Official FHIR R4 spec: [Goal](https://hl7.org/fhir/R4/goal.html). Maturity: Trial Use 2 (FMM 2). # GraphDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/graph-definition A formal computable definition of a graph of resources - that is, a coherent set of resources that form a graph by following references. The Graph Definition resource defines a set and makes rules about the set. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/GraphDefinition/[id]` | | Vread | `GET` | `/fhir/R4/GraphDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/GraphDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/GraphDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/GraphDefinition/[id]` | | Create | `POST` | `/fhir/R4/GraphDefinition` | | Search | `GET` | `/fhir/R4/GraphDefinition` | | History | `GET` | `/fhir/R4/GraphDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this graph definition, represented as a URI (globally unique) | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the graph definition | | `name` | [string](/fhir-elements/primitive/string) | `1..1` | Name for this graph definition (computer friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the graph definition | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for graph definition (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this graph definition is defined | | `start` | [code](/fhir-elements/primitive/code) | `1..1` | Type of resource at which the graph starts | | `profile` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Profile on base resource | | `link` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Links this graph makes rules about | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `start` | token | Type of resource at which the graph starts | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [GraphDefinition](https://hl7.org/fhir/R4/graphdefinition.html). Maturity: Trial Use 1 (FMM 1). # Group Canonical page: https://docs.ovok.com/api/fhir/r4/group Represents a defined collection of entities that may be discussed or acted upon collectively but which are not expected to act collectively, and are not formally or legally recognized; i.e. a collection of entities that isn't an Organization. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Group/[id]` | | Vread | `GET` | `/fhir/R4/Group/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Group/[id]` | | Patch | `PATCH` | `/fhir/R4/Group/[id]` | | Delete | `DELETE` | `/fhir/R4/Group/[id]` | | Create | `POST` | `/fhir/R4/Group` | | Search | `GET` | `/fhir/R4/Group` | | History | `GET` | `/fhir/R4/Group/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Unique id | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether this group's record is in active use | | `type` | [code](/fhir-elements/primitive/code) | `1..1` | person \| animal \| practitioner \| device \| medication \| substance | | `actual` | [boolean](/fhir-elements/primitive/boolean) | `1..1` | Descriptive or actual | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Kind of Group members | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Label for Group | | `quantity` | [unsignedInt](/fhir-elements/primitive/unsigned-int) | `0..1` | Number of members | | `managingEntity` | [Reference](/fhir-elements/complex/reference) | `0..1` | Entity that is the custodian of the Group's definition | | `characteristic` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Include / Exclude group members by Trait | | `member` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Who or what is in group | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `actual` | token | Descriptive or actual | | `characteristic` | token | Kind of characteristic | | `characteristic-value` | composite | A composite of both characteristic and value | | `code` | token | The kind of resources contained | | `exclude` | token | Group includes or excludes | | `identifier` | token | Unique id | | `managing-entity` | reference | Entity that is the custodian of the Group's definition | | `member` | reference | Reference to the group member | | `type` | token | The type of resources the group contains | | `value` | token | Value held by characteristic | ## Reference [#reference] Official FHIR R4 spec: [Group](https://hl7.org/fhir/R4/group.html). Maturity: Trial Use 1 (FMM 1). # GuidanceResponse Canonical page: https://docs.ovok.com/api/fhir/r4/guidance-response A guidance response is the formal response to a guidance request, including any output parameters returned by the evaluation, as well as the description of any proposed actions to be taken. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/GuidanceResponse/[id]` | | Vread | `GET` | `/fhir/R4/GuidanceResponse/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/GuidanceResponse/[id]` | | Patch | `PATCH` | `/fhir/R4/GuidanceResponse/[id]` | | Delete | `DELETE` | `/fhir/R4/GuidanceResponse/[id]` | | Create | `POST` | `/fhir/R4/GuidanceResponse` | | Search | `GET` | `/fhir/R4/GuidanceResponse` | | History | `GET` | `/fhir/R4/GuidanceResponse/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `requestIdentifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | The identifier of the request associated with this response, if any | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier | | `module[x]` | [uri](/fhir-elements/primitive/uri), [canonical](/fhir-elements/primitive/canonical), [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | What guidance was requested | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | success \| data-requested \| data-required \| in-progress \| failure \| entered-in-error | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Patient the request was performed for | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter during which the response was returned | | `occurrenceDateTime` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the guidance response was processed | | `performer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Device returning the guidance | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Why guidance is needed | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Why guidance is needed | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Additional notes about the response | | `evaluationMessage` | [Reference](/fhir-elements/complex/reference) | `0..*` | Messages resulting from the evaluation of the artifact or artifacts | | `outputParameters` | [Reference](/fhir-elements/complex/reference) | `0..1` | The output parameters of the evaluation, if any | | `result` | [Reference](/fhir-elements/complex/reference) | `0..1` | Proposed actions, if any | | `dataRequirement` | [DataRequirement](/fhir-elements/complex/data-requirement) | `0..*` | Additional required data | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `identifier` | token | The identifier of the guidance response | | `patient` | reference | The identity of a patient to search for guidance response results | | `request` | token | The identifier of the request associated with the response | | `subject` | reference | The subject that the guidance response is about | ## Reference [#reference] Official FHIR R4 spec: [GuidanceResponse](https://hl7.org/fhir/R4/guidanceresponse.html). Maturity: Trial Use 2 (FMM 2). # HealthcareService Canonical page: https://docs.ovok.com/api/fhir/r4/healthcare-service The details of a healthcare service available at a location. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/HealthcareService/[id]` | | Vread | `GET` | `/fhir/R4/HealthcareService/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/HealthcareService/[id]` | | Patch | `PATCH` | `/fhir/R4/HealthcareService/[id]` | | Delete | `DELETE` | `/fhir/R4/HealthcareService/[id]` | | Create | `POST` | `/fhir/R4/HealthcareService` | | Search | `GET` | `/fhir/R4/HealthcareService` | | History | `GET` | `/fhir/R4/HealthcareService/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External identifiers for this item | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether this HealthcareService record is in active use | | `providedBy` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization that provides this service | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Broad category of service being performed or delivered | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Type of service that may be delivered or performed | | `specialty` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Specialties handled by the HealthcareService | | `location` | [Reference](/fhir-elements/complex/reference) | `0..*` | Location(s) where service may be provided | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Description of service as presented to a consumer while searching | | `comment` | [string](/fhir-elements/primitive/string) | `0..1` | Additional description and/or any specific issues not covered elsewhere | | `extraDetails` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Extra details about the service that can't be placed in the other fields | | `photo` | [Attachment](/fhir-elements/complex/attachment) | `0..1` | Facilitates quick identification of the service | | `telecom` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | Contacts related to the healthcare service | | `coverageArea` | [Reference](/fhir-elements/complex/reference) | `0..*` | Location(s) service is intended for/available to | | `serviceProvisionCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Conditions under which service is available/offered | | `eligibility` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Specific eligibility requirements required to use the service | | `program` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Programs that this service is applicable to | | `characteristic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Collection of characteristics (attributes) | | `communication` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The language that this service is offered in | | `referralMethod` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Ways that the service accepts referrals | | `appointmentRequired` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | If an appointment is required for access to this service | | `availableTime` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Times the Service Site is available | | `notAvailable` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Not available during this time due to provided reason | | `availabilityExceptions` | [string](/fhir-elements/primitive/string) | `0..1` | Description of availability exceptions | | `endpoint` | [Reference](/fhir-elements/complex/reference) | `0..*` | Technical endpoints providing access to electronic services operated for the healthcare service | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `active` | token | The Healthcare Service is currently marked as active | | `characteristic` | token | One of the HealthcareService's characteristics | | `coverage-area` | reference | Location(s) service is intended for/available to | | `endpoint` | reference | Technical endpoints providing access to electronic services operated for the healthcare service | | `identifier` | token | External identifiers for this item | | `location` | reference | The location of the Healthcare Service | | `name` | string | A portion of the Healthcare service name | | `organization` | reference | The organization that provides this Healthcare Service | | `program` | token | One of the Programs supported by this HealthcareService | | `service-category` | token | Service Category of the Healthcare Service | | `service-type` | token | The type of service provided by this healthcare service | | `specialty` | token | The specialty of the service provided by this healthcare service | ## Reference [#reference] Official FHIR R4 spec: [HealthcareService](https://hl7.org/fhir/R4/healthcareservice.html). Maturity: Trial Use 2 (FMM 2). # ImagingStudy Canonical page: https://docs.ovok.com/api/fhir/r4/imaging-study Representation of the content produced in a DICOM imaging study. A study comprises a set of series, each of which includes a set of Service-Object Pair Instances (SOP Instances - images or other data) acquired or produced in a common context. A series is of only one modality (e.g. X-ray, CT, MR, ultrasound), but a study may have multiple series of different modalities. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ImagingStudy/[id]` | | Vread | `GET` | `/fhir/R4/ImagingStudy/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ImagingStudy/[id]` | | Patch | `PATCH` | `/fhir/R4/ImagingStudy/[id]` | | Delete | `DELETE` | `/fhir/R4/ImagingStudy/[id]` | | Create | `POST` | `/fhir/R4/ImagingStudy` | | Search | `GET` | `/fhir/R4/ImagingStudy` | | History | `GET` | `/fhir/R4/ImagingStudy/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Identifiers for the whole study | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | registered \| available \| cancelled \| entered-in-error \| unknown | | `modality` | [Coding](/fhir-elements/complex/coding) | `0..*` | All series modality if actual acquisition modalities | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who or what is the subject of the study | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter with which this imaging study is associated | | `started` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the study was started | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Request fulfilled | | `referrer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Referring physician | | `interpreter` | [Reference](/fhir-elements/complex/reference) | `0..*` | Who interpreted images | | `endpoint` | [Reference](/fhir-elements/complex/reference) | `0..*` | Study access endpoint | | `numberOfSeries` | [unsignedInt](/fhir-elements/primitive/unsigned-int) | `0..1` | Number of Study Related Series | | `numberOfInstances` | [unsignedInt](/fhir-elements/primitive/unsigned-int) | `0..1` | Number of Study Related Instances | | `procedureReference` | [Reference](/fhir-elements/complex/reference) | `0..1` | The performed Procedure reference | | `procedureCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The performed procedure code | | `location` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where ImagingStudy occurred | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Why the study was requested | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Why was study performed | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | User-defined comments | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Institution-generated description | | `series` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Each study has one or more series of instances | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `basedon` | reference | The order for the image | | `bodysite` | token | The body site studied | | `dicom-class` | token | The type of the instance | | `encounter` | reference | The context of the study | | `endpoint` | reference | The endpoint for the study or series | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `instance` | token | SOP Instance UID for an instance | | `interpreter` | reference | Who interpreted the images | | `modality` | token | The modality of the series | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `performer` | reference | The person who performed the study | | `reason` | token | The reason for the study | | `referrer` | reference | The referring physician | | `series` | token | DICOM Series Instance UID for a series | | `started` | date | When the study was started | | `status` | token | The status of the study | | `subject` | reference | Who the study is about | ## Reference [#reference] Official FHIR R4 spec: [ImagingStudy](https://hl7.org/fhir/R4/imagingstudy.html). Maturity: Trial Use 3 (FMM 3). # ImmunizationEvaluation Canonical page: https://docs.ovok.com/api/fhir/r4/immunization-evaluation Describes a comparison of an immunization event against published recommendations to determine if the administration is "valid" in relation to those recommendations. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ImmunizationEvaluation/[id]` | | Vread | `GET` | `/fhir/R4/ImmunizationEvaluation/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ImmunizationEvaluation/[id]` | | Patch | `PATCH` | `/fhir/R4/ImmunizationEvaluation/[id]` | | Delete | `DELETE` | `/fhir/R4/ImmunizationEvaluation/[id]` | | Create | `POST` | `/fhir/R4/ImmunizationEvaluation` | | Search | `GET` | `/fhir/R4/ImmunizationEvaluation` | | History | `GET` | `/fhir/R4/ImmunizationEvaluation/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | completed \| entered-in-error | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who this evaluation is for | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date evaluation was performed | | `authority` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who is responsible for publishing the recommendations | | `targetDisease` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Evaluation target disease | | `immunizationEvent` | [Reference](/fhir-elements/complex/reference) | `1..1` | Immunization being evaluated | | `doseStatus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Status of the dose relative to published recommendations | | `doseStatusReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Reason for the dose status | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Evaluation notes | | `series` | [string](/fhir-elements/primitive/string) | `0..1` | Name of vaccine series | | `doseNumber[x]` | [positiveInt](/fhir-elements/primitive/positive-int), [string](/fhir-elements/primitive/string) | `0..1` | Dose number within series | | `seriesDoses[x]` | [positiveInt](/fhir-elements/primitive/positive-int), [string](/fhir-elements/primitive/string) | `0..1` | Recommended number of doses for immunity | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `date` | date | Date the evaluation was generated | | `dose-status` | token | The status of the dose relative to published recommendations | | `identifier` | token | ID of the evaluation | | `immunization-event` | reference | The vaccine administration event being evaluated | | `patient` | reference | The patient being evaluated | | `status` | token | Immunization evaluation status | | `target-disease` | token | The vaccine preventable disease being evaluated against | ## Reference [#reference] Official FHIR R4 spec: [ImmunizationEvaluation](https://hl7.org/fhir/R4/immunizationevaluation.html). Maturity: Draft (FMM 0). # ImmunizationRecommendation Canonical page: https://docs.ovok.com/api/fhir/r4/immunization-recommendation A patient's point-in-time set of recommendations (i.e. forecasting) according to a published schedule with optional supporting justification. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ImmunizationRecommendation/[id]` | | Vread | `GET` | `/fhir/R4/ImmunizationRecommendation/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ImmunizationRecommendation/[id]` | | Patch | `PATCH` | `/fhir/R4/ImmunizationRecommendation/[id]` | | Delete | `DELETE` | `/fhir/R4/ImmunizationRecommendation/[id]` | | Create | `POST` | `/fhir/R4/ImmunizationRecommendation` | | Search | `GET` | `/fhir/R4/ImmunizationRecommendation` | | History | `GET` | `/fhir/R4/ImmunizationRecommendation/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who this profile is for | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Date recommendation(s) created | | `authority` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who is responsible for protocol | | `recommendation` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | Vaccine administration recommendations | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `date` | date | Date recommendation(s) created | | `identifier` | token | Business identifier | | `information` | reference | Patient observations supporting recommendation | | `patient` | reference | Who this profile is for | | `status` | token | Vaccine recommendation status | | `support` | reference | Past immunizations supporting recommendation | | `target-disease` | token | Disease to be immunized against | | `vaccine-type` | token | Vaccine or vaccine group recommendation applies to | ## Reference [#reference] Official FHIR R4 spec: [ImmunizationRecommendation](https://hl7.org/fhir/R4/immunizationrecommendation.html). Maturity: Trial Use 1 (FMM 1). # Immunization Canonical page: https://docs.ovok.com/api/fhir/r4/immunization Describes the event of a patient being administered a vaccine or a record of an immunization as reported by a patient, a clinician or another party. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Immunization/[id]` | | Vread | `GET` | `/fhir/R4/Immunization/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Immunization/[id]` | | Patch | `PATCH` | `/fhir/R4/Immunization/[id]` | | Delete | `DELETE` | `/fhir/R4/Immunization/[id]` | | Create | `POST` | `/fhir/R4/Immunization` | | Search | `GET` | `/fhir/R4/Immunization` | | History | `GET` | `/fhir/R4/Immunization/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | completed \| entered-in-error \| not-done | | `statusReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Reason not done | | `vaccineCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Vaccine product administered | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who was immunized | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter immunization was part of | | `occurrence[x]` | [dateTime](/fhir-elements/primitive/date-time), [string](/fhir-elements/primitive/string) | `1..1` | Vaccine administration date | | `recorded` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the immunization was first captured in the subject's record | | `primarySource` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Indicates context the data was recorded in | | `reportOrigin` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Indicates the source of a secondarily reported record | | `location` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where immunization occurred | | `manufacturer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Vaccine manufacturer | | `lotNumber` | [string](/fhir-elements/primitive/string) | `0..1` | Vaccine lot number | | `expirationDate` | [date](/fhir-elements/primitive/date) | `0..1` | Vaccine expiration date | | `site` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Body site vaccine was administered | | `route` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | How vaccine entered body | | `doseQuantity` | [Quantity](/fhir-elements/complex/quantity) | `0..1` | Amount of vaccine administered | | `performer` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Who performed event | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Additional immunization notes | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Why immunization occurred | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Why immunization occurred | | `isSubpotent` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Dose potency | | `subpotentReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Reason for being subpotent | | `education` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Educational material presented to patient | | `programEligibility` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Patient eligibility for a vaccination program | | `fundingSource` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Funding source for the vaccine | | `reaction` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Details of a reaction that follows immunization | | `protocolApplied` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Protocol followed by the provider | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `location` | reference | The service delivery location or facility in which the vaccine was / was to be administered | | `lot-number` | string | Vaccine Lot Number | | `manufacturer` | reference | Vaccine Manufacturer | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `performer` | reference | The practitioner or organization who played a role in the vaccination | | `reaction` | reference | Additional information on reaction | | `reaction-date` | date | When reaction started | | `reason-code` | token | Reason why the vaccine was administered | | `reason-reference` | reference | Why immunization occurred | | `series` | string | The series being followed by the provider | | `status` | token | Immunization event status | | `status-reason` | token | Reason why the vaccine was not administered | | `target-disease` | token | The target disease the dose is being administered against | | `vaccine-code` | token | Vaccine Product Administered | ## Reference [#reference] Official FHIR R4 spec: [Immunization](https://hl7.org/fhir/R4/immunization.html). Maturity: Trial Use 3 (FMM 3). # ImplementationGuide Canonical page: https://docs.ovok.com/api/fhir/r4/implementation-guide A set of rules of how a particular interoperability or standards problem is solved - typically through the use of FHIR resources. This resource is used to gather all the parts of an implementation guide into a logical whole and to publish a computable definition of all the parts. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ImplementationGuide/[id]` | | Vread | `GET` | `/fhir/R4/ImplementationGuide/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ImplementationGuide/[id]` | | Patch | `PATCH` | `/fhir/R4/ImplementationGuide/[id]` | | Delete | `DELETE` | `/fhir/R4/ImplementationGuide/[id]` | | Create | `POST` | `/fhir/R4/ImplementationGuide` | | Search | `GET` | `/fhir/R4/ImplementationGuide` | | History | `GET` | `/fhir/R4/ImplementationGuide/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `1..1` | Canonical identifier for this implementation guide, represented as a URI (globally unique) | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the implementation guide | | `name` | [string](/fhir-elements/primitive/string) | `1..1` | Name for this implementation guide (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this implementation guide (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the implementation guide | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for implementation guide (if applicable) | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `packageId` | [id](/fhir-elements/primitive/id) | `1..1` | NPM Package name for IG | | `license` | [code](/fhir-elements/primitive/code) | `0..1` | SPDX license code for this IG (or not-open-source) | | `fhirVersion` | [code](/fhir-elements/primitive/code) | `1..*` | FHIR Version(s) this Implementation Guide targets | | `dependsOn` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Another Implementation guide this depends on | | `global` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Profiles that apply globally | | `definition` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Information needed to build the IG | | `manifest` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Information about an assembled IG | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `depends-on` | reference | Identity of the IG that this depends on | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `experimental` | token | For testing purposes, not real usage | | `global` | reference | Profile that all resources must conform to | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `resource` | reference | Location of the resource | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `title` | string | Multiple Resources: CapabilityStatement: The human-friendly name of the capability statement ; CodeSystem: The human-friendly name of the code system ; ConceptMap: The human-friendly name of the concept map ; ImplementationGuide: The human-friendly name of the implementation guide ; MessageDefinition: The human-friendly name of the message definition ; OperationDefinition: The human-friendly name of the operation definition ; StructureDefinition: The human-friendly name of the structure definition ; StructureMap: The human-friendly name of the structure map ; TerminologyCapabilities: The human-friendly name of the terminology capabilities ; ValueSet: The human-friendly name of the value set | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [ImplementationGuide](https://hl7.org/fhir/R4/implementationguide.html). Maturity: Trial Use 1 (FMM 1). # FHIR resources Canonical page: https://docs.ovok.com/api/fhir/r4 FHIR R4 organizes clinical and administrative information into typed resources. Each resource has a defined structure, cardinalities, data types, and standard interactions. Ovok exposes FHIR resource APIs for application workflows; the exact interactions available to a project are determined by its API capabilities. This reference is generated from the official HL7 FHIR R4 core definitions package, release 4.0.1. It covers **146 concrete resource definitions**, including each resource's purpose, standard interaction paths, top-level elements, resource-specific search parameters, and maturity level. ## Choose a resource [#choose-a-resource] Start with the records most commonly used in remote monitoring and care applications: - [CarePlan](/api/fhir/r4/care-plan) — Describes the intention of how one or more practitioners intend to deliver care for a particular patient, group or community for a period of time, possibly limited to care for a specific condition or set of conditions. - [Device](/api/fhir/r4/device) — A type of a manufactured item that is used in the provision of healthcare without being substantially changed through that activity. The device may be a medical or non-medical device. - [Encounter](/api/fhir/r4/encounter) — An interaction between a patient and healthcare provider(s) for the purpose of providing healthcare service(s) or assessing the health status of a patient. - [Medication](/api/fhir/r4/medication) — This resource is primarily used for the identification and definition of a medication for the purposes of prescribing, dispensing, and administering a medication as well as for making statements about medication use. - [Observation](/api/fhir/r4/observation) — Measurements and simple assertions made about a patient, device or other subject. - [Patient](/api/fhir/r4/patient) — Demographics and other administrative information about an individual or animal receiving care or other health-related services. - [Procedure](/api/fhir/r4/procedure) — An action that is or was performed on or for a patient. This can be a physical intervention like an operation, or less invasive like long term services, counseling, or hypnotherapy. The sidebar contains the complete alphabetized resource list. For errors, FHIR operations return an [`OperationOutcome`](/api/fhir/r4/operation-outcome), not Ovok Problem Details; see the [Error responses guide](/errors) for the distinction. ## How to read a resource page [#how-to-read-a-resource-page] ### Resource structure [#resource-structure] Each resource is defined by elements. A page lists the top-level elements, their types, cardinalities, and short descriptions. For example, a `Patient` can have multiple identifiers and names, while an `Observation` has a required status and code and may carry a value, subject, device, and reference range. Follow linked data types to the [FHIR Elements](/fhir-elements) reference. ### Cardinality [#cardinality] Cardinality states how many times an element can appear. `0..1` is optional and singular, `1..1` is required and singular, `0..*` is optional and repeating, and `1..*` is required and repeating. A choice element such as `value[x]` means one of the listed types is used in a resource instance. ### Interactions [#interactions] FHIR defines a REST interaction pattern for reading, creating, updating, deleting, searching, and reading history. Resource pages show the corresponding R4 route shape using `[id]` and `[vid]` placeholders. The table documents the FHIR pattern; check your project's capability statement before relying on a particular interaction. ### Search parameters [#search-parameters] FHIR search uses named parameters defined for each resource. The generated page lists the parameter name, FHIR search type, and definition from the R4 package. Server support can be narrower than the specification, and search modifiers or chained searches should be checked against the Ovok API capabilities. ## Specification maturity [#specification-maturity] Each resource page reports the maturity level supplied by HL7. Maturity ranges from Draft through Trial Use levels to Normative; it describes the specification's maturity, not Ovok certification or project readiness. ## Source and version [#source-and-version] The pages are synchronized from [HL7's FHIR R4 core package](https://hl7.org/fhir/R4/downloads.html), version 4.0.1. Refer to the [official FHIR R4 specification](https://hl7.org/fhir/R4/) for normative definitions and implementation guidance. # InsurancePlan Canonical page: https://docs.ovok.com/api/fhir/r4/insurance-plan Details of a Health Insurance product/plan provided by an organization. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/InsurancePlan/[id]` | | Vread | `GET` | `/fhir/R4/InsurancePlan/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/InsurancePlan/[id]` | | Patch | `PATCH` | `/fhir/R4/InsurancePlan/[id]` | | Delete | `DELETE` | `/fhir/R4/InsurancePlan/[id]` | | Create | `POST` | `/fhir/R4/InsurancePlan` | | Search | `GET` | `/fhir/R4/InsurancePlan` | | History | `GET` | `/fhir/R4/InsurancePlan/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for Product | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | draft \| active \| retired \| unknown | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Kind of product | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Official name | | `alias` | [string](/fhir-elements/primitive/string) | `0..*` | Alternate names | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | When the product is available | | `ownedBy` | [Reference](/fhir-elements/complex/reference) | `0..1` | Plan issuer | | `administeredBy` | [Reference](/fhir-elements/complex/reference) | `0..1` | Product administrator | | `coverageArea` | [Reference](/fhir-elements/complex/reference) | `0..*` | Where product applies | | `contact` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Contact for the product | | `endpoint` | [Reference](/fhir-elements/complex/reference) | `0..*` | Technical endpoint | | `network` | [Reference](/fhir-elements/complex/reference) | `0..*` | What networks are Included | | `coverage` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Coverage details | | `plan` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Plan details | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `address` | string | A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text | | `address-city` | string | A city specified in an address | | `address-country` | string | A country specified in an address | | `address-postalcode` | string | A postal code specified in an address | | `address-state` | string | A state specified in an address | | `address-use` | token | A use code specified in an address | | `administered-by` | reference | Product administrator | | `endpoint` | reference | Technical endpoint | | `identifier` | token | Any identifier for the organization (not the accreditation issuer's identifier) | | `name` | string | A portion of the organization's name or alias | | `owned-by` | reference | An organization of which this organization forms a part | | `phonetic` | string | A portion of the organization's name using some kind of phonetic matching algorithm | | `status` | token | Is the Organization record active | | `type` | token | A code for the type of organization | ## Reference [#reference] Official FHIR R4 spec: [InsurancePlan](https://hl7.org/fhir/R4/insuranceplan.html). Maturity: Draft (FMM 0). # Invoice Canonical page: https://docs.ovok.com/api/fhir/r4/invoice Invoice containing collected ChargeItems from an Account with calculated individual and total price for Billing purpose. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Invoice/[id]` | | Vread | `GET` | `/fhir/R4/Invoice/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Invoice/[id]` | | Patch | `PATCH` | `/fhir/R4/Invoice/[id]` | | Delete | `DELETE` | `/fhir/R4/Invoice/[id]` | | Create | `POST` | `/fhir/R4/Invoice` | | Search | `GET` | `/fhir/R4/Invoice` | | History | `GET` | `/fhir/R4/Invoice/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for item | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| issued \| balanced \| cancelled \| entered-in-error | | `cancelledReason` | [string](/fhir-elements/primitive/string) | `0..1` | Reason for cancellation of this Invoice | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Type of Invoice | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Recipient(s) of goods and services | | `recipient` | [Reference](/fhir-elements/complex/reference) | `0..1` | Recipient of this invoice | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Invoice date / posting date | | `participant` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Participant in creation of this Invoice | | `issuer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Issuing Organization of Invoice | | `account` | [Reference](/fhir-elements/complex/reference) | `0..1` | Account that is being balanced | | `lineItem` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Line items of this Invoice | | `totalPriceComponent` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Components of Invoice total | | `totalNet` | [Money](/fhir-elements/complex/money) | `0..1` | Net total of this Invoice | | `totalGross` | [Money](/fhir-elements/complex/money) | `0..1` | Gross total of this Invoice | | `paymentTerms` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Payment details | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments made about the invoice | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `account` | reference | Account that is being balanced | | `date` | date | Invoice date / posting date | | `identifier` | token | Business Identifier for item | | `issuer` | reference | Issuing Organization of Invoice | | `participant` | reference | Individual who was involved | | `participant-role` | token | Type of involvement in creation of this Invoice | | `patient` | reference | Recipient(s) of goods and services | | `recipient` | reference | Recipient of this invoice | | `status` | token | draft \| issued \| balanced \| cancelled \| entered-in-error | | `subject` | reference | Recipient(s) of goods and services | | `totalgross` | quantity | Gross total of this Invoice | | `totalnet` | quantity | Net total of this Invoice | | `type` | token | Type of Invoice | ## Reference [#reference] Official FHIR R4 spec: [Invoice](https://hl7.org/fhir/R4/invoice.html). Maturity: Draft (FMM 0). # Library Canonical page: https://docs.ovok.com/api/fhir/r4/library The Library resource is a general-purpose container for knowledge asset definitions. It can be used to describe and expose existing knowledge assets such as logic libraries and information model descriptions, as well as to describe a collection of knowledge assets. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Library/[id]` | | Vread | `GET` | `/fhir/R4/Library/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Library/[id]` | | Patch | `PATCH` | `/fhir/R4/Library/[id]` | | Delete | `DELETE` | `/fhir/R4/Library/[id]` | | Create | `POST` | `/fhir/R4/Library` | | Search | `GET` | `/fhir/R4/Library` | | History | `GET` | `/fhir/R4/Library/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this library, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the library | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the library | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this library (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this library (human friendly) | | `subtitle` | [string](/fhir-elements/primitive/string) | `0..1` | Subordinate title of the library | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | logic-library \| model-definition \| asset-collection \| module-definition | | `subject[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `0..1` | Type of individual the library content is focused on | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the library | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for library (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this library is defined | | `usage` | [string](/fhir-elements/primitive/string) | `0..1` | Describes the clinical usage of the library | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the library was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the library was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the library is expected to be used | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | E.g. Education, Treatment, Assessment, etc. | | `author` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who authored the content | | `editor` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who edited the content | | `reviewer` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who reviewed the content | | `endorser` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who endorsed the content | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | Additional documentation, citations, etc. | | `parameter` | [ParameterDefinition](/fhir-elements/complex/parameter-definition) | `0..*` | Parameters defined by the library | | `dataRequirement` | [DataRequirement](/fhir-elements/complex/data-requirement) | `0..*` | What data is referenced by this library | | `content` | [Attachment](/fhir-elements/complex/attachment) | `0..*` | Contents of the library, either embedded or referenced | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `composed-of` | reference | What resource is being referenced | | `content-type` | token | The type of content in the library (e.g. text/cql) | | `context` | token | A use context assigned to the library | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the library | | `context-type` | token | A type of use context assigned to the library | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the library | | `context-type-value` | composite | A use context type and value assigned to the library | | `date` | date | The library publication date | | `depends-on` | reference | What resource is being referenced | | `derived-from` | reference | What resource is being referenced | | `description` | string | The description of the library | | `effective` | date | The time during which the library is intended to be in use | | `identifier` | token | External identifier for the library | | `jurisdiction` | token | Intended jurisdiction for the library | | `name` | string | Computationally friendly name of the library | | `predecessor` | reference | What resource is being referenced | | `publisher` | string | Name of the publisher of the library | | `status` | token | The current status of the library | | `successor` | reference | What resource is being referenced | | `title` | string | The human-friendly name of the library | | `topic` | token | Topics associated with the module | | `type` | token | The type of the library (e.g. logic-library, model-definition, asset-collection, module-definition) | | `url` | uri | The uri that identifies the library | | `version` | token | The business version of the library | ## Reference [#reference] Official FHIR R4 spec: [Library](https://hl7.org/fhir/R4/library.html). Maturity: Trial Use 2 (FMM 2). # Linkage Canonical page: https://docs.ovok.com/api/fhir/r4/linkage Identifies two or more records (resource instances) that refer to the same real-world "occurrence". These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Linkage/[id]` | | Vread | `GET` | `/fhir/R4/Linkage/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Linkage/[id]` | | Patch | `PATCH` | `/fhir/R4/Linkage/[id]` | | Delete | `DELETE` | `/fhir/R4/Linkage/[id]` | | Create | `POST` | `/fhir/R4/Linkage` | | Search | `GET` | `/fhir/R4/Linkage` | | History | `GET` | `/fhir/R4/Linkage/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether this linkage assertion is active or not | | `author` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who is responsible for linkages | | `item` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | Item to be linked | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `author` | reference | Author of the Linkage | | `item` | reference | Matches on any item in the Linkage | | `source` | reference | Matches on any item in the Linkage with a type of 'source' | ## Reference [#reference] Official FHIR R4 spec: [Linkage](https://hl7.org/fhir/R4/linkage.html). Maturity: Draft (FMM 0). # List Canonical page: https://docs.ovok.com/api/fhir/r4/list A list is a curated collection of resources. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/List/[id]` | | Vread | `GET` | `/fhir/R4/List/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/List/[id]` | | Patch | `PATCH` | `/fhir/R4/List/[id]` | | Delete | `DELETE` | `/fhir/R4/List/[id]` | | Create | `POST` | `/fhir/R4/List` | | Search | `GET` | `/fhir/R4/List` | | History | `GET` | `/fhir/R4/List/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | current \| retired \| entered-in-error | | `mode` | [code](/fhir-elements/primitive/code) | `1..1` | working \| snapshot \| changes | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Descriptive name for the list | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | What the purpose of this list is | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | If all resources have the same subject | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Context in which list created | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the list was prepared | | `source` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who and/or what defined the list contents (aka Author) | | `orderedBy` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | What order the list has | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments about the list | | `entry` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Entries in the list | | `emptyReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Why list is empty | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `empty-reason` | token | Why list is empty | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `item` | reference | Actual entry | | `notes` | string | The annotation - text content (as markdown) | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `source` | reference | Who and/or what defined the list contents (aka Author) | | `status` | token | current \| retired \| entered-in-error | | `subject` | reference | If all resources have the same subject | | `title` | string | Descriptive name for the list | ## Reference [#reference] Official FHIR R4 spec: [List](https://hl7.org/fhir/R4/list.html). Maturity: Trial Use 1 (FMM 1). # Location Canonical page: https://docs.ovok.com/api/fhir/r4/location Details and position information for a physical place where services are provided and resources and participants may be stored, found, contained, or accommodated. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Location/[id]` | | Vread | `GET` | `/fhir/R4/Location/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Location/[id]` | | Patch | `PATCH` | `/fhir/R4/Location/[id]` | | Delete | `DELETE` | `/fhir/R4/Location/[id]` | | Create | `POST` | `/fhir/R4/Location` | | Search | `GET` | `/fhir/R4/Location` | | History | `GET` | `/fhir/R4/Location/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Unique code or number identifying the location to its users | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | active \| suspended \| inactive | | `operationalStatus` | [Coding](/fhir-elements/complex/coding) | `0..1` | The operational status of the location (typically only for a bed/room) | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the location as used by humans | | `alias` | [string](/fhir-elements/primitive/string) | `0..*` | A list of alternate names that the location is known as, or was known as, in the past | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Additional details about the location that could be displayed as further information to identify the location beyond its name | | `mode` | [code](/fhir-elements/primitive/code) | `0..1` | instance \| kind | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Type of function performed | | `telecom` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | Contact details of the location | | `address` | [Address](/fhir-elements/complex/address) | `0..1` | Physical location | | `physicalType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Physical form of the location | | `position` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | The absolute geographic location | | `managingOrganization` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization responsible for provisioning and upkeep | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..1` | Another Location this one is physically a part of | | `hoursOfOperation` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | What days/times during a week is this location usually open | | `availabilityExceptions` | [string](/fhir-elements/primitive/string) | `0..1` | Description of availability exceptions | | `endpoint` | [Reference](/fhir-elements/complex/reference) | `0..*` | Technical endpoints providing access to services operated for the location | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `address` | string | A (part of the) address of the location | | `address-city` | string | A city specified in an address | | `address-country` | string | A country specified in an address | | `address-postalcode` | string | A postal code specified in an address | | `address-state` | string | A state specified in an address | | `address-use` | token | A use code specified in an address | | `endpoint` | reference | Technical endpoints providing access to services operated for the location | | `identifier` | token | An identifier for the location | | `name` | string | A portion of the location's name or alias | | `near` | special | Search for locations where the location.position is near to, or within a specified distance of, the provided coordinates expressed as [latitude]\|[longitude]\|[distance]\|[units] (using the WGS84 datum, see notes). If the units are omitted, then kms should be assumed. If the distance is omitted, then the server can use its own discretion as to what distances should be considered near (and units are irrelevant) Servers may search using various techniques that might have differing accuracies, depending on implementation efficiency. Requires the near-distance parameter to be provided also | | `operational-status` | token | Searches for locations (typically bed/room) that have an operational status (e.g. contaminated, housekeeping) | | `organization` | reference | Searches for locations that are managed by the provided organization | | `partof` | reference | A location of which this location is a part | | `status` | token | Searches for locations with a specific kind of status | | `type` | token | A code for the type of location | ## Reference [#reference] Official FHIR R4 spec: [Location](https://hl7.org/fhir/R4/location.html). Maturity: Trial Use 3 (FMM 3). # MeasureReport Canonical page: https://docs.ovok.com/api/fhir/r4/measure-report The MeasureReport resource contains the results of the calculation of a measure; and optionally a reference to the resources involved in that calculation. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MeasureReport/[id]` | | Vread | `GET` | `/fhir/R4/MeasureReport/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MeasureReport/[id]` | | Patch | `PATCH` | `/fhir/R4/MeasureReport/[id]` | | Delete | `DELETE` | `/fhir/R4/MeasureReport/[id]` | | Create | `POST` | `/fhir/R4/MeasureReport` | | Search | `GET` | `/fhir/R4/MeasureReport` | | History | `GET` | `/fhir/R4/MeasureReport/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the MeasureReport | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | complete \| pending \| error | | `type` | [code](/fhir-elements/primitive/code) | `1..1` | individual \| subject-list \| summary \| data-collection | | `measure` | [canonical](/fhir-elements/primitive/canonical) | `1..1` | What measure was calculated | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | What individual(s) the report is for | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the report was generated | | `reporter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who is reporting the data | | `period` | [Period](/fhir-elements/complex/period) | `1..1` | What period the report covers | | `improvementNotation` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | increase \| decrease | | `group` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Measure results for each group | | `evaluatedResource` | [Reference](/fhir-elements/complex/reference) | `0..*` | What data was used to calculate the measure score | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `date` | date | The date of the measure report | | `evaluated-resource` | reference | An evaluated resource referenced by the measure report | | `identifier` | token | External identifier of the measure report to be returned | | `measure` | reference | The measure to return measure report results for | | `patient` | reference | The identity of a patient to search for individual measure report results for | | `period` | date | The period of the measure report | | `reporter` | reference | The reporter to return measure report results for | | `status` | token | The status of the measure report | | `subject` | reference | The identity of a subject to search for individual measure report results for | ## Reference [#reference] Official FHIR R4 spec: [MeasureReport](https://hl7.org/fhir/R4/measurereport.html). Maturity: Trial Use 2 (FMM 2). # Measure Canonical page: https://docs.ovok.com/api/fhir/r4/measure The Measure resource provides the definition of a quality measure. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Measure/[id]` | | Vread | `GET` | `/fhir/R4/Measure/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Measure/[id]` | | Patch | `PATCH` | `/fhir/R4/Measure/[id]` | | Delete | `DELETE` | `/fhir/R4/Measure/[id]` | | Create | `POST` | `/fhir/R4/Measure` | | Search | `GET` | `/fhir/R4/Measure` | | History | `GET` | `/fhir/R4/Measure/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this measure, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the measure | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the measure | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this measure (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this measure (human friendly) | | `subtitle` | [string](/fhir-elements/primitive/string) | `0..1` | Subordinate title of the measure | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `subject[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `0..1` | E.g. Patient, Practitioner, RelatedPerson, Organization, Location, Device | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the measure | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for measure (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this measure is defined | | `usage` | [string](/fhir-elements/primitive/string) | `0..1` | Describes the clinical usage of the measure | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the measure was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the measure was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the measure is expected to be used | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The category of the measure, such as Education, Treatment, Assessment, etc. | | `author` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who authored the content | | `editor` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who edited the content | | `reviewer` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who reviewed the content | | `endorser` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who endorsed the content | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | Additional documentation, citations, etc. | | `library` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Logic used by the measure | | `disclaimer` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Disclaimer for use of the measure or its referenced content | | `scoring` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | proportion \| ratio \| continuous-variable \| cohort | | `compositeScoring` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | opportunity \| all-or-nothing \| linear \| weighted | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | process \| outcome \| structure \| patient-reported-outcome \| composite | | `riskAdjustment` | [string](/fhir-elements/primitive/string) | `0..1` | How risk adjustment is applied for this measure | | `rateAggregation` | [string](/fhir-elements/primitive/string) | `0..1` | How is rate aggregation performed for this measure | | `rationale` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Detailed description of why the measure exists | | `clinicalRecommendationStatement` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Summary of clinical guidelines | | `improvementNotation` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | increase \| decrease | | `definition` | [markdown](/fhir-elements/primitive/markdown) | `0..*` | Defined terms used in the measure documentation | | `guidance` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Additional guidance for implementers | | `group` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Population criteria group | | `supplementalData` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | What other data should be reported with the measure | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `composed-of` | reference | What resource is being referenced | | `context` | token | A use context assigned to the measure | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the measure | | `context-type` | token | A type of use context assigned to the measure | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the measure | | `context-type-value` | composite | A use context type and value assigned to the measure | | `date` | date | The measure publication date | | `depends-on` | reference | What resource is being referenced | | `derived-from` | reference | What resource is being referenced | | `description` | string | The description of the measure | | `effective` | date | The time during which the measure is intended to be in use | | `identifier` | token | External identifier for the measure | | `jurisdiction` | token | Intended jurisdiction for the measure | | `name` | string | Computationally friendly name of the measure | | `predecessor` | reference | What resource is being referenced | | `publisher` | string | Name of the publisher of the measure | | `status` | token | The current status of the measure | | `successor` | reference | What resource is being referenced | | `title` | string | The human-friendly name of the measure | | `topic` | token | Topics associated with the measure | | `url` | uri | The uri that identifies the measure | | `version` | token | The business version of the measure | ## Reference [#reference] Official FHIR R4 spec: [Measure](https://hl7.org/fhir/R4/measure.html). Maturity: Trial Use 2 (FMM 2). # Media Canonical page: https://docs.ovok.com/api/fhir/r4/media A photo, video, or audio recording acquired or used in healthcare. The actual content may be inline or provided by direct reference. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Media/[id]` | | Vread | `GET` | `/fhir/R4/Media/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Media/[id]` | | Patch | `PATCH` | `/fhir/R4/Media/[id]` | | Delete | `DELETE` | `/fhir/R4/Media/[id]` | | Create | `POST` | `/fhir/R4/Media` | | Search | `GET` | `/fhir/R4/Media` | | History | `GET` | `/fhir/R4/Media/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Identifier(s) for the image | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Procedure that caused this media to be created | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Part of referenced event | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | preparation \| in-progress \| not-done \| on-hold \| stopped \| completed \| entered-in-error \| unknown | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Classification of media as image, video, or audio | | `modality` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The type of acquisition equipment/process | | `view` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Imaging view, e.g. Lateral or Antero-posterior | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who/What this Media is a record of | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter associated with media | | `created[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period) | `0..1` | When Media was collected | | `issued` | [instant](/fhir-elements/primitive/instant) | `0..1` | Date/Time this version was made available | | `operator` | [Reference](/fhir-elements/complex/reference) | `0..1` | The person who generated the image | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Why was event performed? | | `bodySite` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Observed body part | | `deviceName` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the device/manufacturer | | `device` | [Reference](/fhir-elements/complex/reference) | `0..1` | Observing Device | | `height` | [positiveInt](/fhir-elements/primitive/positive-int) | `0..1` | Height of the image in pixels (photo/video) | | `width` | [positiveInt](/fhir-elements/primitive/positive-int) | `0..1` | Width of the image in pixels (photo/video) | | `frames` | [positiveInt](/fhir-elements/primitive/positive-int) | `0..1` | Number of frames if > 1 (photo) | | `duration` | [decimal](/fhir-elements/primitive/decimal) | `0..1` | Length in seconds (audio / video) | | `content` | [Attachment](/fhir-elements/complex/attachment) | `1..1` | Actual Media - reference or data | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments made about the media | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `based-on` | reference | Procedure that caused this media to be created | | `created` | date | When Media was collected | | `device` | reference | Observing Device | | `encounter` | reference | Encounter associated with media | | `identifier` | token | Identifier(s) for the image | | `modality` | token | The type of acquisition equipment/process | | `operator` | reference | The person who generated the image | | `patient` | reference | Who/What this Media is a record of | | `site` | token | Observed body part | | `status` | token | preparation \| in-progress \| not-done \| on-hold \| stopped \| completed \| entered-in-error \| unknown | | `subject` | reference | Who/What this Media is a record of | | `type` | token | Classification of media as image, video, or audio | | `view` | token | Imaging view, e.g. Lateral or Antero-posterior | ## Reference [#reference] Official FHIR R4 spec: [Media](https://hl7.org/fhir/R4/media.html). Maturity: Trial Use 1 (FMM 1). # MedicationAdministration Canonical page: https://docs.ovok.com/api/fhir/r4/medication-administration Describes the event of a patient consuming or otherwise being administered a medication. This may be as simple as swallowing a tablet or it may be a long running infusion. Related resources tie this event to the authorizing prescription, and the specific encounter between patient and health care practitioner. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicationAdministration/[id]` | | Vread | `GET` | `/fhir/R4/MedicationAdministration/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicationAdministration/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicationAdministration/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicationAdministration/[id]` | | Create | `POST` | `/fhir/R4/MedicationAdministration` | | Search | `GET` | `/fhir/R4/MedicationAdministration` | | History | `GET` | `/fhir/R4/MedicationAdministration/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External identifier | | `instantiates` | [uri](/fhir-elements/primitive/uri) | `0..*` | Instantiates protocol or definition | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Part of referenced event | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | in-progress \| not-done \| on-hold \| completed \| entered-in-error \| stopped \| unknown | | `statusReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Reason administration not performed | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Type of medication usage | | `medication[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `1..1` | What was administered | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who received medication | | `context` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter or Episode of Care administered as part of | | `supportingInformation` | [Reference](/fhir-elements/complex/reference) | `0..*` | Additional information to support administration | | `effective[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period) | `1..1` | Start and end time of administration | | `performer` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Who performed the medication administration and what they did | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Reason administration performed | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Condition or observation that supports why the medication was administered | | `request` | [Reference](/fhir-elements/complex/reference) | `0..1` | Request administration performed against | | `device` | [Reference](/fhir-elements/complex/reference) | `0..*` | Device used to administer | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Information about the administration | | `dosage` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Details of how medication was taken | | `eventHistory` | [Reference](/fhir-elements/complex/reference) | `0..*` | A list of events of interest in the lifecycle | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `context` | reference | Return administrations that share this encounter or episode of care | | `device` | reference | Return administrations with this administration device identity | | `effective-time` | date | Date administration happened (or did not happen) | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `medication` | reference | Multiple Resources: MedicationAdministration: Return administrations of this medication resource ; MedicationDispense: Returns dispenses of this medicine resource ; MedicationRequest: Return prescriptions for this medication reference ; MedicationStatement: Return statements of this medication reference | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `performer` | reference | The identity of the individual who administered the medication | | `reason-given` | token | Reasons for administering the medication | | `reason-not-given` | token | Reasons for not administering the medication | | `request` | reference | The identity of a request to list administrations from | | `status` | token | Multiple Resources: MedicationAdministration: MedicationAdministration event status (for example one of active/paused/completed/nullified) ; MedicationDispense: Returns dispenses with a specified dispense status ; MedicationRequest: Status of the prescription ; MedicationStatement: Return statements that match the given status | | `subject` | reference | The identity of the individual or group to list administrations for | ## Reference [#reference] Official FHIR R4 spec: [MedicationAdministration](https://hl7.org/fhir/R4/medicationadministration.html). Maturity: Trial Use 2 (FMM 2). # MedicationDispense Canonical page: https://docs.ovok.com/api/fhir/r4/medication-dispense Indicates that a medication product is to be or has been dispensed for a named person/patient. This includes a description of the medication product (supply) provided and the instructions for administering the medication. The medication dispense is the result of a pharmacy system responding to a medication order. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicationDispense/[id]` | | Vread | `GET` | `/fhir/R4/MedicationDispense/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicationDispense/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicationDispense/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicationDispense/[id]` | | Create | `POST` | `/fhir/R4/MedicationDispense` | | Search | `GET` | `/fhir/R4/MedicationDispense` | | History | `GET` | `/fhir/R4/MedicationDispense/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External identifier | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Event that dispense is part of | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | preparation \| in-progress \| cancelled \| on-hold \| completed \| entered-in-error \| stopped \| declined \| unknown | | `statusReason[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `0..1` | Why a dispense was not performed | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Type of medication dispense | | `medication[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `1..1` | What medication was supplied | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who the dispense is for | | `context` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter / Episode associated with event | | `supportingInformation` | [Reference](/fhir-elements/complex/reference) | `0..*` | Information that supports the dispensing of the medication | | `performer` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Who performed event | | `location` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where the dispense occurred | | `authorizingPrescription` | [Reference](/fhir-elements/complex/reference) | `0..*` | Medication order that authorizes the dispense | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Trial fill, partial fill, emergency fill, etc. | | `quantity` | [Quantity](/fhir-elements/complex/quantity) | `0..1` | Amount dispensed | | `daysSupply` | [Quantity](/fhir-elements/complex/quantity) | `0..1` | Amount of medication expressed as a timing amount | | `whenPrepared` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When product was packaged and reviewed | | `whenHandedOver` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When product was given out | | `destination` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where the medication was sent | | `receiver` | [Reference](/fhir-elements/complex/reference) | `0..*` | Who collected the medication | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Information about the dispense | | `dosageInstruction` | [Dosage](/fhir-elements/complex/dosage) | `0..*` | How the medication is to be used by the patient or administered by the caregiver | | `substitution` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Whether a substitution was performed on the dispense | | `detectedIssue` | [Reference](/fhir-elements/complex/reference) | `0..*` | Clinical issue with action | | `eventHistory` | [Reference](/fhir-elements/complex/reference) | `0..*` | A list of relevant lifecycle events | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `context` | reference | Returns dispenses with a specific context (episode or episode of care) | | `destination` | reference | Returns dispenses that should be sent to a specific destination | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `medication` | reference | Multiple Resources: MedicationAdministration: Return administrations of this medication resource ; MedicationDispense: Returns dispenses of this medicine resource ; MedicationRequest: Return prescriptions for this medication reference ; MedicationStatement: Return statements of this medication reference | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `performer` | reference | Returns dispenses performed by a specific individual | | `prescription` | reference | Multiple Resources: MedicationDispense: The identity of a prescription to list dispenses from | | `receiver` | reference | The identity of a receiver to list dispenses for | | `responsibleparty` | reference | Returns dispenses with the specified responsible party | | `status` | token | Multiple Resources: MedicationAdministration: MedicationAdministration event status (for example one of active/paused/completed/nullified) ; MedicationDispense: Returns dispenses with a specified dispense status ; MedicationRequest: Status of the prescription ; MedicationStatement: Return statements that match the given status | | `subject` | reference | The identity of a patient for whom to list dispenses | | `type` | token | Returns dispenses of a specific type | | `whenhandedover` | date | Returns dispenses handed over on this date | | `whenprepared` | date | Returns dispenses prepared on this date | ## Reference [#reference] Official FHIR R4 spec: [MedicationDispense](https://hl7.org/fhir/R4/medicationdispense.html). Maturity: Trial Use 2 (FMM 2). # MedicationKnowledge Canonical page: https://docs.ovok.com/api/fhir/r4/medication-knowledge Information about a medication that is used to support knowledge. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicationKnowledge/[id]` | | Vread | `GET` | `/fhir/R4/MedicationKnowledge/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicationKnowledge/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicationKnowledge/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicationKnowledge/[id]` | | Create | `POST` | `/fhir/R4/MedicationKnowledge` | | Search | `GET` | `/fhir/R4/MedicationKnowledge` | | History | `GET` | `/fhir/R4/MedicationKnowledge/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Code that identifies this medication | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | active \| inactive \| entered-in-error | | `manufacturer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Manufacturer of the item | | `doseForm` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | powder \| tablets \| capsule + | | `amount` | [Quantity](/fhir-elements/complex/quantity) | `0..1` | Amount of drug in package | | `synonym` | [string](/fhir-elements/primitive/string) | `0..*` | Additional names for a medication | | `relatedMedicationKnowledge` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Associated or related medication information | | `associatedMedication` | [Reference](/fhir-elements/complex/reference) | `0..*` | A medication resource that is associated with this medication | | `productType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Category of the medication or product | | `monograph` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Associated documentation about the medication | | `ingredient` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Active or inactive ingredient | | `preparationInstruction` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | The instructions for preparing the medication | | `intendedRoute` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The intended or approved route of administration | | `cost` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The pricing of the medication | | `monitoringProgram` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Program under which a medication is reviewed | | `administrationGuidelines` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Guidelines for administration of the medication | | `medicineClassification` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Categorization of the medication within a formulary or classification system | | `packaging` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Details about packaged medications | | `drugCharacteristic` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Specifies descriptive properties of the medicine | | `contraindication` | [Reference](/fhir-elements/complex/reference) | `0..*` | Potential clinical issue with or between medication(s) | | `regulatory` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Regulatory information about a medication | | `kinetics` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The time course of drug absorption, distribution, metabolism and excretion of a medication from the body | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `classification` | token | Specific category assigned to the medication | | `classification-type` | token | The type of category for the medication (for example, therapeutic classification, therapeutic sub-classification) | | `code` | token | Code that identifies this medication | | `doseform` | token | powder \| tablets \| capsule + | | `ingredient` | reference | Medication(s) or substance(s) contained in the medication | | `ingredient-code` | token | Medication(s) or substance(s) contained in the medication | | `manufacturer` | reference | Manufacturer of the item | | `monitoring-program-name` | token | Name of the reviewing program | | `monitoring-program-type` | token | Type of program under which the medication is monitored | | `monograph` | reference | Associated documentation about the medication | | `monograph-type` | token | The category of medication document | | `source-cost` | token | The source or owner for the price information | | `status` | token | active \| inactive \| entered-in-error | ## Reference [#reference] Official FHIR R4 spec: [MedicationKnowledge](https://hl7.org/fhir/R4/medicationknowledge.html). Maturity: Draft (FMM 0). # MedicationRequest Canonical page: https://docs.ovok.com/api/fhir/r4/medication-request An order or request for both supply of the medication and the instructions for administration of the medication to a patient. The resource is called "MedicationRequest" rather than "MedicationPrescription" or "MedicationOrder" to generalize the use across inpatient and outpatient settings, including care plans, etc., and to harmonize with workflow patterns. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicationRequest/[id]` | | Vread | `GET` | `/fhir/R4/MedicationRequest/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicationRequest/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicationRequest/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicationRequest/[id]` | | Create | `POST` | `/fhir/R4/MedicationRequest` | | Search | `GET` | `/fhir/R4/MedicationRequest` | | History | `GET` | `/fhir/R4/MedicationRequest/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External ids for this request | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| on-hold \| cancelled \| completed \| entered-in-error \| stopped \| draft \| unknown | | `statusReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Reason for current status | | `intent` | [code](/fhir-elements/primitive/code) | `1..1` | proposal \| plan \| order \| original-order \| reflex-order \| filler-order \| instance-order \| option | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Type of medication usage | | `priority` | [code](/fhir-elements/primitive/code) | `0..1` | routine \| urgent \| asap \| stat | | `doNotPerform` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | True if request is prohibiting action | | `reported[x]` | [boolean](/fhir-elements/primitive/boolean), [Reference](/fhir-elements/complex/reference) | `0..1` | Reported rather than primary record | | `medication[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `1..1` | Medication to be taken | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who or group medication request is for | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter created as part of encounter/admission/stay | | `supportingInformation` | [Reference](/fhir-elements/complex/reference) | `0..*` | Information to support ordering of the medication | | `authoredOn` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When request was initially authored | | `requester` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who/What requested the Request | | `performer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Intended performer of administration | | `performerType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Desired kind of performer of the medication administration | | `recorder` | [Reference](/fhir-elements/complex/reference) | `0..1` | Person who entered the request | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Reason or indication for ordering or not ordering the medication | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Condition or observation that supports why the prescription is being written | | `instantiatesCanonical` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Instantiates FHIR protocol or definition | | `instantiatesUri` | [uri](/fhir-elements/primitive/uri) | `0..*` | Instantiates external protocol or definition | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | What request fulfills | | `groupIdentifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Composite request this is part of | | `courseOfTherapyType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Overall pattern of medication administration | | `insurance` | [Reference](/fhir-elements/complex/reference) | `0..*` | Associated insurance coverage | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Information about the prescription | | `dosageInstruction` | [Dosage](/fhir-elements/complex/dosage) | `0..*` | How the medication should be taken | | `dispenseRequest` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Medication supply authorization | | `substitution` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Any restrictions on medication substitution | | `priorPrescription` | [Reference](/fhir-elements/complex/reference) | `0..1` | An order/prescription that is being replaced | | `detectedIssue` | [Reference](/fhir-elements/complex/reference) | `0..*` | Clinical Issue with action | | `eventHistory` | [Reference](/fhir-elements/complex/reference) | `0..*` | A list of events of interest in the lifecycle | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `authoredon` | date | Return prescriptions written on this date | | `category` | token | Returns prescriptions with different categories | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `date` | date | Multiple Resources: MedicationRequest: Returns medication request to be administered on a specific date | | `encounter` | reference | Multiple Resources: MedicationRequest: Return prescriptions with this encounter identifier | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `intended-dispenser` | reference | Returns prescriptions intended to be dispensed by this Organization | | `intended-performer` | reference | Returns the intended performer of the administration of the medication request | | `intended-performertype` | token | Returns requests for a specific type of performer | | `intent` | token | Returns prescriptions with different intents | | `medication` | reference | Multiple Resources: MedicationAdministration: Return administrations of this medication resource ; MedicationDispense: Returns dispenses of this medicine resource ; MedicationRequest: Return prescriptions for this medication reference ; MedicationStatement: Return statements of this medication reference | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `priority` | token | Returns prescriptions with different priorities | | `requester` | reference | Returns prescriptions prescribed by this prescriber | | `status` | token | Multiple Resources: MedicationAdministration: MedicationAdministration event status (for example one of active/paused/completed/nullified) ; MedicationDispense: Returns dispenses with a specified dispense status ; MedicationRequest: Status of the prescription ; MedicationStatement: Return statements that match the given status | | `subject` | reference | The identity of a patient to list orders for | ## Reference [#reference] Official FHIR R4 spec: [MedicationRequest](https://hl7.org/fhir/R4/medicationrequest.html). Maturity: Trial Use 3 (FMM 3). # MedicationStatement Canonical page: https://docs.ovok.com/api/fhir/r4/medication-statement A record of a medication that is being consumed by a patient. A MedicationStatement may indicate that the patient may be taking the medication now or has taken the medication in the past or will be taking the medication in the future. The source of this information can be the patient, significant other (such as a family member or spouse), or a clinician. A common scenario where this information is captured is during the history taking process during a patient visit or stay. The medication information may come from sources such as the patient's memory, from a prescription bottle, or from a list of medications the patient, clinician or other party maintains. The primary difference between a medication statement and a medication administration is that the medication administration has complete administration information and is based on actual administration information from the person who administered the medication. A medication statement is often, if not always, less specific. There is no required date/time when the medication was administered, in fact we only know that a source has reported the patient is taking this medication, where details such as time, quantity, or rate or even medication product may be incomplete or missing or less precise. As stated earlier, the medication statement information may come from the patient's memory, from a prescription bottle or from a list of medications the patient, clinician or other party maintains. Medication administration is more formal and is not missing detailed information. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicationStatement/[id]` | | Vread | `GET` | `/fhir/R4/MedicationStatement/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicationStatement/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicationStatement/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicationStatement/[id]` | | Create | `POST` | `/fhir/R4/MedicationStatement` | | Search | `GET` | `/fhir/R4/MedicationStatement` | | History | `GET` | `/fhir/R4/MedicationStatement/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External identifier | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Fulfils plan, proposal or order | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Part of referenced event | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| completed \| entered-in-error \| intended \| stopped \| on-hold \| unknown \| not-taken | | `statusReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Reason for current status | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Type of medication usage | | `medication[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `1..1` | What medication was taken | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who is/was taking the medication | | `context` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter / Episode associated with MedicationStatement | | `effective[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period) | `0..1` | The date/time or interval when the medication is/was/will be taken | | `dateAsserted` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the statement was asserted? | | `informationSource` | [Reference](/fhir-elements/complex/reference) | `0..1` | Person or organization that provided the information about the taking of this medication | | `derivedFrom` | [Reference](/fhir-elements/complex/reference) | `0..*` | Additional supporting information | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Reason for why the medication is being/was taken | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Condition or observation that supports why the medication is being/was taken | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Further information about the statement | | `dosage` | [Dosage](/fhir-elements/complex/dosage) | `0..*` | Details of how medication is/was taken or should be taken | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `category` | token | Returns statements of this category of medicationstatement | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `context` | reference | Returns statements for a specific context (episode or episode of Care). | | `effective` | date | Date when patient was taking (or not taking) the medication | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `medication` | reference | Multiple Resources: MedicationAdministration: Return administrations of this medication resource ; MedicationDispense: Returns dispenses of this medicine resource ; MedicationRequest: Return prescriptions for this medication reference ; MedicationStatement: Return statements of this medication reference | | `part-of` | reference | Returns statements that are part of another event. | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `source` | reference | Who or where the information in the statement came from | | `status` | token | Multiple Resources: MedicationAdministration: MedicationAdministration event status (for example one of active/paused/completed/nullified) ; MedicationDispense: Returns dispenses with a specified dispense status ; MedicationRequest: Status of the prescription ; MedicationStatement: Return statements that match the given status | | `subject` | reference | The identity of a patient, animal or group to list statements for | ## Reference [#reference] Official FHIR R4 spec: [MedicationStatement](https://hl7.org/fhir/R4/medicationstatement.html). Maturity: Trial Use 3 (FMM 3). # Medication Canonical page: https://docs.ovok.com/api/fhir/r4/medication This resource is primarily used for the identification and definition of a medication for the purposes of prescribing, dispensing, and administering a medication as well as for making statements about medication use. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Medication/[id]` | | Vread | `GET` | `/fhir/R4/Medication/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Medication/[id]` | | Patch | `PATCH` | `/fhir/R4/Medication/[id]` | | Delete | `DELETE` | `/fhir/R4/Medication/[id]` | | Create | `POST` | `/fhir/R4/Medication` | | Search | `GET` | `/fhir/R4/Medication` | | History | `GET` | `/fhir/R4/Medication/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier for this medication | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Codes that identify this medication | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | active \| inactive \| entered-in-error | | `manufacturer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Manufacturer of the item | | `form` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | powder \| tablets \| capsule + | | `amount` | [Ratio](/fhir-elements/complex/ratio) | `0..1` | Amount of drug in package | | `ingredient` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Active or inactive ingredient | | `batch` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Details about packaged medications | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `expiration-date` | date | Returns medications in a batch with this expiration date | | `form` | token | Returns medications for a specific dose form | | `identifier` | token | Returns medications with this external identifier | | `ingredient` | reference | Returns medications for this ingredient reference | | `ingredient-code` | token | Returns medications for this ingredient code | | `lot-number` | token | Returns medications in a batch with this lot number | | `manufacturer` | reference | Returns medications made or sold for this manufacturer | | `status` | token | Returns medications for this status | ## Reference [#reference] Official FHIR R4 spec: [Medication](https://hl7.org/fhir/R4/medication.html). Maturity: Trial Use 3 (FMM 3). # MedicinalProductAuthorization Canonical page: https://docs.ovok.com/api/fhir/r4/medicinal-product-authorization The regulatory authorization of a medicinal product. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicinalProductAuthorization/[id]` | | Vread | `GET` | `/fhir/R4/MedicinalProductAuthorization/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicinalProductAuthorization/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicinalProductAuthorization/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicinalProductAuthorization/[id]` | | Create | `POST` | `/fhir/R4/MedicinalProductAuthorization` | | Search | `GET` | `/fhir/R4/MedicinalProductAuthorization` | | History | `GET` | `/fhir/R4/MedicinalProductAuthorization/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier for the marketing authorization, as assigned by a regulator | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | The medicinal product that is being authorized | | `country` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The country in which the marketing authorization has been granted | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Jurisdiction within a country | | `status` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The status of the marketing authorization | | `statusDate` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | The date at which the given status has become applicable | | `restoreDate` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | The date when a suspended the marketing or the marketing authorization of the product is anticipated to be restored | | `validityPeriod` | [Period](/fhir-elements/complex/period) | `0..1` | The beginning of the time period in which the marketing authorization is in the specific status shall be specified A complete date consisting of day, month and year shall be specified using the ISO 8601 date format | | `dataExclusivityPeriod` | [Period](/fhir-elements/complex/period) | `0..1` | A period of time after authorization before generic product applicatiosn can be submitted | | `dateOfFirstAuthorization` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | The date when the first authorization was granted by a Medicines Regulatory Agency | | `internationalBirthDate` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date of first marketing authorization for a company's new medicinal product in any country in the World | | `legalBasis` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The legal framework against which this authorization is granted | | `jurisdictionalAuthorization` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Authorization in areas within a country | | `holder` | [Reference](/fhir-elements/complex/reference) | `0..1` | Marketing Authorization Holder | | `regulator` | [Reference](/fhir-elements/complex/reference) | `0..1` | Medicines Regulatory Agency | | `procedure` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | The regulatory procedure for granting or amending a marketing authorization | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `country` | token | The country in which the marketing authorization has been granted | | `holder` | reference | Marketing Authorization Holder | | `identifier` | token | Business identifier for the marketing authorization, as assigned by a regulator | | `status` | token | The status of the marketing authorization | | `subject` | reference | The medicinal product that is being authorized | ## Reference [#reference] Official FHIR R4 spec: [MedicinalProductAuthorization](https://hl7.org/fhir/R4/medicinalproductauthorization.html). Maturity: Draft (FMM 0). # MedicinalProductContraindication Canonical page: https://docs.ovok.com/api/fhir/r4/medicinal-product-contraindication The clinical particulars - indications, contraindications etc. of a medicinal product, including for regulatory purposes. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicinalProductContraindication/[id]` | | Vread | `GET` | `/fhir/R4/MedicinalProductContraindication/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicinalProductContraindication/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicinalProductContraindication/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicinalProductContraindication/[id]` | | Create | `POST` | `/fhir/R4/MedicinalProductContraindication` | | Search | `GET` | `/fhir/R4/MedicinalProductContraindication` | | History | `GET` | `/fhir/R4/MedicinalProductContraindication/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..*` | The medication for which this is an indication | | `disease` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The disease, symptom or procedure for the contraindication | | `diseaseStatus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The status of the disease or symptom for the contraindication | | `comorbidity` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | A comorbidity (concurrent condition) or coinfection | | `therapeuticIndication` | [Reference](/fhir-elements/complex/reference) | `0..*` | Information about the use of the medicinal product in relation to other therapies as part of the indication | | `otherTherapy` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Information about the use of the medicinal product in relation to other therapies described as part of the indication | | `population` | [Population](/fhir-elements/complex/population) | `0..*` | The population group to which this applies | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `subject` | reference | The medication for which this is an contraindication | ## Reference [#reference] Official FHIR R4 spec: [MedicinalProductContraindication](https://hl7.org/fhir/R4/medicinalproductcontraindication.html). Maturity: Draft (FMM 0). # MedicinalProductIndication Canonical page: https://docs.ovok.com/api/fhir/r4/medicinal-product-indication Indication for the Medicinal Product. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicinalProductIndication/[id]` | | Vread | `GET` | `/fhir/R4/MedicinalProductIndication/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicinalProductIndication/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicinalProductIndication/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicinalProductIndication/[id]` | | Create | `POST` | `/fhir/R4/MedicinalProductIndication` | | Search | `GET` | `/fhir/R4/MedicinalProductIndication` | | History | `GET` | `/fhir/R4/MedicinalProductIndication/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..*` | The medication for which this is an indication | | `diseaseSymptomProcedure` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The disease, symptom or procedure that is the indication for treatment | | `diseaseStatus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The status of the disease or symptom for which the indication applies | | `comorbidity` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Comorbidity (concurrent condition) or co-infection as part of the indication | | `intendedEffect` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The intended effect, aim or strategy to be achieved by the indication | | `duration` | [Quantity](/fhir-elements/complex/quantity) | `0..1` | Timing or duration information as part of the indication | | `otherTherapy` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Information about the use of the medicinal product in relation to other therapies described as part of the indication | | `undesirableEffect` | [Reference](/fhir-elements/complex/reference) | `0..*` | Describe the undesirable effects of the medicinal product | | `population` | [Population](/fhir-elements/complex/population) | `0..*` | The population group to which this applies | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `subject` | reference | The medication for which this is an indication | ## Reference [#reference] Official FHIR R4 spec: [MedicinalProductIndication](https://hl7.org/fhir/R4/medicinalproductindication.html). Maturity: Draft (FMM 0). # MedicinalProductIngredient Canonical page: https://docs.ovok.com/api/fhir/r4/medicinal-product-ingredient An ingredient of a manufactured item or pharmaceutical product. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicinalProductIngredient/[id]` | | Vread | `GET` | `/fhir/R4/MedicinalProductIngredient/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicinalProductIngredient/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicinalProductIngredient/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicinalProductIngredient/[id]` | | Create | `POST` | `/fhir/R4/MedicinalProductIngredient` | | Search | `GET` | `/fhir/R4/MedicinalProductIngredient` | | History | `GET` | `/fhir/R4/MedicinalProductIngredient/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Identifier for the ingredient | | `role` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Ingredient role e.g. Active ingredient, excipient | | `allergenicIndicator` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | If the ingredient is a known or suspected allergen | | `manufacturer` | [Reference](/fhir-elements/complex/reference) | `0..*` | Manufacturer of this Ingredient | | `specifiedSubstance` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A specified substance that comprises this ingredient | | `substance` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | The ingredient substance | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [MedicinalProductIngredient](https://hl7.org/fhir/R4/medicinalproductingredient.html). Maturity: Draft (FMM 0). # MedicinalProductInteraction Canonical page: https://docs.ovok.com/api/fhir/r4/medicinal-product-interaction The interactions of the medicinal product with other medicinal products, or other forms of interactions. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicinalProductInteraction/[id]` | | Vread | `GET` | `/fhir/R4/MedicinalProductInteraction/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicinalProductInteraction/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicinalProductInteraction/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicinalProductInteraction/[id]` | | Create | `POST` | `/fhir/R4/MedicinalProductInteraction` | | Search | `GET` | `/fhir/R4/MedicinalProductInteraction` | | History | `GET` | `/fhir/R4/MedicinalProductInteraction/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..*` | The medication for which this is a described interaction | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | The interaction described | | `interactant` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The specific medication, food or laboratory test that interacts | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The type of the interaction e.g. drug-drug interaction, drug-food interaction, drug-lab test interaction | | `effect` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The effect of the interaction, for example "reduced gastric absorption of primary medication" | | `incidence` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The incidence of the interaction, e.g. theoretical, observed | | `management` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Actions for managing the interaction | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `subject` | reference | The medication for which this is an interaction | ## Reference [#reference] Official FHIR R4 spec: [MedicinalProductInteraction](https://hl7.org/fhir/R4/medicinalproductinteraction.html). Maturity: Draft (FMM 0). # MedicinalProductManufactured Canonical page: https://docs.ovok.com/api/fhir/r4/medicinal-product-manufactured The manufactured item as contained in the packaged medicinal product. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicinalProductManufactured/[id]` | | Vread | `GET` | `/fhir/R4/MedicinalProductManufactured/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicinalProductManufactured/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicinalProductManufactured/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicinalProductManufactured/[id]` | | Create | `POST` | `/fhir/R4/MedicinalProductManufactured` | | Search | `GET` | `/fhir/R4/MedicinalProductManufactured` | | History | `GET` | `/fhir/R4/MedicinalProductManufactured/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `manufacturedDoseForm` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Dose form as manufactured and before any transformation into the pharmaceutical product | | `unitOfPresentation` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The “real world” units in which the quantity of the manufactured item is described | | `quantity` | [Quantity](/fhir-elements/complex/quantity) | `1..1` | The quantity or "count number" of the manufactured item | | `manufacturer` | [Reference](/fhir-elements/complex/reference) | `0..*` | Manufacturer of the item (Note that this should be named "manufacturer" but it currently causes technical issues) | | `ingredient` | [Reference](/fhir-elements/complex/reference) | `0..*` | Ingredient | | `physicalCharacteristics` | [ProdCharacteristic](/fhir-elements/complex/prod-characteristic) | `0..1` | Dimensions, color etc. | | `otherCharacteristics` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Other codeable characteristics | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [MedicinalProductManufactured](https://hl7.org/fhir/R4/medicinalproductmanufactured.html). Maturity: Draft (FMM 0). # MedicinalProductPackaged Canonical page: https://docs.ovok.com/api/fhir/r4/medicinal-product-packaged A medicinal product in a container or package. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicinalProductPackaged/[id]` | | Vread | `GET` | `/fhir/R4/MedicinalProductPackaged/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicinalProductPackaged/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicinalProductPackaged/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicinalProductPackaged/[id]` | | Create | `POST` | `/fhir/R4/MedicinalProductPackaged` | | Search | `GET` | `/fhir/R4/MedicinalProductPackaged` | | History | `GET` | `/fhir/R4/MedicinalProductPackaged/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Unique identifier | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..*` | The product with this is a pack for | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Textual description | | `legalStatusOfSupply` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The legal status of supply of the medicinal product as classified by the regulator | | `marketingStatus` | [MarketingStatus](/fhir-elements/complex/marketing-status) | `0..*` | Marketing information | | `marketingAuthorization` | [Reference](/fhir-elements/complex/reference) | `0..1` | Manufacturer of this Package Item | | `manufacturer` | [Reference](/fhir-elements/complex/reference) | `0..*` | Manufacturer of this Package Item | | `batchIdentifier` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Batch numbering | | `packageItem` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | A packaging item, as a contained for medicine, possibly with other packaging items within | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `identifier` | token | Unique identifier | | `subject` | reference | The product with this is a pack for | ## Reference [#reference] Official FHIR R4 spec: [MedicinalProductPackaged](https://hl7.org/fhir/R4/medicinalproductpackaged.html). Maturity: Draft (FMM 0). # MedicinalProductPharmaceutical Canonical page: https://docs.ovok.com/api/fhir/r4/medicinal-product-pharmaceutical A pharmaceutical product described in terms of its composition and dose form. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicinalProductPharmaceutical/[id]` | | Vread | `GET` | `/fhir/R4/MedicinalProductPharmaceutical/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicinalProductPharmaceutical/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicinalProductPharmaceutical/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicinalProductPharmaceutical/[id]` | | Create | `POST` | `/fhir/R4/MedicinalProductPharmaceutical` | | Search | `GET` | `/fhir/R4/MedicinalProductPharmaceutical` | | History | `GET` | `/fhir/R4/MedicinalProductPharmaceutical/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | An identifier for the pharmaceutical medicinal product | | `administrableDoseForm` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | The administrable dose form, after necessary reconstitution | | `unitOfPresentation` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Todo | | `ingredient` | [Reference](/fhir-elements/complex/reference) | `0..*` | Ingredient | | `device` | [Reference](/fhir-elements/complex/reference) | `0..*` | Accompanying device | | `characteristics` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Characteristics e.g. a products onset of action | | `routeOfAdministration` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | The path by which the pharmaceutical product is taken into or makes contact with the body | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `identifier` | token | An identifier for the pharmaceutical medicinal product | | `route` | token | Coded expression for the route | | `target-species` | token | Coded expression for the species | ## Reference [#reference] Official FHIR R4 spec: [MedicinalProductPharmaceutical](https://hl7.org/fhir/R4/medicinalproductpharmaceutical.html). Maturity: Draft (FMM 0). # MedicinalProductUndesirableEffect Canonical page: https://docs.ovok.com/api/fhir/r4/medicinal-product-undesirable-effect Describe the undesirable effects of the medicinal product. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicinalProductUndesirableEffect/[id]` | | Vread | `GET` | `/fhir/R4/MedicinalProductUndesirableEffect/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicinalProductUndesirableEffect/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicinalProductUndesirableEffect/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicinalProductUndesirableEffect/[id]` | | Create | `POST` | `/fhir/R4/MedicinalProductUndesirableEffect` | | Search | `GET` | `/fhir/R4/MedicinalProductUndesirableEffect` | | History | `GET` | `/fhir/R4/MedicinalProductUndesirableEffect/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..*` | The medication for which this is an indication | | `symptomConditionEffect` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The symptom, condition or undesirable effect | | `classification` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Classification of the effect | | `frequencyOfOccurrence` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The frequency of occurrence of the effect | | `population` | [Population](/fhir-elements/complex/population) | `0..*` | The population group to which this applies | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `subject` | reference | The medication for which this is an undesirable effect | ## Reference [#reference] Official FHIR R4 spec: [MedicinalProductUndesirableEffect](https://hl7.org/fhir/R4/medicinalproductundesirableeffect.html). Maturity: Draft (FMM 0). # MedicinalProduct Canonical page: https://docs.ovok.com/api/fhir/r4/medicinal-product Detailed definition of a medicinal product, typically for uses other than direct patient care (e.g. regulatory use). These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MedicinalProduct/[id]` | | Vread | `GET` | `/fhir/R4/MedicinalProduct/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MedicinalProduct/[id]` | | Patch | `PATCH` | `/fhir/R4/MedicinalProduct/[id]` | | Delete | `DELETE` | `/fhir/R4/MedicinalProduct/[id]` | | Create | `POST` | `/fhir/R4/MedicinalProduct` | | Search | `GET` | `/fhir/R4/MedicinalProduct` | | History | `GET` | `/fhir/R4/MedicinalProduct/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier for this product. Could be an MPID | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Regulatory type, e.g. Investigational or Authorized | | `domain` | [Coding](/fhir-elements/complex/coding) | `0..1` | If this medicine applies to human or veterinary uses | | `combinedPharmaceuticalDoseForm` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The dose form for a single part product, or combined form of a multiple part product | | `legalStatusOfSupply` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The legal status of supply of the medicinal product as classified by the regulator | | `additionalMonitoringIndicator` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Whether the Medicinal Product is subject to additional monitoring for regulatory reasons | | `specialMeasures` | [string](/fhir-elements/primitive/string) | `0..*` | Whether the Medicinal Product is subject to special measures for regulatory reasons | | `paediatricUseIndicator` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | If authorised for use in children | | `productClassification` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Allows the product to be classified by various systems | | `marketingStatus` | [MarketingStatus](/fhir-elements/complex/marketing-status) | `0..*` | Marketing status of the medicinal product, in contrast to marketing authorizaton | | `pharmaceuticalProduct` | [Reference](/fhir-elements/complex/reference) | `0..*` | Pharmaceutical aspects of product | | `packagedMedicinalProduct` | [Reference](/fhir-elements/complex/reference) | `0..*` | Package representation for the product | | `attachedDocument` | [Reference](/fhir-elements/complex/reference) | `0..*` | Supporting documentation, typically for regulatory submission | | `masterFile` | [Reference](/fhir-elements/complex/reference) | `0..*` | A master file for to the medicinal product (e.g. Pharmacovigilance System Master File) | | `contact` | [Reference](/fhir-elements/complex/reference) | `0..*` | A product specific contact, person (in a role), or an organization | | `clinicalTrial` | [Reference](/fhir-elements/complex/reference) | `0..*` | Clinical trials or studies that this product is involved in | | `name` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | The product's name, including full name and possibly coded parts | | `crossReference` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Reference to another product, e.g. for linking authorised to investigational product | | `manufacturingBusinessOperation` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | An operation applied to the product, for manufacturing or adminsitrative purpose | | `specialDesignation` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Indicates if the medicinal product has an orphan designation for the treatment of a rare disease | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `identifier` | token | Business identifier for this product. Could be an MPID | | `name` | string | The full product name | | `name-language` | token | Language code for this name | ## Reference [#reference] Official FHIR R4 spec: [MedicinalProduct](https://hl7.org/fhir/R4/medicinalproduct.html). Maturity: Draft (FMM 0). # MessageDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/message-definition Defines the characteristics of a message that can be shared between systems, including the type of event that initiates the message, the content to be transmitted and what response(s), if any, are permitted. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MessageDefinition/[id]` | | Vread | `GET` | `/fhir/R4/MessageDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MessageDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/MessageDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/MessageDefinition/[id]` | | Create | `POST` | `/fhir/R4/MessageDefinition` | | Search | `GET` | `/fhir/R4/MessageDefinition` | | History | `GET` | `/fhir/R4/MessageDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Business Identifier for a given MessageDefinition | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Primary key for the message definition on a given server | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the message definition | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this message definition (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this message definition (human friendly) | | `replaces` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Takes the place of | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the message definition | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for message definition (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this message definition is defined | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `base` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Definition this one is based on | | `parent` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Protocol/workflow this is part of | | `event[x]` | [Coding](/fhir-elements/complex/coding), [uri](/fhir-elements/primitive/uri) | `1..1` | Event code or link to the EventDefinition | | `category` | [code](/fhir-elements/primitive/code) | `0..1` | consequence \| currency \| notification | | `focus` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Resource(s) that are the subject of the event | | `responseRequired` | [code](/fhir-elements/primitive/code) | `0..1` | always \| on-error \| never \| on-success | | `allowedResponse` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Responses to this message | | `graph` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Canonical reference to a GraphDefinition | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `category` | token | The behavior associated with the message | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `event` | token | The event that triggers the message or link to the event definition. | | `focus` | token | A resource that is a permitted focus of the message | | `identifier` | token | Multiple Resources: CodeSystem: External identifier for the code system ; ConceptMap: External identifier for the concept map ; MessageDefinition: External identifier for the message definition ; StructureDefinition: External identifier for the structure definition ; StructureMap: External identifier for the structure map ; ValueSet: External identifier for the value set | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `parent` | reference | A resource that is the parent of the definition | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `title` | string | Multiple Resources: CapabilityStatement: The human-friendly name of the capability statement ; CodeSystem: The human-friendly name of the code system ; ConceptMap: The human-friendly name of the concept map ; ImplementationGuide: The human-friendly name of the implementation guide ; MessageDefinition: The human-friendly name of the message definition ; OperationDefinition: The human-friendly name of the operation definition ; StructureDefinition: The human-friendly name of the structure definition ; StructureMap: The human-friendly name of the structure map ; TerminologyCapabilities: The human-friendly name of the terminology capabilities ; ValueSet: The human-friendly name of the value set | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [MessageDefinition](https://hl7.org/fhir/R4/messagedefinition.html). Maturity: Trial Use 1 (FMM 1). # MessageHeader Canonical page: https://docs.ovok.com/api/fhir/r4/message-header The header for a message exchange that is either requesting or responding to an action. The reference(s) that are the subject of the action as well as other information related to the action are typically transmitted in a bundle in which the MessageHeader resource instance is the first resource in the bundle. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MessageHeader/[id]` | | Vread | `GET` | `/fhir/R4/MessageHeader/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MessageHeader/[id]` | | Patch | `PATCH` | `/fhir/R4/MessageHeader/[id]` | | Delete | `DELETE` | `/fhir/R4/MessageHeader/[id]` | | Create | `POST` | `/fhir/R4/MessageHeader` | | Search | `GET` | `/fhir/R4/MessageHeader` | | History | `GET` | `/fhir/R4/MessageHeader/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `event[x]` | [Coding](/fhir-elements/complex/coding), [uri](/fhir-elements/primitive/uri) | `1..1` | Code for the event this message represents or link to event definition | | `destination` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Message destination application(s) | | `sender` | [Reference](/fhir-elements/complex/reference) | `0..1` | Real world sender of the message | | `enterer` | [Reference](/fhir-elements/complex/reference) | `0..1` | The source of the data entry | | `author` | [Reference](/fhir-elements/complex/reference) | `0..1` | The source of the decision | | `source` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..1` | Message source application | | `responsible` | [Reference](/fhir-elements/complex/reference) | `0..1` | Final responsibility for event | | `reason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Cause of event | | `response` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | If this is a reply to prior message | | `focus` | [Reference](/fhir-elements/complex/reference) | `0..*` | The actual content of the message | | `definition` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Link to the definition for this message | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `author` | reference | The source of the decision | | `code` | token | ok \| transient-error \| fatal-error | | `destination` | string | Name of system | | `destination-uri` | uri | Actual destination address or id | | `enterer` | reference | The source of the data entry | | `event` | token | Code for the event this message represents or link to event definition | | `focus` | reference | The actual content of the message | | `receiver` | reference | Intended "real-world" recipient for the data | | `response-id` | token | Id of original message | | `responsible` | reference | Final responsibility for event | | `sender` | reference | Real world sender of the message | | `source` | string | Name of system | | `source-uri` | uri | Actual message source address or id | | `target` | reference | Particular delivery destination within the destination | ## Reference [#reference] Official FHIR R4 spec: [MessageHeader](https://hl7.org/fhir/R4/messageheader.html). Maturity: Trial Use 4 (FMM 4). # MolecularSequence Canonical page: https://docs.ovok.com/api/fhir/r4/molecular-sequence Raw data describing a biological sequence. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/MolecularSequence/[id]` | | Vread | `GET` | `/fhir/R4/MolecularSequence/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/MolecularSequence/[id]` | | Patch | `PATCH` | `/fhir/R4/MolecularSequence/[id]` | | Delete | `DELETE` | `/fhir/R4/MolecularSequence/[id]` | | Create | `POST` | `/fhir/R4/MolecularSequence` | | Search | `GET` | `/fhir/R4/MolecularSequence` | | History | `GET` | `/fhir/R4/MolecularSequence/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Unique ID for this particular sequence. This is a FHIR-defined id | | `type` | [code](/fhir-elements/primitive/code) | `0..1` | aa \| dna \| rna | | `coordinateSystem` | [integer](/fhir-elements/primitive/integer) | `1..1` | Base number of coordinate system (0 for 0-based numbering or coordinates, inclusive start, exclusive end, 1 for 1-based numbering, inclusive start, inclusive end) | | `patient` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who and/or what this is about | | `specimen` | [Reference](/fhir-elements/complex/reference) | `0..1` | Specimen used for sequencing | | `device` | [Reference](/fhir-elements/complex/reference) | `0..1` | The method for sequencing | | `performer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who should be responsible for test result | | `quantity` | [Quantity](/fhir-elements/complex/quantity) | `0..1` | The number of copies of the sequence of interest. (RNASeq) | | `referenceSeq` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | A sequence used as reference | | `variant` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Variant in sequence | | `observedSeq` | [string](/fhir-elements/primitive/string) | `0..1` | Sequence that was observed | | `quality` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | An set of value as quality of sequence | | `readCoverage` | [integer](/fhir-elements/primitive/integer) | `0..1` | Average number of reads representing a given nucleotide in the reconstructed sequence | | `repository` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | External repository which contains detailed report related with observedSeq in this resource | | `pointer` | [Reference](/fhir-elements/complex/reference) | `0..*` | Pointer to next atomic sequence | | `structureVariant` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Structural variant | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `chromosome` | token | Chromosome number of the reference sequence | | `chromosome-variant-coordinate` | composite | Search parameter by chromosome and variant coordinate. This will refer to part of a locus or part of a gene where search region will be represented in 1-based system. Since the coordinateSystem can either be 0-based or 1-based, this search query will include the result of both coordinateSystem that contains the equivalent segment of the gene or whole genome sequence. For example, a search for sequence can be represented as `chromosome-variant-coordinate=1$lt345$gt123`, this means it will search for the MolecularSequence resource with variants on chromosome 1 and with position >123 and <345, where in 1-based system resource, all strings within region 1:124-344 will be revealed, while in 0-based system resource, all strings within region 1:123-344 will be revealed. You may want to check detail about 0-based v.s. 1-based above. | | `chromosome-window-coordinate` | composite | Search parameter by chromosome and window. This will refer to part of a locus or part of a gene where search region will be represented in 1-based system. Since the coordinateSystem can either be 0-based or 1-based, this search query will include the result of both coordinateSystem that contains the equivalent segment of the gene or whole genome sequence. For example, a search for sequence can be represented as `chromosome-window-coordinate=1$lt345$gt123`, this means it will search for the MolecularSequence resource with a window on chromosome 1 and with position >123 and <345, where in 1-based system resource, all strings within region 1:124-344 will be revealed, while in 0-based system resource, all strings within region 1:123-344 will be revealed. You may want to check detail about 0-based v.s. 1-based above. | | `identifier` | token | The unique identity for a particular sequence | | `patient` | reference | The subject that the observation is about | | `referenceseqid` | token | Reference Sequence of the sequence | | `referenceseqid-variant-coordinate` | composite | Search parameter by reference sequence and variant coordinate. This will refer to part of a locus or part of a gene where search region will be represented in 1-based system. Since the coordinateSystem can either be 0-based or 1-based, this search query will include the result of both coordinateSystem that contains the equivalent segment of the gene or whole genome sequence. For example, a search for sequence can be represented as `referenceSeqId-variant-coordinate=NC_000001.11$lt345$gt123`, this means it will search for the MolecularSequence resource with variants on NC_000001.11 and with position >123 and <345, where in 1-based system resource, all strings within region NC_000001.11:124-344 will be revealed, while in 0-based system resource, all strings within region NC_000001.11:123-344 will be revealed. You may want to check detail about 0-based v.s. 1-based above. | | `referenceseqid-window-coordinate` | composite | Search parameter by reference sequence and window. This will refer to part of a locus or part of a gene where search region will be represented in 1-based system. Since the coordinateSystem can either be 0-based or 1-based, this search query will include the result of both coordinateSystem that contains the equivalent segment of the gene or whole genome sequence. For example, a search for sequence can be represented as `referenceSeqId-window-coordinate=NC_000001.11$lt345$gt123`, this means it will search for the MolecularSequence resource with a window on NC_000001.11 and with position >123 and <345, where in 1-based system resource, all strings within region NC_000001.11:124-344 will be revealed, while in 0-based system resource, all strings within region NC_000001.11:123-344 will be revealed. You may want to check detail about 0-based v.s. 1-based above. | | `type` | token | Amino Acid Sequence/ DNA Sequence / RNA Sequence | | `variant-end` | number | End position (0-based exclusive, which menas the acid at this position will not be included, 1-based inclusive, which means the acid at this position will be included) of the variant. | | `variant-start` | number | Start position (0-based inclusive, 1-based inclusive, that means the nucleic acid or amino acid at this position will be included) of the variant. | | `window-end` | number | End position (0-based exclusive, which menas the acid at this position will not be included, 1-based inclusive, which means the acid at this position will be included) of the reference sequence. | | `window-start` | number | Start position (0-based inclusive, 1-based inclusive, that means the nucleic acid or amino acid at this position will be included) of the reference sequence. | ## Reference [#reference] Official FHIR R4 spec: [MolecularSequence](https://hl7.org/fhir/R4/molecularsequence.html). Maturity: Trial Use 1 (FMM 1). # NamingSystem Canonical page: https://docs.ovok.com/api/fhir/r4/naming-system A curated namespace that issues unique symbols within that namespace for the identification of concepts, people, devices, etc. Represents a "System" used within the Identifier and Coding data types. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/NamingSystem/[id]` | | Vread | `GET` | `/fhir/R4/NamingSystem/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/NamingSystem/[id]` | | Patch | `PATCH` | `/fhir/R4/NamingSystem/[id]` | | Delete | `DELETE` | `/fhir/R4/NamingSystem/[id]` | | Create | `POST` | `/fhir/R4/NamingSystem` | | Search | `GET` | `/fhir/R4/NamingSystem` | | History | `GET` | `/fhir/R4/NamingSystem/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `name` | [string](/fhir-elements/primitive/string) | `1..1` | Name for this naming system (computer friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `kind` | [code](/fhir-elements/primitive/code) | `1..1` | codesystem \| identifier \| root | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `responsible` | [string](/fhir-elements/primitive/string) | `0..1` | Who maintains system namespace? | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | e.g. driver, provider, patient, bank etc. | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the naming system | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for naming system (if applicable) | | `usage` | [string](/fhir-elements/primitive/string) | `0..1` | How/where is it used | | `uniqueId` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | Unique identifiers used for system | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `contact` | string | Name of an individual to contact | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `id-type` | token | oid \| uuid \| uri \| other | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `kind` | token | codesystem \| identifier \| root | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `period` | date | When is identifier valid? | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `responsible` | string | Who maintains system namespace? | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `telecom` | token | Contact details for individual or organization | | `type` | token | e.g. driver, provider, patient, bank etc. | | `value` | string | The unique identifier | ## Reference [#reference] Official FHIR R4 spec: [NamingSystem](https://hl7.org/fhir/R4/namingsystem.html). Maturity: Trial Use 1 (FMM 1). # NutritionOrder Canonical page: https://docs.ovok.com/api/fhir/r4/nutrition-order A request to supply a diet, formula feeding (enteral) or oral nutritional supplement to a patient/resident. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/NutritionOrder/[id]` | | Vread | `GET` | `/fhir/R4/NutritionOrder/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/NutritionOrder/[id]` | | Patch | `PATCH` | `/fhir/R4/NutritionOrder/[id]` | | Delete | `DELETE` | `/fhir/R4/NutritionOrder/[id]` | | Create | `POST` | `/fhir/R4/NutritionOrder` | | Search | `GET` | `/fhir/R4/NutritionOrder` | | History | `GET` | `/fhir/R4/NutritionOrder/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Identifiers assigned to this order | | `instantiatesCanonical` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Instantiates FHIR protocol or definition | | `instantiatesUri` | [uri](/fhir-elements/primitive/uri) | `0..*` | Instantiates external protocol or definition | | `instantiates` | [uri](/fhir-elements/primitive/uri) | `0..*` | Instantiates protocol or definition | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| on-hold \| revoked \| completed \| entered-in-error \| unknown | | `intent` | [code](/fhir-elements/primitive/code) | `1..1` | proposal \| plan \| directive \| order \| original-order \| reflex-order \| filler-order \| instance-order \| option | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | The person who requires the diet, formula or nutritional supplement | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | The encounter associated with this nutrition order | | `dateTime` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Date and time the nutrition order was requested | | `orderer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who ordered the diet, formula or nutritional supplement | | `allergyIntolerance` | [Reference](/fhir-elements/complex/reference) | `0..*` | List of the patient's food and nutrition-related allergies and intolerances | | `foodPreferenceModifier` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Order-specific modifier about the type of food that should be given | | `excludeFoodModifier` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Order-specific modifier about the type of food that should not be given | | `oralDiet` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Oral diet components | | `supplement` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Supplement components | | `enteralFormula` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Enteral formula components | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `additive` | token | Type of module component to add to the feeding | | `datetime` | date | Return nutrition orders requested on this date | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `formula` | token | Type of enteral or infant formula | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `instantiates-canonical` | reference | Instantiates FHIR protocol or definition | | `instantiates-uri` | uri | Instantiates external protocol or definition | | `oraldiet` | token | Type of diet that can be consumed orally (i.e., take via the mouth). | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `provider` | reference | The identity of the provider who placed the nutrition order | | `status` | token | Status of the nutrition order. | | `supplement` | token | Type of supplement product requested | ## Reference [#reference] Official FHIR R4 spec: [NutritionOrder](https://hl7.org/fhir/R4/nutritionorder.html). Maturity: Trial Use 2 (FMM 2). # ObservationDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/observation-definition Set of definitional characteristics for a kind of observation or measurement produced or consumed by an orderable health care service. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ObservationDefinition/[id]` | | Vread | `GET` | `/fhir/R4/ObservationDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ObservationDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/ObservationDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/ObservationDefinition/[id]` | | Create | `POST` | `/fhir/R4/ObservationDefinition` | | Search | `GET` | `/fhir/R4/ObservationDefinition` | | History | `GET` | `/fhir/R4/ObservationDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Category of observation | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Type of observation (code / type) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier for this ObservationDefinition instance | | `permittedDataType` | [code](/fhir-elements/primitive/code) | `0..*` | Quantity \| CodeableConcept \| string \| boolean \| integer \| Range \| Ratio \| SampledData \| time \| dateTime \| Period | | `multipleResultsAllowed` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Multiple results allowed | | `method` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Method used to produce the observation | | `preferredReportName` | [string](/fhir-elements/primitive/string) | `0..1` | Preferred report name | | `quantitativeDetails` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Characteristics of quantitative results | | `qualifiedInterval` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Qualified range for continuous and ordinal observation results | | `validCodedValueSet` | [Reference](/fhir-elements/complex/reference) | `0..1` | Value set of valid coded values for the observations conforming to this ObservationDefinition | | `normalCodedValueSet` | [Reference](/fhir-elements/complex/reference) | `0..1` | Value set of normal coded values for the observations conforming to this ObservationDefinition | | `abnormalCodedValueSet` | [Reference](/fhir-elements/complex/reference) | `0..1` | Value set of abnormal coded values for the observations conforming to this ObservationDefinition | | `criticalCodedValueSet` | [Reference](/fhir-elements/complex/reference) | `0..1` | Value set of critical coded values for the observations conforming to this ObservationDefinition | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [ObservationDefinition](https://hl7.org/fhir/R4/observationdefinition.html). Maturity: Draft (FMM 0). # Observation Canonical page: https://docs.ovok.com/api/fhir/r4/observation Measurements and simple assertions made about a patient, device or other subject. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Observation/[id]` | | Vread | `GET` | `/fhir/R4/Observation/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Observation/[id]` | | Patch | `PATCH` | `/fhir/R4/Observation/[id]` | | Delete | `DELETE` | `/fhir/R4/Observation/[id]` | | Create | `POST` | `/fhir/R4/Observation` | | Search | `GET` | `/fhir/R4/Observation` | | History | `GET` | `/fhir/R4/Observation/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for observation | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Fulfills plan, proposal or order | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Part of referenced event | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | registered \| preliminary \| final \| amended + | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Classification of type of observation | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | Type of observation (code / type) | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who and/or what the observation is about | | `focus` | [Reference](/fhir-elements/complex/reference) | `0..*` | What the observation is about, when it is not about the subject of record | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Healthcare event during which this observation is made | | `effective[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period), [Timing](/fhir-elements/complex/timing), [instant](/fhir-elements/primitive/instant) | `0..1` | Clinically relevant time/time-period for observation | | `issued` | [instant](/fhir-elements/primitive/instant) | `0..1` | Date/Time this version was made available | | `performer` | [Reference](/fhir-elements/complex/reference) | `0..*` | Who is responsible for the observation | | `value[x]` | [Quantity](/fhir-elements/complex/quantity), [CodeableConcept](/fhir-elements/complex/codeable-concept), [string](/fhir-elements/primitive/string), [boolean](/fhir-elements/primitive/boolean), [integer](/fhir-elements/primitive/integer), [Range](/fhir-elements/complex/range), [Ratio](/fhir-elements/complex/ratio), [SampledData](/fhir-elements/complex/sampled-data), [time](/fhir-elements/primitive/time), [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period) | `0..1` | Actual result | | `dataAbsentReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Why the result is missing | | `interpretation` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | High, low, normal, etc. | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments about the observation | | `bodySite` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Observed body part | | `method` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | How it was done | | `specimen` | [Reference](/fhir-elements/complex/reference) | `0..1` | Specimen used for this observation | | `device` | [Reference](/fhir-elements/complex/reference) | `0..1` | (Measurement) Device | | `referenceRange` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Provides guide for interpretation | | `hasMember` | [Reference](/fhir-elements/complex/reference) | `0..*` | Related resource that belongs to the Observation group | | `derivedFrom` | [Reference](/fhir-elements/complex/reference) | `0..*` | Related measurements the observation is made from | | `component` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Component results | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `amino-acid-change` | string | HGVS Protein Change | | `based-on` | reference | Reference to the service request. | | `category` | token | The classification of the type of observation | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `code-value-concept` | composite | Code and coded value parameter pair | | `code-value-date` | composite | Code and date/time value parameter pair | | `code-value-quantity` | composite | Code and quantity value parameter pair | | `code-value-string` | composite | Code and string value parameter pair | | `combo-code` | token | The code of the observation type or component type | | `combo-code-value-concept` | composite | Code and coded value parameter pair, including in components | | `combo-code-value-quantity` | composite | Code and quantity value parameter pair, including in components | | `combo-data-absent-reason` | token | The reason why the expected value in the element Observation.value[x] or Observation.component.value[x] is missing. | | `combo-value-concept` | token | The value or component value of the observation, if the value is a CodeableConcept | | `combo-value-quantity` | quantity | The value or component value of the observation, if the value is a Quantity, or a SampledData (just search on the bounds of the values in sampled data) | | `component-code` | token | The component code of the observation type | | `component-code-value-concept` | composite | Component code and component coded value parameter pair | | `component-code-value-quantity` | composite | Component code and component quantity value parameter pair | | `component-data-absent-reason` | token | The reason why the expected value in the element Observation.component.value[x] is missing. | | `component-value-concept` | token | The value of the component observation, if the value is a CodeableConcept | | `component-value-quantity` | quantity | The value of the component observation, if the value is a Quantity, or a SampledData (just search on the bounds of the values in sampled data) | | `data-absent-reason` | token | The reason why the expected value in the element Observation.value[x] is missing. | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `derived-from` | reference | Related measurements the observation is made from | | `device` | reference | The Device that generated the observation data. | | `dna-variant` | string | HGVS DNA variant | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `focus` | reference | The focus of an observation when the focus is not the patient of record. | | `gene-amino-acid-change` | string | HGNC gene symbol and HGVS Protein change | | `gene-dnavariant` | string | HGNC gene symbol and HGVS DNA Variant | | `gene-identifier` | token | HGNC gene symbol and identifier | | `has-member` | reference | Related resource that belongs to the Observation group | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `method` | token | The method used for the observation | | `part-of` | reference | Part of referenced event | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `performer` | reference | Who performed the observation | | `specimen` | reference | Specimen used for this observation | | `status` | token | The status of the observation | | `subject` | reference | The subject that the observation is about | | `value-concept` | token | The value of the observation, if the value is a CodeableConcept | | `value-date` | date | The value of the observation, if the value is a date or period of time | | `value-quantity` | quantity | The value of the observation, if the value is a Quantity, or a SampledData (just search on the bounds of the values in sampled data) | | `value-string` | string | The value of the observation, if the value is a string, and also searches in CodeableConcept.text | ## Reference [#reference] Official FHIR R4 spec: [Observation](https://hl7.org/fhir/R4/observation.html). Maturity: Trial Use 5 (FMM 5). # OperationDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/operation-definition A formal computable definition of an operation (on the RESTful interface) or a named query (using the search interaction). These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/OperationDefinition/[id]` | | Vread | `GET` | `/fhir/R4/OperationDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/OperationDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/OperationDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/OperationDefinition/[id]` | | Create | `POST` | `/fhir/R4/OperationDefinition` | | Search | `GET` | `/fhir/R4/OperationDefinition` | | History | `GET` | `/fhir/R4/OperationDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this operation definition, represented as a URI (globally unique) | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the operation definition | | `name` | [string](/fhir-elements/primitive/string) | `1..1` | Name for this operation definition (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this operation definition (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `kind` | [code](/fhir-elements/primitive/code) | `1..1` | operation \| query | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the operation definition | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for operation definition (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this operation definition is defined | | `affectsState` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether content is changed by the operation | | `code` | [code](/fhir-elements/primitive/code) | `1..1` | Name used to invoke the operation | | `comment` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Additional information about use | | `base` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Marks this as a profile of the base | | `resource` | [code](/fhir-elements/primitive/code) | `0..*` | Types this operation applies to | | `system` | [boolean](/fhir-elements/primitive/boolean) | `1..1` | Invoke at the system level? | | `type` | [boolean](/fhir-elements/primitive/boolean) | `1..1` | Invoke at the type level? | | `instance` | [boolean](/fhir-elements/primitive/boolean) | `1..1` | Invoke on an instance? | | `inputProfile` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Validation information for in parameters | | `outputProfile` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Validation information for out parameters | | `parameter` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Parameters for the operation/query | | `overload` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Define overloaded variants for when generating code | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `base` | reference | Marks this as a profile of the base | | `code` | token | Name used to invoke the operation | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `input-profile` | reference | Validation information for in parameters | | `instance` | token | Invoke on an instance? | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `kind` | token | operation \| query | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `output-profile` | reference | Validation information for out parameters | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `system` | token | Invoke at the system level? | | `title` | string | Multiple Resources: CapabilityStatement: The human-friendly name of the capability statement ; CodeSystem: The human-friendly name of the code system ; ConceptMap: The human-friendly name of the concept map ; ImplementationGuide: The human-friendly name of the implementation guide ; MessageDefinition: The human-friendly name of the message definition ; OperationDefinition: The human-friendly name of the operation definition ; StructureDefinition: The human-friendly name of the structure definition ; StructureMap: The human-friendly name of the structure map ; TerminologyCapabilities: The human-friendly name of the terminology capabilities ; ValueSet: The human-friendly name of the value set | | `type` | token | Invoke at the type level? | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [OperationDefinition](https://hl7.org/fhir/R4/operationdefinition.html). Maturity: Trial Use 5 (FMM 5). # OperationOutcome Canonical page: https://docs.ovok.com/api/fhir/r4/operation-outcome A collection of error, warning, or information messages that result from a system action. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/OperationOutcome/[id]` | | Vread | `GET` | `/fhir/R4/OperationOutcome/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/OperationOutcome/[id]` | | Patch | `PATCH` | `/fhir/R4/OperationOutcome/[id]` | | Delete | `DELETE` | `/fhir/R4/OperationOutcome/[id]` | | Create | `POST` | `/fhir/R4/OperationOutcome` | | Search | `GET` | `/fhir/R4/OperationOutcome` | | History | `GET` | `/fhir/R4/OperationOutcome/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `issue` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | A single issue associated with the action | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [OperationOutcome](https://hl7.org/fhir/R4/operationoutcome.html). Maturity: Trial Use 5 (FMM 5). # OrganizationAffiliation Canonical page: https://docs.ovok.com/api/fhir/r4/organization-affiliation Defines an affiliation/assotiation/relationship between 2 distinct oganizations, that is not a part-of relationship/sub-division relationship. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/OrganizationAffiliation/[id]` | | Vread | `GET` | `/fhir/R4/OrganizationAffiliation/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/OrganizationAffiliation/[id]` | | Patch | `PATCH` | `/fhir/R4/OrganizationAffiliation/[id]` | | Delete | `DELETE` | `/fhir/R4/OrganizationAffiliation/[id]` | | Create | `POST` | `/fhir/R4/OrganizationAffiliation` | | Search | `GET` | `/fhir/R4/OrganizationAffiliation` | | History | `GET` | `/fhir/R4/OrganizationAffiliation/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifiers that are specific to this role | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether this organization affiliation record is in active use | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | The period during which the participatingOrganization is affiliated with the primary organization | | `organization` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization where the role is available | | `participatingOrganization` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization that provides/performs the role (e.g. providing services or is a member of) | | `network` | [Reference](/fhir-elements/complex/reference) | `0..*` | Health insurance provider network in which the participatingOrganization provides the role's services (if defined) at the indicated locations (if defined) | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Definition of the role the participatingOrganization plays | | `specialty` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Specific specialty of the participatingOrganization in the context of the role | | `location` | [Reference](/fhir-elements/complex/reference) | `0..*` | The location(s) at which the role occurs | | `healthcareService` | [Reference](/fhir-elements/complex/reference) | `0..*` | Healthcare services provided through the role | | `telecom` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | Contact details at the participatingOrganization relevant to this Affiliation | | `endpoint` | [Reference](/fhir-elements/complex/reference) | `0..*` | Technical endpoints providing access to services operated for this role | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `active` | token | Whether this organization affiliation record is in active use | | `date` | date | The period during which the participatingOrganization is affiliated with the primary organization | | `email` | token | A value in an email contact | | `endpoint` | reference | Technical endpoints providing access to services operated for this role | | `identifier` | token | An organization affiliation's Identifier | | `location` | reference | The location(s) at which the role occurs | | `network` | reference | Health insurance provider network in which the participatingOrganization provides the role's services (if defined) at the indicated locations (if defined) | | `participating-organization` | reference | The organization that provides services to the primary organization | | `phone` | token | A value in a phone contact | | `primary-organization` | reference | The organization that receives the services from the participating organization | | `role` | token | Definition of the role the participatingOrganization plays | | `service` | reference | Healthcare services provided through the role | | `specialty` | token | Specific specialty of the participatingOrganization in the context of the role | | `telecom` | token | The value in any kind of contact | ## Reference [#reference] Official FHIR R4 spec: [OrganizationAffiliation](https://hl7.org/fhir/R4/organizationaffiliation.html). Maturity: Draft (FMM 0). # Organization Canonical page: https://docs.ovok.com/api/fhir/r4/organization A formally or informally recognized grouping of people or organizations formed for the purpose of achieving some form of collective action. Includes companies, institutions, corporations, departments, community groups, healthcare practice groups, payer/insurer, etc. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Organization/[id]` | | Vread | `GET` | `/fhir/R4/Organization/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Organization/[id]` | | Patch | `PATCH` | `/fhir/R4/Organization/[id]` | | Delete | `DELETE` | `/fhir/R4/Organization/[id]` | | Create | `POST` | `/fhir/R4/Organization` | | Search | `GET` | `/fhir/R4/Organization` | | History | `GET` | `/fhir/R4/Organization/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Identifies this organization across multiple systems | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether the organization's record is still in active use | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Kind of organization | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name used for the organization | | `alias` | [string](/fhir-elements/primitive/string) | `0..*` | A list of alternate names that the organization is known as, or was known as in the past | | `telecom` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | A contact detail for the organization | | `address` | [Address](/fhir-elements/complex/address) | `0..*` | An address for the organization | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..1` | The organization of which this organization forms a part | | `contact` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Contact for the organization for a certain purpose | | `endpoint` | [Reference](/fhir-elements/complex/reference) | `0..*` | Technical endpoints providing access to services operated for the organization | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `active` | token | Is the Organization record active | | `address` | string | A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text | | `address-city` | string | A city specified in an address | | `address-country` | string | A country specified in an address | | `address-postalcode` | string | A postal code specified in an address | | `address-state` | string | A state specified in an address | | `address-use` | token | A use code specified in an address | | `endpoint` | reference | Technical endpoints providing access to services operated for the organization | | `identifier` | token | Any identifier for the organization (not the accreditation issuer's identifier) | | `name` | string | A portion of the organization's name or alias | | `partof` | reference | An organization of which this organization forms a part | | `phonetic` | string | A portion of the organization's name using some kind of phonetic matching algorithm | | `type` | token | A code for the type of organization | ## Reference [#reference] Official FHIR R4 spec: [Organization](https://hl7.org/fhir/R4/organization.html). Maturity: Trial Use 3 (FMM 3). # Parameters Canonical page: https://docs.ovok.com/api/fhir/r4/parameters This resource is a non-persisted resource used to pass information into and back from an [operation](https://hl7.org/fhir/R4/operations.html). It has no other use, and there is no RESTful endpoint associated with it. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Parameters/[id]` | | Vread | `GET` | `/fhir/R4/Parameters/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Parameters/[id]` | | Patch | `PATCH` | `/fhir/R4/Parameters/[id]` | | Delete | `DELETE` | `/fhir/R4/Parameters/[id]` | | Create | `POST` | `/fhir/R4/Parameters` | | Search | `GET` | `/fhir/R4/Parameters` | | History | `GET` | `/fhir/R4/Parameters/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `parameter` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Operation Parameter | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [Parameters](https://hl7.org/fhir/R4/parameters.html). Maturity: Trial Use 5 (FMM 5). # Patient Canonical page: https://docs.ovok.com/api/fhir/r4/patient Demographics and other administrative information about an individual or animal receiving care or other health-related services. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Patient/[id]` | | Vread | `GET` | `/fhir/R4/Patient/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Patient/[id]` | | Patch | `PATCH` | `/fhir/R4/Patient/[id]` | | Delete | `DELETE` | `/fhir/R4/Patient/[id]` | | Create | `POST` | `/fhir/R4/Patient` | | Search | `GET` | `/fhir/R4/Patient` | | History | `GET` | `/fhir/R4/Patient/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | An identifier for this patient | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether this patient's record is in active use | | `name` | [HumanName](/fhir-elements/complex/human-name) | `0..*` | A name associated with the patient | | `telecom` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | A contact detail for the individual | | `gender` | [code](/fhir-elements/primitive/code) | `0..1` | male \| female \| other \| unknown | | `birthDate` | [date](/fhir-elements/primitive/date) | `0..1` | The date of birth for the individual | | `deceased[x]` | [boolean](/fhir-elements/primitive/boolean), [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Indicates if the individual is deceased or not | | `address` | [Address](/fhir-elements/complex/address) | `0..*` | An address for the individual | | `maritalStatus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Marital (civil) status of a patient | | `multipleBirth[x]` | [boolean](/fhir-elements/primitive/boolean), [integer](/fhir-elements/primitive/integer) | `0..1` | Whether patient is part of a multiple birth | | `photo` | [Attachment](/fhir-elements/complex/attachment) | `0..*` | Image of the patient | | `contact` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A contact party (e.g. guardian, partner, friend) for the patient | | `communication` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A language which may be used to communicate with the patient about his or her health | | `generalPractitioner` | [Reference](/fhir-elements/complex/reference) | `0..*` | Patient's nominated primary care provider | | `managingOrganization` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization that is the custodian of the patient record | | `link` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Link to another patient resource that concerns the same actual person | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `active` | token | Whether the patient record is active | | `address` | string | Multiple Resources: Patient: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; Person: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; Practitioner: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; RelatedPerson: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text | | `address-city` | string | Multiple Resources: Patient: A city specified in an address ; Person: A city specified in an address ; Practitioner: A city specified in an address ; RelatedPerson: A city specified in an address | | `address-country` | string | Multiple Resources: Patient: A country specified in an address ; Person: A country specified in an address ; Practitioner: A country specified in an address ; RelatedPerson: A country specified in an address | | `address-postalcode` | string | Multiple Resources: Patient: A postalCode specified in an address ; Person: A postal code specified in an address ; Practitioner: A postalCode specified in an address ; RelatedPerson: A postal code specified in an address | | `address-state` | string | Multiple Resources: Patient: A state specified in an address ; Person: A state specified in an address ; Practitioner: A state specified in an address ; RelatedPerson: A state specified in an address | | `address-use` | token | Multiple Resources: Patient: A use code specified in an address ; Person: A use code specified in an address ; Practitioner: A use code specified in an address ; RelatedPerson: A use code specified in an address | | `age` | number | Searches for patients based on age as calculated based on current date and date of birth. Deceased patients are excluded from the search. | | `birthdate` | date | Multiple Resources: Patient: The patient's date of birth ; Person: The person's date of birth ; RelatedPerson: The Related Person's date of birth | | `birthOrderBoolean` | token | Search based on whether a patient was part of a multiple birth or not. | | `death-date` | date | The date of death has been provided and satisfies this search value | | `deceased` | token | This patient has been marked as deceased, or as a death date entered | | `email` | token | Multiple Resources: Patient: A value in an email contact ; Person: A value in an email contact ; Practitioner: A value in an email contact ; PractitionerRole: A value in an email contact ; RelatedPerson: A value in an email contact | | `family` | string | Multiple Resources: Patient: A portion of the family name of the patient ; Practitioner: A portion of the family name | | `gender` | token | Multiple Resources: Patient: Gender of the patient ; Person: The gender of the person ; Practitioner: Gender of the practitioner ; RelatedPerson: Gender of the related person | | `general-practitioner` | reference | Patient's nominated general practitioner, not the organization that manages the record | | `given` | string | Multiple Resources: Patient: A portion of the given name of the patient ; Practitioner: A portion of the given name | | `identifier` | token | A patient identifier | | `language` | token | Language code (irrespective of use value) | | `link` | reference | All patients linked to the given patient | | `mothersMaidenName` | string | Search based on patient's mother's maiden name | | `name` | string | A server defined search that may match any of the string fields in the HumanName, including family, give, prefix, suffix, suffix, and/or text | | `organization` | reference | The organization that is the custodian of the patient record | | `part-agree` | reference | Search by url for a participation agreement, which is stored in a DocumentReference | | `phone` | token | Multiple Resources: Patient: A value in a phone contact ; Person: A value in a phone contact ; Practitioner: A value in a phone contact ; PractitionerRole: A value in a phone contact ; RelatedPerson: A value in a phone contact | | `phonetic` | string | Multiple Resources: Patient: A portion of either family or given name using some kind of phonetic matching algorithm ; Person: A portion of name using some kind of phonetic matching algorithm ; Practitioner: A portion of either family or given name using some kind of phonetic matching algorithm ; RelatedPerson: A portion of name using some kind of phonetic matching algorithm | | `telecom` | token | Multiple Resources: Patient: The value in any kind of telecom details of the patient ; Person: The value in any kind of contact ; Practitioner: The value in any kind of contact ; PractitionerRole: The value in any kind of contact ; RelatedPerson: The value in any kind of contact | ## Reference [#reference] Official FHIR R4 spec: [Patient](https://hl7.org/fhir/R4/patient.html). Maturity: Trial Use 5 (FMM 5). # PaymentNotice Canonical page: https://docs.ovok.com/api/fhir/r4/payment-notice This resource provides the status of the payment for goods and services rendered, and the request and response resource references. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/PaymentNotice/[id]` | | Vread | `GET` | `/fhir/R4/PaymentNotice/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/PaymentNotice/[id]` | | Patch | `PATCH` | `/fhir/R4/PaymentNotice/[id]` | | Delete | `DELETE` | `/fhir/R4/PaymentNotice/[id]` | | Create | `POST` | `/fhir/R4/PaymentNotice` | | Search | `GET` | `/fhir/R4/PaymentNotice` | | History | `GET` | `/fhir/R4/PaymentNotice/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for the payment noctice | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| cancelled \| draft \| entered-in-error | | `request` | [Reference](/fhir-elements/complex/reference) | `0..1` | Request reference | | `response` | [Reference](/fhir-elements/complex/reference) | `0..1` | Response reference | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Creation date | | `provider` | [Reference](/fhir-elements/complex/reference) | `0..1` | Responsible practitioner | | `payment` | [Reference](/fhir-elements/complex/reference) | `1..1` | Payment reference | | `paymentDate` | [date](/fhir-elements/primitive/date) | `0..1` | Payment or clearing date | | `payee` | [Reference](/fhir-elements/complex/reference) | `0..1` | Party being paid | | `recipient` | [Reference](/fhir-elements/complex/reference) | `1..1` | Party being notified | | `amount` | [Money](/fhir-elements/complex/money) | `1..1` | Monetary amount of the payment | | `paymentStatus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Issued or cleared Status of the payment | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `created` | date | Creation date fro the notice | | `identifier` | token | The business identifier of the notice | | `payment-status` | token | The type of payment notice | | `provider` | reference | The reference to the provider | | `request` | reference | The Claim | | `response` | reference | The ClaimResponse | | `status` | token | The status of the payment notice | ## Reference [#reference] Official FHIR R4 spec: [PaymentNotice](https://hl7.org/fhir/R4/paymentnotice.html). Maturity: Trial Use 2 (FMM 2). # PaymentReconciliation Canonical page: https://docs.ovok.com/api/fhir/r4/payment-reconciliation This resource provides the details including amount of a payment and allocates the payment items being paid. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/PaymentReconciliation/[id]` | | Vread | `GET` | `/fhir/R4/PaymentReconciliation/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/PaymentReconciliation/[id]` | | Patch | `PATCH` | `/fhir/R4/PaymentReconciliation/[id]` | | Delete | `DELETE` | `/fhir/R4/PaymentReconciliation/[id]` | | Create | `POST` | `/fhir/R4/PaymentReconciliation` | | Search | `GET` | `/fhir/R4/PaymentReconciliation` | | History | `GET` | `/fhir/R4/PaymentReconciliation/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for a payment reconciliation | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| cancelled \| draft \| entered-in-error | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | Period covered | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Creation date | | `paymentIssuer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Party generating payment | | `request` | [Reference](/fhir-elements/complex/reference) | `0..1` | Reference to requesting resource | | `requestor` | [Reference](/fhir-elements/complex/reference) | `0..1` | Responsible practitioner | | `outcome` | [code](/fhir-elements/primitive/code) | `0..1` | queued \| complete \| error \| partial | | `disposition` | [string](/fhir-elements/primitive/string) | `0..1` | Disposition message | | `paymentDate` | [date](/fhir-elements/primitive/date) | `1..1` | When payment issued | | `paymentAmount` | [Money](/fhir-elements/complex/money) | `1..1` | Total amount of Payment | | `paymentIdentifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Business identifier for the payment | | `detail` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Settlement particulars | | `formCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Printed form identifier | | `processNote` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Note concerning processing | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `created` | date | The creation date | | `disposition` | string | The contents of the disposition message | | `identifier` | token | The business identifier of the ExplanationOfBenefit | | `outcome` | token | The processing outcome | | `payment-issuer` | reference | The organization which generated this resource | | `request` | reference | The reference to the claim | | `requestor` | reference | The reference to the provider who submitted the claim | | `status` | token | The status of the payment reconciliation | ## Reference [#reference] Official FHIR R4 spec: [PaymentReconciliation](https://hl7.org/fhir/R4/paymentreconciliation.html). Maturity: Trial Use 2 (FMM 2). # Person Canonical page: https://docs.ovok.com/api/fhir/r4/person Demographics and administrative information about a person independent of a specific health-related context. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Person/[id]` | | Vread | `GET` | `/fhir/R4/Person/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Person/[id]` | | Patch | `PATCH` | `/fhir/R4/Person/[id]` | | Delete | `DELETE` | `/fhir/R4/Person/[id]` | | Create | `POST` | `/fhir/R4/Person` | | Search | `GET` | `/fhir/R4/Person` | | History | `GET` | `/fhir/R4/Person/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | A human identifier for this person | | `name` | [HumanName](/fhir-elements/complex/human-name) | `0..*` | A name associated with the person | | `telecom` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | A contact detail for the person | | `gender` | [code](/fhir-elements/primitive/code) | `0..1` | male \| female \| other \| unknown | | `birthDate` | [date](/fhir-elements/primitive/date) | `0..1` | The date on which the person was born | | `address` | [Address](/fhir-elements/complex/address) | `0..*` | One or more addresses for the person | | `photo` | [Attachment](/fhir-elements/complex/attachment) | `0..1` | Image of the person | | `managingOrganization` | [Reference](/fhir-elements/complex/reference) | `0..1` | The organization that is the custodian of the person record | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | This person's record is in active use | | `link` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Link to a resource that concerns the same actual person | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `address` | string | Multiple Resources: Patient: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; Person: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; Practitioner: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; RelatedPerson: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text | | `address-city` | string | Multiple Resources: Patient: A city specified in an address ; Person: A city specified in an address ; Practitioner: A city specified in an address ; RelatedPerson: A city specified in an address | | `address-country` | string | Multiple Resources: Patient: A country specified in an address ; Person: A country specified in an address ; Practitioner: A country specified in an address ; RelatedPerson: A country specified in an address | | `address-postalcode` | string | Multiple Resources: Patient: A postalCode specified in an address ; Person: A postal code specified in an address ; Practitioner: A postalCode specified in an address ; RelatedPerson: A postal code specified in an address | | `address-state` | string | Multiple Resources: Patient: A state specified in an address ; Person: A state specified in an address ; Practitioner: A state specified in an address ; RelatedPerson: A state specified in an address | | `address-use` | token | Multiple Resources: Patient: A use code specified in an address ; Person: A use code specified in an address ; Practitioner: A use code specified in an address ; RelatedPerson: A use code specified in an address | | `birthdate` | date | Multiple Resources: Patient: The patient's date of birth ; Person: The person's date of birth ; RelatedPerson: The Related Person's date of birth | | `email` | token | Multiple Resources: Patient: A value in an email contact ; Person: A value in an email contact ; Practitioner: A value in an email contact ; PractitionerRole: A value in an email contact ; RelatedPerson: A value in an email contact | | `gender` | token | Multiple Resources: Patient: Gender of the patient ; Person: The gender of the person ; Practitioner: Gender of the practitioner ; RelatedPerson: Gender of the related person | | `identifier` | token | A person Identifier | | `link` | reference | Any link has this Patient, Person, RelatedPerson or Practitioner reference | | `name` | string | A server defined search that may match any of the string fields in the HumanName, including family, give, prefix, suffix, suffix, and/or text | | `organization` | reference | The organization at which this person record is being managed | | `patient` | reference | The Person links to this Patient | | `phone` | token | Multiple Resources: Patient: A value in a phone contact ; Person: A value in a phone contact ; Practitioner: A value in a phone contact ; PractitionerRole: A value in a phone contact ; RelatedPerson: A value in a phone contact | | `phonetic` | string | Multiple Resources: Patient: A portion of either family or given name using some kind of phonetic matching algorithm ; Person: A portion of name using some kind of phonetic matching algorithm ; Practitioner: A portion of either family or given name using some kind of phonetic matching algorithm ; RelatedPerson: A portion of name using some kind of phonetic matching algorithm | | `practitioner` | reference | The Person links to this Practitioner | | `relatedperson` | reference | The Person links to this RelatedPerson | | `telecom` | token | Multiple Resources: Patient: The value in any kind of telecom details of the patient ; Person: The value in any kind of contact ; Practitioner: The value in any kind of contact ; PractitionerRole: The value in any kind of contact ; RelatedPerson: The value in any kind of contact | ## Reference [#reference] Official FHIR R4 spec: [Person](https://hl7.org/fhir/R4/person.html). Maturity: Trial Use 2 (FMM 2). # PlanDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/plan-definition This resource allows for the definition of various types of plans as a sharable, consumable, and executable artifact. The resource is general enough to support the description of a broad range of clinical artifacts such as clinical decision support rules, order sets and protocols. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/PlanDefinition/[id]` | | Vread | `GET` | `/fhir/R4/PlanDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/PlanDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/PlanDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/PlanDefinition/[id]` | | Create | `POST` | `/fhir/R4/PlanDefinition` | | Search | `GET` | `/fhir/R4/PlanDefinition` | | History | `GET` | `/fhir/R4/PlanDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this plan definition, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the plan definition | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the plan definition | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this plan definition (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this plan definition (human friendly) | | `subtitle` | [string](/fhir-elements/primitive/string) | `0..1` | Subordinate title of the plan definition | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | order-set \| clinical-protocol \| eca-rule \| workflow-definition | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `subject[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `0..1` | Type of individual the plan definition is focused on | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the plan definition | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for plan definition (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this plan definition is defined | | `usage` | [string](/fhir-elements/primitive/string) | `0..1` | Describes the clinical usage of the plan | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the plan definition was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the plan definition was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the plan definition is expected to be used | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | E.g. Education, Treatment, Assessment | | `author` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who authored the content | | `editor` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who edited the content | | `reviewer` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who reviewed the content | | `endorser` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who endorsed the content | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | Additional documentation, citations | | `library` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Logic used by the plan definition | | `goal` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | What the plan is trying to accomplish | | `action` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Action defined by the plan | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `composed-of` | reference | What resource is being referenced | | `context` | token | A use context assigned to the plan definition | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the plan definition | | `context-type` | token | A type of use context assigned to the plan definition | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the plan definition | | `context-type-value` | composite | A use context type and value assigned to the plan definition | | `date` | date | The plan definition publication date | | `definition` | reference | Activity or plan definitions used by plan definition | | `depends-on` | reference | What resource is being referenced | | `derived-from` | reference | What resource is being referenced | | `description` | string | The description of the plan definition | | `effective` | date | The time during which the plan definition is intended to be in use | | `identifier` | token | External identifier for the plan definition | | `jurisdiction` | token | Intended jurisdiction for the plan definition | | `name` | string | Computationally friendly name of the plan definition | | `predecessor` | reference | What resource is being referenced | | `publisher` | string | Name of the publisher of the plan definition | | `status` | token | The current status of the plan definition | | `successor` | reference | What resource is being referenced | | `title` | string | The human-friendly name of the plan definition | | `topic` | token | Topics associated with the module | | `type` | token | The type of artifact the plan (e.g. order-set, eca-rule, protocol) | | `url` | uri | The uri that identifies the plan definition | | `version` | token | The business version of the plan definition | ## Reference [#reference] Official FHIR R4 spec: [PlanDefinition](https://hl7.org/fhir/R4/plandefinition.html). Maturity: Trial Use 2 (FMM 2). # PractitionerRole Canonical page: https://docs.ovok.com/api/fhir/r4/practitioner-role A specific set of Roles/Locations/specialties/services that a practitioner may perform at an organization for a period of time. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/PractitionerRole/[id]` | | Vread | `GET` | `/fhir/R4/PractitionerRole/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/PractitionerRole/[id]` | | Patch | `PATCH` | `/fhir/R4/PractitionerRole/[id]` | | Delete | `DELETE` | `/fhir/R4/PractitionerRole/[id]` | | Create | `POST` | `/fhir/R4/PractitionerRole` | | Search | `GET` | `/fhir/R4/PractitionerRole` | | History | `GET` | `/fhir/R4/PractitionerRole/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifiers that are specific to a role/location | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether this practitioner role record is in active use | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | The period during which the practitioner is authorized to perform in these role(s) | | `practitioner` | [Reference](/fhir-elements/complex/reference) | `0..1` | Practitioner that is able to provide the defined services for the organization | | `organization` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization where the roles are available | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Roles which this practitioner may perform | | `specialty` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Specific specialty of the practitioner | | `location` | [Reference](/fhir-elements/complex/reference) | `0..*` | The location(s) at which this practitioner provides care | | `healthcareService` | [Reference](/fhir-elements/complex/reference) | `0..*` | The list of healthcare services that this worker provides for this role's Organization/Location(s) | | `telecom` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | Contact details that are specific to the role/location/service | | `availableTime` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Times the Service Site is available | | `notAvailable` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Not available during this time due to provided reason | | `availabilityExceptions` | [string](/fhir-elements/primitive/string) | `0..1` | Description of availability exceptions | | `endpoint` | [Reference](/fhir-elements/complex/reference) | `0..*` | Technical endpoints providing access to services operated for the practitioner with this role | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `active` | token | Whether this practitioner role record is in active use | | `date` | date | The period during which the practitioner is authorized to perform in these role(s) | | `email` | token | Multiple Resources: Patient: A value in an email contact ; Person: A value in an email contact ; Practitioner: A value in an email contact ; PractitionerRole: A value in an email contact ; RelatedPerson: A value in an email contact | | `endpoint` | reference | Technical endpoints providing access to services operated for the practitioner with this role | | `identifier` | token | A practitioner's Identifier | | `location` | reference | One of the locations at which this practitioner provides care | | `organization` | reference | The identity of the organization the practitioner represents / acts on behalf of | | `phone` | token | Multiple Resources: Patient: A value in a phone contact ; Person: A value in a phone contact ; Practitioner: A value in a phone contact ; PractitionerRole: A value in a phone contact ; RelatedPerson: A value in a phone contact | | `practitioner` | reference | Practitioner that is able to provide the defined services for the organization | | `role` | token | The practitioner can perform this role at for the organization | | `service` | reference | The list of healthcare services that this worker provides for this role's Organization/Location(s) | | `specialty` | token | The practitioner has this specialty at an organization | | `telecom` | token | Multiple Resources: Patient: The value in any kind of telecom details of the patient ; Person: The value in any kind of contact ; Practitioner: The value in any kind of contact ; PractitionerRole: The value in any kind of contact ; RelatedPerson: The value in any kind of contact | ## Reference [#reference] Official FHIR R4 spec: [PractitionerRole](https://hl7.org/fhir/R4/practitionerrole.html). Maturity: Trial Use 2 (FMM 2). # Practitioner Canonical page: https://docs.ovok.com/api/fhir/r4/practitioner A person who is directly or indirectly involved in the provisioning of healthcare. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Practitioner/[id]` | | Vread | `GET` | `/fhir/R4/Practitioner/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Practitioner/[id]` | | Patch | `PATCH` | `/fhir/R4/Practitioner/[id]` | | Delete | `DELETE` | `/fhir/R4/Practitioner/[id]` | | Create | `POST` | `/fhir/R4/Practitioner` | | Search | `GET` | `/fhir/R4/Practitioner` | | History | `GET` | `/fhir/R4/Practitioner/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | An identifier for the person as this agent | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether this practitioner's record is in active use | | `name` | [HumanName](/fhir-elements/complex/human-name) | `0..*` | The name(s) associated with the practitioner | | `telecom` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | A contact detail for the practitioner (that apply to all roles) | | `address` | [Address](/fhir-elements/complex/address) | `0..*` | Address(es) of the practitioner that are not role specific (typically home address) | | `gender` | [code](/fhir-elements/primitive/code) | `0..1` | male \| female \| other \| unknown | | `birthDate` | [date](/fhir-elements/primitive/date) | `0..1` | The date on which the practitioner was born | | `photo` | [Attachment](/fhir-elements/complex/attachment) | `0..*` | Image of the person | | `qualification` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Certification, licenses, or training pertaining to the provision of care | | `communication` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | A language the practitioner can use in patient communication | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `active` | token | Whether the practitioner record is active | | `address` | string | Multiple Resources: Patient: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; Person: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; Practitioner: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; RelatedPerson: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text | | `address-city` | string | Multiple Resources: Patient: A city specified in an address ; Person: A city specified in an address ; Practitioner: A city specified in an address ; RelatedPerson: A city specified in an address | | `address-country` | string | Multiple Resources: Patient: A country specified in an address ; Person: A country specified in an address ; Practitioner: A country specified in an address ; RelatedPerson: A country specified in an address | | `address-postalcode` | string | Multiple Resources: Patient: A postalCode specified in an address ; Person: A postal code specified in an address ; Practitioner: A postalCode specified in an address ; RelatedPerson: A postal code specified in an address | | `address-state` | string | Multiple Resources: Patient: A state specified in an address ; Person: A state specified in an address ; Practitioner: A state specified in an address ; RelatedPerson: A state specified in an address | | `address-use` | token | Multiple Resources: Patient: A use code specified in an address ; Person: A use code specified in an address ; Practitioner: A use code specified in an address ; RelatedPerson: A use code specified in an address | | `communication` | token | One of the languages that the practitioner can communicate with | | `email` | token | Multiple Resources: Patient: A value in an email contact ; Person: A value in an email contact ; Practitioner: A value in an email contact ; PractitionerRole: A value in an email contact ; RelatedPerson: A value in an email contact | | `family` | string | Multiple Resources: Patient: A portion of the family name of the patient ; Practitioner: A portion of the family name | | `gender` | token | Multiple Resources: Patient: Gender of the patient ; Person: The gender of the person ; Practitioner: Gender of the practitioner ; RelatedPerson: Gender of the related person | | `given` | string | Multiple Resources: Patient: A portion of the given name of the patient ; Practitioner: A portion of the given name | | `identifier` | token | A practitioner's Identifier | | `name` | string | A server defined search that may match any of the string fields in the HumanName, including family, give, prefix, suffix, suffix, and/or text | | `phone` | token | Multiple Resources: Patient: A value in a phone contact ; Person: A value in a phone contact ; Practitioner: A value in a phone contact ; PractitionerRole: A value in a phone contact ; RelatedPerson: A value in a phone contact | | `phonetic` | string | Multiple Resources: Patient: A portion of either family or given name using some kind of phonetic matching algorithm ; Person: A portion of name using some kind of phonetic matching algorithm ; Practitioner: A portion of either family or given name using some kind of phonetic matching algorithm ; RelatedPerson: A portion of name using some kind of phonetic matching algorithm | | `telecom` | token | Multiple Resources: Patient: The value in any kind of telecom details of the patient ; Person: The value in any kind of contact ; Practitioner: The value in any kind of contact ; PractitionerRole: The value in any kind of contact ; RelatedPerson: The value in any kind of contact | ## Reference [#reference] Official FHIR R4 spec: [Practitioner](https://hl7.org/fhir/R4/practitioner.html). Maturity: Trial Use 3 (FMM 3). # Procedure Canonical page: https://docs.ovok.com/api/fhir/r4/procedure An action that is or was performed on or for a patient. This can be a physical intervention like an operation, or less invasive like long term services, counseling, or hypnotherapy. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Procedure/[id]` | | Vread | `GET` | `/fhir/R4/Procedure/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Procedure/[id]` | | Patch | `PATCH` | `/fhir/R4/Procedure/[id]` | | Delete | `DELETE` | `/fhir/R4/Procedure/[id]` | | Create | `POST` | `/fhir/R4/Procedure` | | Search | `GET` | `/fhir/R4/Procedure` | | History | `GET` | `/fhir/R4/Procedure/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Identifiers for this procedure | | `instantiatesCanonical` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Instantiates FHIR protocol or definition | | `instantiatesUri` | [uri](/fhir-elements/primitive/uri) | `0..*` | Instantiates external protocol or definition | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | A request for this procedure | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Part of referenced event | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | preparation \| in-progress \| not-done \| on-hold \| stopped \| completed \| entered-in-error \| unknown | | `statusReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Reason for current status | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Classification of the procedure | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Identification of the procedure | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who the procedure was performed on | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter created as part of | | `performed[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period), [string](/fhir-elements/primitive/string), [Age](/fhir-elements/complex/age), [Range](/fhir-elements/complex/range) | `0..1` | When the procedure was performed | | `recorder` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who recorded the procedure | | `asserter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Person who asserts this procedure | | `performer` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The people who performed the procedure | | `location` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where the procedure happened | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Coded reason procedure performed | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | The justification that the procedure was performed | | `bodySite` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Target body sites | | `outcome` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The result of procedure | | `report` | [Reference](/fhir-elements/complex/reference) | `0..*` | Any report resulting from the procedure | | `complication` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Complication following the procedure | | `complicationDetail` | [Reference](/fhir-elements/complex/reference) | `0..*` | A condition that is a result of the procedure | | `followUp` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Instructions for follow up | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Additional information about the procedure | | `focalDevice` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Manipulated, implanted, or removed device | | `usedReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Items used during procedure | | `usedCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Coded items used during the procedure | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `based-on` | reference | A request for this procedure | | `category` | token | Classification of the procedure | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `instantiates-canonical` | reference | Instantiates FHIR protocol or definition | | `instantiates-uri` | uri | Instantiates external protocol or definition | | `location` | reference | Where the procedure happened | | `part-of` | reference | Part of referenced event | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `performer` | reference | The reference to the practitioner | | `reason-code` | token | Coded reason procedure performed | | `reason-reference` | reference | The justification that the procedure was performed | | `status` | token | preparation \| in-progress \| not-done \| on-hold \| stopped \| completed \| entered-in-error \| unknown | | `subject` | reference | Search by subject | ## Reference [#reference] Official FHIR R4 spec: [Procedure](https://hl7.org/fhir/R4/procedure.html). Maturity: Trial Use 3 (FMM 3). # Provenance Canonical page: https://docs.ovok.com/api/fhir/r4/provenance Provenance of a resource is a record that describes entities and processes involved in producing and delivering or otherwise influencing that resource. Provenance provides a critical foundation for assessing authenticity, enabling trust, and allowing reproducibility. Provenance assertions are a form of contextual metadata and can themselves become important records with their own provenance. Provenance statement indicates clinical significance in terms of confidence in authenticity, reliability, and trustworthiness, integrity, and stage in lifecycle (e.g. Document Completion - has the artifact been legally authenticated), all of which may impact security, privacy, and trust policies. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Provenance/[id]` | | Vread | `GET` | `/fhir/R4/Provenance/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Provenance/[id]` | | Patch | `PATCH` | `/fhir/R4/Provenance/[id]` | | Delete | `DELETE` | `/fhir/R4/Provenance/[id]` | | Create | `POST` | `/fhir/R4/Provenance` | | Search | `GET` | `/fhir/R4/Provenance` | | History | `GET` | `/fhir/R4/Provenance/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `target` | [Reference](/fhir-elements/complex/reference) | `1..*` | Target Reference(s) (usually version specific) | | `occurred[x]` | [Period](/fhir-elements/complex/period), [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the activity occurred | | `recorded` | [instant](/fhir-elements/primitive/instant) | `1..1` | When the activity was recorded / updated | | `policy` | [uri](/fhir-elements/primitive/uri) | `0..*` | Policy or plan the activity was defined by | | `location` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where the activity occurred, if relevant | | `reason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Reason the activity is occurring | | `activity` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Activity that occurred | | `agent` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | Actor involved | | `entity` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | An entity used in this activity | | `signature` | [Signature](/fhir-elements/complex/signature) | `0..*` | Signature on target | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `agent` | reference | Who participated | | `agent-role` | token | What the agents role was | | `agent-type` | token | How the agent participated | | `entity` | reference | Identity of entity | | `location` | reference | Where the activity occurred, if relevant | | `patient` | reference | Target Reference(s) (usually version specific) | | `recorded` | date | When the activity was recorded / updated | | `signature-type` | token | Indication of the reason the entity signed the object(s) | | `target` | reference | Target Reference(s) (usually version specific) | | `when` | date | When the activity occurred | ## Reference [#reference] Official FHIR R4 spec: [Provenance](https://hl7.org/fhir/R4/provenance.html). Maturity: Trial Use 3 (FMM 3). # QuestionnaireResponse Canonical page: https://docs.ovok.com/api/fhir/r4/questionnaire-response A structured set of questions and their answers. The questions are ordered and grouped into coherent subsets, corresponding to the structure of the grouping of the questionnaire being responded to. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/QuestionnaireResponse/[id]` | | Vread | `GET` | `/fhir/R4/QuestionnaireResponse/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/QuestionnaireResponse/[id]` | | Patch | `PATCH` | `/fhir/R4/QuestionnaireResponse/[id]` | | Delete | `DELETE` | `/fhir/R4/QuestionnaireResponse/[id]` | | Create | `POST` | `/fhir/R4/QuestionnaireResponse` | | Search | `GET` | `/fhir/R4/QuestionnaireResponse` | | History | `GET` | `/fhir/R4/QuestionnaireResponse/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Unique id for this set of answers | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Request fulfilled by this QuestionnaireResponse | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Part of this action | | `questionnaire` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Form being answered | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | in-progress \| completed \| amended \| entered-in-error \| stopped | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | The subject of the questions | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter created as part of | | `authored` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date the answers were gathered | | `author` | [Reference](/fhir-elements/complex/reference) | `0..1` | Person who received and recorded the answers | | `source` | [Reference](/fhir-elements/complex/reference) | `0..1` | The person who answered the questions | | `item` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Groups and questions | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `author` | reference | The author of the questionnaire response | | `authored` | date | When the questionnaire response was last changed | | `based-on` | reference | Plan/proposal/order fulfilled by this questionnaire response | | `encounter` | reference | Encounter associated with the questionnaire response | | `identifier` | token | The unique identifier for the questionnaire response | | `item-subject` | reference | Allows searching for QuestionnaireResponses by item value where the item has isSubject=true | | `part-of` | reference | Procedure or observation this questionnaire response was performed as a part of | | `patient` | reference | The patient that is the subject of the questionnaire response | | `questionnaire` | reference | The questionnaire the answers are provided for | | `source` | reference | The individual providing the information reflected in the questionnaire respose | | `status` | token | The status of the questionnaire response | | `subject` | reference | The subject of the questionnaire response | ## Reference [#reference] Official FHIR R4 spec: [QuestionnaireResponse](https://hl7.org/fhir/R4/questionnaireresponse.html). Maturity: Trial Use 3 (FMM 3). # Questionnaire Canonical page: https://docs.ovok.com/api/fhir/r4/questionnaire A structured set of questions intended to guide the collection of answers from end-users. Questionnaires provide detailed control over order, presentation, phraseology and grouping to allow coherent, consistent data collection. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Questionnaire/[id]` | | Vread | `GET` | `/fhir/R4/Questionnaire/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Questionnaire/[id]` | | Patch | `PATCH` | `/fhir/R4/Questionnaire/[id]` | | Delete | `DELETE` | `/fhir/R4/Questionnaire/[id]` | | Create | `POST` | `/fhir/R4/Questionnaire` | | Search | `GET` | `/fhir/R4/Questionnaire` | | History | `GET` | `/fhir/R4/Questionnaire/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this questionnaire, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the questionnaire | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the questionnaire | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this questionnaire (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this questionnaire (human friendly) | | `derivedFrom` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Instantiates protocol or definition | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `subjectType` | [code](/fhir-elements/primitive/code) | `0..*` | Resource that can be subject of QuestionnaireResponse | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the questionnaire | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for questionnaire (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this questionnaire is defined | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the questionnaire was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the questionnaire was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the questionnaire is expected to be used | | `code` | [Coding](/fhir-elements/complex/coding) | `0..*` | Concept that represents the overall questionnaire | | `item` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Questions and sections within the Questionnaire | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `code` | token | A code that corresponds to one of its items in the questionnaire | | `context` | token | A use context assigned to the questionnaire | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the questionnaire | | `context-type` | token | A type of use context assigned to the questionnaire | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the questionnaire | | `context-type-value` | composite | A use context type and value assigned to the questionnaire | | `date` | date | The questionnaire publication date | | `definition` | uri | ElementDefinition - details for the item | | `description` | string | The description of the questionnaire | | `effective` | date | The time during which the questionnaire is intended to be in use | | `identifier` | token | External identifier for the questionnaire | | `jurisdiction` | token | Intended jurisdiction for the questionnaire | | `name` | string | Computationally friendly name of the questionnaire | | `publisher` | string | Name of the publisher of the questionnaire | | `status` | token | The current status of the questionnaire | | `subject-type` | token | Resource that can be subject of QuestionnaireResponse | | `title` | string | The human-friendly name of the questionnaire | | `url` | uri | The uri that identifies the questionnaire | | `version` | token | The business version of the questionnaire | ## Reference [#reference] Official FHIR R4 spec: [Questionnaire](https://hl7.org/fhir/R4/questionnaire.html). Maturity: Trial Use 3 (FMM 3). # RelatedPerson Canonical page: https://docs.ovok.com/api/fhir/r4/related-person Information about a person that is involved in the care for a patient, but who is not the target of healthcare, nor has a formal responsibility in the care process. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/RelatedPerson/[id]` | | Vread | `GET` | `/fhir/R4/RelatedPerson/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/RelatedPerson/[id]` | | Patch | `PATCH` | `/fhir/R4/RelatedPerson/[id]` | | Delete | `DELETE` | `/fhir/R4/RelatedPerson/[id]` | | Create | `POST` | `/fhir/R4/RelatedPerson` | | Search | `GET` | `/fhir/R4/RelatedPerson` | | History | `GET` | `/fhir/R4/RelatedPerson/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | A human identifier for this person | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether this related person's record is in active use | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | The patient this person is related to | | `relationship` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The nature of the relationship | | `name` | [HumanName](/fhir-elements/complex/human-name) | `0..*` | A name associated with the person | | `telecom` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | A contact detail for the person | | `gender` | [code](/fhir-elements/primitive/code) | `0..1` | male \| female \| other \| unknown | | `birthDate` | [date](/fhir-elements/primitive/date) | `0..1` | The date on which the related person was born | | `address` | [Address](/fhir-elements/complex/address) | `0..*` | Address where the related person can be contacted or visited | | `photo` | [Attachment](/fhir-elements/complex/attachment) | `0..*` | Image of the person | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | Period of time that this relationship is considered valid | | `communication` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A language which may be used to communicate with about the patient's health | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `active` | token | Indicates if the related person record is active | | `address` | string | Multiple Resources: Patient: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; Person: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; Practitioner: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text ; RelatedPerson: A server defined search that may match any of the string fields in the Address, including line, city, district, state, country, postalCode, and/or text | | `address-city` | string | Multiple Resources: Patient: A city specified in an address ; Person: A city specified in an address ; Practitioner: A city specified in an address ; RelatedPerson: A city specified in an address | | `address-country` | string | Multiple Resources: Patient: A country specified in an address ; Person: A country specified in an address ; Practitioner: A country specified in an address ; RelatedPerson: A country specified in an address | | `address-postalcode` | string | Multiple Resources: Patient: A postalCode specified in an address ; Person: A postal code specified in an address ; Practitioner: A postalCode specified in an address ; RelatedPerson: A postal code specified in an address | | `address-state` | string | Multiple Resources: Patient: A state specified in an address ; Person: A state specified in an address ; Practitioner: A state specified in an address ; RelatedPerson: A state specified in an address | | `address-use` | token | Multiple Resources: Patient: A use code specified in an address ; Person: A use code specified in an address ; Practitioner: A use code specified in an address ; RelatedPerson: A use code specified in an address | | `birthdate` | date | Multiple Resources: Patient: The patient's date of birth ; Person: The person's date of birth ; RelatedPerson: The Related Person's date of birth | | `email` | token | Multiple Resources: Patient: A value in an email contact ; Person: A value in an email contact ; Practitioner: A value in an email contact ; PractitionerRole: A value in an email contact ; RelatedPerson: A value in an email contact | | `gender` | token | Multiple Resources: Patient: Gender of the patient ; Person: The gender of the person ; Practitioner: Gender of the practitioner ; RelatedPerson: Gender of the related person | | `identifier` | token | An Identifier of the RelatedPerson | | `name` | string | A server defined search that may match any of the string fields in the HumanName, including family, give, prefix, suffix, suffix, and/or text | | `patient` | reference | The patient this related person is related to | | `phone` | token | Multiple Resources: Patient: A value in a phone contact ; Person: A value in a phone contact ; Practitioner: A value in a phone contact ; PractitionerRole: A value in a phone contact ; RelatedPerson: A value in a phone contact | | `phonetic` | string | Multiple Resources: Patient: A portion of either family or given name using some kind of phonetic matching algorithm ; Person: A portion of name using some kind of phonetic matching algorithm ; Practitioner: A portion of either family or given name using some kind of phonetic matching algorithm ; RelatedPerson: A portion of name using some kind of phonetic matching algorithm | | `relationship` | token | The relationship between the patient and the relatedperson | | `telecom` | token | Multiple Resources: Patient: The value in any kind of telecom details of the patient ; Person: The value in any kind of contact ; Practitioner: The value in any kind of contact ; PractitionerRole: The value in any kind of contact ; RelatedPerson: The value in any kind of contact | ## Reference [#reference] Official FHIR R4 spec: [RelatedPerson](https://hl7.org/fhir/R4/relatedperson.html). Maturity: Trial Use 2 (FMM 2). # RequestGroup Canonical page: https://docs.ovok.com/api/fhir/r4/request-group A group of related requests that can be used to capture intended activities that have inter-dependencies such as "give this medication after that one". These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/RequestGroup/[id]` | | Vread | `GET` | `/fhir/R4/RequestGroup/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/RequestGroup/[id]` | | Patch | `PATCH` | `/fhir/R4/RequestGroup/[id]` | | Delete | `DELETE` | `/fhir/R4/RequestGroup/[id]` | | Create | `POST` | `/fhir/R4/RequestGroup` | | Search | `GET` | `/fhir/R4/RequestGroup` | | History | `GET` | `/fhir/R4/RequestGroup/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business identifier | | `instantiatesCanonical` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Instantiates FHIR protocol or definition | | `instantiatesUri` | [uri](/fhir-elements/primitive/uri) | `0..*` | Instantiates external protocol or definition | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Fulfills plan, proposal, or order | | `replaces` | [Reference](/fhir-elements/complex/reference) | `0..*` | Request(s) replaced by this request | | `groupIdentifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Composite request this is part of | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| on-hold \| revoked \| completed \| entered-in-error \| unknown | | `intent` | [code](/fhir-elements/primitive/code) | `1..1` | proposal \| plan \| directive \| order \| original-order \| reflex-order \| filler-order \| instance-order \| option | | `priority` | [code](/fhir-elements/primitive/code) | `0..1` | routine \| urgent \| asap \| stat | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | What's being requested/ordered | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who the request group is about | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Created as part of | | `authoredOn` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the request group was authored | | `author` | [Reference](/fhir-elements/complex/reference) | `0..1` | Device or practitioner that authored the request group | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Why the request group is needed | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Why the request group is needed | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Additional notes about the response | | `action` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Proposed actions, if any | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `author` | reference | The author of the request group | | `authored` | date | The date the request group was authored | | `code` | token | The code of the request group | | `encounter` | reference | The encounter the request group applies to | | `group-identifier` | token | The group identifier for the request group | | `identifier` | token | External identifiers for the request group | | `instantiates-canonical` | reference | The FHIR-based definition from which the request group is realized | | `instantiates-uri` | uri | The external definition from which the request group is realized | | `intent` | token | The intent of the request group | | `participant` | reference | The participant in the requests in the group | | `patient` | reference | The identity of a patient to search for request groups | | `priority` | token | The priority of the request group | | `status` | token | The status of the request group | | `subject` | reference | The subject that the request group is about | ## Reference [#reference] Official FHIR R4 spec: [RequestGroup](https://hl7.org/fhir/R4/requestgroup.html). Maturity: Trial Use 2 (FMM 2). # ResearchDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/research-definition The ResearchDefinition resource describes the conditional state (population and any exposures being compared within the population) and outcome (if specified) that the knowledge (evidence, assertion, recommendation) is about. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ResearchDefinition/[id]` | | Vread | `GET` | `/fhir/R4/ResearchDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ResearchDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/ResearchDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/ResearchDefinition/[id]` | | Create | `POST` | `/fhir/R4/ResearchDefinition` | | Search | `GET` | `/fhir/R4/ResearchDefinition` | | History | `GET` | `/fhir/R4/ResearchDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this research definition, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the research definition | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the research definition | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this research definition (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this research definition (human friendly) | | `shortTitle` | [string](/fhir-elements/primitive/string) | `0..1` | Title for use in informal contexts | | `subtitle` | [string](/fhir-elements/primitive/string) | `0..1` | Subordinate title of the ResearchDefinition | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `subject[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `0..1` | E.g. Patient, Practitioner, RelatedPerson, Organization, Location, Device | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the research definition | | `comment` | [string](/fhir-elements/primitive/string) | `0..*` | Used for footnotes or explanatory notes | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for research definition (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this research definition is defined | | `usage` | [string](/fhir-elements/primitive/string) | `0..1` | Describes the clinical usage of the ResearchDefinition | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the research definition was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the research definition was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the research definition is expected to be used | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The category of the ResearchDefinition, such as Education, Treatment, Assessment, etc. | | `author` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who authored the content | | `editor` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who edited the content | | `reviewer` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who reviewed the content | | `endorser` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who endorsed the content | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | Additional documentation, citations, etc. | | `library` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Logic used by the ResearchDefinition | | `population` | [Reference](/fhir-elements/complex/reference) | `1..1` | What population? | | `exposure` | [Reference](/fhir-elements/complex/reference) | `0..1` | What exposure? | | `exposureAlternative` | [Reference](/fhir-elements/complex/reference) | `0..1` | What alternative exposure state? | | `outcome` | [Reference](/fhir-elements/complex/reference) | `0..1` | What outcome? | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `composed-of` | reference | What resource is being referenced | | `context` | token | A use context assigned to the research definition | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the research definition | | `context-type` | token | A type of use context assigned to the research definition | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the research definition | | `context-type-value` | composite | A use context type and value assigned to the research definition | | `date` | date | The research definition publication date | | `depends-on` | reference | What resource is being referenced | | `derived-from` | reference | What resource is being referenced | | `description` | string | The description of the research definition | | `effective` | date | The time during which the research definition is intended to be in use | | `identifier` | token | External identifier for the research definition | | `jurisdiction` | token | Intended jurisdiction for the research definition | | `name` | string | Computationally friendly name of the research definition | | `predecessor` | reference | What resource is being referenced | | `publisher` | string | Name of the publisher of the research definition | | `status` | token | The current status of the research definition | | `successor` | reference | What resource is being referenced | | `title` | string | The human-friendly name of the research definition | | `topic` | token | Topics associated with the ResearchDefinition | | `url` | uri | The uri that identifies the research definition | | `version` | token | The business version of the research definition | ## Reference [#reference] Official FHIR R4 spec: [ResearchDefinition](https://hl7.org/fhir/R4/researchdefinition.html). Maturity: Draft (FMM 0). # ResearchElementDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/research-element-definition The ResearchElementDefinition resource describes a "PICO" element that knowledge (evidence, assertion, recommendation) is about. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ResearchElementDefinition/[id]` | | Vread | `GET` | `/fhir/R4/ResearchElementDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ResearchElementDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/ResearchElementDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/ResearchElementDefinition/[id]` | | Create | `POST` | `/fhir/R4/ResearchElementDefinition` | | Search | `GET` | `/fhir/R4/ResearchElementDefinition` | | History | `GET` | `/fhir/R4/ResearchElementDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this research element definition, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the research element definition | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the research element definition | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this research element definition (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this research element definition (human friendly) | | `shortTitle` | [string](/fhir-elements/primitive/string) | `0..1` | Title for use in informal contexts | | `subtitle` | [string](/fhir-elements/primitive/string) | `0..1` | Subordinate title of the ResearchElementDefinition | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `subject[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `0..1` | E.g. Patient, Practitioner, RelatedPerson, Organization, Location, Device | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the research element definition | | `comment` | [string](/fhir-elements/primitive/string) | `0..*` | Used for footnotes or explanatory notes | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for research element definition (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this research element definition is defined | | `usage` | [string](/fhir-elements/primitive/string) | `0..1` | Describes the clinical usage of the ResearchElementDefinition | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the research element definition was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the research element definition was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the research element definition is expected to be used | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The category of the ResearchElementDefinition, such as Education, Treatment, Assessment, etc. | | `author` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who authored the content | | `editor` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who edited the content | | `reviewer` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who reviewed the content | | `endorser` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who endorsed the content | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | Additional documentation, citations, etc. | | `library` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Logic used by the ResearchElementDefinition | | `type` | [code](/fhir-elements/primitive/code) | `1..1` | population \| exposure \| outcome | | `variableType` | [code](/fhir-elements/primitive/code) | `0..1` | dichotomous \| continuous \| descriptive | | `characteristic` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | What defines the members of the research element | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `composed-of` | reference | What resource is being referenced | | `context` | token | A use context assigned to the research element definition | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the research element definition | | `context-type` | token | A type of use context assigned to the research element definition | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the research element definition | | `context-type-value` | composite | A use context type and value assigned to the research element definition | | `date` | date | The research element definition publication date | | `depends-on` | reference | What resource is being referenced | | `derived-from` | reference | What resource is being referenced | | `description` | string | The description of the research element definition | | `effective` | date | The time during which the research element definition is intended to be in use | | `identifier` | token | External identifier for the research element definition | | `jurisdiction` | token | Intended jurisdiction for the research element definition | | `name` | string | Computationally friendly name of the research element definition | | `predecessor` | reference | What resource is being referenced | | `publisher` | string | Name of the publisher of the research element definition | | `status` | token | The current status of the research element definition | | `successor` | reference | What resource is being referenced | | `title` | string | The human-friendly name of the research element definition | | `topic` | token | Topics associated with the ResearchElementDefinition | | `url` | uri | The uri that identifies the research element definition | | `version` | token | The business version of the research element definition | ## Reference [#reference] Official FHIR R4 spec: [ResearchElementDefinition](https://hl7.org/fhir/R4/researchelementdefinition.html). Maturity: Draft (FMM 0). # ResearchStudy Canonical page: https://docs.ovok.com/api/fhir/r4/research-study A process where a researcher or organization plans and then executes a series of steps intended to increase the field of healthcare-related knowledge. This includes studies of safety, efficacy, comparative effectiveness and other information about medications, devices, therapies and other interventional and investigative techniques. A ResearchStudy involves the gathering of information about human or animal subjects. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ResearchStudy/[id]` | | Vread | `GET` | `/fhir/R4/ResearchStudy/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ResearchStudy/[id]` | | Patch | `PATCH` | `/fhir/R4/ResearchStudy/[id]` | | Delete | `DELETE` | `/fhir/R4/ResearchStudy/[id]` | | Create | `POST` | `/fhir/R4/ResearchStudy` | | Search | `GET` | `/fhir/R4/ResearchStudy` | | History | `GET` | `/fhir/R4/ResearchStudy/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for study | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this study | | `protocol` | [Reference](/fhir-elements/complex/reference) | `0..*` | Steps followed in executing study | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Part of larger study | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| administratively-completed \| approved \| closed-to-accrual \| closed-to-accrual-and-intervention \| completed \| disapproved \| in-review \| temporarily-closed-to-accrual \| temporarily-closed-to-accrual-and-intervention \| withdrawn | | `primaryPurposeType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | treatment \| prevention \| diagnostic \| supportive-care \| screening \| health-services-research \| basic-science \| device-feasibility | | `phase` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | n-a \| early-phase-1 \| phase-1 \| phase-1-phase-2 \| phase-2 \| phase-2-phase-3 \| phase-3 \| phase-4 | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Classifications for the study | | `focus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Drugs, devices, etc. under study | | `condition` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Condition being studied | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the study | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | References and dependencies | | `keyword` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Used to search for the study | | `location` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Geographic region(s) for study | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | What this is study doing | | `enrollment` | [Reference](/fhir-elements/complex/reference) | `0..*` | Inclusion & exclusion criteria | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | When the study began and ended | | `sponsor` | [Reference](/fhir-elements/complex/reference) | `0..1` | Organization that initiates and is legally responsible for the study | | `principalInvestigator` | [Reference](/fhir-elements/complex/reference) | `0..1` | Researcher who oversees multiple aspects of the study | | `site` | [Reference](/fhir-elements/complex/reference) | `0..*` | Facility where study activities are conducted | | `reasonStopped` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | accrual-goal-met \| closed-due-to-toxicity \| closed-due-to-lack-of-study-progress \| temporarily-closed-per-study-design | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments made about the study | | `arm` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Defined path through the study for a subject | | `objective` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A goal for the study | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `category` | token | Classifications for the study | | `date` | date | When the study began and ended | | `focus` | token | Drugs, devices, etc. under study | | `identifier` | token | Business Identifier for study | | `keyword` | token | Used to search for the study | | `location` | token | Geographic region(s) for study | | `partof` | reference | Part of larger study | | `principalinvestigator` | reference | Researcher who oversees multiple aspects of the study | | `protocol` | reference | Steps followed in executing study | | `site` | reference | Facility where study activities are conducted | | `sponsor` | reference | Organization that initiates and is legally responsible for the study | | `status` | token | active \| administratively-completed \| approved \| closed-to-accrual \| closed-to-accrual-and-intervention \| completed \| disapproved \| in-review \| temporarily-closed-to-accrual \| temporarily-closed-to-accrual-and-intervention \| withdrawn | | `title` | string | Name for this study | ## Reference [#reference] Official FHIR R4 spec: [ResearchStudy](https://hl7.org/fhir/R4/researchstudy.html). Maturity: Trial Use 1 (FMM 1). # ResearchSubject Canonical page: https://docs.ovok.com/api/fhir/r4/research-subject A physical entity which is the primary unit of operational and/or administrative interest in a study. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ResearchSubject/[id]` | | Vread | `GET` | `/fhir/R4/ResearchSubject/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ResearchSubject/[id]` | | Patch | `PATCH` | `/fhir/R4/ResearchSubject/[id]` | | Delete | `DELETE` | `/fhir/R4/ResearchSubject/[id]` | | Create | `POST` | `/fhir/R4/ResearchSubject` | | Search | `GET` | `/fhir/R4/ResearchSubject` | | History | `GET` | `/fhir/R4/ResearchSubject/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for research subject in a study | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | candidate \| eligible \| follow-up \| ineligible \| not-registered \| off-study \| on-study \| on-study-intervention \| on-study-observation \| pending-on-study \| potential-candidate \| screening \| withdrawn | | `period` | [Period](/fhir-elements/complex/period) | `0..1` | Start and end of participation | | `study` | [Reference](/fhir-elements/complex/reference) | `1..1` | Study subject is part of | | `individual` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who is part of study | | `assignedArm` | [string](/fhir-elements/primitive/string) | `0..1` | What path should be followed | | `actualArm` | [string](/fhir-elements/primitive/string) | `0..1` | What path was followed | | `consent` | [Reference](/fhir-elements/complex/reference) | `0..1` | Agreement to participate in study | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `date` | date | Start and end of participation | | `identifier` | token | Business Identifier for research subject in a study | | `individual` | reference | Who is part of study | | `patient` | reference | Who is part of study | | `status` | token | candidate \| eligible \| follow-up \| ineligible \| not-registered \| off-study \| on-study \| on-study-intervention \| on-study-observation \| pending-on-study \| potential-candidate \| screening \| withdrawn | | `study` | reference | Study subject is part of | ## Reference [#reference] Official FHIR R4 spec: [ResearchSubject](https://hl7.org/fhir/R4/researchsubject.html). Maturity: Trial Use 1 (FMM 1). # RiskAssessment Canonical page: https://docs.ovok.com/api/fhir/r4/risk-assessment An assessment of the likely outcome(s) for a patient or other subject as well as the likelihood of each outcome. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/RiskAssessment/[id]` | | Vread | `GET` | `/fhir/R4/RiskAssessment/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/RiskAssessment/[id]` | | Patch | `PATCH` | `/fhir/R4/RiskAssessment/[id]` | | Delete | `DELETE` | `/fhir/R4/RiskAssessment/[id]` | | Create | `POST` | `/fhir/R4/RiskAssessment` | | Search | `GET` | `/fhir/R4/RiskAssessment` | | History | `GET` | `/fhir/R4/RiskAssessment/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Unique identifier for the assessment | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..1` | Request fulfilled by this assessment | | `parent` | [Reference](/fhir-elements/complex/reference) | `0..1` | Part of this occurrence | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | registered \| preliminary \| final \| amended + | | `method` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Evaluation mechanism | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Type of assessment | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who/what does assessment apply to? | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where was assessment performed? | | `occurrence[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period) | `0..1` | When was assessment made? | | `condition` | [Reference](/fhir-elements/complex/reference) | `0..1` | Condition assessed | | `performer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who did assessment? | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Why the assessment was necessary? | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Why the assessment was necessary? | | `basis` | [Reference](/fhir-elements/complex/reference) | `0..*` | Information used in assessment | | `prediction` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Outcome predicted | | `mitigation` | [string](/fhir-elements/primitive/string) | `0..1` | How to reduce risk | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments on the risk assessment | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `condition` | reference | Condition assessed | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `method` | token | Evaluation mechanism | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `performer` | reference | Who did assessment? | | `probability` | number | Likelihood of specified outcome | | `risk` | token | Likelihood of specified outcome as a qualitative value | | `subject` | reference | Who/what does assessment apply to? | ## Reference [#reference] Official FHIR R4 spec: [RiskAssessment](https://hl7.org/fhir/R4/riskassessment.html). Maturity: Trial Use 1 (FMM 1). # RiskEvidenceSynthesis Canonical page: https://docs.ovok.com/api/fhir/r4/risk-evidence-synthesis The RiskEvidenceSynthesis resource describes the likelihood of an outcome in a population plus exposure state where the risk estimate is derived from a combination of research studies. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/RiskEvidenceSynthesis/[id]` | | Vread | `GET` | `/fhir/R4/RiskEvidenceSynthesis/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/RiskEvidenceSynthesis/[id]` | | Patch | `PATCH` | `/fhir/R4/RiskEvidenceSynthesis/[id]` | | Delete | `DELETE` | `/fhir/R4/RiskEvidenceSynthesis/[id]` | | Create | `POST` | `/fhir/R4/RiskEvidenceSynthesis` | | Search | `GET` | `/fhir/R4/RiskEvidenceSynthesis` | | History | `GET` | `/fhir/R4/RiskEvidenceSynthesis/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this risk evidence synthesis, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the risk evidence synthesis | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the risk evidence synthesis | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this risk evidence synthesis (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this risk evidence synthesis (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the risk evidence synthesis | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Used for footnotes or explanatory notes | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for risk evidence synthesis (if applicable) | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `approvalDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the risk evidence synthesis was approved by publisher | | `lastReviewDate` | [date](/fhir-elements/primitive/date) | `0..1` | When the risk evidence synthesis was last reviewed | | `effectivePeriod` | [Period](/fhir-elements/complex/period) | `0..1` | When the risk evidence synthesis is expected to be used | | `topic` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The category of the EffectEvidenceSynthesis, such as Education, Treatment, Assessment, etc. | | `author` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who authored the content | | `editor` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who edited the content | | `reviewer` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who reviewed the content | | `endorser` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Who endorsed the content | | `relatedArtifact` | [RelatedArtifact](/fhir-elements/complex/related-artifact) | `0..*` | Additional documentation, citations, etc. | | `synthesisType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Type of synthesis | | `studyType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Type of study | | `population` | [Reference](/fhir-elements/complex/reference) | `1..1` | What population? | | `exposure` | [Reference](/fhir-elements/complex/reference) | `0..1` | What exposure? | | `outcome` | [Reference](/fhir-elements/complex/reference) | `1..1` | What outcome? | | `sampleSize` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | What sample size was involved? | | `riskEstimate` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | What was the estimated risk | | `certainty` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | How certain is the risk | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `context` | token | A use context assigned to the risk evidence synthesis | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the risk evidence synthesis | | `context-type` | token | A type of use context assigned to the risk evidence synthesis | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the risk evidence synthesis | | `context-type-value` | composite | A use context type and value assigned to the risk evidence synthesis | | `date` | date | The risk evidence synthesis publication date | | `description` | string | The description of the risk evidence synthesis | | `effective` | date | The time during which the risk evidence synthesis is intended to be in use | | `identifier` | token | External identifier for the risk evidence synthesis | | `jurisdiction` | token | Intended jurisdiction for the risk evidence synthesis | | `name` | string | Computationally friendly name of the risk evidence synthesis | | `publisher` | string | Name of the publisher of the risk evidence synthesis | | `status` | token | The current status of the risk evidence synthesis | | `title` | string | The human-friendly name of the risk evidence synthesis | | `url` | uri | The uri that identifies the risk evidence synthesis | | `version` | token | The business version of the risk evidence synthesis | ## Reference [#reference] Official FHIR R4 spec: [RiskEvidenceSynthesis](https://hl7.org/fhir/R4/riskevidencesynthesis.html). Maturity: Draft (FMM 0). # Schedule Canonical page: https://docs.ovok.com/api/fhir/r4/schedule A container for slots of time that may be available for booking appointments. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Schedule/[id]` | | Vread | `GET` | `/fhir/R4/Schedule/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Schedule/[id]` | | Patch | `PATCH` | `/fhir/R4/Schedule/[id]` | | Delete | `DELETE` | `/fhir/R4/Schedule/[id]` | | Create | `POST` | `/fhir/R4/Schedule` | | Search | `GET` | `/fhir/R4/Schedule` | | History | `GET` | `/fhir/R4/Schedule/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Ids for this item | | `active` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether this schedule is in active use | | `serviceCategory` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | High-level category | | `serviceType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Specific service | | `specialty` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Type of specialty needed | | `actor` | [Reference](/fhir-elements/complex/reference) | `1..*` | Resource(s) that availability information is being provided for | | `planningHorizon` | [Period](/fhir-elements/complex/period) | `0..1` | Period of time covered by schedule | | `comment` | [string](/fhir-elements/primitive/string) | `0..1` | Comments on availability | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `active` | token | Is the schedule in active use | | `actor` | reference | The individual(HealthcareService, Practitioner, Location, ...) to find a Schedule for | | `date` | date | Search for Schedule resources that have a period that contains this date specified | | `identifier` | token | A Schedule Identifier | | `service-category` | token | High-level category | | `service-type` | token | The type of appointments that can be booked into associated slot(s) | | `specialty` | token | Type of specialty needed | ## Reference [#reference] Official FHIR R4 spec: [Schedule](https://hl7.org/fhir/R4/schedule.html). Maturity: Trial Use 3 (FMM 3). # SearchParameter Canonical page: https://docs.ovok.com/api/fhir/r4/search-parameter A search parameter that defines a named search item that can be used to search/filter on a resource. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/SearchParameter/[id]` | | Vread | `GET` | `/fhir/R4/SearchParameter/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/SearchParameter/[id]` | | Patch | `PATCH` | `/fhir/R4/SearchParameter/[id]` | | Delete | `DELETE` | `/fhir/R4/SearchParameter/[id]` | | Create | `POST` | `/fhir/R4/SearchParameter` | | Search | `GET` | `/fhir/R4/SearchParameter` | | History | `GET` | `/fhir/R4/SearchParameter/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `1..1` | Canonical identifier for this search parameter, represented as a URI (globally unique) | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the search parameter | | `name` | [string](/fhir-elements/primitive/string) | `1..1` | Name for this search parameter (computer friendly) | | `derivedFrom` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Original definition for the search parameter | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `1..1` | Natural language description of the search parameter | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for search parameter (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this search parameter is defined | | `code` | [code](/fhir-elements/primitive/code) | `1..1` | Code used in URL | | `base` | [code](/fhir-elements/primitive/code) | `1..*` | The resource type(s) this search parameter applies to | | `type` | [code](/fhir-elements/primitive/code) | `1..1` | number \| date \| string \| token \| reference \| composite \| quantity \| uri \| special | | `expression` | [string](/fhir-elements/primitive/string) | `0..1` | FHIRPath expression that extracts the values | | `xpath` | [string](/fhir-elements/primitive/string) | `0..1` | XPath that extracts the values | | `xpathUsage` | [code](/fhir-elements/primitive/code) | `0..1` | normal \| phonetic \| nearby \| distance \| other | | `target` | [code](/fhir-elements/primitive/code) | `0..*` | Types of resource (if a resource reference) | | `multipleOr` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Allow multiple values per parameter (or) | | `multipleAnd` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Allow multiple parameters (and) | | `comparator` | [code](/fhir-elements/primitive/code) | `0..*` | eq \| ne \| gt \| lt \| ge \| le \| sa \| eb \| ap | | `modifier` | [code](/fhir-elements/primitive/code) | `0..*` | missing \| exact \| contains \| not \| text \| in \| not-in \| below \| above \| type \| identifier \| ofType | | `chain` | [string](/fhir-elements/primitive/string) | `0..*` | Chained names supported | | `component` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | For Composite resources to define the parts | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `base` | token | The resource type(s) this search parameter applies to | | `code` | token | Code used in URL | | `component` | reference | Defines how the part works | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `derived-from` | reference | Original definition for the search parameter | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `target` | token | Types of resource (if a resource reference) | | `type` | token | number \| date \| string \| token \| reference \| composite \| quantity \| uri \| special | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [SearchParameter](https://hl7.org/fhir/R4/searchparameter.html). Maturity: Trial Use 3 (FMM 3). # ServiceRequest Canonical page: https://docs.ovok.com/api/fhir/r4/service-request A record of a request for service such as diagnostic investigations, treatments, or operations to be performed. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ServiceRequest/[id]` | | Vread | `GET` | `/fhir/R4/ServiceRequest/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ServiceRequest/[id]` | | Patch | `PATCH` | `/fhir/R4/ServiceRequest/[id]` | | Delete | `DELETE` | `/fhir/R4/ServiceRequest/[id]` | | Create | `POST` | `/fhir/R4/ServiceRequest` | | Search | `GET` | `/fhir/R4/ServiceRequest` | | History | `GET` | `/fhir/R4/ServiceRequest/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Identifiers assigned to this order | | `instantiatesCanonical` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Instantiates FHIR protocol or definition | | `instantiatesUri` | [uri](/fhir-elements/primitive/uri) | `0..*` | Instantiates external protocol or definition | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | What request fulfills | | `replaces` | [Reference](/fhir-elements/complex/reference) | `0..*` | What request replaces | | `requisition` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Composite Request ID | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| on-hold \| revoked \| completed \| entered-in-error \| unknown | | `intent` | [code](/fhir-elements/primitive/code) | `1..1` | proposal \| plan \| directive \| order \| original-order \| reflex-order \| filler-order \| instance-order \| option | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Classification of service | | `priority` | [code](/fhir-elements/primitive/code) | `0..1` | routine \| urgent \| asap \| stat | | `doNotPerform` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | True if service/procedure should not be performed | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | What is being requested/ordered | | `orderDetail` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Additional order information | | `quantity[x]` | [Quantity](/fhir-elements/complex/quantity), [Ratio](/fhir-elements/complex/ratio), [Range](/fhir-elements/complex/range) | `0..1` | Service amount | | `subject` | [Reference](/fhir-elements/complex/reference) | `1..1` | Individual or Entity the service is ordered for | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Encounter in which the request was created | | `occurrence[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period), [Timing](/fhir-elements/complex/timing) | `0..1` | When service should occur | | `asNeeded[x]` | [boolean](/fhir-elements/primitive/boolean), [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Preconditions for service | | `authoredOn` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date request signed | | `requester` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who/what is requesting service | | `performerType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Performer role | | `performer` | [Reference](/fhir-elements/complex/reference) | `0..*` | Requested performer | | `locationCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Requested location | | `locationReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Requested location | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Explanation/Justification for procedure or service | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | Explanation/Justification for service or service | | `insurance` | [Reference](/fhir-elements/complex/reference) | `0..*` | Associated insurance coverage | | `supportingInfo` | [Reference](/fhir-elements/complex/reference) | `0..*` | Additional clinical information | | `specimen` | [Reference](/fhir-elements/complex/reference) | `0..*` | Procedure Samples | | `bodySite` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Location on Body | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments | | `patientInstruction` | [string](/fhir-elements/primitive/string) | `0..1` | Patient or consumer-oriented instructions | | `relevantHistory` | [Reference](/fhir-elements/complex/reference) | `0..*` | Request provenance | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `authored` | date | Date request signed | | `based-on` | reference | What request fulfills | | `body-site` | token | Where procedure is going to be done | | `category` | token | Classification of service | | `code` | token | Multiple Resources: AllergyIntolerance: Code that identifies the allergy or intolerance ; Condition: Code for the condition ; DeviceRequest: Code for what is being requested/ordered ; DiagnosticReport: The code for the report, as opposed to codes for the atomic results, which are the names on the observation resource referred to from the result ; FamilyMemberHistory: A search by a condition code ; List: What the purpose of this list is ; Medication: Returns medications for a specific code ; MedicationAdministration: Return administrations of this medication code ; MedicationDispense: Returns dispenses of this medicine code ; MedicationRequest: Return prescriptions of this medication code ; MedicationStatement: Return statements of this medication code ; Observation: The code of the observation type ; Procedure: A code to identify a procedure ; ServiceRequest: What is being requested/ordered | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `instantiates-canonical` | reference | Instantiates FHIR protocol or definition | | `instantiates-uri` | uri | Instantiates external protocol or definition | | `intent` | token | proposal \| plan \| directive \| order \| original-order \| reflex-order \| filler-order \| instance-order \| option | | `occurrence` | date | When service should occur | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `performer` | reference | Requested performer | | `performer-type` | token | Performer role | | `priority` | token | routine \| urgent \| asap \| stat | | `replaces` | reference | What request replaces | | `requester` | reference | Who/what is requesting service | | `requisition` | token | Composite Request ID | | `specimen` | reference | Specimen to be tested | | `status` | token | draft \| active \| on-hold \| revoked \| completed \| entered-in-error \| unknown | | `subject` | reference | Search by subject | ## Reference [#reference] Official FHIR R4 spec: [ServiceRequest](https://hl7.org/fhir/R4/servicerequest.html). Maturity: Trial Use 2 (FMM 2). # Slot Canonical page: https://docs.ovok.com/api/fhir/r4/slot A slot of time on a schedule that may be available for booking appointments. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Slot/[id]` | | Vread | `GET` | `/fhir/R4/Slot/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Slot/[id]` | | Patch | `PATCH` | `/fhir/R4/Slot/[id]` | | Delete | `DELETE` | `/fhir/R4/Slot/[id]` | | Create | `POST` | `/fhir/R4/Slot` | | Search | `GET` | `/fhir/R4/Slot` | | History | `GET` | `/fhir/R4/Slot/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Ids for this item | | `serviceCategory` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | A broad categorization of the service that is to be performed during this appointment | | `serviceType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The type of appointments that can be booked into this slot (ideally this would be an identifiable service - which is at a location, rather than the location itself). If provided then this overrides the value provided on the availability resource | | `specialty` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The specialty of a practitioner that would be required to perform the service requested in this appointment | | `appointmentType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The style of appointment or patient that may be booked in the slot (not service type) | | `schedule` | [Reference](/fhir-elements/complex/reference) | `1..1` | The schedule resource that this slot defines an interval of status information | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | busy \| free \| busy-unavailable \| busy-tentative \| entered-in-error | | `start` | [instant](/fhir-elements/primitive/instant) | `1..1` | Date/Time that the slot is to begin | | `end` | [instant](/fhir-elements/primitive/instant) | `1..1` | Date/Time that the slot is to conclude | | `overbooked` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | This slot has already been overbooked, appointments are unlikely to be accepted for this time | | `comment` | [string](/fhir-elements/primitive/string) | `0..1` | Comments on the slot to describe any extended information. Such as custom constraints on the slot | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `appointment-type` | token | The style of appointment or patient that may be booked in the slot (not service type) | | `identifier` | token | A Slot Identifier | | `schedule` | reference | The Schedule Resource that we are seeking a slot within | | `service-category` | token | A broad categorization of the service that is to be performed during this appointment | | `service-type` | token | The type of appointments that can be booked into the slot | | `specialty` | token | The specialty of a practitioner that would be required to perform the service requested in this appointment | | `start` | date | Appointment date/time. | | `status` | token | The free/busy status of the appointment | ## Reference [#reference] Official FHIR R4 spec: [Slot](https://hl7.org/fhir/R4/slot.html). Maturity: Trial Use 3 (FMM 3). # SpecimenDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/specimen-definition A kind of specimen with associated set of requirements. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/SpecimenDefinition/[id]` | | Vread | `GET` | `/fhir/R4/SpecimenDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/SpecimenDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/SpecimenDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/SpecimenDefinition/[id]` | | Create | `POST` | `/fhir/R4/SpecimenDefinition` | | Search | `GET` | `/fhir/R4/SpecimenDefinition` | | History | `GET` | `/fhir/R4/SpecimenDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Business identifier of a kind of specimen | | `typeCollected` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Kind of material to collect | | `patientPreparation` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Patient preparation for collection | | `timeAspect` | [string](/fhir-elements/primitive/string) | `0..1` | Time aspect for collection | | `collection` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Specimen collection procedure | | `typeTested` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Specimen in container intended for testing by lab | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `container` | token | The type of specimen conditioned in container expected by the lab | | `identifier` | token | The unique identifier associated with the specimen | | `type` | token | The type of collected specimen | ## Reference [#reference] Official FHIR R4 spec: [SpecimenDefinition](https://hl7.org/fhir/R4/specimendefinition.html). Maturity: Draft (FMM 0). # Specimen Canonical page: https://docs.ovok.com/api/fhir/r4/specimen A sample to be used for analysis. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Specimen/[id]` | | Vread | `GET` | `/fhir/R4/Specimen/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Specimen/[id]` | | Patch | `PATCH` | `/fhir/R4/Specimen/[id]` | | Delete | `DELETE` | `/fhir/R4/Specimen/[id]` | | Create | `POST` | `/fhir/R4/Specimen` | | Search | `GET` | `/fhir/R4/Specimen` | | History | `GET` | `/fhir/R4/Specimen/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External Identifier | | `accessionIdentifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Identifier assigned by the lab | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | available \| unavailable \| unsatisfactory \| entered-in-error | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Kind of material that forms the specimen | | `subject` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where the specimen came from. This may be from patient(s), from a location (e.g., the source of an environmental sample), or a sampling of a substance or a device | | `receivedTime` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | The time when specimen was received for processing | | `parent` | [Reference](/fhir-elements/complex/reference) | `0..*` | Specimen from which this specimen originated | | `request` | [Reference](/fhir-elements/complex/reference) | `0..*` | Why the specimen was collected | | `collection` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Collection details | | `processing` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Processing and processing step details | | `container` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Direct container of specimen (tube/slide, etc.) | | `condition` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | State of the specimen | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `accession` | token | The accession number associated with the specimen | | `bodysite` | token | The code for the body site from where the specimen originated | | `collected` | date | The date the specimen was collected | | `collector` | reference | Who collected the specimen | | `container` | token | The kind of specimen container | | `container-id` | token | The unique identifier associated with the specimen container | | `identifier` | token | The unique identifier associated with the specimen | | `parent` | reference | The parent of the specimen | | `patient` | reference | The patient the specimen comes from | | `status` | token | available \| unavailable \| unsatisfactory \| entered-in-error | | `subject` | reference | The subject of the specimen | | `type` | token | The specimen type | ## Reference [#reference] Official FHIR R4 spec: [Specimen](https://hl7.org/fhir/R4/specimen.html). Maturity: Trial Use 2 (FMM 2). # StructureDefinition Canonical page: https://docs.ovok.com/api/fhir/r4/structure-definition A definition of a FHIR structure. This resource is used to describe the underlying resources, data types defined in FHIR, and also for describing extensions and constraints on resources and data types. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/StructureDefinition/[id]` | | Vread | `GET` | `/fhir/R4/StructureDefinition/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/StructureDefinition/[id]` | | Patch | `PATCH` | `/fhir/R4/StructureDefinition/[id]` | | Delete | `DELETE` | `/fhir/R4/StructureDefinition/[id]` | | Create | `POST` | `/fhir/R4/StructureDefinition` | | Search | `GET` | `/fhir/R4/StructureDefinition` | | History | `GET` | `/fhir/R4/StructureDefinition/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `1..1` | Canonical identifier for this structure definition, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the structure definition | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the structure definition | | `name` | [string](/fhir-elements/primitive/string) | `1..1` | Name for this structure definition (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this structure definition (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the structure definition | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for structure definition (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this structure definition is defined | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `keyword` | [Coding](/fhir-elements/complex/coding) | `0..*` | Assist with indexing and finding | | `fhirVersion` | [code](/fhir-elements/primitive/code) | `0..1` | FHIR Version this StructureDefinition targets | | `mapping` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | External specification that the content is mapped to | | `kind` | [code](/fhir-elements/primitive/code) | `1..1` | primitive-type \| complex-type \| resource \| logical | | `abstract` | [boolean](/fhir-elements/primitive/boolean) | `1..1` | Whether the structure is abstract | | `context` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | If an extension, where it can be used in instances | | `contextInvariant` | [string](/fhir-elements/primitive/string) | `0..*` | FHIRPath invariants - when the extension can be used | | `type` | [uri](/fhir-elements/primitive/uri) | `1..1` | Type defined or constrained by this structure | | `baseDefinition` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Definition that this type is constrained/specialized from | | `derivation` | [code](/fhir-elements/primitive/code) | `0..1` | specialization \| constraint - How relates to base definition | | `snapshot` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Snapshot view of the structure | | `differential` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Differential view of the structure | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `abstract` | token | Whether the structure is abstract | | `base` | reference | Definition that this type is constrained/specialized from | | `base-path` | token | Path that identifies the base element | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `derivation` | token | specialization \| constraint - How relates to base definition | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `experimental` | token | For testing purposes, not real usage | | `ext-context` | token | The system is the URL for the context-type: e.g. http://hl7.org/fhir/extension-context-type#element\|CodeableConcept.text | | `identifier` | token | Multiple Resources: CodeSystem: External identifier for the code system ; ConceptMap: External identifier for the concept map ; MessageDefinition: External identifier for the message definition ; StructureDefinition: External identifier for the structure definition ; StructureMap: External identifier for the structure map ; ValueSet: External identifier for the value set | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `keyword` | token | A code for the StructureDefinition | | `kind` | token | primitive-type \| complex-type \| resource \| logical | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `path` | token | A path that is constrained in the StructureDefinition | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `title` | string | Multiple Resources: CapabilityStatement: The human-friendly name of the capability statement ; CodeSystem: The human-friendly name of the code system ; ConceptMap: The human-friendly name of the concept map ; ImplementationGuide: The human-friendly name of the implementation guide ; MessageDefinition: The human-friendly name of the message definition ; OperationDefinition: The human-friendly name of the operation definition ; StructureDefinition: The human-friendly name of the structure definition ; StructureMap: The human-friendly name of the structure map ; TerminologyCapabilities: The human-friendly name of the terminology capabilities ; ValueSet: The human-friendly name of the value set | | `type` | uri | Type defined or constrained by this structure | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `valueset` | reference | A vocabulary binding reference | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [StructureDefinition](https://hl7.org/fhir/R4/structuredefinition.html). Maturity: Trial Use 5 (FMM 5). # StructureMap Canonical page: https://docs.ovok.com/api/fhir/r4/structure-map A Map of relationships between 2 structures that can be used to transform data. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/StructureMap/[id]` | | Vread | `GET` | `/fhir/R4/StructureMap/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/StructureMap/[id]` | | Patch | `PATCH` | `/fhir/R4/StructureMap/[id]` | | Delete | `DELETE` | `/fhir/R4/StructureMap/[id]` | | Create | `POST` | `/fhir/R4/StructureMap` | | Search | `GET` | `/fhir/R4/StructureMap` | | History | `GET` | `/fhir/R4/StructureMap/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `1..1` | Canonical identifier for this structure map, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the structure map | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the structure map | | `name` | [string](/fhir-elements/primitive/string) | `1..1` | Name for this structure map (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this structure map (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the structure map | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for structure map (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this structure map is defined | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `structure` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Structure Definition used by this map | | `import` | [canonical](/fhir-elements/primitive/canonical) | `0..*` | Other maps used by this map (canonical URLs) | | `group` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | Named sections for reader convenience | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `identifier` | token | Multiple Resources: CodeSystem: External identifier for the code system ; ConceptMap: External identifier for the concept map ; MessageDefinition: External identifier for the message definition ; StructureDefinition: External identifier for the structure definition ; StructureMap: External identifier for the structure map ; ValueSet: External identifier for the value set | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `title` | string | Multiple Resources: CapabilityStatement: The human-friendly name of the capability statement ; CodeSystem: The human-friendly name of the code system ; ConceptMap: The human-friendly name of the concept map ; ImplementationGuide: The human-friendly name of the implementation guide ; MessageDefinition: The human-friendly name of the message definition ; OperationDefinition: The human-friendly name of the operation definition ; StructureDefinition: The human-friendly name of the structure definition ; StructureMap: The human-friendly name of the structure map ; TerminologyCapabilities: The human-friendly name of the terminology capabilities ; ValueSet: The human-friendly name of the value set | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [StructureMap](https://hl7.org/fhir/R4/structuremap.html). Maturity: Trial Use 2 (FMM 2). # Subscription Canonical page: https://docs.ovok.com/api/fhir/r4/subscription The subscription resource is used to define a push-based subscription from a server to another system. Once a subscription is registered with the server, the server checks every resource that is created or updated, and if the resource matches the given criteria, it sends a message on the defined "channel" so that another system can take an appropriate action. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Subscription/[id]` | | Vread | `GET` | `/fhir/R4/Subscription/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Subscription/[id]` | | Patch | `PATCH` | `/fhir/R4/Subscription/[id]` | | Delete | `DELETE` | `/fhir/R4/Subscription/[id]` | | Create | `POST` | `/fhir/R4/Subscription` | | Search | `GET` | `/fhir/R4/Subscription` | | History | `GET` | `/fhir/R4/Subscription/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | requested \| active \| error \| off | | `contact` | [ContactPoint](/fhir-elements/complex/contact-point) | `0..*` | Contact details for source (e.g. troubleshooting) | | `end` | [instant](/fhir-elements/primitive/instant) | `0..1` | When to automatically delete the subscription | | `reason` | [string](/fhir-elements/primitive/string) | `1..1` | Description of why this subscription was created | | `criteria` | [string](/fhir-elements/primitive/string) | `1..1` | Rule for server push | | `error` | [string](/fhir-elements/primitive/string) | `0..1` | Latest error note | | `channel` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..1` | The channel on which to report matches to the criteria | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `contact` | token | Contact details for the subscription | | `criteria` | string | The search rules used to determine when to send a notification | | `payload` | token | The mime-type of the notification payload | | `status` | token | The current state of the subscription | | `type` | token | The type of channel for the sent notifications | | `url` | uri | The uri that will receive the notifications | ## Reference [#reference] Official FHIR R4 spec: [Subscription](https://hl7.org/fhir/R4/subscription.html). Maturity: Trial Use 3 (FMM 3). # SubstanceNucleicAcid Canonical page: https://docs.ovok.com/api/fhir/r4/substance-nucleic-acid Nucleic acids are defined by three distinct elements: the base, sugar and linkage. Individual substance/moiety IDs will be created for each of these elements. The nucleotide sequence will be always entered in the 5’-3’ direction. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/SubstanceNucleicAcid/[id]` | | Vread | `GET` | `/fhir/R4/SubstanceNucleicAcid/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/SubstanceNucleicAcid/[id]` | | Patch | `PATCH` | `/fhir/R4/SubstanceNucleicAcid/[id]` | | Delete | `DELETE` | `/fhir/R4/SubstanceNucleicAcid/[id]` | | Create | `POST` | `/fhir/R4/SubstanceNucleicAcid` | | Search | `GET` | `/fhir/R4/SubstanceNucleicAcid` | | History | `GET` | `/fhir/R4/SubstanceNucleicAcid/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `sequenceType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The type of the sequence shall be specified based on a controlled vocabulary | | `numberOfSubunits` | [integer](/fhir-elements/primitive/integer) | `0..1` | The number of linear sequences of nucleotides linked through phosphodiester bonds shall be described. Subunits would be strands of nucleic acids that are tightly associated typically through Watson-Crick base pairing. NOTE: If not specified in the reference source, the assumption is that there is 1 subunit | | `areaOfHybridisation` | [string](/fhir-elements/primitive/string) | `0..1` | The area of hybridisation shall be described if applicable for double stranded RNA or DNA. The number associated with the subunit followed by the number associated to the residue shall be specified in increasing order. The underscore “” shall be used as separator as follows: “Subunitnumber Residue” | | `oligoNucleotideType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | (TBC) | | `subunit` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Subunits are listed in order of decreasing length; sequences of the same length will be ordered by molecular weight; subunits that have identical sequences will be repeated multiple times | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [SubstanceNucleicAcid](https://hl7.org/fhir/R4/substancenucleicacid.html). Maturity: Draft (FMM 0). # SubstancePolymer Canonical page: https://docs.ovok.com/api/fhir/r4/substance-polymer Todo. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/SubstancePolymer/[id]` | | Vread | `GET` | `/fhir/R4/SubstancePolymer/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/SubstancePolymer/[id]` | | Patch | `PATCH` | `/fhir/R4/SubstancePolymer/[id]` | | Delete | `DELETE` | `/fhir/R4/SubstancePolymer/[id]` | | Create | `POST` | `/fhir/R4/SubstancePolymer` | | Search | `GET` | `/fhir/R4/SubstancePolymer` | | History | `GET` | `/fhir/R4/SubstancePolymer/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `class` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Todo | | `geometry` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Todo | | `copolymerConnectivity` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Todo | | `modification` | [string](/fhir-elements/primitive/string) | `0..*` | Todo | | `monomerSet` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Todo | | `repeat` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Todo | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [SubstancePolymer](https://hl7.org/fhir/R4/substancepolymer.html). Maturity: Draft (FMM 0). # SubstanceProtein Canonical page: https://docs.ovok.com/api/fhir/r4/substance-protein A SubstanceProtein is defined as a single unit of a linear amino acid sequence, or a combination of subunits that are either covalently linked or have a defined invariant stoichiometric relationship. This includes all synthetic, recombinant and purified SubstanceProteins of defined sequence, whether the use is therapeutic or prophylactic. This set of elements will be used to describe albumins, coagulation factors, cytokines, growth factors, peptide/SubstanceProtein hormones, enzymes, toxins, toxoids, recombinant vaccines, and immunomodulators. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/SubstanceProtein/[id]` | | Vread | `GET` | `/fhir/R4/SubstanceProtein/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/SubstanceProtein/[id]` | | Patch | `PATCH` | `/fhir/R4/SubstanceProtein/[id]` | | Delete | `DELETE` | `/fhir/R4/SubstanceProtein/[id]` | | Create | `POST` | `/fhir/R4/SubstanceProtein` | | Search | `GET` | `/fhir/R4/SubstanceProtein` | | History | `GET` | `/fhir/R4/SubstanceProtein/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `sequenceType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The SubstanceProtein descriptive elements will only be used when a complete or partial amino acid sequence is available or derivable from a nucleic acid sequence | | `numberOfSubunits` | [integer](/fhir-elements/primitive/integer) | `0..1` | Number of linear sequences of amino acids linked through peptide bonds. The number of subunits constituting the SubstanceProtein shall be described. It is possible that the number of subunits can be variable | | `disulfideLinkage` | [string](/fhir-elements/primitive/string) | `0..*` | The disulphide bond between two cysteine residues either on the same subunit or on two different subunits shall be described. The position of the disulfide bonds in the SubstanceProtein shall be listed in increasing order of subunit number and position within subunit followed by the abbreviation of the amino acids involved. The disulfide linkage positions shall actually contain the amino acid Cysteine at the respective positions | | `subunit` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | This subclause refers to the description of each subunit constituting the SubstanceProtein. A subunit is a linear sequence of amino acids linked through peptide bonds. The Subunit information shall be provided when the finished SubstanceProtein is a complex of multiple sequences; subunits are not used to delineate domains within a single sequence. Subunits are listed in order of decreasing length; sequences of the same length will be ordered by decreasing molecular weight; subunits that have identical sequences will be repeated multiple times | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [SubstanceProtein](https://hl7.org/fhir/R4/substanceprotein.html). Maturity: Draft (FMM 0). # SubstanceReferenceInformation Canonical page: https://docs.ovok.com/api/fhir/r4/substance-reference-information Todo. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/SubstanceReferenceInformation/[id]` | | Vread | `GET` | `/fhir/R4/SubstanceReferenceInformation/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/SubstanceReferenceInformation/[id]` | | Patch | `PATCH` | `/fhir/R4/SubstanceReferenceInformation/[id]` | | Delete | `DELETE` | `/fhir/R4/SubstanceReferenceInformation/[id]` | | Create | `POST` | `/fhir/R4/SubstanceReferenceInformation` | | Search | `GET` | `/fhir/R4/SubstanceReferenceInformation` | | History | `GET` | `/fhir/R4/SubstanceReferenceInformation/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `comment` | [string](/fhir-elements/primitive/string) | `0..1` | Todo | | `gene` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Todo | | `geneElement` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Todo | | `classification` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Todo | | `target` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Todo | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [SubstanceReferenceInformation](https://hl7.org/fhir/R4/substancereferenceinformation.html). Maturity: Draft (FMM 0). # SubstanceSourceMaterial Canonical page: https://docs.ovok.com/api/fhir/r4/substance-source-material Source material shall capture information on the taxonomic and anatomical origins as well as the fraction of a material that can result in or can be modified to form a substance. This set of data elements shall be used to define polymer substances isolated from biological matrices. Taxonomic and anatomical origins shall be described using a controlled vocabulary as required. This information is captured for naturally derived polymers ( . starch) and structurally diverse substances. For Organisms belonging to the Kingdom Plantae the Substance level defines the fresh material of a single species or infraspecies, the Herbal Drug and the Herbal preparation. For Herbal preparations, the fraction information will be captured at the Substance information level and additional information for herbal extracts will be captured at the Specified Substance Group 1 information level. See for further explanation the Substance Class: Structurally Diverse and the herbal annex. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/SubstanceSourceMaterial/[id]` | | Vread | `GET` | `/fhir/R4/SubstanceSourceMaterial/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/SubstanceSourceMaterial/[id]` | | Patch | `PATCH` | `/fhir/R4/SubstanceSourceMaterial/[id]` | | Delete | `DELETE` | `/fhir/R4/SubstanceSourceMaterial/[id]` | | Create | `POST` | `/fhir/R4/SubstanceSourceMaterial` | | Search | `GET` | `/fhir/R4/SubstanceSourceMaterial` | | History | `GET` | `/fhir/R4/SubstanceSourceMaterial/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `sourceMaterialClass` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | General high level classification of the source material specific to the origin of the material | | `sourceMaterialType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The type of the source material shall be specified based on a controlled vocabulary. For vaccines, this subclause refers to the class of infectious agent | | `sourceMaterialState` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The state of the source material when extracted | | `organismId` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | The unique identifier associated with the source material parent organism shall be specified | | `organismName` | [string](/fhir-elements/primitive/string) | `0..1` | The organism accepted Scientific name shall be provided based on the organism taxonomy | | `parentSubstanceId` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | The parent of the herbal drug Ginkgo biloba, Leaf is the substance ID of the substance (fresh) of Ginkgo biloba L. or Ginkgo biloba L. (Whole plant) | | `parentSubstanceName` | [string](/fhir-elements/primitive/string) | `0..*` | The parent substance of the Herbal Drug, or Herbal preparation | | `countryOfOrigin` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The country where the plant material is harvested or the countries where the plasma is sourced from as laid down in accordance with the Plasma Master File. For “Plasma-derived substances” the attribute country of origin provides information about the countries used for the manufacturing of the Cryopoor plama or Crioprecipitate | | `geographicalLocation` | [string](/fhir-elements/primitive/string) | `0..*` | The place/region where the plant is harvested or the places/regions where the animal source material has its habitat | | `developmentStage` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Stage of life for animals, plants, insects and microorganisms. This information shall be provided only when the substance is significantly different in these stages (e.g. foetal bovine serum) | | `fractionDescription` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Many complex materials are fractions of parts of plants, animals, or minerals. Fraction elements are often necessary to define both Substances and Specified Group 1 Substances. For substances derived from Plants, fraction information will be captured at the Substance information level ( . Oils, Juices and Exudates). Additional information for Extracts, such as extraction solvent composition, will be captured at the Specified Substance Group 1 information level. For plasma-derived products fraction information will be captured at the Substance and the Specified Substance Group 1 levels | | `organism` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | This subclause describes the organism which the substance is derived from. For vaccines, the parent organism shall be specified based on these subclause elements. As an example, full taxonomy will be described for the Substance Name: ., Leaf | | `partDescription` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | To do | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | — | — | No resource-specific search parameters are listed in the package. | ## Reference [#reference] Official FHIR R4 spec: [SubstanceSourceMaterial](https://hl7.org/fhir/R4/substancesourcematerial.html). Maturity: Draft (FMM 0). # SubstanceSpecification Canonical page: https://docs.ovok.com/api/fhir/r4/substance-specification The detailed description of a substance, typically at a level beyond what is used for prescribing. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/SubstanceSpecification/[id]` | | Vread | `GET` | `/fhir/R4/SubstanceSpecification/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/SubstanceSpecification/[id]` | | Patch | `PATCH` | `/fhir/R4/SubstanceSpecification/[id]` | | Delete | `DELETE` | `/fhir/R4/SubstanceSpecification/[id]` | | Create | `POST` | `/fhir/R4/SubstanceSpecification` | | Search | `GET` | `/fhir/R4/SubstanceSpecification` | | History | `GET` | `/fhir/R4/SubstanceSpecification/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Identifier by which this substance is known | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | High level categorization, e.g. polymer or nucleic acid | | `status` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Status of substance within the catalogue e.g. approved | | `domain` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | If the substance applies to only human or veterinary use | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Textual description of the substance | | `source` | [Reference](/fhir-elements/complex/reference) | `0..*` | Supporting literature | | `comment` | [string](/fhir-elements/primitive/string) | `0..1` | Textual comment about this record of a substance | | `moiety` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Moiety, for structural modifications | | `property` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | General specifications for this substance, including how it is related to other substances | | `referenceInformation` | [Reference](/fhir-elements/complex/reference) | `0..1` | General information detailing this substance | | `structure` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Structural information | | `code` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Codes associated with the substance | | `name` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Names applicable to this substance | | `molecularWeight` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | The molecular weight or weight range (for proteins, polymers or nucleic acids) | | `relationship` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A link between this substance and another, with details of the relationship | | `nucleicAcid` | [Reference](/fhir-elements/complex/reference) | `0..1` | Data items specific to nucleic acids | | `polymer` | [Reference](/fhir-elements/complex/reference) | `0..1` | Data items specific to polymers | | `protein` | [Reference](/fhir-elements/complex/reference) | `0..1` | Data items specific to proteins | | `sourceMaterial` | [Reference](/fhir-elements/complex/reference) | `0..1` | Material or taxonomic/anatomical source for the substance | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `code` | token | The specific code | ## Reference [#reference] Official FHIR R4 spec: [SubstanceSpecification](https://hl7.org/fhir/R4/substancespecification.html). Maturity: Draft (FMM 0). # Substance Canonical page: https://docs.ovok.com/api/fhir/r4/substance A homogeneous material with a definite composition. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Substance/[id]` | | Vread | `GET` | `/fhir/R4/Substance/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Substance/[id]` | | Patch | `PATCH` | `/fhir/R4/Substance/[id]` | | Delete | `DELETE` | `/fhir/R4/Substance/[id]` | | Create | `POST` | `/fhir/R4/Substance` | | Search | `GET` | `/fhir/R4/Substance` | | History | `GET` | `/fhir/R4/Substance/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Unique identifier | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | active \| inactive \| entered-in-error | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | What class/type of substance this is | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `1..1` | What substance this is | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Textual description of the substance, comments | | `instance` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | If this describes a specific package/container of the substance | | `ingredient` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Composition information about the substance | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `category` | token | The category of the substance | | `code` | token | The code of the substance or ingredient | | `container-identifier` | token | Identifier of the package/container | | `expiry` | date | Expiry date of package or container of substance | | `identifier` | token | Unique identifier for the substance | | `quantity` | quantity | Amount of substance in the package | | `status` | token | active \| inactive \| entered-in-error | | `substance-reference` | reference | A component of the substance | ## Reference [#reference] Official FHIR R4 spec: [Substance](https://hl7.org/fhir/R4/substance.html). Maturity: Trial Use 2 (FMM 2). # SupplyDelivery Canonical page: https://docs.ovok.com/api/fhir/r4/supply-delivery Record of delivery of what is supplied. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/SupplyDelivery/[id]` | | Vread | `GET` | `/fhir/R4/SupplyDelivery/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/SupplyDelivery/[id]` | | Patch | `PATCH` | `/fhir/R4/SupplyDelivery/[id]` | | Delete | `DELETE` | `/fhir/R4/SupplyDelivery/[id]` | | Create | `POST` | `/fhir/R4/SupplyDelivery` | | Search | `GET` | `/fhir/R4/SupplyDelivery` | | History | `GET` | `/fhir/R4/SupplyDelivery/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | External identifier | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Fulfills plan, proposal or order | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Part of referenced event | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | in-progress \| completed \| abandoned \| entered-in-error | | `patient` | [Reference](/fhir-elements/complex/reference) | `0..1` | Patient for whom the item is supplied | | `type` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Category of dispense event | | `suppliedItem` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | The item that is delivered or supplied | | `occurrence[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period), [Timing](/fhir-elements/complex/timing) | `0..1` | When event occurred | | `supplier` | [Reference](/fhir-elements/complex/reference) | `0..1` | Dispenser | | `destination` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where the Supply was sent | | `receiver` | [Reference](/fhir-elements/complex/reference) | `0..*` | Who collected the Supply | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `receiver` | reference | Who collected the Supply | | `status` | token | in-progress \| completed \| abandoned \| entered-in-error | | `supplier` | reference | Dispenser | ## Reference [#reference] Official FHIR R4 spec: [SupplyDelivery](https://hl7.org/fhir/R4/supplydelivery.html). Maturity: Trial Use 1 (FMM 1). # SupplyRequest Canonical page: https://docs.ovok.com/api/fhir/r4/supply-request A record of a request for a medication, substance or device used in the healthcare setting. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/SupplyRequest/[id]` | | Vread | `GET` | `/fhir/R4/SupplyRequest/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/SupplyRequest/[id]` | | Patch | `PATCH` | `/fhir/R4/SupplyRequest/[id]` | | Delete | `DELETE` | `/fhir/R4/SupplyRequest/[id]` | | Create | `POST` | `/fhir/R4/SupplyRequest` | | Search | `GET` | `/fhir/R4/SupplyRequest` | | History | `GET` | `/fhir/R4/SupplyRequest/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for SupplyRequest | | `status` | [code](/fhir-elements/primitive/code) | `0..1` | draft \| active \| suspended + | | `category` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | The kind of supply (central, non-stock, etc.) | | `priority` | [code](/fhir-elements/primitive/code) | `0..1` | routine \| urgent \| asap \| stat | | `item[x]` | [CodeableConcept](/fhir-elements/complex/codeable-concept), [Reference](/fhir-elements/complex/reference) | `1..1` | Medication, Substance, or Device requested to be supplied | | `quantity` | [Quantity](/fhir-elements/complex/quantity) | `1..1` | The requested amount of the item indicated | | `parameter` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Ordered item details | | `occurrence[x]` | [dateTime](/fhir-elements/primitive/date-time), [Period](/fhir-elements/complex/period), [Timing](/fhir-elements/complex/timing) | `0..1` | When the request should be fulfilled | | `authoredOn` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the request was made | | `requester` | [Reference](/fhir-elements/complex/reference) | `0..1` | Individual making the request | | `supplier` | [Reference](/fhir-elements/complex/reference) | `0..*` | Who is intended to fulfill the request | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The reason why the supply item was requested | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..*` | The reason why the supply item was requested | | `deliverFrom` | [Reference](/fhir-elements/complex/reference) | `0..1` | The origin of the supply | | `deliverTo` | [Reference](/fhir-elements/complex/reference) | `0..1` | The destination of the supply | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `category` | token | The kind of supply (central, non-stock, etc.) | | `date` | date | Multiple Resources: AllergyIntolerance: Date first version of the resource instance was recorded ; CarePlan: Time period plan covers ; CareTeam: Time period team covers ; ClinicalImpression: When the assessment was documented ; Composition: Composition editing time ; Consent: When this Consent was created or indexed ; DiagnosticReport: The clinically relevant time of the report ; Encounter: A date within the period the Encounter lasted ; EpisodeOfCare: The provided date search value falls within the episode of care's period ; FamilyMemberHistory: When history was recorded or last updated ; Flag: Time period when flag is active ; Immunization: Vaccination (non)-Administration Date ; List: When the list was prepared ; Observation: Obtained date/time. If the obtained element is a period, a date that falls in the period ; Procedure: When the procedure was performed ; RiskAssessment: When was assessment made? ; SupplyRequest: When the request was made | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `requester` | reference | Individual making the request | | `status` | token | draft \| active \| suspended + | | `subject` | reference | The destination of the supply | | `supplier` | reference | Who is intended to fulfill the request | ## Reference [#reference] Official FHIR R4 spec: [SupplyRequest](https://hl7.org/fhir/R4/supplyrequest.html). Maturity: Trial Use 1 (FMM 1). # Task Canonical page: https://docs.ovok.com/api/fhir/r4/task A task to be performed. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/Task/[id]` | | Vread | `GET` | `/fhir/R4/Task/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/Task/[id]` | | Patch | `PATCH` | `/fhir/R4/Task/[id]` | | Delete | `DELETE` | `/fhir/R4/Task/[id]` | | Create | `POST` | `/fhir/R4/Task` | | Search | `GET` | `/fhir/R4/Task` | | History | `GET` | `/fhir/R4/Task/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Task Instance Identifier | | `instantiatesCanonical` | [canonical](/fhir-elements/primitive/canonical) | `0..1` | Formal definition of task | | `instantiatesUri` | [uri](/fhir-elements/primitive/uri) | `0..1` | Formal definition of task | | `basedOn` | [Reference](/fhir-elements/complex/reference) | `0..*` | Request fulfilled by this task | | `groupIdentifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Requisition or grouper id | | `partOf` | [Reference](/fhir-elements/complex/reference) | `0..*` | Composite task | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| requested \| received \| accepted \| + | | `statusReason` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Reason for current status | | `businessStatus` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | E.g. "Specimen collected", "IV prepped" | | `intent` | [code](/fhir-elements/primitive/code) | `1..1` | unknown \| proposal \| plan \| order \| original-order \| reflex-order \| filler-order \| instance-order \| option | | `priority` | [code](/fhir-elements/primitive/code) | `0..1` | routine \| urgent \| asap \| stat | | `code` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Task Type | | `description` | [string](/fhir-elements/primitive/string) | `0..1` | Human-readable explanation of task | | `focus` | [Reference](/fhir-elements/complex/reference) | `0..1` | What task is acting on | | `for` | [Reference](/fhir-elements/complex/reference) | `0..1` | Beneficiary of the Task | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Healthcare event during which this task originated | | `executionPeriod` | [Period](/fhir-elements/complex/period) | `0..1` | Start and end time of execution | | `authoredOn` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Task Creation Date | | `lastModified` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Task Last Modified Date | | `requester` | [Reference](/fhir-elements/complex/reference) | `0..1` | Who is asking for task to be done | | `performerType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Requested performer | | `owner` | [Reference](/fhir-elements/complex/reference) | `0..1` | Responsible individual | | `location` | [Reference](/fhir-elements/complex/reference) | `0..1` | Where task occurs | | `reasonCode` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | Why task is needed | | `reasonReference` | [Reference](/fhir-elements/complex/reference) | `0..1` | Why task is needed | | `insurance` | [Reference](/fhir-elements/complex/reference) | `0..*` | Associated insurance coverage | | `note` | [Annotation](/fhir-elements/complex/annotation) | `0..*` | Comments made about the task | | `relevantHistory` | [Reference](/fhir-elements/complex/reference) | `0..*` | Key events in history of the Task | | `restriction` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Constraints on fulfillment tasks | | `input` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Information used to perform task | | `output` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Information produced as part of task | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `authored-on` | date | Search by creation date | | `based-on` | reference | Search by requests this task is based on | | `business-status` | token | Search by business status | | `code` | token | Search by task code | | `encounter` | reference | Search by encounter | | `focus` | reference | Search by task focus | | `group-identifier` | token | Search by group identifier | | `identifier` | token | Search for a task instance by its business identifier | | `intent` | token | Search by task intent | | `modified` | date | Search by last modification date | | `owner` | reference | Search by task owner | | `part-of` | reference | Search by task this task is part of | | `patient` | reference | Search by patient | | `performer` | token | Search by recommended type of performer (e.g., Requester, Performer, Scheduler). | | `period` | date | Search by period Task is/was underway | | `priority` | token | Search by task priority | | `requester` | reference | Search by task requester | | `status` | token | Search by task status | | `subject` | reference | Search by subject | ## Reference [#reference] Official FHIR R4 spec: [Task](https://hl7.org/fhir/R4/task.html). Maturity: Trial Use 2 (FMM 2). # TerminologyCapabilities Canonical page: https://docs.ovok.com/api/fhir/r4/terminology-capabilities A TerminologyCapabilities resource documents a set of capabilities (behaviors) of a FHIR Terminology Server that may be used as a statement of actual server functionality or a statement of required or desired server implementation. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/TerminologyCapabilities/[id]` | | Vread | `GET` | `/fhir/R4/TerminologyCapabilities/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/TerminologyCapabilities/[id]` | | Patch | `PATCH` | `/fhir/R4/TerminologyCapabilities/[id]` | | Delete | `DELETE` | `/fhir/R4/TerminologyCapabilities/[id]` | | Create | `POST` | `/fhir/R4/TerminologyCapabilities` | | Search | `GET` | `/fhir/R4/TerminologyCapabilities` | | History | `GET` | `/fhir/R4/TerminologyCapabilities/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this terminology capabilities, represented as a URI (globally unique) | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the terminology capabilities | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this terminology capabilities (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this terminology capabilities (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the terminology capabilities | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for terminology capabilities (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this terminology capabilities is defined | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `kind` | [code](/fhir-elements/primitive/code) | `1..1` | instance \| capability \| requirements | | `software` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Software that is covered by this terminology capability statement | | `implementation` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | If this describes a specific instance | | `lockedDate` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Whether lockedDate is supported | | `codeSystem` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A code system supported by the server | | `expansion` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Information about the ValueSet/$expand operation | | `codeSearch` | [code](/fhir-elements/primitive/code) | `0..1` | explicit \| all | | `validateCode` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Information about the ValueSet/$validate-code operation | | `translation` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Information about the ConceptMap/$translate operation | | `closure` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Information about the ConceptMap/$closure operation | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `title` | string | Multiple Resources: CapabilityStatement: The human-friendly name of the capability statement ; CodeSystem: The human-friendly name of the code system ; ConceptMap: The human-friendly name of the concept map ; ImplementationGuide: The human-friendly name of the implementation guide ; MessageDefinition: The human-friendly name of the message definition ; OperationDefinition: The human-friendly name of the operation definition ; StructureDefinition: The human-friendly name of the structure definition ; StructureMap: The human-friendly name of the structure map ; TerminologyCapabilities: The human-friendly name of the terminology capabilities ; ValueSet: The human-friendly name of the value set | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [TerminologyCapabilities](https://hl7.org/fhir/R4/terminologycapabilities.html). Maturity: Draft (FMM 0). # TestReport Canonical page: https://docs.ovok.com/api/fhir/r4/test-report A summary of information based on the results of executing a TestScript. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/TestReport/[id]` | | Vread | `GET` | `/fhir/R4/TestReport/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/TestReport/[id]` | | Patch | `PATCH` | `/fhir/R4/TestReport/[id]` | | Delete | `DELETE` | `/fhir/R4/TestReport/[id]` | | Create | `POST` | `/fhir/R4/TestReport` | | Search | `GET` | `/fhir/R4/TestReport` | | History | `GET` | `/fhir/R4/TestReport/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | External identifier | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Informal name of the executed TestScript | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | completed \| in-progress \| waiting \| stopped \| entered-in-error | | `testScript` | [Reference](/fhir-elements/complex/reference) | `1..1` | Reference to the version-specific TestScript that was executed to produce this TestReport | | `result` | [code](/fhir-elements/primitive/code) | `1..1` | pass \| fail \| pending | | `score` | [decimal](/fhir-elements/primitive/decimal) | `0..1` | The final score (percentage of tests passed) resulting from the execution of the TestScript | | `tester` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the tester producing this report (Organization or individual) | | `issued` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the TestScript was executed and this TestReport was generated | | `participant` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A participant in the test execution, either the execution engine, a client, or a server | | `setup` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | The results of the series of required setup operations before the tests were executed | | `test` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A test executed from the test script | | `teardown` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | The results of running the series of required clean up steps | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `identifier` | token | An external identifier for the test report | | `issued` | date | The test report generation date | | `participant` | uri | The reference to a participant in the test execution | | `result` | token | The result disposition of the test execution | | `tester` | string | The name of the testing organization | | `testscript` | reference | The test script executed to produce this report | ## Reference [#reference] Official FHIR R4 spec: [TestReport](https://hl7.org/fhir/R4/testreport.html). Maturity: Draft (FMM 0). # TestScript Canonical page: https://docs.ovok.com/api/fhir/r4/test-script A structured set of tests against a FHIR server or client implementation to determine compliance against the FHIR specification. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/TestScript/[id]` | | Vread | `GET` | `/fhir/R4/TestScript/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/TestScript/[id]` | | Patch | `PATCH` | `/fhir/R4/TestScript/[id]` | | Delete | `DELETE` | `/fhir/R4/TestScript/[id]` | | Create | `POST` | `/fhir/R4/TestScript` | | Search | `GET` | `/fhir/R4/TestScript` | | History | `GET` | `/fhir/R4/TestScript/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `1..1` | Canonical identifier for this test script, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..1` | Additional identifier for the test script | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the test script | | `name` | [string](/fhir-elements/primitive/string) | `1..1` | Name for this test script (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this test script (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the test script | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for test script (if applicable) | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this test script is defined | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `origin` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | An abstract server representing a client or sender in a message exchange | | `destination` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | An abstract server representing a destination or receiver in a message exchange | | `metadata` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Required capability that is assumed to function correctly on the FHIR server being tested | | `fixture` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Fixture in the test script - by reference (uri) | | `profile` | [Reference](/fhir-elements/complex/reference) | `0..*` | Reference of the validation profile | | `variable` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Placeholder for evaluated elements | | `setup` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | A series of required setup operations before tests are executed | | `test` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | A test in this script | | `teardown` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | A series of required clean up steps | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `context` | token | A use context assigned to the test script | | `context-quantity` | quantity | A quantity- or range-valued use context assigned to the test script | | `context-type` | token | A type of use context assigned to the test script | | `context-type-quantity` | composite | A use context type and quantity- or range-based value assigned to the test script | | `context-type-value` | composite | A use context type and value assigned to the test script | | `date` | date | The test script publication date | | `description` | string | The description of the test script | | `identifier` | token | External identifier for the test script | | `jurisdiction` | token | Intended jurisdiction for the test script | | `name` | string | Computationally friendly name of the test script | | `publisher` | string | Name of the publisher of the test script | | `status` | token | The current status of the test script | | `testscript-capability` | string | TestScript required and validated capability | | `title` | string | The human-friendly name of the test script | | `url` | uri | The uri that identifies the test script | | `version` | token | The business version of the test script | ## Reference [#reference] Official FHIR R4 spec: [TestScript](https://hl7.org/fhir/R4/testscript.html). Maturity: Trial Use 2 (FMM 2). # ValueSet Canonical page: https://docs.ovok.com/api/fhir/r4/value-set A ValueSet resource instance specifies a set of codes drawn from one or more code systems, intended for use in a particular context. Value sets link between [[[CodeSystem]]] definitions and their use in [coded elements](https://hl7.org/fhir/R4/terminologies.html). These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/ValueSet/[id]` | | Vread | `GET` | `/fhir/R4/ValueSet/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/ValueSet/[id]` | | Patch | `PATCH` | `/fhir/R4/ValueSet/[id]` | | Delete | `DELETE` | `/fhir/R4/ValueSet/[id]` | | Create | `POST` | `/fhir/R4/ValueSet` | | Search | `GET` | `/fhir/R4/ValueSet` | | History | `GET` | `/fhir/R4/ValueSet/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `url` | [uri](/fhir-elements/primitive/uri) | `0..1` | Canonical identifier for this value set, represented as a URI (globally unique) | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Additional identifier for the value set (business identifier) | | `version` | [string](/fhir-elements/primitive/string) | `0..1` | Business version of the value set | | `name` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this value set (computer friendly) | | `title` | [string](/fhir-elements/primitive/string) | `0..1` | Name for this value set (human friendly) | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | draft \| active \| retired \| unknown | | `experimental` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | For testing purposes, not real usage | | `date` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | Date last changed | | `publisher` | [string](/fhir-elements/primitive/string) | `0..1` | Name of the publisher (organization or individual) | | `contact` | [ContactDetail](/fhir-elements/complex/contact-detail) | `0..*` | Contact details for the publisher | | `description` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Natural language description of the value set | | `useContext` | [UsageContext](/fhir-elements/complex/usage-context) | `0..*` | The context that the content is intended to support | | `jurisdiction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | Intended jurisdiction for value set (if applicable) | | `immutable` | [boolean](/fhir-elements/primitive/boolean) | `0..1` | Indicates whether or not any change to the content logical definition may occur | | `purpose` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Why this value set is defined | | `copyright` | [markdown](/fhir-elements/primitive/markdown) | `0..1` | Use and/or publishing restrictions | | `compose` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Content logical definition of the value set (CLD) | | `expansion` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Used when the value set is "expanded" | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `code` | token | This special parameter searches for codes in the value set. See additional notes on the ValueSet resource | | `context` | token | Multiple Resources: CapabilityStatement: A use context assigned to the capability statement ; CodeSystem: A use context assigned to the code system ; CompartmentDefinition: A use context assigned to the compartment definition ; ConceptMap: A use context assigned to the concept map ; GraphDefinition: A use context assigned to the graph definition ; ImplementationGuide: A use context assigned to the implementation guide ; MessageDefinition: A use context assigned to the message definition ; NamingSystem: A use context assigned to the naming system ; OperationDefinition: A use context assigned to the operation definition ; SearchParameter: A use context assigned to the search parameter ; StructureDefinition: A use context assigned to the structure definition ; StructureMap: A use context assigned to the structure map ; TerminologyCapabilities: A use context assigned to the terminology capabilities ; ValueSet: A use context assigned to the value set | | `context-quantity` | quantity | Multiple Resources: CapabilityStatement: A quantity- or range-valued use context assigned to the capability statement ; CodeSystem: A quantity- or range-valued use context assigned to the code system ; CompartmentDefinition: A quantity- or range-valued use context assigned to the compartment definition ; ConceptMap: A quantity- or range-valued use context assigned to the concept map ; GraphDefinition: A quantity- or range-valued use context assigned to the graph definition ; ImplementationGuide: A quantity- or range-valued use context assigned to the implementation guide ; MessageDefinition: A quantity- or range-valued use context assigned to the message definition ; NamingSystem: A quantity- or range-valued use context assigned to the naming system ; OperationDefinition: A quantity- or range-valued use context assigned to the operation definition ; SearchParameter: A quantity- or range-valued use context assigned to the search parameter ; StructureDefinition: A quantity- or range-valued use context assigned to the structure definition ; StructureMap: A quantity- or range-valued use context assigned to the structure map ; TerminologyCapabilities: A quantity- or range-valued use context assigned to the terminology capabilities ; ValueSet: A quantity- or range-valued use context assigned to the value set | | `context-type` | token | Multiple Resources: CapabilityStatement: A type of use context assigned to the capability statement ; CodeSystem: A type of use context assigned to the code system ; CompartmentDefinition: A type of use context assigned to the compartment definition ; ConceptMap: A type of use context assigned to the concept map ; GraphDefinition: A type of use context assigned to the graph definition ; ImplementationGuide: A type of use context assigned to the implementation guide ; MessageDefinition: A type of use context assigned to the message definition ; NamingSystem: A type of use context assigned to the naming system ; OperationDefinition: A type of use context assigned to the operation definition ; SearchParameter: A type of use context assigned to the search parameter ; StructureDefinition: A type of use context assigned to the structure definition ; StructureMap: A type of use context assigned to the structure map ; TerminologyCapabilities: A type of use context assigned to the terminology capabilities ; ValueSet: A type of use context assigned to the value set | | `context-type-quantity` | composite | Multiple Resources: CapabilityStatement: A use context type and quantity- or range-based value assigned to the capability statement ; CodeSystem: A use context type and quantity- or range-based value assigned to the code system ; CompartmentDefinition: A use context type and quantity- or range-based value assigned to the compartment definition ; ConceptMap: A use context type and quantity- or range-based value assigned to the concept map ; GraphDefinition: A use context type and quantity- or range-based value assigned to the graph definition ; ImplementationGuide: A use context type and quantity- or range-based value assigned to the implementation guide ; MessageDefinition: A use context type and quantity- or range-based value assigned to the message definition ; NamingSystem: A use context type and quantity- or range-based value assigned to the naming system ; OperationDefinition: A use context type and quantity- or range-based value assigned to the operation definition ; SearchParameter: A use context type and quantity- or range-based value assigned to the search parameter ; StructureDefinition: A use context type and quantity- or range-based value assigned to the structure definition ; StructureMap: A use context type and quantity- or range-based value assigned to the structure map ; TerminologyCapabilities: A use context type and quantity- or range-based value assigned to the terminology capabilities ; ValueSet: A use context type and quantity- or range-based value assigned to the value set | | `context-type-value` | composite | Multiple Resources: CapabilityStatement: A use context type and value assigned to the capability statement ; CodeSystem: A use context type and value assigned to the code system ; CompartmentDefinition: A use context type and value assigned to the compartment definition ; ConceptMap: A use context type and value assigned to the concept map ; GraphDefinition: A use context type and value assigned to the graph definition ; ImplementationGuide: A use context type and value assigned to the implementation guide ; MessageDefinition: A use context type and value assigned to the message definition ; NamingSystem: A use context type and value assigned to the naming system ; OperationDefinition: A use context type and value assigned to the operation definition ; SearchParameter: A use context type and value assigned to the search parameter ; StructureDefinition: A use context type and value assigned to the structure definition ; StructureMap: A use context type and value assigned to the structure map ; TerminologyCapabilities: A use context type and value assigned to the terminology capabilities ; ValueSet: A use context type and value assigned to the value set | | `date` | date | Multiple Resources: CapabilityStatement: The capability statement publication date ; CodeSystem: The code system publication date ; CompartmentDefinition: The compartment definition publication date ; ConceptMap: The concept map publication date ; GraphDefinition: The graph definition publication date ; ImplementationGuide: The implementation guide publication date ; MessageDefinition: The message definition publication date ; NamingSystem: The naming system publication date ; OperationDefinition: The operation definition publication date ; SearchParameter: The search parameter publication date ; StructureDefinition: The structure definition publication date ; StructureMap: The structure map publication date ; TerminologyCapabilities: The terminology capabilities publication date ; ValueSet: The value set publication date | | `description` | string | Multiple Resources: CapabilityStatement: The description of the capability statement ; CodeSystem: The description of the code system ; CompartmentDefinition: The description of the compartment definition ; ConceptMap: The description of the concept map ; GraphDefinition: The description of the graph definition ; ImplementationGuide: The description of the implementation guide ; MessageDefinition: The description of the message definition ; NamingSystem: The description of the naming system ; OperationDefinition: The description of the operation definition ; SearchParameter: The description of the search parameter ; StructureDefinition: The description of the structure definition ; StructureMap: The description of the structure map ; TerminologyCapabilities: The description of the terminology capabilities ; ValueSet: The description of the value set | | `expansion` | uri | Identifies the value set expansion (business identifier) | | `identifier` | token | Multiple Resources: CodeSystem: External identifier for the code system ; ConceptMap: External identifier for the concept map ; MessageDefinition: External identifier for the message definition ; StructureDefinition: External identifier for the structure definition ; StructureMap: External identifier for the structure map ; ValueSet: External identifier for the value set | | `jurisdiction` | token | Multiple Resources: CapabilityStatement: Intended jurisdiction for the capability statement ; CodeSystem: Intended jurisdiction for the code system ; ConceptMap: Intended jurisdiction for the concept map ; GraphDefinition: Intended jurisdiction for the graph definition ; ImplementationGuide: Intended jurisdiction for the implementation guide ; MessageDefinition: Intended jurisdiction for the message definition ; NamingSystem: Intended jurisdiction for the naming system ; OperationDefinition: Intended jurisdiction for the operation definition ; SearchParameter: Intended jurisdiction for the search parameter ; StructureDefinition: Intended jurisdiction for the structure definition ; StructureMap: Intended jurisdiction for the structure map ; TerminologyCapabilities: Intended jurisdiction for the terminology capabilities ; ValueSet: Intended jurisdiction for the value set | | `name` | string | Multiple Resources: CapabilityStatement: Computationally friendly name of the capability statement ; CodeSystem: Computationally friendly name of the code system ; CompartmentDefinition: Computationally friendly name of the compartment definition ; ConceptMap: Computationally friendly name of the concept map ; GraphDefinition: Computationally friendly name of the graph definition ; ImplementationGuide: Computationally friendly name of the implementation guide ; MessageDefinition: Computationally friendly name of the message definition ; NamingSystem: Computationally friendly name of the naming system ; OperationDefinition: Computationally friendly name of the operation definition ; SearchParameter: Computationally friendly name of the search parameter ; StructureDefinition: Computationally friendly name of the structure definition ; StructureMap: Computationally friendly name of the structure map ; TerminologyCapabilities: Computationally friendly name of the terminology capabilities ; ValueSet: Computationally friendly name of the value set | | `publisher` | string | Multiple Resources: CapabilityStatement: Name of the publisher of the capability statement ; CodeSystem: Name of the publisher of the code system ; CompartmentDefinition: Name of the publisher of the compartment definition ; ConceptMap: Name of the publisher of the concept map ; GraphDefinition: Name of the publisher of the graph definition ; ImplementationGuide: Name of the publisher of the implementation guide ; MessageDefinition: Name of the publisher of the message definition ; NamingSystem: Name of the publisher of the naming system ; OperationDefinition: Name of the publisher of the operation definition ; SearchParameter: Name of the publisher of the search parameter ; StructureDefinition: Name of the publisher of the structure definition ; StructureMap: Name of the publisher of the structure map ; TerminologyCapabilities: Name of the publisher of the terminology capabilities ; ValueSet: Name of the publisher of the value set | | `reference` | uri | A code system included or excluded in the value set or an imported value set | | `status` | token | Multiple Resources: CapabilityStatement: The current status of the capability statement ; CodeSystem: The current status of the code system ; CompartmentDefinition: The current status of the compartment definition ; ConceptMap: The current status of the concept map ; GraphDefinition: The current status of the graph definition ; ImplementationGuide: The current status of the implementation guide ; MessageDefinition: The current status of the message definition ; NamingSystem: The current status of the naming system ; OperationDefinition: The current status of the operation definition ; SearchParameter: The current status of the search parameter ; StructureDefinition: The current status of the structure definition ; StructureMap: The current status of the structure map ; TerminologyCapabilities: The current status of the terminology capabilities ; ValueSet: The current status of the value set | | `title` | string | Multiple Resources: CapabilityStatement: The human-friendly name of the capability statement ; CodeSystem: The human-friendly name of the code system ; ConceptMap: The human-friendly name of the concept map ; ImplementationGuide: The human-friendly name of the implementation guide ; MessageDefinition: The human-friendly name of the message definition ; OperationDefinition: The human-friendly name of the operation definition ; StructureDefinition: The human-friendly name of the structure definition ; StructureMap: The human-friendly name of the structure map ; TerminologyCapabilities: The human-friendly name of the terminology capabilities ; ValueSet: The human-friendly name of the value set | | `url` | uri | Multiple Resources: CapabilityStatement: The uri that identifies the capability statement ; CodeSystem: The uri that identifies the code system ; CompartmentDefinition: The uri that identifies the compartment definition ; ConceptMap: The uri that identifies the concept map ; GraphDefinition: The uri that identifies the graph definition ; ImplementationGuide: The uri that identifies the implementation guide ; MessageDefinition: The uri that identifies the message definition ; OperationDefinition: The uri that identifies the operation definition ; SearchParameter: The uri that identifies the search parameter ; StructureDefinition: The uri that identifies the structure definition ; StructureMap: The uri that identifies the structure map ; TerminologyCapabilities: The uri that identifies the terminology capabilities ; ValueSet: The uri that identifies the value set | | `version` | token | Multiple Resources: CapabilityStatement: The business version of the capability statement ; CodeSystem: The business version of the code system ; CompartmentDefinition: The business version of the compartment definition ; ConceptMap: The business version of the concept map ; GraphDefinition: The business version of the graph definition ; ImplementationGuide: The business version of the implementation guide ; MessageDefinition: The business version of the message definition ; OperationDefinition: The business version of the operation definition ; SearchParameter: The business version of the search parameter ; StructureDefinition: The business version of the structure definition ; StructureMap: The business version of the structure map ; TerminologyCapabilities: The business version of the terminology capabilities ; ValueSet: The business version of the value set | ## Reference [#reference] Official FHIR R4 spec: [ValueSet](https://hl7.org/fhir/R4/valueset.html). Maturity: Trial Use 5 (FMM 5). # VerificationResult Canonical page: https://docs.ovok.com/api/fhir/r4/verification-result Describes validation requirements, source(s), status and dates for one or more elements. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/VerificationResult/[id]` | | Vread | `GET` | `/fhir/R4/VerificationResult/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/VerificationResult/[id]` | | Patch | `PATCH` | `/fhir/R4/VerificationResult/[id]` | | Delete | `DELETE` | `/fhir/R4/VerificationResult/[id]` | | Create | `POST` | `/fhir/R4/VerificationResult` | | Search | `GET` | `/fhir/R4/VerificationResult` | | History | `GET` | `/fhir/R4/VerificationResult/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `target` | [Reference](/fhir-elements/complex/reference) | `0..*` | A resource that was validated | | `targetLocation` | [string](/fhir-elements/primitive/string) | `0..*` | The fhirpath location(s) within the resource that was validated | | `need` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | none \| initial \| periodic | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | attested \| validated \| in-process \| req-revalid \| val-fail \| reval-fail | | `statusDate` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | When the validation status was updated | | `validationType` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | nothing \| primary \| multiple | | `validationProcess` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..*` | The primary process by which the target is validated (edit check; value set; primary source; multiple sources; standalone; in context) | | `frequency` | [Timing](/fhir-elements/complex/timing) | `0..1` | Frequency of revalidation | | `lastPerformed` | [dateTime](/fhir-elements/primitive/date-time) | `0..1` | The date/time validation was last completed (including failed validations) | | `nextScheduled` | [date](/fhir-elements/primitive/date) | `0..1` | The date when target is next validated, if appropriate | | `failureAction` | [CodeableConcept](/fhir-elements/complex/codeable-concept) | `0..1` | fatal \| warn \| rec-only \| none | | `primarySource` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Information about the primary source(s) involved in validation | | `attestation` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..1` | Information about the entity attesting to information | | `validator` | [BackboneElement](/fhir-elements/complex/backbone-element) | `0..*` | Information about the entity validating information | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `target` | reference | A resource that was validated | ## Reference [#reference] Official FHIR R4 spec: [VerificationResult](https://hl7.org/fhir/R4/verificationresult.html). Maturity: Draft (FMM 0). # VisionPrescription Canonical page: https://docs.ovok.com/api/fhir/r4/vision-prescription An authorization for the provision of glasses and/or contact lenses to a patient. These interaction paths describe standard FHIR R4 patterns. Availability can depend on the API capabilities enabled for your Ovok project. | **Interaction** | **Method** | **Path** | | --- | --- | --- | | Read | `GET` | `/fhir/R4/VisionPrescription/[id]` | | Vread | `GET` | `/fhir/R4/VisionPrescription/[id]/_history/[vid]` | | Update | `PUT` | `/fhir/R4/VisionPrescription/[id]` | | Patch | `PATCH` | `/fhir/R4/VisionPrescription/[id]` | | Delete | `DELETE` | `/fhir/R4/VisionPrescription/[id]` | | Create | `POST` | `/fhir/R4/VisionPrescription` | | Search | `GET` | `/fhir/R4/VisionPrescription` | | History | `GET` | `/fhir/R4/VisionPrescription/[id]/_history` | ## Top-level elements [#top-level-elements] | **Element** | **Type** | **Cardinality** | **Description** | | --- | --- | --- | --- | | `id` | [string](/fhir-elements/primitive/string) | `0..1` | Logical id of this artifact | | `meta` | [Meta](/fhir-elements/complex/meta) | `0..1` | Metadata about the resource | | `implicitRules` | [uri](/fhir-elements/primitive/uri) | `0..1` | A set of rules under which this content was created | | `language` | [code](/fhir-elements/primitive/code) | `0..1` | Language of the resource content | | `text` | [Narrative](/fhir-elements/complex/narrative) | `0..1` | Text summary of the resource, for human interpretation | | `contained` | [Resource](/fhir-elements/foundation/resource) | `0..*` | Contained, inline Resources | | `extension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Additional content defined by implementations | | `modifierExtension` | [Extension](/fhir-elements/complex/extension) | `0..*` | Extensions that cannot be ignored | | `identifier` | [Identifier](/fhir-elements/complex/identifier) | `0..*` | Business Identifier for vision prescription | | `status` | [code](/fhir-elements/primitive/code) | `1..1` | active \| cancelled \| draft \| entered-in-error | | `created` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | Response creation date | | `patient` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who prescription is for | | `encounter` | [Reference](/fhir-elements/complex/reference) | `0..1` | Created during encounter / admission / stay | | `dateWritten` | [dateTime](/fhir-elements/primitive/date-time) | `1..1` | When prescription was authorized | | `prescriber` | [Reference](/fhir-elements/complex/reference) | `1..1` | Who authorized the vision prescription | | `lensSpecification` | [BackboneElement](/fhir-elements/complex/backbone-element) | `1..*` | Vision lens authorization | ## Resource-specific search parameters [#resource-specific-search-parameters] | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `datewritten` | date | Return prescriptions written on this date | | `encounter` | reference | Multiple Resources: Composition: Context of the Composition ; DeviceRequest: Encounter during which request was created ; DiagnosticReport: The Encounter when the order was made ; DocumentReference: Context of the document content ; Flag: Alert relevant during encounter ; List: Context in which list created ; NutritionOrder: Return nutrition orders with this encounter identifier ; Observation: Encounter related to the observation ; Procedure: Encounter created as part of ; RiskAssessment: Where was assessment performed? ; ServiceRequest: An encounter in which this request is made ; VisionPrescription: Return prescriptions with this encounter identifier | | `identifier` | token | Multiple Resources: AllergyIntolerance: External ids for this item ; CarePlan: External Ids for this plan ; CareTeam: External Ids for this team ; Composition: Version-independent identifier for the Composition ; Condition: A unique identifier of the condition record ; Consent: Identifier for this record (external references) ; DetectedIssue: Unique id for the detected issue ; DeviceRequest: Business identifier for request/order ; DiagnosticReport: An identifier for the report ; DocumentManifest: Unique Identifier for the set of documents ; DocumentReference: Master Version Specific Identifier ; Encounter: Identifier(s) by which this encounter is known ; EpisodeOfCare: Business Identifier(s) relevant for this EpisodeOfCare ; FamilyMemberHistory: A search by a record identifier ; Goal: External Ids for this goal ; ImagingStudy: Identifiers for the Study, such as DICOM Study Instance UID and Accession number ; Immunization: Business identifier ; List: Business identifier ; MedicationAdministration: Return administrations with this external identifier ; MedicationDispense: Returns dispenses with this external identifier ; MedicationRequest: Return prescriptions with this external identifier ; MedicationStatement: Return statements with this external identifier ; NutritionOrder: Return nutrition orders with this external identifier ; Observation: The unique id for a particular observation ; Procedure: A unique identifier for a procedure ; RiskAssessment: Unique identifier for the assessment ; ServiceRequest: Identifiers assigned to this order ; SupplyDelivery: External identifier ; SupplyRequest: Business Identifier for SupplyRequest ; VisionPrescription: Return prescriptions with this external identifier | | `patient` | reference | Multiple Resources: AllergyIntolerance: Who the sensitivity is for ; CarePlan: Who the care plan is for ; CareTeam: Who care team is for ; ClinicalImpression: Patient or group assessed ; Composition: Who and/or what the composition is about ; Condition: Who has the condition? ; Consent: Who the consent applies to ; DetectedIssue: Associated patient ; DeviceRequest: Individual the service is ordered for ; DeviceUseStatement: Search by subject - a patient ; DiagnosticReport: The subject of the report if a patient ; DocumentManifest: The subject of the set of documents ; DocumentReference: Who/what is the subject of the document ; Encounter: The patient or group present at the encounter ; EpisodeOfCare: The patient who is the focus of this episode of care ; FamilyMemberHistory: The identity of a subject to list family member history items for ; Flag: The identity of a subject to list flags for ; Goal: Who this goal is intended for ; ImagingStudy: Who the study is about ; Immunization: The patient for the vaccination record ; List: If all resources have the same subject ; MedicationAdministration: The identity of a patient to list administrations for ; MedicationDispense: The identity of a patient to list dispenses for ; MedicationRequest: Returns prescriptions for a specific patient ; MedicationStatement: Returns statements for a specific patient. ; NutritionOrder: The identity of the person who requires the diet, formula or nutritional supplement ; Observation: The subject that the observation is about (if patient) ; Procedure: Search by subject - a patient ; RiskAssessment: Who/what does assessment apply to? ; ServiceRequest: Search by subject - a patient ; SupplyDelivery: Patient for whom the item is supplied ; VisionPrescription: The identity of a patient to list dispenses for | | `prescriber` | reference | Who authorized the vision prescription | | `status` | token | The status of the vision prescription | ## Reference [#reference] Official FHIR R4 spec: [VisionPrescription](https://hl7.org/fhir/R4/visionprescription.html). Maturity: Trial Use 2 (FMM 2). # API reference Canonical page: https://docs.ovok.com/api The Ovok API is a JSON API over HTTPS. Each page in this reference covers one operation: what it does, who may call it, its parameters and responses, and a request you can send from the page. | | | | --- | --- | | Base URL | `https://api.sandbox.ovok.com` | | Authentication | `Authorization: Bearer {{ACCESS_TOKEN}}`, from [sign-in](/authentication) | | FHIR | `https://api.sandbox.ovok.com/fhir/R4/`, documented under [FHIR R4](/api/fhir) | | Errors | [`application/problem+json`](/errors), with a stable `type` URI per error | ## Errors on every route [#errors-on-every-route] Each operation lists its own errors. Any route can also answer with these: | Status | Meaning | | --- | --- | | [`401`](/errors/unauthenticated) | The bearer token is missing, invalid or expired. The response includes `WWW-Authenticate: Bearer`. | | [`429`](/errors/too-many-requests) | Too many requests. Wait the seconds in `Retry-After`, then retry. | | [`500`](/errors/internal-error) | Unexpected server fault. Retry; if it persists, contact support with the `traceId`. | | [`503`](/errors/service-unavailable) | Over capacity or briefly unavailable. Wait the seconds in `Retry-After`, then retry. | ## Availability [#availability] Routes reach the sandbox first, then staging and production. Each operation page shows the environments that serve it. Routes being retired are listed with their sunset date and replacements in [deprecated routes](/deprecated-routes). ## See also [#see-also] - [Authentication](/authentication) - [Access policies](/access-policies) - [Errors](/errors) - [JavaScript SDK](/web-sdk) # Changelog Canonical page: https://docs.ovok.com/changelog Each entry covers one production release of the Ovok API and its SDKs: the highlights first, then every change by product area, labelled **Breaking** or **Non-breaking**. Breaking changes link to their upgrade path. Development and release-candidate builds don't appear here. To check whether a route or SDK page is available in an environment or on a release channel, use the badges on its page. ## See also [#see-also] - [Deprecated routes](/deprecated-routes) - [Errors](/errors) - [JavaScript SDK](/web-sdk) # Deprecated routes Canonical page: https://docs.ovok.com/deprecated-routes Every route below stops answering on **1 December 2026** (`2026-12-01T00:00:00Z`). Until then each one works exactly as it does today. Move to the replacement before that date. ## How a deprecated route tells you [#how-a-deprecated-route-tells-you] Each answer from a deprecated route carries three headers: | Header | Example | Meaning | |---|---|---| | `Deprecation` ([RFC 9745](https://www.rfc-editor.org/rfc/rfc9745)) | `@1729209600` | When the route was deprecated, in Unix seconds (`@1729209600` is 18 October 2024). | | `Sunset` ([RFC 8594](https://www.rfc-editor.org/rfc/rfc8594)) | `Tue, 01 Dec 2026 00:00:00 GMT` | When the route stops answering, as an HTTP-date. | | `Link` | see the example below | This page as `rel="deprecation"` and `rel="sunset"`, and the replacement as `rel="successor-version"` when there is one. | For example, a login through the legacy route on the sandbox: ```bash curl -i -X POST https://api.sandbox.ovok.com/auth/login \ -H 'Content-Type: application/json' \ -d '{"email": "jane@example.com", "password": "…"}' ``` ```http HTTP/1.1 200 OK Content-Type: application/json Deprecation: @1729209600 Sunset: Tue, 01 Dec 2026 00:00:00 GMT Link: ; rel="deprecation"; type="text/html", ; rel="sunset"; type="text/html", ; rel="successor-version" ``` A browser client can read all three headers: they are CORS-exposed. In the OpenAPI documents each deprecated operation has `deprecated: true`, a description that names the sunset day and the replacement, and an `x-ovok-deprecation` extension: `{ "deprecated": "2024-10-18", "sunset": "2026-12-01", "successors": ["/v2/auth/login"] }`. A replacement path that names a parameter of the deprecated route (`:id`, `:resourceType`) carries the value the caller sent, so `GET /resource/Patient` links to ``. ### What your client should do [#what-your-client-should-do] 1. When an answer carries `Deprecation`, log a warning with the method, the path, the `Sunset` date and the `rel="successor-version"` link. Don't fail the request: the route still works. 2. Move each call to its replacement from the tables below before the `Sunset` date. After that date the route no longer answers. A route marked deprecated currently omits these headers on a `401` or `403` that is refused before the route runs, for example a missing or expired token. A fix is in progress. Until then, rely on the tables below rather than on a refusal's headers. ## Legacy FHIR CRUD (deprecated 18 October 2024) [#legacy-fhir-crud-deprecated-18-october-2024] The replacement is the FHIR R4 API: standard FHIR request and response bodies, not the legacy DTOs. | Deprecated route | Replacement | |---|---| | `POST`, `GET /account`; `GET`, `PUT`, `DELETE /account/:id` | `/fhir/R4/Account`, same methods | | `POST`, `GET /appointment`; `GET`, `PUT`, `DELETE /appointment/:id` | `/fhir/R4/Appointment`, same methods | | `POST`, `GET /device`; `GET`, `PUT`, `DELETE /device/:id` | `/fhir/R4/Device`, same methods | | `POST`, `GET /document-reference`; `GET`, `PATCH /document-reference/:id` | `/fhir/R4/DocumentReference` for the resource; `POST /document`, `GET /document`, `GET`, `PATCH /document/:id` for files | | `POST`, `GET /location`; `GET`, `PUT`, `DELETE /location/:id` | `/fhir/R4/Location`, same methods | | `GET /location/schedule`, `GET /location/:id/schedule` | No combined route: read `/fhir/R4/Location` and `/fhir/R4/Schedule` | | `POST`, `GET /observation`; `GET`, `PUT`, `DELETE /observation/:id` | `/fhir/R4/Observation`, same methods | | `POST`, `GET /patient`; `GET`, `PUT`, `PATCH`, `DELETE /patient/:id` | `/fhir/R4/Patient`, same methods | | `GET /patient/:id/observation` | `GET /fhir/R4/Observation/$lastn?patient=Patient/:id` | | `POST`, `GET /questionnaire`; `GET`, `PUT`, `DELETE /questionnaire/:id` | `/fhir/R4/Questionnaire`, same methods | | `POST`, `GET /resource/:resourceType`; `GET`, `PUT`, `PATCH`, `DELETE /resource/:resourceType/:id` | `/fhir/R4/:resourceType`, same methods | | `POST`, `GET /schedule`; `GET`, `PUT`, `DELETE /schedule/:id` | `/fhir/R4/Schedule`, same methods | | `GET`, `POST /bot/execute` | `GET`, `POST /bots?identifier=\|` | | `GET`, `POST /bot/:id/execute` | None: run a bot by identifier through `/bots` | ## Files (deprecated 18 October 2024) [#files-deprecated-18-october-2024] | Deprecated route | Replacement | |---|---| | `POST /binary/single` | `POST /document`: it answers a signed upload form, and the file goes straight to storage | | `POST /binary/multiple` | None as a batch: call `POST /document` once per file | | `GET /binary/:documentReferenceId` | `GET /document/:id` (a `307` to a signed URL) | ## Authentication (deprecated 18 October 2024) [#authentication-deprecated-18-october-2024] | Deprecated route | Replacement | |---|---| | `POST /auth/login` | `POST /v2/auth/login` | | `POST /auth/change-password` | `PATCH /v2/auth/change-password` | | `POST /auth/reset-password` | `POST /v2/auth/reset-password` | | `POST /auth/set-password` | `POST /v2/auth/reset-password/process` | | `PATCH /auth/update-email` | None | | `DELETE /auth/deregister-user` | `DELETE /auth/delete` | | `POST /auth/signup` | `POST /auth/tenant/Patient/register` or `POST /auth/tenant/Practitioner/register` | | `POST /auth/external/google` | None | | `POST /auth/external/apple` | None | | `POST /auth/tan-login/:tan` | `POST /auth/login/tan`, with the TAN in the body | ## Video calls (deprecated 18 October 2024) [#video-calls-deprecated-18-october-2024] | Deprecated route | Replacement | |---|---| | `POST /v3/video-call/appointment` | `POST /video-call/livekit/appointment` | | `POST /v3/video-call/user-access` | `POST /video-call/livekit/user-access/:appointmentId` | | `POST /v3/video-call/guest-access` | `POST /video-call/livekit/guest-access/:appointmentId` | ## Slim (dashboard) routes [#slim-dashboard-routes] | Deprecated route | Deprecated on | Replacement | |---|---|---| | `GET /v1/slim/query_new` | 13 April 2026 | `GET /v1/slim/device/live` | | `GET /v1/slim/query_new/telemetry` | 13 April 2026 | `GET /v1/slim/device/live/telemetry` | | `GET`, `POST /v1/slim/user/medical-settings-notifications-consent` | 2 October 2026 | `GET`, `POST /v1/me/consent/medical` | | `GET /v1/slim/notifications` | 3 October 2026 | `GET /v1/slim/notifications/oob` (out of bed), `/alarms` (device alarms and attention presses), `/medical` (HR/BR) | | Any `/v{n}/carehub/...` path | 30 September 2026 | The same path under `/v{n}/slim/...` | `/v{n}/carehub/...` is a hidden alias: it is in no OpenAPI document, and every answer, refusals included, links its own `/v{n}/slim/...` path as `rel="successor-version"`. When the slim route is itself deprecated, `Deprecation` carries that route's date. ## Invitations (deprecated 22 October 2026) [#invitations-deprecated-22-october-2026] The share invitations are now named by purpose. Each old route still works exactly as before, with the same gates and status codes, and carries `Deprecation: @1792627200` and a `rel="successor-version"` link to its replacement. | Deprecated route | Replacement | What to change | |---|---|---| | `POST /v1/invites/practitioner` | `POST /v1/invites/record-share` | Add `"recipient": "practitioner"` to the body. See [Share a record with a practitioner](/invitations/share-with-practitioner). | | `POST /v1/invites/practitioner/accept` | `POST /v1/invites/record-share/accept` | Nothing else. The new route also accepts [carer invites](/invitations/share-with-a-carer#step-2-accept). | | `POST /v1/invites/patient` | `POST /v1/invites/care` | Nothing else. See [Invite a patient into care](/invitations/invite-a-patient). | | `POST /v1/invites/patient/accept` | `POST /v1/invites/care/accept` | Nothing else. | Until the sunset, a practitioner offer or a care invitation sent through either route can be accepted on either. Carer invitations exist only on the new routes. ## Deprecated fields [#deprecated-fields] `POST /auth/refresh-token` still answers `access_token`, `refresh_token` and `expires_in` beside `accessToken`, `refreshToken` and `expiresIn`. The snake-case fields are deprecated in the OpenAPI schema; read the camel-case ones. They have no sunset date yet. # ACCOUNT EXISTS Canonical page: https://docs.ovok.com/errors/account-exists **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/account-exists`](https://docs.ovok.com/errors/account-exists). ## What this means [#what-this-means] An email address already belongs to an Ovok account, so registration or provisioning cannot create another account with it. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Confirm the address and whether its owner should sign in, reuse an existing account, or follow the supported invitation flow. Do not create a second account with a modified address. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Patient registration](/authentication/patient-registration) - [Practitioner registration](/authentication/practitioner-registration) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # ADDRESS HAS ACCOUNT Canonical page: https://docs.ovok.com/errors/address-has-account **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/address-has-account`](https://docs.ovok.com/errors/address-has-account). ## What this means [#what-this-means] When a patient invited the address it had no account, but by the time the invite was accepted the address had one, for example as a patient or a practitioner of the project. One address can hold only one kind of account in a project. Nothing was written, and the invite stays unused. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Ask the patient to send a new invite to an address that has no account, or have the person accept with the address they already use as a carer. Retrying the same invite gives the same answer. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Share readings with a carer](/invitations/share-with-a-carer) - [Carers](/authentication/carers) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # ALREADY SUBSCRIBED Canonical page: https://docs.ovok.com/errors/already-subscribed **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/already-subscribed`](https://docs.ovok.com/errors/already-subscribed). ## What this means [#what-this-means] The customer already has a subscription, so self-service checkout cannot create another one. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Read the current subscription first and confirm the billing customer and parent project. Enterprise contracts are a separate billing path. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # APP URL NOT ALLOWED Canonical page: https://docs.ovok.com/errors/app-url-not-allowed **HTTP 400.** Stable Problem Details type: [`https://docs.ovok.com/errors/app-url-not-allowed`](https://docs.ovok.com/errors/app-url-not-allowed). ## What this means [#what-this-means] The supplied patient or practitioner application URL points to the Ovok API host and cannot be used as a return destination. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check the URL scheme and hostname. Configure a real app origin or deep link, not the API base URL. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Patient app URL setting](/settings-and-features/settings/patient-app-url) - [Practitioner app URL setting](/settings-and-features/settings/practitioner-app-url) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # APP URL NOT CONFIGURED Canonical page: https://docs.ovok.com/errors/app-url-not-configured **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/app-url-not-configured`](https://docs.ovok.com/errors/app-url-not-configured). ## What this means [#what-this-means] The project has no usable patient or practitioner app URL for an invitation or wearable-connection flow that needs a return destination. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Ask an administrator to review the relevant app URL setting in this environment. Patient and practitioner URLs resolve independently. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Patient app URL setting](/settings-and-features/settings/patient-app-url) - [Practitioner app URL setting](/settings-and-features/settings/practitioner-app-url) - [Patient invitations](/invitations/invite-a-patient) - [Team invitations](/invitations/team-members) - [Connect a patient's wearable](/wearables/connect-a-patient) - [Wearables API reference](/wearables/api-reference#patient-connections) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # BILLING DISABLED Canonical page: https://docs.ovok.com/errors/billing-disabled **HTTP 403.** Stable Problem Details type: [`https://docs.ovok.com/errors/billing-disabled`](https://docs.ovok.com/errors/billing-disabled). ## What this means [#what-this-means] Payments are not enabled in this Ovok deployment. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check that the request targets the intended environment. A deployment administrator must enable billing and its provider configuration. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # BILLING HUB Canonical page: https://docs.ovok.com/errors/billing-hub **HTTP 403.** Stable Problem Details type: [`https://docs.ovok.com/errors/billing-hub`](https://docs.ovok.com/errors/billing-hub). ## What this means [#what-this-means] This deployment is the central billing hub and does not accept this customer-facing billing operation. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check the base URL and send the operation to the customer-facing deployment that owns the subscription. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # CLIENT_ERROR Canonical page: https://docs.ovok.com/errors/client-error **Fallback for an unmapped 4xx response.** Problem type: [`https://docs.ovok.com/errors/client-error`](https://docs.ovok.com/errors/client-error). ## What this means [#what-this-means] The request was rejected, but Ovok has no more specific status-based problem page for this 4xx response. An endpoint-specific machine code, when present, takes precedence; otherwise use the HTTP status and the response details to understand what the endpoint rejected. ## Troubleshooting [#troubleshooting] Confirm the base URL, route, active project, HTTP method, and request headers against the endpoint documentation. Then inspect `detail` and any entries in `errors` for a rejected field or condition. If the route documents a more specific error code, use that endpoint guidance too. A client error usually needs a request or access change; repeating identical input will not resolve it. ## Retry safely [#retry-safely] Correct the request or the condition identified by the endpoint first, then submit it once. Do not build client logic that treats every 4xx response as transient or retries it unchanged. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # CLIENT ID RESERVED Canonical page: https://docs.ovok.com/errors/client-id-reserved **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/client-id-reserved`](https://docs.ovok.com/errors/client-id-reserved). ## What this means [#what-this-means] The Withings client ID belongs to Ovok's legacy Withings device integration, so a project cannot save it as its cloud wearables app. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Register a new app at Withings for the project and save its client ID and secret instead. The legacy device integration keeps working on its own app. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Set up wearable providers](/wearables/set-up-providers) - [Wearables API reference](/wearables/api-reference#provider-setup) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # CMS API KEY LIMIT Canonical page: https://docs.ovok.com/errors/cms-api-key-limit **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/cms-api-key-limit`](https://docs.ovok.com/errors/cms-api-key-limit). ## What this means [#what-this-means] The project already holds the maximum of 20 CMS API keys. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] List existing keys and ask their owners whether an unused key can be revoked safely before creating another. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [CMS API keys](/cms#api-keys) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # CMS API KEY NOT FOUND Canonical page: https://docs.ovok.com/errors/cms-api-key-not-found **HTTP 404.** Stable Problem Details type: [`https://docs.ovok.com/errors/cms-api-key-not-found`](https://docs.ovok.com/errors/cms-api-key-not-found). ## What this means [#what-this-means] The CMS API key identifier does not exist in the authenticated project. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Verify the ID and project. Key IDs are project-scoped; refresh the key list before retrying. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [CMS API keys](/cms#api-keys) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # CONFLICT Canonical page: https://docs.ovok.com/errors/conflict **HTTP 409.** Problem type: [`https://docs.ovok.com/errors/conflict`](https://docs.ovok.com/errors/conflict). ## What this means [#what-this-means] The requested operation conflicts with the resource's current state. This can happen when another operation changed the resource after it was read or when the requested transition is not valid from its current state. ## Troubleshooting [#troubleshooting] Read the resource again and compare its current values and status with the values your request was based on. Check whether another user or process updated it, whether the action has already been completed, and whether the endpoint permits that transition. Preserve unrelated changes while reconciling the fields that conflict; do not overwrite the latest resource with a stale copy. ## Retry safely [#retry-safely] After reconciling against the latest state, construct a new request that represents the intended change and submit it once. If the operation may already have succeeded, verify the result before repeating it. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # CONNECTION CHANGED Canonical page: https://docs.ovok.com/errors/connection-changed **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/connection-changed`](https://docs.ovok.com/errors/connection-changed). ## What this means [#what-this-means] The patient reconnected the wearable provider while a sync of the earlier connection was running. Ovok wrote nothing over the new connection. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Sync again: the new connection is used. If this repeats, check that your app does not start a connection and a sync at the same time. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Sync a connection](/wearables/api-reference#sync-a-connection) - [Sync and read wearable data](/wearables/sync-and-read-data) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # CONNECTION NOT FOUND Canonical page: https://docs.ovok.com/errors/connection-not-found **HTTP 404.** Stable Problem Details type: [`https://docs.ovok.com/errors/connection-not-found`](https://docs.ovok.com/errors/connection-not-found). ## What this means [#what-this-means] The patient has no current wearable connection for the requested provider. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Confirm patient, provider and project, then read the current connection list. A prior disconnect invalidates old identifiers. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Connect a patient's wearable](/wearables/connect-a-patient) - [Wearables API reference](/wearables/api-reference#patient-connections) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # CONTENT_TOO_LARGE Canonical page: https://docs.ovok.com/errors/content-too-large **HTTP 413.** Problem type: [`https://docs.ovok.com/errors/content-too-large`](https://docs.ovok.com/errors/content-too-large). ## What this means [#what-this-means] The request body is larger than the endpoint or an intermediary can accept. The response does not establish a universal size limit; limits can depend on the route and deployment. ## Troubleshooting [#troubleshooting] Measure the serialized request body, not only the size of the source file or object. Look for large embedded content, repeated fields, or a batch that can be divided. Check the endpoint documentation for any route-specific limits and confirm that your client is sending only the fields the operation needs. ## Retry safely [#retry-safely] Send a smaller request. If you split a batch, follow that endpoint's ordering and relationship rules so that dependent records remain valid. Retrying the same body unchanged will fail again. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # EMAIL NOT VERIFIED Canonical page: https://docs.ovok.com/errors/email-not-verified **HTTP 403.** Stable Problem Details type: [`https://docs.ovok.com/errors/email-not-verified`](https://docs.ovok.com/errors/email-not-verified). ## What this means [#what-this-means] The account's email address has not been verified, so this sign-in step is blocked. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Confirm mail delivery to the address on file. The password-reset flow verifies the address; check spam filtering before requesting another message. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Authentication troubleshooting](/authentication/troubleshooting) - [Practitioner sign-in](/authentication/practitioner-login) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # ENCRYPTION UNAVAILABLE Canonical page: https://docs.ovok.com/errors/encryption-unavailable **HTTP 503.** Stable Problem Details type: [`https://docs.ovok.com/errors/encryption-unavailable`](https://docs.ovok.com/errors/encryption-unavailable). ## What this means [#what-this-means] This server cannot encrypt a secret, so provider configuration was not saved. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Ask a deployment administrator to check encryption-key availability without sharing key material. Do not resend secrets until the service is ready. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Set up email](/email-templates/set-up-email) - [Email troubleshooting](/email-templates/troubleshooting) ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # ENTERPRISE CONTRACT Canonical page: https://docs.ovok.com/errors/enterprise-contract **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/enterprise-contract`](https://docs.ovok.com/errors/enterprise-contract). ## What this means [#what-this-means] The customer is billed under an Enterprise contract, so self-service subscription operations are unavailable. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Confirm the customer's billing contract and account. Use the contract owner's billing path rather than starting card checkout. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # EVENTS UNAVAILABLE Canonical page: https://docs.ovok.com/errors/events-unavailable **HTTP 503.** Stable Problem Details type: [`https://docs.ovok.com/errors/events-unavailable`](https://docs.ovok.com/errors/events-unavailable). ## What this means [#what-this-means] Ovok could not read the project's request-event service in time or the service is temporarily unavailable. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Inspect `Retry-After`, retain the request trace ID, and check if failures affect all event-history reads. Verify write state before repeating related operations. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # FAILED_DEPENDENCY Canonical page: https://docs.ovok.com/errors/failed-dependency **HTTP 424.** Problem type: [`https://docs.ovok.com/errors/failed-dependency`](https://docs.ovok.com/errors/failed-dependency). ## What this means [#what-this-means] The requested operation depends on another operation that did not succeed. The response's `detail`, field errors, and endpoint documentation may identify which prerequisite needs attention. ## Troubleshooting [#troubleshooting] Check that the prerequisite resource or operation exists, completed successfully, and belongs to the expected project. Verify referenced identifiers and required values against the latest state, then inspect the dependent endpoint's documented order of operations. If the prerequisite itself returned an error, troubleshoot that error first rather than repeatedly submitting the dependent request. ## Retry safely [#retry-safely] Resolve the failed prerequisite, confirm its result, and then retry only the dependent operation if that operation is safe to repeat. If either step may have partially completed, read the current state before replaying it. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # FEATURE_NOT_CONFIGURED Canonical page: https://docs.ovok.com/errors/feature-not-configured **HTTP 501.** Stable Problem Details type: [`https://docs.ovok.com/errors/feature-not-configured`](https://docs.ovok.com/errors/feature-not-configured). ## What this means [#what-this-means] Ovok recognizes the requested feature or integration, but it is not enabled or cannot be configured in this deployment. For example, a wearable provider may return this error when wearable secret storage is unavailable. ## Troubleshooting [#troubleshooting] Confirm that the request is going to the intended environment and that the integration is supported there. Ask the project administrator to check the endpoint's setup requirements, whether the integration is enabled, and whether its required configuration is available. Do not put integration credentials in a support message or error report. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Set up wearable providers](/wearables/set-up-providers) - [Wearables API reference](/wearables/api-reference#provider-setup) ## Retry safely [#retry-safely] A retry with the same request will not configure the feature. Retry after an administrator confirms that setup has changed, using the endpoint's documented request format. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # FORBIDDEN Canonical page: https://docs.ovok.com/errors/forbidden **HTTP 403.** Problem type: [`https://docs.ovok.com/errors/forbidden`](https://docs.ovok.com/errors/forbidden). ## What this means [#what-this-means] The request was authenticated, but the caller is not allowed to perform this operation on the requested resource or in the current project context. ## Troubleshooting [#troubleshooting] Check which user or service identity made the request and confirm that the client selected the intended project and environment. Ask an administrator to verify the caller's role, project membership, and permission for this operation and resource. A valid sign-in does not by itself grant access to every project or action. ## Retry safely [#retry-safely] Retry only after using the correct identity or after an administrator changes the relevant access. Repeating the request with the same identity and permissions will not help; do not send credentials when asking for access support. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # FROM REQUIRED Canonical page: https://docs.ovok.com/errors/from-required **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/from-required`](https://docs.ovok.com/errors/from-required). ## What this means [#what-this-means] The configured email provider requires a sender address that the project does not have. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Set a valid sender address and verify it with the provider. Confirm the selected provider matches the request. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Set up email](/email-templates/set-up-email) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # GONE Canonical page: https://docs.ovok.com/errors/gone **HTTP 410.** Problem type: [`https://docs.ovok.com/errors/gone`](https://docs.ovok.com/errors/gone). ## What this means [#what-this-means] The requested resource or action is no longer available. The endpoint may use this response for an item or action that has expired, been consumed, or been retired; consult its documentation for the exact lifecycle. ## Troubleshooting [#troubleshooting] Confirm the environment and identifier, then check the endpoint's documented lifecycle and whether the action has already been used or revoked. If the request came from a saved link or an earlier workflow step, verify that it is still current. Avoid repeatedly submitting a stale identifier or reusing an expired action. ## Retry safely [#retry-safely] Use the current resource or start a new supported workflow if the endpoint allows it. Do not assume that refreshing the same link or replaying the same request will restore an unavailable action. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # Error responses Canonical page: https://docs.ovok.com/errors Ovok's standard HTTP API errors use the [RFC 9457 Problem Details](https://www.rfc-editor.org/rfc/rfc9457) media type, `application/problem+json`. The response keeps the legacy fields used by existing clients while exposing a stable problem type, the HTTP status, a request path, a trace ID, and structured field errors. ## Response body [#response-body] ```json { "type": "https://docs.ovok.com/errors/validation-failed", "status": 422, "detail": "The request has invalid fields.", "instance": "/v1/slim/patient", "traceId": "01JQEXAMPLE8D2A4B6C", "errors": [ { "field": "email", "code": "FIELD_INVALID_EMAIL", "params": null } ], "statusCode": 422, "error": "Unprocessable Entity", "timestamp": "2026-10-22T00:00:00.000Z", "path": "/v1/slim/patient", "message": ["email must be an email"], "requestId": "request-id" } ``` `type` is a stable URI for the error category. Its slug normally comes from the HTTP status mapping below; an endpoint may use a specific machine code instead. Use `status` for HTTP handling and `type` for category-specific handling. `detail` is human-readable and may be `null`; do not parse it for program logic. `instance` is the request path without its query string. `traceId` identifies the request in Ovok's tracing and logs. It may be `null` when no trace context is available. Include it when reporting an error to support. The legacy `requestId`, `statusCode`, `error`, `timestamp`, `path`, and `message` fields are retained for existing clients during migration. ## Field errors [#field-errors] `errors` is always an array in this response format. A field-level error contains: | Field | Meaning | | --- | --- | | `field` | Request field or resource path; `null` when the error is not tied to one field. | | `code` | Machine-readable reason for this field error, such as `FIELD_INVALID_EMAIL` or `FIELD_REQUIRED`. | | `params` | Optional constraint values, or `null` when there are none. | Correct the fields named by `errors` before retrying. The API limits the response to 100 field errors. These nested `errors[].code` values are field codes; they are separate from the top-level problem `type`. ## Stable status types [#stable-status-types] When no endpoint-specific machine code is supplied, the problem type is `https://docs.ovok.com/errors/`. The pages below document the types mapped by the current Ovok core release. | Status | Type | | --- | --- | | 400 | [`malformed-request`](/errors/malformed-request) | | 401 | [`unauthenticated`](/errors/unauthenticated) | | 403 | [`forbidden`](/errors/forbidden) | | 404 | [`not-found`](/errors/not-found) | | 405 | [`method-not-allowed`](/errors/method-not-allowed) | | 406 | [`not-acceptable`](/errors/not-acceptable) | | 408 | [`request-timeout`](/errors/request-timeout) | | 409 | [`conflict`](/errors/conflict) | | 410 | [`gone`](/errors/gone) | | 412 | [`precondition-failed`](/errors/precondition-failed) | | 413 | [`content-too-large`](/errors/content-too-large) | | 415 | [`unsupported-media-type`](/errors/unsupported-media-type) | | 422 | [`validation-failed`](/errors/validation-failed) | | 423 | [`locked`](/errors/locked) | | 424 | [`failed-dependency`](/errors/failed-dependency) | | 428 | [`precondition-required`](/errors/precondition-required) | | 429 | [`too-many-requests`](/errors/too-many-requests) | | 500 | [`internal-error`](/errors/internal-error) | | 501 | [`not-implemented`](/errors/not-implemented); a configured machine code may use [`feature-not-configured`](/errors/feature-not-configured) | | 502 | [`upstream-error`](/errors/upstream-error) | | 503 | [`service-unavailable`](/errors/service-unavailable) | | 504 | [`upstream-timeout`](/errors/upstream-timeout) | | Other 4xx | [`client-error`](/errors/client-error) | | Other 5xx | [`server-error`](/errors/server-error) | An endpoint can supply a stable machine code that replaces the status-derived type. The [endpoint-specific machine-code registry](/errors/machine-codes) lists all 64 types emitted by the audited core release, with one troubleshooting page per type. It was checked against merged `ovok-core` development commit `9a6ca1c2523079bcb8f7d4cbee583681c475d683`; update the registry and pages when a backend change adds or removes a type. Published HTTP endpoint error sections link their status values to the generic guidance and each listed machine code to its canonical page. Some backend operations have no dedicated public route page yet; their machine-code page remains the reference and links to the closest available guide where one exists. ## Protocol-specific errors [#protocol-specific-errors] Not every Ovok API uses Problem Details. FHIR routes return a FHIR [`OperationOutcome`](/api/fhir/r4/operation-outcome); interpret its `issue` entries and expressions using the FHIR format. OAuth token endpoints and the MCP authorization flow keep their protocol-specific error members; the [account refresh route](/authentication/account/refresh-token) documents its own status outcomes. MCP authentication, JSON-RPC, and tool-call failures keep their distinct response bodies; see [MCP server troubleshooting](/working-with-ai-agents/mcp-server) and [MCP tools](/working-with-ai-agents/mcp-tools). GraphQL requests use the GraphQL `errors` response envelope; see the [GraphQL API guide](/graphql). Do not parse these protocol responses as Problem Details. ## Top-level `code` [#top-level-code] Ovok does not currently add a top-level `code` member to Problem Details. The FhirStore client interprets a string top-level `code` as the complete error and can lose the rest of the response body. Use `type`, `status`, and the documented field errors instead. The nested `errors[].code` remains available for validation. # INTERNAL_ERROR Canonical page: https://docs.ovok.com/errors/internal-error **HTTP 500.** Problem type: [`https://docs.ovok.com/errors/internal-error`](https://docs.ovok.com/errors/internal-error). ## What this means [#what-this-means] Ovok encountered an unexpected failure while processing the request. The response may not explain the internal cause; the `traceId` helps an administrator locate the corresponding server-side record. ## Troubleshooting [#troubleshooting] Record the HTTP status, problem `type`, request path, response timestamp, and `traceId`. Before repeating a write or other state-changing operation, read the affected resource or check the operation's documented status because the response alone may not tell you whether the change took effect. ## Retry safely [#retry-safely] For an operation that is safe to repeat, make a small number of attempts with a delay between them. Avoid tight retry loops. If the error persists, stop retrying until the issue is understood. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # INVALID LINK Canonical page: https://docs.ovok.com/errors/invalid-link **HTTP 400.** Stable Problem Details type: [`https://docs.ovok.com/errors/invalid-link`](https://docs.ovok.com/errors/invalid-link). ## What this means [#what-this-means] The verification link is invalid, expired, or already used. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Use the newest link for the right account and environment. A mail scanner or another browser session may already have consumed a one-time link. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Patient registration](/authentication/patient-registration) - [Practitioner registration](/authentication/practitioner-registration) - [Authentication troubleshooting](/authentication/troubleshooting) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # INVALID SECRET Canonical page: https://docs.ovok.com/errors/invalid-secret **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/invalid-secret`](https://docs.ovok.com/errors/invalid-secret). ## What this means [#what-this-means] The supplied provider secret does not match the format accepted by the selected integration. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check provider and credential type, remove accidental whitespace, and ensure the secret was not truncated. Never put secrets in logs or support messages. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Set up email](/email-templates/set-up-email) - [Email troubleshooting](/email-templates/troubleshooting) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # INVALID SETTING VALUE Canonical page: https://docs.ovok.com/errors/invalid-setting-value **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/invalid-setting-value`](https://docs.ovok.com/errors/invalid-setting-value). ## What this means [#what-this-means] The supplied project setting is not valid for that setting's type or accepted values. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check the setting's documented value shape. For URLs verify format; for policy references confirm the policy belongs to this project. Review nested field errors. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Settings and features](/settings-and-features) - [Patient app URL setting](/settings-and-features/settings/patient-app-url) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # INVALID SIGNATURE Canonical page: https://docs.ovok.com/errors/invalid-signature **HTTP 401.** Stable Problem Details type: [`https://docs.ovok.com/errors/invalid-signature`](https://docs.ovok.com/errors/invalid-signature). ## What this means [#what-this-means] A wearable provider notification arrived without a valid signature or URL token, so Ovok ignored it. The answer carries `WWW-Authenticate`. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] For Suunto, check that the `webhookSecret` saved in Ovok equals the notification secret in Suunto's portal. For Withings, the URL token changes when the client ID changes; patients then reconnect and are subscribed with the new URL. A notification Ovok refuses is not lost data: the daily sync still reads it. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Webhook URLs](/wearables/set-up-providers#webhook-urls) - [Wearables webhooks](/wearables/api-reference#webhooks) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # INVALID STATE Canonical page: https://docs.ovok.com/errors/invalid-state **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/invalid-state`](https://docs.ovok.com/errors/invalid-state). ## What this means [#what-this-means] The wearable authorization state is expired, already used, or bound to another provider or attempt. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Start a fresh authorization for the same patient and provider. Confirm the callback uses the state from that attempt and was not submitted twice. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Connect a patient's wearable](/wearables/connect-a-patient) - [Wearables OAuth callback](/wearables/api-reference#oauth-callback) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # INVALID SWITCH Canonical page: https://docs.ovok.com/errors/invalid-switch **HTTP 400.** Stable Problem Details type: [`https://docs.ovok.com/errors/invalid-switch`](https://docs.ovok.com/errors/invalid-switch). ## What this means [#what-this-means] The project-switch token is malformed, expired, used at the wrong step, or already completed. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Restart switching in one browser session and follow its password and MFA steps in order. Use the token returned by the latest attempt. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Authentication project setup](/authentication/project-setup) - [Authentication troubleshooting](/authentication/troubleshooting) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # INVALID TEMPLATE CONTENT Canonical page: https://docs.ovok.com/errors/invalid-template-content **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/invalid-template-content`](https://docs.ovok.com/errors/invalid-template-content). ## What this means [#what-this-means] Template content does not satisfy the selected email provider's requirements. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check name, language, domain, subject and HTML requirements. SMTP requires subject and HTML; managed providers can reject those fields. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Map email templates](/email-templates/map-templates) - [Email troubleshooting](/email-templates/troubleshooting) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # INVALID TEMPLATE ID Canonical page: https://docs.ovok.com/errors/invalid-template-id **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/invalid-template-id`](https://docs.ovok.com/errors/invalid-template-id). ## What this means [#what-this-means] The template identifier is invalid for the selected email provider. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Copy the exact current ID from that provider's catalogue. Confirm the template and credential belong to the configured provider. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Email template catalogue](/email-templates/template-catalogue) - [Map email templates](/email-templates/map-templates) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # INVITATION NOT CONFIGURED Canonical page: https://docs.ovok.com/errors/invitation-not-configured **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/invitation-not-configured`](https://docs.ovok.com/errors/invitation-not-configured). ## What this means [#what-this-means] The project lacks a valid default access policy required for the invitation flow. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Ask an administrator to configure the default patient or practitioner policy. Confirm it exists in this project and grants intended least privilege. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Default practitioner access policy](/settings-and-features/settings/default-practitioner-access-policy) - [Invite a patient](/invitations/invite-a-patient) - [Invite practitioners](/invitations/team-members) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # LIVE READS OVER CAPACITY Canonical page: https://docs.ovok.com/errors/live-reads-over-capacity **HTTP 503.** Stable Problem Details type: [`https://docs.ovok.com/errors/live-reads-over-capacity`](https://docs.ovok.com/errors/live-reads-over-capacity). ## What this means [#what-this-means] The server reached its concurrent live-read limit and shed the request. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Use `Retry-After` or `retryAfterSec`; reduce parallel dashboard reads and prevent synchronized retry bursts. This does not mean the result is empty. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Medical notifications](/slim-apis/notifications/list-medical-notifications) - [Live device telemetry](/slim-apis/telemetry/get-device-telemetry-and-alerts) - [Real-time trends](/slim-apis/trends/get-realtime-trends-graphs) ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # LOCKED Canonical page: https://docs.ovok.com/errors/locked **HTTP 423.** Problem type: [`https://docs.ovok.com/errors/locked`](https://docs.ovok.com/errors/locked). ## What this means [#what-this-means] The resource is locked and cannot be changed now. The lock may be associated with another operation or a workflow described by the endpoint. ## Troubleshooting [#troubleshooting] Confirm that the request targets the intended resource and check the endpoint's guidance for lock ownership or lifecycle. If another process is updating the resource, allow it to finish instead of starting competing updates. Avoid rapid polling or repeated writes while the resource remains locked. ## Retry safely [#retry-safely] Wait for the lock to clear, read the resource again, and confirm that it is still appropriate to apply your change. Then retry once. If the lock remains unexpectedly, ask an administrator to check its state. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # Endpoint-specific error types Canonical page: https://docs.ovok.com/errors/machine-codes Ovok uses the following endpoint-specific machine codes to choose a stable Problem Details `type`. This inventory was checked against merged `ovok-core` development commit `6e295b659132da0d97f474508bbbea4b038310b3`, plus the four carer types added at `6a0d0f675`. It covers 82 app-defined types in addition to the status-derived types on the [Error responses](/errors) page. A source change that adds a new machine code must update this registry and its troubleshooting page. Use the `type` URI as the stable category. Legacy response fields can vary by endpoint; do not assume the machine code is a top-level Problem Details `code`. The page for each type explains its status, likely cause, checks, and safe next step. | Problem type | HTTP | Machine-code slug | Meaning | | --- | ---: | --- | --- | | [`account-exists`](/errors/account-exists) | 409 | `ACCOUNT_EXISTS` | An email address already belongs to an Ovok account, so registration or provisioning cannot create another account with it. | | [`address-has-account`](/errors/address-has-account) | 409 | `ADDRESS_HAS_ACCOUNT` | A new carer's address already has an account, so accepting the invite cannot create a carer account for it. | | [`already-subscribed`](/errors/already-subscribed) | 409 | `ALREADY_SUBSCRIBED` | The customer already has a subscription, so self-service checkout cannot create another one. | | [`app-url-not-allowed`](/errors/app-url-not-allowed) | 400 | `APP_URL_NOT_ALLOWED` | The supplied patient or practitioner application URL points to the Ovok API host and cannot be used as a return destination. | | [`app-url-not-configured`](/errors/app-url-not-configured) | 409 | `APP_URL_NOT_CONFIGURED` | The project has no usable patient or practitioner app URL for an invitation or wearable-connection flow that needs a return destination. | | [`billing-disabled`](/errors/billing-disabled) | 403 | `BILLING_DISABLED` | Payments are not enabled in this Ovok deployment. | | [`billing-hub`](/errors/billing-hub) | 403 | `BILLING_HUB` | This deployment is the central billing hub and does not accept this customer-facing billing operation. | | [`client-id-reserved`](/errors/client-id-reserved) | 422 | `CLIENT_ID_RESERVED` | The Withings client ID belongs to Ovok's legacy Withings device integration. | | [`cms-api-key-limit`](/errors/cms-api-key-limit) | 409 | `CMS_API_KEY_LIMIT` | The project already holds the maximum of 20 CMS API keys. | | [`cms-api-key-not-found`](/errors/cms-api-key-not-found) | 404 | `CMS_API_KEY_NOT_FOUND` | The CMS API key identifier does not exist in the authenticated project. | | [`connection-changed`](/errors/connection-changed) | 409 | `CONNECTION_CHANGED` | The patient reconnected the wearable provider during a sync, so nothing was written over the new connection. | | [`connection-not-found`](/errors/connection-not-found) | 404 | `CONNECTION_NOT_FOUND` | The patient has no current wearable connection for the requested provider. | | [`email-not-verified`](/errors/email-not-verified) | 403 | `EMAIL_NOT_VERIFIED` | The account's email address has not been verified, so this sign-in step is blocked. | | [`encryption-unavailable`](/errors/encryption-unavailable) | 503 | `ENCRYPTION_UNAVAILABLE` | This server cannot encrypt a secret, so provider configuration was not saved. | | [`enterprise-contract`](/errors/enterprise-contract) | 409 | `ENTERPRISE_CONTRACT` | The customer is billed under an Enterprise contract, so self-service subscription operations are unavailable. | | [`events-unavailable`](/errors/events-unavailable) | 503 | `EVENTS_UNAVAILABLE` | Ovok could not read the project's request-event service in time or the service is temporarily unavailable. | | [`feature-not-configured`](/errors/feature-not-configured) | 501 | `FEATURE_NOT_CONFIGURED` | The requested feature or integration is recognized but not configured or enabled in this deployment. | | [`from-required`](/errors/from-required) | 422 | `FROM_REQUIRED` | The configured email provider requires a sender address that the project does not have. | | [`invalid-link`](/errors/invalid-link) | 400 | `INVALID_LINK` | The verification link is invalid, expired, or already used. | | [`invalid-secret`](/errors/invalid-secret) | 422 | `INVALID_SECRET` | The supplied provider secret does not match the format accepted by the selected integration. | | [`invalid-setting-value`](/errors/invalid-setting-value) | 422 | `INVALID_SETTING_VALUE` | The supplied project setting is not valid for that setting's type or accepted values. | | [`invalid-signature`](/errors/invalid-signature) | 401 | `INVALID_SIGNATURE` | A wearable provider notification arrived without a valid signature or URL token. | | [`invalid-state`](/errors/invalid-state) | 422 | `INVALID_STATE` | The wearable authorization state is expired, already used, or bound to another provider or attempt. | | [`invalid-switch`](/errors/invalid-switch) | 400 | `INVALID_SWITCH` | The project-switch token is malformed, expired, used at the wrong step, or already completed. | | [`invalid-template-content`](/errors/invalid-template-content) | 422 | `INVALID_TEMPLATE_CONTENT` | Template content does not satisfy the selected email provider's requirements. | | [`invalid-template-id`](/errors/invalid-template-id) | 422 | `INVALID_TEMPLATE_ID` | The template identifier is invalid for the selected email provider. | | [`invitation-not-configured`](/errors/invitation-not-configured) | 409 | `INVITATION_NOT_CONFIGURED` | The project lacks a valid default access policy required for the invitation flow. | | [`live-reads-over-capacity`](/errors/live-reads-over-capacity) | 503 | `LIVE_READS_OVER_CAPACITY` | The server reached its concurrent live-read limit and shed the request. | | [`malformed-notification`](/errors/malformed-notification) | 400 | `MALFORMED_NOTIFICATION` | A wearable provider notification had a body that is neither a JSON object nor form fields. | | [`monthly-request-cap`](/errors/monthly-request-cap) | 429 | `MONTHLY_REQUEST_CAP` | The project has used its monthly API request allowance. | | [`no-subscription`](/errors/no-subscription) | 409 | `NO_SUBSCRIPTION` | There is no subscription on this billing customer to cancel. | | [`not-parent-project`](/errors/not-parent-project) | 403 | `NOT_PARENT_PROJECT` | This billing operation must be made from the parent project that owns the sub-project's billing. | | [`not-your-email`](/errors/not-your-email) | 403 | `NOT_YOUR_EMAIL` | The address in the project-switch request differs from the signed-in account. | | [`not-your-switch`](/errors/not-your-switch) | 403 | `NOT_YOUR_SWITCH` | Another session started or owns this project-switch flow. | | [`parent-project-has-no-access-policy`](/errors/parent-project-has-no-access-policy) | 424 | `PARENT_PROJECT_HAS_NO_ACCESS_POLICY` | The parent project lacks the default access policy required by this child-project operation. | | [`password-required`](/errors/password-required) | 422 | `PASSWORD_REQUIRED` | The invite creates a new carer account, and the request did not include the password to sign in with. | | [`patient-profile-required`](/errors/patient-profile-required) | 403 | `PATIENT_PROFILE_REQUIRED` | This wearable operation needs a patient session, but the current token does not identify a patient profile. | | [`plan-limit-reached`](/errors/plan-limit-reached) | 403 | `PLAN_LIMIT_REACHED` | The project reached a resource or feature limit in its current plan. | | [`practitioner-registration-not-configured`](/errors/practitioner-registration-not-configured) | 409 | `PRACTITIONER_REGISTRATION_NOT_CONFIGURED` | Practitioner registration is enabled but has no valid default access policy for new practitioners. | | [`practitioner-without-access-policy`](/errors/practitioner-without-access-policy) | 409 | `PRACTITIONER_WITHOUT_ACCESS_POLICY` | A share could grant broader access than intended because the practitioner has no access policy. | | [`project-context-required`](/errors/project-context-required) | 403 | `PROJECT_CONTEXT_REQUIRED` | The session has no project context for an operation scoped to one project. | | [`project-not-empty`](/errors/project-not-empty) | 409 | `PROJECT_NOT_EMPTY` | The child project still contains patients, devices, locations, or child projects and cannot be deleted. | | [`project-not-found`](/errors/project-not-found) | 404 | `PROJECT_NOT_FOUND` | The caller does not administer a project matching the requested tenant code, or a wearable webhook URL names a project that does not exist. | | [`provider-configured`](/errors/provider-configured) | 409 | `PROVIDER_CONFIGURED` | The provider is already configured, so a create operation cannot add another configuration. | | [`provider-mismatch`](/errors/provider-mismatch) | 409 | `PROVIDER_MISMATCH` | The template mapping provider does not match the provider configured for the project. | | [`provider-not-available`](/errors/provider-not-available) | 404 | `PROVIDER_NOT_AVAILABLE` | The wearable provider is unavailable or disabled for this project. | | [`provider-not-configured`](/errors/provider-not-configured) | 404 | `PROVIDER_NOT_CONFIGURED` | The requested email or wearable provider has not been set up for this project. | | [`provider-rate-limited`](/errors/provider-rate-limited) | 503 | `PROVIDER_RATE_LIMITED` | The wearable provider is limiting requests from the project's app. | | [`provider-unavailable`](/errors/provider-unavailable) | 502 | `PROVIDER_UNAVAILABLE` | The wearable provider failed, could not be reached, or answered something unreadable. | | [`reconnect-required`](/errors/reconnect-required) | 409 | `RECONNECT_REQUIRED` | The wearable provider no longer accepts the connection; the patient has to connect it again. | | [`related-person-without-access-policy`](/errors/related-person-without-access-policy) | 409 | `RELATED_PERSON_WITHOUT_ACCESS_POLICY` | A carer's membership has no access policy, so adding a share would narrow its access instead of extending it. | | [`sharing-not-configured`](/errors/sharing-not-configured) | 409 | `SHARING_NOT_CONFIGURED` | The project has no patient-sharing access policy, so a carer share cannot be granted. | | [`signals-audit-failed`](/errors/signals-audit-failed) | 503 | `SIGNALS_AUDIT_FAILED` | Ovok could not record an audit event, so the requested Signals change was not applied. | | [`signals-bad-request`](/errors/signals-bad-request) | 422 | `SIGNALS_BAD_REQUEST` | Signals rejected the alert query, or the cursor was not issued by this list operation. | | [`signals-code-invalid`](/errors/signals-code-invalid) | 422 | `SIGNALS_CODE_INVALID` | The vital-sign code is empty, malformed, too long, or contains unsupported characters. | | [`signals-episodes-disabled`](/errors/signals-episodes-disabled) | 409 | `SIGNALS_EPISODES_DISABLED` | Episodic alerts are disabled for the project's Signals tenant. | | [`signals-mint-failed`](/errors/signals-mint-failed) | 503 | `SIGNALS_MINT_FAILED` | Ovok could not provision the resident in Signals and rolled back the related resident creation. | | [`signals-patient-not-enrolled`](/errors/signals-patient-not-enrolled) | 409 | `SIGNALS_PATIENT_NOT_ENROLLED` | The resident is not enrolled in the Signals tenant needed for this operation. | | [`signals-project-migrating`](/errors/signals-project-migrating) | 409 | `SIGNALS_PROJECT_MIGRATING` | The project is moving to another Signals tenant, so tenant-dependent work is temporarily blocked. | | [`signals-shared-tenant`](/errors/signals-shared-tenant) | 409 | `SIGNALS_SHARED_TENANT` | The project uses a shared Signals tenant, so this setting affects every project on that tenant. | | [`signals-tenant-revoke-failed`](/errors/signals-tenant-revoke-failed) | 502 | `SIGNALS_TENANT_REVOKE_FAILED` | The child project was deleted but its Signals tenant could not be revoked. | | [`signals-tenant-unavailable`](/errors/signals-tenant-unavailable) | 503 | `SIGNALS_TENANT_UNAVAILABLE` | The project's Signals tenant is unreachable or not ready to serve the request. | | [`signals-threshold-not-editable`](/errors/signals-threshold-not-editable) | 409 | `SIGNALS_THRESHOLD_NOT_EDITABLE` | The threshold rule is not editable through this route, or a conflicting write is in progress. | | [`signals-unavailable`](/errors/signals-unavailable) | 503 | `SIGNALS_UNAVAILABLE` | Ovok did not get a timely response from Signals for this operation. | | [`signals-undo-failed`](/errors/signals-undo-failed) | 503 | `SIGNALS_UNDO_FAILED` | The Signals change could not be recorded or undone and requires operator reconciliation. | | [`signup-closed`](/errors/signup-closed) | 403 | `SIGNUP_CLOSED` | Public sign-up is closed on this deployment. | | [`state-store-unavailable`](/errors/state-store-unavailable) | 503 | `STATE_STORE_UNAVAILABLE` | Ovok's temporary wearable authorization-state store is unavailable. | | [`subscription-key-not-used`](/errors/subscription-key-not-used) | 422 | `SUBSCRIPTION_KEY_NOT_USED` | A subscription key was sent to a wearable provider that does not accept one. | | [`subscription-key-required`](/errors/subscription-key-required) | 422 | `SUBSCRIPTION_KEY_REQUIRED` | The wearable provider requires a subscription key that was not supplied. | | [`sync-failed`](/errors/sync-failed) | 500 | `SYNC_FAILED` | A wearable sync failed on Ovok's side; nothing was written. | | [`sync-in-progress`](/errors/sync-in-progress) | 409 | `SYNC_IN_PROGRESS` | A sync of this wearable connection is already running. | | [`sync-not-supported`](/errors/sync-not-supported) | 501 | `SYNC_NOT_SUPPORTED` | Ovok can connect this wearable provider but does not sync its data yet. | | [`sync-queue-unavailable`](/errors/sync-queue-unavailable) | 503 | `SYNC_QUEUE_UNAVAILABLE` | Ovok accepted a wearable provider notification but could not queue the sync it asks for. | | [`sync-too-soon`](/errors/sync-too-soon) | 429 | `SYNC_TOO_SOON` | The wearable connection synced less than 15 minutes ago. | | [`too-many-requests`](/errors/too-many-requests) | 429 | `TOO_MANY_REQUESTS` | The request rate exceeded an applicable Ovok limit. | | [`trace-not-found`](/errors/trace-not-found) | 404 | `TRACE_NOT_FOUND` | No request event for this project has the supplied trace identifier. | | [`transaction-too-large`](/errors/transaction-too-large) | 422 | `TRANSACTION_TOO_LARGE` | The FHIR transaction bundle exceeds Ovok's supported entry limit. | | [`unknown-setting`](/errors/unknown-setting) | 400 | `UNKNOWN_SETTING` | The setting name is not supported by this project-settings route. | | [`unknown-template`](/errors/unknown-template) | 400 | `UNKNOWN_TEMPLATE` | The template name is not in the supported template catalogue. | | [`vat-id-required`](/errors/vat-id-required) | 422 | `VAT_ID_REQUIRED` | The customer's region requires a VAT ID for this billing operation. | | [`webhook-not-supported`](/errors/webhook-not-supported) | 404 | `WEBHOOK_NOT_SUPPORTED` | Ovok takes no notifications from this wearable provider. | | [`webhook-secret-not-used`](/errors/webhook-secret-not-used) | 422 | `WEBHOOK_SECRET_NOT_USED` | A `webhookSecret` was sent for a wearable provider that does not take one. | FHIR routes return FHIR `OperationOutcome` resources; OAuth and MCP endpoints use their protocol error formats. These are not members of this Problem Details registry. See [FHIR OperationOutcome](/api/fhir/r4/operation-outcome), [refresh-token OAuth errors](/authentication/account/refresh-token), and the [MCP server troubleshooting guide](/working-with-ai-agents/mcp-server). # MALFORMED NOTIFICATION Canonical page: https://docs.ovok.com/errors/malformed-notification **HTTP 400.** Stable Problem Details type: [`https://docs.ovok.com/errors/malformed-notification`](https://docs.ovok.com/errors/malformed-notification). ## What this means [#what-this-means] A wearable provider notification had a body that is neither a JSON object nor form fields. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check that the provider's portal points at the `webhookUrl` Ovok shows, and not at another endpoint. Nothing needs to be done for a single failed notification; the daily sync still reads the data. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Webhook URLs](/wearables/set-up-providers#webhook-urls) - [Wearables webhooks](/wearables/api-reference#webhooks) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # MALFORMED_REQUEST Canonical page: https://docs.ovok.com/errors/malformed-request **HTTP 400.** Problem type: [`https://docs.ovok.com/errors/malformed-request`](https://docs.ovok.com/errors/malformed-request). ## What this means [#what-this-means] Ovok could not parse the request or the request does not match the format expected by the endpoint. This is different from a request whose parsed values fail business or field validation. ## Troubleshooting [#troubleshooting] Check that the URL and query string are correctly encoded, the JSON is valid, and each value uses the expected shape and type. Compare the method, path, required headers, and request fields with the endpoint documentation. Inspect `detail` and `errors` for a specific location; when they do not identify it, reduce the request to the smallest documented example and add fields back until the problem returns. ## Retry safely [#retry-safely] Correct the syntax or request format before sending it again. Do not retry unchanged input; use the [validation error guidance](/errors/validation-failed) when the request parses but a field value is invalid. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # METHOD_NOT_ALLOWED Canonical page: https://docs.ovok.com/errors/method-not-allowed **HTTP 405.** Problem type: [`https://docs.ovok.com/errors/method-not-allowed`](https://docs.ovok.com/errors/method-not-allowed). ## What this means [#what-this-means] The route was recognized, but it does not accept the HTTP method used for this request. ## Troubleshooting [#troubleshooting] Open the documentation for the exact route and confirm which operation and method it exposes. Check the final URL assembled by your client, including any base path or version prefix, and verify that a redirect, proxy, or wrapper has not changed the method. If you use an SDK, confirm that the method corresponds to the operation you intended. ## Retry safely [#retry-safely] Use a method documented for that route and make sure the request body matches that operation. Repeating the same method on the same route will not resolve a 405; do not guess methods when the endpoint documentation is available. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # MONTHLY REQUEST CAP Canonical page: https://docs.ovok.com/errors/monthly-request-cap **HTTP 429.** Stable Problem Details type: [`https://docs.ovok.com/errors/monthly-request-cap`](https://docs.ovok.com/errors/monthly-request-cap). ## What this means [#what-this-means] The project has used its monthly API request allowance. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Review usage window, plan and background polling. Use the returned `retryAfterSec`; reducing calls will not reset the current quota. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Slim API rate limits](/slim-apis#errors-on-every-route) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # NO SUBSCRIPTION Canonical page: https://docs.ovok.com/errors/no-subscription **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/no-subscription`](https://docs.ovok.com/errors/no-subscription). ## What this means [#what-this-means] There is no subscription on this billing customer to cancel. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Read current billing state and confirm the customer and parent project. It may already be cancelled or owned by a parent. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # NOT_ACCEPTABLE Canonical page: https://docs.ovok.com/errors/not-acceptable **HTTP 406.** Problem type: [`https://docs.ovok.com/errors/not-acceptable`](https://docs.ovok.com/errors/not-acceptable). ## What this means [#what-this-means] The server cannot return a representation accepted by the request. This usually points to response content negotiation, rather than the media type of the request body. ## Troubleshooting [#troubleshooting] Inspect the outgoing `Accept` header and compare it with the response formats documented for the endpoint. Check whether your HTTP library or API gateway added a restrictive value or requested a format the caller cannot parse. Keep `Accept` separate from `Content-Type`: the former describes the response you accept; the latter describes the body you send. ## Retry safely [#retry-safely] Request a documented response format and retry. If you do not need a special representation, remove the custom `Accept` restriction according to your client's configuration; changing the request body's `Content-Type` alone does not fix this error. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # NOT_FOUND Canonical page: https://docs.ovok.com/errors/not-found **HTTP 404.** Problem type: [`https://docs.ovok.com/errors/not-found`](https://docs.ovok.com/errors/not-found). ## What this means [#what-this-means] The requested route or resource could not be found. Some endpoints may also use this response when the caller cannot see a resource, so it does not always prove that the identifier is absent. ## Troubleshooting [#troubleshooting] Check the base URL, route, version prefix, identifier, and active project or environment. Compare the path with the endpoint documentation and verify that the resource was created in the same context. If the identifier appears correct, ask an administrator to confirm your access rather than assuming the resource is safe to recreate. ## Retry safely [#retry-safely] Correct the route or identifier, or use the documented workflow to create a resource only after confirming that no existing resource should be used. Repeating the same lookup will not help if the path, project, or identifier is unchanged. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # NOT_IMPLEMENTED Canonical page: https://docs.ovok.com/errors/not-implemented **HTTP 501.** Problem type: [`https://docs.ovok.com/errors/not-implemented`](https://docs.ovok.com/errors/not-implemented). ## What this means [#what-this-means] The requested operation or integration is unavailable in this deployment. A configured endpoint-specific machine code may instead identify a feature that is not configured; see [feature not configured](/errors/feature-not-configured). ## Troubleshooting [#troubleshooting] Confirm that the route and operation appear in the documentation for the API version and deployment you are using. Check that your client is not calling an operation from a newer or different API. If the operation should be available in this environment, ask the project administrator whether deployment configuration or feature availability differs from your expectation. ## Retry safely [#retry-safely] Do not retry until the operation is supported in the target deployment or the endpoint instructions identify a corrective setup step. A request with the same route and body cannot enable an unimplemented operation. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # NOT PARENT PROJECT Canonical page: https://docs.ovok.com/errors/not-parent-project **HTTP 403.** Stable Problem Details type: [`https://docs.ovok.com/errors/not-parent-project`](https://docs.ovok.com/errors/not-parent-project). ## What this means [#what-this-means] This billing operation must be made from the parent project that owns the sub-project's billing. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check the project hierarchy and use an authorized administrator session for its billing parent. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # NOT YOUR EMAIL Canonical page: https://docs.ovok.com/errors/not-your-email **HTTP 403.** Stable Problem Details type: [`https://docs.ovok.com/errors/not-your-email`](https://docs.ovok.com/errors/not-your-email). ## What this means [#what-this-means] The address in the project-switch request differs from the signed-in account. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Sign in as the account that owns the target address. Check for aliases or unverified address changes. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # NOT YOUR SWITCH Canonical page: https://docs.ovok.com/errors/not-your-switch **HTTP 403.** Stable Problem Details type: [`https://docs.ovok.com/errors/not-your-switch`](https://docs.ovok.com/errors/not-your-switch). ## What this means [#what-this-means] Another session started or owns this project-switch flow. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Return to the initiating browser session. A newer attempt from another tab or device can invalidate the old token. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PARENT PROJECT HAS NO ACCESS POLICY Canonical page: https://docs.ovok.com/errors/parent-project-has-no-access-policy **HTTP 424.** Stable Problem Details type: [`https://docs.ovok.com/errors/parent-project-has-no-access-policy`](https://docs.ovok.com/errors/parent-project-has-no-access-policy). ## What this means [#what-this-means] The parent project lacks the default access policy required by this child-project operation. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check the parent project's policy configuration, not only the child. Ask a parent administrator to create or select a valid default. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PASSWORD REQUIRED Canonical page: https://docs.ovok.com/errors/password-required **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/password-required`](https://docs.ovok.com/errors/password-required). ## What this means [#what-this-means] Accepting a carer invite for an address with no account makes the account, so it needs a `password`. The request sent `null` or left it out. The code was valid; nothing was written. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Show a "choose a password" form and post the same `inviteId` and `code` again with `password`. Apps can use this answer on purpose to decide which form to show. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Share readings with a carer](/invitations/share-with-a-carer#which-form-to-show) - [Carers](/authentication/carers) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PATIENT PROFILE REQUIRED Canonical page: https://docs.ovok.com/errors/patient-profile-required **HTTP 403.** Stable Problem Details type: [`https://docs.ovok.com/errors/patient-profile-required`](https://docs.ovok.com/errors/patient-profile-required). ## What this means [#what-this-means] This wearable operation needs a patient session, but the current token does not identify a patient profile. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Sign in through the patient-facing flow and verify the token has patient and project context. Practitioner tokens cannot substitute. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Connect a patient's wearable](/wearables/connect-a-patient) - [Wearables API reference](/wearables/api-reference#patient-connections) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PLAN LIMIT REACHED Canonical page: https://docs.ovok.com/errors/plan-limit-reached **HTTP 403.** Stable Problem Details type: [`https://docs.ovok.com/errors/plan-limit-reached`](https://docs.ovok.com/errors/plan-limit-reached). ## What this means [#what-this-means] The project reached a resource or feature limit in its current plan. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Read the resource type and limit, then check whether existing usage can safely be reduced or the plan changed. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PRACTITIONER REGISTRATION NOT CONFIGURED Canonical page: https://docs.ovok.com/errors/practitioner-registration-not-configured **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/practitioner-registration-not-configured`](https://docs.ovok.com/errors/practitioner-registration-not-configured). ## What this means [#what-this-means] Practitioner registration is enabled but has no valid default access policy for new practitioners. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Review registration and its default policy together. Confirm the policy still exists in this project and is least-privilege. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Practitioner registration](/authentication/practitioner-registration) - [Default practitioner access policy](/settings-and-features/settings/default-practitioner-access-policy) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PRACTITIONER WITHOUT ACCESS POLICY Canonical page: https://docs.ovok.com/errors/practitioner-without-access-policy **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/practitioner-without-access-policy`](https://docs.ovok.com/errors/practitioner-without-access-policy). ## What this means [#what-this-means] A share could grant broader access than intended because the practitioner has no access policy. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Review the recipient's membership and assign an appropriate policy before sharing. This protects against misleading narrow-share semantics. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Share with a practitioner](/invitations/share-with-practitioner) - [Team members](/invitations/team-members) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PRECONDITION_FAILED Canonical page: https://docs.ovok.com/errors/precondition-failed **HTTP 412.** Problem type: [`https://docs.ovok.com/errors/precondition-failed`](https://docs.ovok.com/errors/precondition-failed). ## What this means [#what-this-means] A condition included with the request no longer matches the resource's current state. The precondition prevented the operation from applying against stale or unexpected data. ## Troubleshooting [#troubleshooting] Read the resource again and compare its current version or other documented condition with the value sent in the request. Identify changes made since that value was obtained, then reconcile them with the change you intended. Do not remove the precondition simply to force the update; it protects against overwriting newer data. ## Retry safely [#retry-safely] Build a new request using the current condition specified by the endpoint documentation and submit it once. If the condition fails again, another update may be occurring; reread and reconcile before trying again. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # PRECONDITION_REQUIRED Canonical page: https://docs.ovok.com/errors/precondition-required **HTTP 428.** Problem type: [`https://docs.ovok.com/errors/precondition-required`](https://docs.ovok.com/errors/precondition-required). ## What this means [#what-this-means] The endpoint requires a precondition, but the request did not include one. This requirement lets the endpoint check that the operation is based on an appropriate resource state. ## Troubleshooting [#troubleshooting] Consult the endpoint documentation to find which condition is required and how to obtain its current value. Read the resource or version information using the documented method, then check that your client preserves and sends the condition with the update. Do not assume that a specific header or field is required unless the endpoint says so. ## Retry safely [#retry-safely] Include the required current condition and send the request again. Do not remove the endpoint's precondition requirement or substitute a guessed value; use [precondition failed](/errors/precondition-failed) if the supplied condition is rejected as stale. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # PROJECT CONTEXT REQUIRED Canonical page: https://docs.ovok.com/errors/project-context-required **HTTP 403.** Stable Problem Details type: [`https://docs.ovok.com/errors/project-context-required`](https://docs.ovok.com/errors/project-context-required). ## What this means [#what-this-means] The session has no project context for an operation scoped to one project. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Select the intended project and obtain a project-bound token. A valid global or service token can still lack project context. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Authentication](/authentication) - [Project setup](/authentication/project-setup) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PROJECT NOT EMPTY Canonical page: https://docs.ovok.com/errors/project-not-empty **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/project-not-empty`](https://docs.ovok.com/errors/project-not-empty). ## What this means [#what-this-means] The child project still contains patients, devices, locations, or child projects and cannot be deleted. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Review returned counts and child IDs. Move or remove dependencies using supported workflows, then check state before retrying deletion. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Delete a child project](/projects/delete-sub-project) - [Slim API child-project deletion](/slim-apis/project/delete-a-child-project) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PROJECT NOT FOUND Canonical page: https://docs.ovok.com/errors/project-not-found **HTTP 404.** Stable Problem Details type: [`https://docs.ovok.com/errors/project-not-found`](https://docs.ovok.com/errors/project-not-found). ## What this means [#what-this-means] The caller does not administer a project matching the requested tenant code, or a wearable webhook URL names a project that does not exist. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check the code and signed-in account. A project outside the caller's administration scope is not discoverable here. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Project administration](/projects) - [Wearables webhooks](/wearables/api-reference#webhooks) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PROVIDER CONFIGURED Canonical page: https://docs.ovok.com/errors/provider-configured **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/provider-configured`](https://docs.ovok.com/errors/provider-configured). ## What this means [#what-this-means] The provider is already configured, so a create operation cannot add another configuration. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Read current provider state and use the update route for changes. Another administrator may have finished setup. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Email provider setup](/email-templates/set-up-email) - [Set up wearable providers](/wearables/set-up-providers) - [Wearables API reference](/wearables/api-reference#provider-setup) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PROVIDER MISMATCH Canonical page: https://docs.ovok.com/errors/provider-mismatch **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/provider-mismatch`](https://docs.ovok.com/errors/provider-mismatch). ## What this means [#what-this-means] The template mapping provider does not match the provider configured for the project. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Read provider and mapping together, including language and domain. Do not assume mappings transfer between provider implementations. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Map email templates](/email-templates/map-templates) - [Email troubleshooting](/email-templates/troubleshooting) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PROVIDER NOT AVAILABLE Canonical page: https://docs.ovok.com/errors/provider-not-available **HTTP 404.** Stable Problem Details type: [`https://docs.ovok.com/errors/provider-not-available`](https://docs.ovok.com/errors/provider-not-available). ## What this means [#what-this-means] The wearable provider is unavailable or disabled for this project. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check deployment support and project provider settings. A supported but disabled provider must be enabled before use. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Connect a patient's wearable](/wearables/connect-a-patient) - [Wearables API reference](/wearables/api-reference#patient-connections) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PROVIDER NOT CONFIGURED Canonical page: https://docs.ovok.com/errors/provider-not-configured **HTTP 404.** Stable Problem Details type: [`https://docs.ovok.com/errors/provider-not-configured`](https://docs.ovok.com/errors/provider-not-configured). ## What this means [#what-this-means] The requested email or wearable provider has not been set up for this project. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Confirm the provider expected by the route and complete its setup before reading or changing provider-specific configuration. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Set up email](/email-templates/set-up-email) - [Email troubleshooting](/email-templates/troubleshooting) - [Set up wearable providers](/wearables/set-up-providers) - [Wearables API reference](/wearables/api-reference#provider-setup) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PROVIDER RATE LIMITED Canonical page: https://docs.ovok.com/errors/provider-rate-limited **HTTP 503.** Stable Problem Details type: [`https://docs.ovok.com/errors/provider-rate-limited`](https://docs.ovok.com/errors/provider-rate-limited). ## What this means [#what-this-means] The wearable provider is limiting requests from the project's app. Nothing was written and `syncedThrough` did not move. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Wait the number of seconds in the `Retry-After` header, which carries the provider's own delay, before syncing again. If it happens often, review your app's rate limits at the provider. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Sync a connection](/wearables/api-reference#sync-a-connection) - [Sync and read wearable data](/wearables/sync-and-read-data) ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # PROVIDER UNAVAILABLE Canonical page: https://docs.ovok.com/errors/provider-unavailable **HTTP 502.** Stable Problem Details type: [`https://docs.ovok.com/errors/provider-unavailable`](https://docs.ovok.com/errors/provider-unavailable). ## What this means [#what-this-means] The wearable provider failed, could not be reached, or answered something Ovok could not read. Nothing was written and `syncedThrough` did not move. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Try again later; the daily sync also retries, and the next sync covers the missed days within the 30-day window. Check the provider's status page if it lasts. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Sync a connection](/wearables/api-reference#sync-a-connection) - [Sync and read wearable data](/wearables/sync-and-read-data) ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # RECONNECT REQUIRED Canonical page: https://docs.ovok.com/errors/reconnect-required **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/reconnect-required`](https://docs.ovok.com/errors/reconnect-required). ## What this means [#what-this-means] The provider no longer accepts this wearable connection, for example because the patient removed the app's access in their provider account or the provider revoked the grant. Ovok stops syncing it until the patient connects again. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Ask the patient to connect the provider again with `POST /v1/wearables/connections//authorize`; a new connection clears the flag. Until then, `GET /v1/wearables/connections` shows `reconnectRequired: true`. Syncing again without reconnecting returns the same error. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Sync a connection](/wearables/api-reference#sync-a-connection) - [Sync and read wearable data](/wearables/sync-and-read-data) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # RELATED PERSON WITHOUT ACCESS POLICY Canonical page: https://docs.ovok.com/errors/related-person-without-access-policy **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/related-person-without-access-policy`](https://docs.ovok.com/errors/related-person-without-access-policy). ## What this means [#what-this-means] A membership with no AccessPolicy reaches the whole project. A carer membership always gets Ovok's built-in carer policy, so this means the membership was changed by hand. Ovok refuses to add the share rather than change what the account can reach. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Ask a project admin to restore the carer's membership with its built-in policy, or remove the membership and have the patient invite the carer again. Do not give a carer membership full project access. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Carers](/authentication/carers) - [Share readings with a carer](/invitations/share-with-a-carer) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # REQUEST_TIMEOUT Canonical page: https://docs.ovok.com/errors/request-timeout **HTTP 408.** Problem type: [`https://docs.ovok.com/errors/request-timeout`](https://docs.ovok.com/errors/request-timeout). ## What this means [#what-this-means] The request did not complete within the server's time limit. The timeout response alone may not establish whether a state-changing operation completed, so verify the outcome before replaying it. ## Troubleshooting [#troubleshooting] Check whether the client or gateway also applied a shorter timeout, and note the affected route and request time. For a write, read the resource or check the documented operation status to see whether the change took effect. If the same read-only request repeatedly times out, reduce unnecessary response data where the endpoint supports it and report the `traceId`. ## Retry safely [#retry-safely] Retry a read or other safe operation after a short delay, with a bounded retry policy. Before repeating a write, confirm its current result and follow any endpoint-specific deduplication guidance. Avoid simultaneous retries of the same timed-out operation. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # SERVER_ERROR Canonical page: https://docs.ovok.com/errors/server-error **Fallback for an unmapped 5xx response.** Problem type: [`https://docs.ovok.com/errors/server-error`](https://docs.ovok.com/errors/server-error). ## What this means [#what-this-means] The request received a server-side error, but no more specific status-based problem page applies. Use the HTTP `status`, problem `type`, and response details to distinguish this from a specific upstream or service-availability error. ## Troubleshooting [#troubleshooting] Record the response status, `type`, request path, timestamp, and `traceId`. If the request changed data, inspect the resource or operation status before replaying it. Check whether the issue affects one route or multiple requests and whether a later request succeeds; this helps an administrator locate a transient or recurring failure. ## Retry safely [#retry-safely] Retry only when the operation is safe to repeat, using a bounded delay between attempts. Avoid rapid retry loops and verify the result before replaying writes. If the error persists, stop retrying until the issue is understood. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # SERVICE_UNAVAILABLE Canonical page: https://docs.ovok.com/errors/service-unavailable **HTTP 503.** Problem type: [`https://docs.ovok.com/errors/service-unavailable`](https://docs.ovok.com/errors/service-unavailable). ## What this means [#what-this-means] Ovok or a required upstream service is temporarily unavailable or at capacity. The service may recover without a change to your request. ## Troubleshooting [#troubleshooting] Check whether the response includes a `Retry-After` header and whether the failure is limited to one endpoint or affects several calls. Avoid increasing request concurrency while the service is unavailable. For a state-changing request, check the resource or operation status before sending it again. ## Retry safely [#retry-safely] Honor `Retry-After` when it is present. Otherwise use a bounded backoff with a delay between attempts, and retry only an operation that is safe to repeat. If service remains unavailable, stop retrying until it recovers. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # SHARING NOT CONFIGURED Canonical page: https://docs.ovok.com/errors/sharing-not-configured **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/sharing-not-configured`](https://docs.ovok.com/errors/sharing-not-configured). ## What this means [#what-this-means] Patient sharing creates a read-only AccessPolicy that every carer share points at. The project's reference to it is missing, so the share cannot be added to the carer's membership. Nothing was written. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Ask a project admin to turn patient sharing on again with `PUT /v1/patient-sharing/settings` and `{"enabled": true}`. That recreates the policy. Then accept the invite again; it stays valid until it expires. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [PATIENT_SHARING_ENABLED](/settings-and-features/settings/patient-sharing-enabled) - [Share readings with a carer](/invitations/share-with-a-carer) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS AUDIT FAILED Canonical page: https://docs.ovok.com/errors/signals-audit-failed **HTTP 503.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-audit-failed`](https://docs.ovok.com/errors/signals-audit-failed). ## What this means [#what-this-means] Ovok could not record an audit event, so the requested Signals change was not applied. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Preserve `traceId` and read the setting to confirm it stayed unchanged. Check audit storage health before retrying the write. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] The routes that answered this error were removed with Ovok's `/v1/signals` API. A new Signals API is being designed; see [Working with Signals](/signals/connected-ovok). ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS BAD REQUEST Canonical page: https://docs.ovok.com/errors/signals-bad-request **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-bad-request`](https://docs.ovok.com/errors/signals-bad-request). ## What this means [#what-this-means] Signals rejected the alert query, or the cursor was not issued by this list operation. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Pass back the exact opaque cursor from the same list and project. Otherwise check supported filters and query encodings. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] The routes that answered this error were removed with Ovok's `/v1/signals` API. A new Signals API is being designed; see [Working with Signals](/signals/connected-ovok). ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS CODE INVALID Canonical page: https://docs.ovok.com/errors/signals-code-invalid **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-code-invalid`](https://docs.ovok.com/errors/signals-code-invalid). ## What this means [#what-this-means] The vital-sign code is empty, malformed, too long, or contains unsupported characters. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Use a supported threshold code, remove spaces and slashes, and avoid sending a display label or a list to a single-code route. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] The routes that answered this error were removed with Ovok's `/v1/signals` API. A new Signals API is being designed; see [Working with Signals](/signals/connected-ovok). ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS EPISODES DISABLED Canonical page: https://docs.ovok.com/errors/signals-episodes-disabled **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-episodes-disabled`](https://docs.ovok.com/errors/signals-episodes-disabled). ## What this means [#what-this-means] Episodic alerts are disabled for the project's Signals tenant. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Ask the project or tenant administrator whether alerts should be enabled. Shared-tenant settings can affect several projects. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] The routes that answered this error were removed with Ovok's `/v1/signals` API. A new Signals API is being designed; see [Working with Signals](/signals/connected-ovok). ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS MINT FAILED Canonical page: https://docs.ovok.com/errors/signals-mint-failed **HTTP 503.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-mint-failed`](https://docs.ovok.com/errors/signals-mint-failed). ## What this means [#what-this-means] Ovok could not provision the resident in Signals and rolled back the related resident creation. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check the trace with an administrator and verify there is no partial patient. Confirm Signals availability and project-to-tenant configuration. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Create a patient](/slim-apis/patient/create-patient) - [Enable a patient in Signals](/signals/enable-signals-patient) ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS PATIENT NOT ENROLLED Canonical page: https://docs.ovok.com/errors/signals-patient-not-enrolled **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-patient-not-enrolled`](https://docs.ovok.com/errors/signals-patient-not-enrolled). ## What this means [#what-this-means] The resident is not enrolled in the Signals tenant needed for this operation. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Confirm project membership and completion of enrollment. An Ovok patient record alone does not prove Signals enrollment has finished. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Enable a patient in Signals](/signals/enable-signals-patient) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS PROJECT MIGRATING Canonical page: https://docs.ovok.com/errors/signals-project-migrating **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-project-migrating`](https://docs.ovok.com/errors/signals-project-migrating). ## What this means [#what-this-means] The project is moving to another Signals tenant, so tenant-dependent work is temporarily blocked. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check migration state with an administrator and avoid tenant-setting changes while the move runs. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Signals tenant connection](/signals/connected-ovok) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS SHARED TENANT Canonical page: https://docs.ovok.com/errors/signals-shared-tenant **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-shared-tenant`](https://docs.ovok.com/errors/signals-shared-tenant). ## What this means [#what-this-means] The project uses a shared Signals tenant, so this setting affects every project on that tenant. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Confirm the change is safe across projects and coordinate with the tenant owner. Use supported migration for project-specific settings. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Signals connection](/signals/connected-ovok) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS TENANT REVOKE FAILED Canonical page: https://docs.ovok.com/errors/signals-tenant-revoke-failed **HTTP 502.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-tenant-revoke-failed`](https://docs.ovok.com/errors/signals-tenant-revoke-failed). ## What this means [#what-this-means] The child project was deleted but its Signals tenant could not be revoked. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Treat deletion and tenant cleanup separately. Use `traceId` to inspect revocation state before retrying cleanup. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Delete a child project](/projects/delete-sub-project) ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS TENANT UNAVAILABLE Canonical page: https://docs.ovok.com/errors/signals-tenant-unavailable **HTTP 503.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-tenant-unavailable`](https://docs.ovok.com/errors/signals-tenant-unavailable). ## What this means [#what-this-means] The project's Signals tenant is unreachable or not ready to serve the request. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check tenant health and project assignment. Use `Retry-After` if provided; do not treat the response as missing patient data. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Signals connection and status](/signals/connected-ovok) ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS THRESHOLD NOT EDITABLE Canonical page: https://docs.ovok.com/errors/signals-threshold-not-editable **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-threshold-not-editable`](https://docs.ovok.com/errors/signals-threshold-not-editable). ## What this means [#what-this-means] The threshold rule is not editable through this route, or a conflicting write is in progress. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Read the effective rule and source. Confirm ownership, code and whether another update is still running. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] The routes that answered this error were removed with Ovok's `/v1/signals` API. A new Signals API is being designed; see [Working with Signals](/signals/connected-ovok). ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS UNAVAILABLE Canonical page: https://docs.ovok.com/errors/signals-unavailable **HTTP 503.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-unavailable`](https://docs.ovok.com/errors/signals-unavailable). ## What this means [#what-this-means] Ovok did not get a timely response from Signals for this operation. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Use `Retry-After` or `retryAfterSec`, identify whether one tenant or all Signals reads fail, and do not interpret this as an empty result. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Medical notifications](/slim-apis/notifications/list-medical-notifications) ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNALS UNDO FAILED Canonical page: https://docs.ovok.com/errors/signals-undo-failed **HTTP 503.** Stable Problem Details type: [`https://docs.ovok.com/errors/signals-undo-failed`](https://docs.ovok.com/errors/signals-undo-failed). ## What this means [#what-this-means] The Signals change could not be recorded or undone and requires operator reconciliation. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Stop repeating the write. Preserve `traceId` and ask an administrator to inspect rollback and audit state. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] The routes that answered this error were removed with Ovok's `/v1/signals` API. A new Signals API is being designed; see [Working with Signals](/signals/connected-ovok). ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SIGNUP CLOSED Canonical page: https://docs.ovok.com/errors/signup-closed **HTTP 403.** Stable Problem Details type: [`https://docs.ovok.com/errors/signup-closed`](https://docs.ovok.com/errors/signup-closed). ## What this means [#what-this-means] Public sign-up is closed on this deployment. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check the environment and use its supported invitation or sign-up flow. Public sign-up may be limited to the sandbox. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Patient registration](/authentication/patient-registration) - [Practitioner registration](/authentication/practitioner-registration) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # STATE STORE UNAVAILABLE Canonical page: https://docs.ovok.com/errors/state-store-unavailable **HTTP 503.** Stable Problem Details type: [`https://docs.ovok.com/errors/state-store-unavailable`](https://docs.ovok.com/errors/state-store-unavailable). ## What this means [#what-this-means] Ovok's temporary wearable authorization-state store is unavailable. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Preserve trace ID but never expose the state token. After recovery, start a new authorization rather than replaying an old callback. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Connect a patient's wearable](/wearables/connect-a-patient) - [Wearables OAuth callback](/wearables/api-reference#oauth-callback) ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SUBSCRIPTION KEY NOT USED Canonical page: https://docs.ovok.com/errors/subscription-key-not-used **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/subscription-key-not-used`](https://docs.ovok.com/errors/subscription-key-not-used). ## What this means [#what-this-means] A subscription key was sent to a wearable provider that does not accept one. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check the selected provider and omit `subscriptionKey` unless its setup guide requires it. Do not mix provider-specific fields. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Set up wearable providers](/wearables/set-up-providers) - [Wearables API reference](/wearables/api-reference#provider-setup) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SUBSCRIPTION KEY REQUIRED Canonical page: https://docs.ovok.com/errors/subscription-key-required **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/subscription-key-required`](https://docs.ovok.com/errors/subscription-key-required). ## What this means [#what-this-means] The wearable provider requires a subscription key that was not supplied. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Obtain the key from the correct provider account and environment. Store it as a secret and send it in the documented field only. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Set up wearable providers](/wearables/set-up-providers) - [Wearables API reference](/wearables/api-reference#provider-setup) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SYNC FAILED Canonical page: https://docs.ovok.com/errors/sync-failed **HTTP 500.** Stable Problem Details type: [`https://docs.ovok.com/errors/sync-failed`](https://docs.ovok.com/errors/sync-failed). ## What this means [#what-this-means] A wearable sync failed on Ovok's side. Nothing was written and `syncedThrough` did not move, so the next sync reads the same window again. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Try again later; the daily sync also retries. If it keeps failing for one provider across patients, the project's app at the provider may be misconfigured, for example a rotated client secret: check the provider's credentials in the console. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Sync a connection](/wearables/api-reference#sync-a-connection) - [Sync and read wearable data](/wearables/sync-and-read-data) ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SYNC IN PROGRESS Canonical page: https://docs.ovok.com/errors/sync-in-progress **HTTP 409.** Stable Problem Details type: [`https://docs.ovok.com/errors/sync-in-progress`](https://docs.ovok.com/errors/sync-in-progress). ## What this means [#what-this-means] A sync of this wearable connection is already running, either an earlier on-demand sync or the daily sync. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Wait for the running sync to finish, then read `GET /v1/wearables/connections`: `syncedThrough` moves when it completes. Do not start a second sync from another device or tab. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Sync a connection](/wearables/api-reference#sync-a-connection) - [Sync and read wearable data](/wearables/sync-and-read-data) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SYNC NOT SUPPORTED Canonical page: https://docs.ovok.com/errors/sync-not-supported **HTTP 501.** Stable Problem Details type: [`https://docs.ovok.com/errors/sync-not-supported`](https://docs.ovok.com/errors/sync-not-supported). ## What this means [#what-this-means] Ovok can connect this wearable provider but does not sync its data yet. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Keep the connection: it is used once sync for the provider is available. Check the [provider matrix](/wearables) for what each provider syncs today, and hide the sync action for this provider in your app. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Sync a connection](/wearables/api-reference#sync-a-connection) - [Sync and read wearable data](/wearables/sync-and-read-data) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SYNC QUEUE UNAVAILABLE Canonical page: https://docs.ovok.com/errors/sync-queue-unavailable **HTTP 503.** Stable Problem Details type: [`https://docs.ovok.com/errors/sync-queue-unavailable`](https://docs.ovok.com/errors/sync-queue-unavailable). ## What this means [#what-this-means] Ovok accepted a wearable provider notification but could not queue the sync it asks for. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] The provider retries the notification; the daily sync is the backstop. If it lasts, contact Ovok support. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Webhook URLs](/wearables/set-up-providers#webhook-urls) - [Wearables webhooks](/wearables/api-reference#webhooks) ## Retry safely [#retry-safely] For a 5xx response, wait for `Retry-After` when present and retry with bounded backoff. Before replaying a write, read the affected resource or operation state to avoid duplicate effects. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # SYNC TOO SOON Canonical page: https://docs.ovok.com/errors/sync-too-soon **HTTP 429.** Stable Problem Details type: [`https://docs.ovok.com/errors/sync-too-soon`](https://docs.ovok.com/errors/sync-too-soon). ## What this means [#what-this-means] The wearable connection synced less than 15 minutes ago. Ovok did not contact the provider. The cooldown counts from the connection's `syncedThrough`, so it also applies right after the daily sync. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Wait the number of seconds in the `Retry-After` header before syncing again, or rely on the daily sync. Disable the app's sync button for that long rather than retrying automatically. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Sync a connection](/wearables/api-reference#sync-a-connection) - [Sync and read wearable data](/wearables/sync-and-read-data) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # TOO_MANY_REQUESTS Canonical page: https://docs.ovok.com/errors/too-many-requests **HTTP 429.** Problem type: [`https://docs.ovok.com/errors/too-many-requests`](https://docs.ovok.com/errors/too-many-requests). ## What this means [#what-this-means] The request rate is above the current limit. Sending more requests immediately can prolong the interruption, especially when multiple workers retry together. ## Troubleshooting [#troubleshooting] Check for a `Retry-After` response header and review how quickly your application is sending requests, including parallel workers and automatic client retries. Reduce concurrency or queue non-urgent work so that retries do not create another burst. If 429 responses continue at a low request rate, ask an administrator to review the applicable endpoint or deployment limits. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Slim API rate limits](/slim-apis#errors-on-every-route) ## Retry safely [#retry-safely] Wait for `Retry-After` when present; otherwise back off before retrying. Use bounded attempts and retry only operations that are safe to repeat. For writes, verify the result or use the endpoint's documented deduplication mechanism before replaying a request. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # TRACE NOT FOUND Canonical page: https://docs.ovok.com/errors/trace-not-found **HTTP 404.** Stable Problem Details type: [`https://docs.ovok.com/errors/trace-not-found`](https://docs.ovok.com/errors/trace-not-found). ## What this means [#what-this-means] No request event for this project has the supplied trace identifier. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Check the ID, original response, timestamp and project that handled the request. Events can be project-scoped or outside retention. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # TRANSACTION TOO LARGE Canonical page: https://docs.ovok.com/errors/transaction-too-large **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/transaction-too-large`](https://docs.ovok.com/errors/transaction-too-large). ## What this means [#what-this-means] The FHIR transaction bundle exceeds Ovok's supported entry limit. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Count entries and divide the bundle into dependency-safe transactions. Keep references resolvable and verify each result before continuing. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Transaction bundles](/settings-and-features/features/transaction-bundles) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # UNAUTHENTICATED Canonical page: https://docs.ovok.com/errors/unauthenticated **HTTP 401.** Problem type: [`https://docs.ovok.com/errors/unauthenticated`](https://docs.ovok.com/errors/unauthenticated). ## What this means [#what-this-means] The request did not include credentials that Ovok accepts. The token may be missing, expired, invalid, or intended for a different environment. ## Troubleshooting [#troubleshooting] Check that the request includes the current access token using the authentication scheme required by the API, and confirm that your client is calling the intended environment. If the token may have expired, refresh it or sign in again using the documented authentication flow. Check that a proxy or client wrapper has not removed the authorization header. ## Retry safely [#retry-safely] Obtain valid credentials and send the request again. Do not retry repeatedly with the same rejected token, and never include the token itself in logs, screenshots, or a support report. If fresh credentials still receive 401, ask an administrator to check the authentication setup. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # UNKNOWN SETTING Canonical page: https://docs.ovok.com/errors/unknown-setting **HTTP 400.** Stable Problem Details type: [`https://docs.ovok.com/errors/unknown-setting`](https://docs.ovok.com/errors/unknown-setting). ## What this means [#what-this-means] The setting name is not supported by this project-settings route. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Use the accepted keys in the response with exact spelling and call the matching boolean or text setting endpoint. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Settings and features](/settings-and-features) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # UNKNOWN TEMPLATE Canonical page: https://docs.ovok.com/errors/unknown-template **HTTP 400.** Stable Problem Details type: [`https://docs.ovok.com/errors/unknown-template`](https://docs.ovok.com/errors/unknown-template). ## What this means [#what-this-means] The template name is not in the supported template catalogue. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Use an accepted name from the response. A template name differs from a provider's external template ID. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Email template catalogue](/email-templates/template-catalogue) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # UNSUPPORTED_MEDIA_TYPE Canonical page: https://docs.ovok.com/errors/unsupported-media-type **HTTP 415.** Problem type: [`https://docs.ovok.com/errors/unsupported-media-type`](https://docs.ovok.com/errors/unsupported-media-type). ## What this means [#what-this-means] The request body uses a media type the endpoint does not accept. This concerns the format of the content you send, rather than the format you asked the server to return. ## Troubleshooting [#troubleshooting] Inspect the request's `Content-Type` header and compare it with the endpoint documentation. Confirm that the serialized body matches that media type and that the header was not inherited from a different request. For example, JSON text should not be labeled as a different body format. Use `Accept` guidance separately for response format errors. ## Retry safely [#retry-safely] Set `Content-Type` to a documented media type and send a body encoded in that format. Do not resend the same body under a guessed content type; see [not acceptable](/errors/not-acceptable) for errors about the requested response representation. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # UPSTREAM_ERROR Canonical page: https://docs.ovok.com/errors/upstream-error **HTTP 502.** Problem type: [`https://docs.ovok.com/errors/upstream-error`](https://docs.ovok.com/errors/upstream-error). ## What this means [#what-this-means] An upstream service returned a response Ovok could not use or could not be reached. This points to communication between Ovok and a dependency, not necessarily to invalid request fields. ## Troubleshooting [#troubleshooting] Check whether the failing operation depends on an external integration or other upstream service, and whether the endpoint documents a status or recovery procedure for it. Note whether the failure is intermittent or limited to one integration. Before repeating a write, inspect the resource or operation status because the upstream may have processed the request even if Ovok could not return a usable response. ## Retry safely [#retry-safely] For a safe operation, wait briefly and retry with a bounded backoff. Do not send repeated concurrent attempts. If the failure persists, stop retrying until the upstream service is checked. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # UPSTREAM_TIMEOUT Canonical page: https://docs.ovok.com/errors/upstream-timeout **HTTP 504.** Problem type: [`https://docs.ovok.com/errors/upstream-timeout`](https://docs.ovok.com/errors/upstream-timeout). ## What this means [#what-this-means] A required upstream service did not answer before the request deadline. The timeout does not by itself tell you whether the upstream completed a state-changing action. ## Troubleshooting [#troubleshooting] Check the affected endpoint and integration, and note whether the issue repeats or affects multiple operations. For a write or external action, verify the current resource or documented operation status before replaying the request. If the call has a documented asynchronous status check, use that instead of starting parallel copies of the same work. ## Retry safely [#retry-safely] Retry only a safe operation after a delay, using a bounded backoff. Confirm the result before repeating a write, and avoid overlapping retries. If timeouts persist, stop retrying until the upstream service is checked. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # VALIDATION_FAILED Canonical page: https://docs.ovok.com/errors/validation-failed **HTTP 422.** Problem type: [`https://docs.ovok.com/errors/validation-failed`](https://docs.ovok.com/errors/validation-failed). ## What this means [#what-this-means] The request was understood, but one or more submitted values failed validation. This differs from a malformed request: the endpoint could parse the request, then rejected its content. ## Troubleshooting [#troubleshooting] Inspect each entry in `errors`. Use `field` to find the affected property or resource path, `code` to identify the machine-readable reason, and `params` for optional constraint values. Check required fields, expected value types, formats, and documented constraints; correct only the affected values while preserving valid data. The API returns at most 100 field errors, so a large request may need more than one correction pass. ## Retry safely [#retry-safely] Fix the reported values and submit the corrected request. Do not branch application behavior on the human-readable `detail` string; use `type`, `status`, and the nested field error codes. Repeating unchanged values will produce the same validation failure. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Do not include access tokens or sensitive patient data. The [Error responses guide](/errors) explains the response fields and field-level errors. # VAT ID REQUIRED Canonical page: https://docs.ovok.com/errors/vat-id-required **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/vat-id-required`](https://docs.ovok.com/errors/vat-id-required). ## What this means [#what-this-means] The customer's region requires a VAT ID for this billing operation. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Confirm billing country and legal entity, then provide a valid country-appropriate VAT ID instead of changing the billing country. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # WEBHOOK NOT SUPPORTED Canonical page: https://docs.ovok.com/errors/webhook-not-supported **HTTP 404.** Stable Problem Details type: [`https://docs.ovok.com/errors/webhook-not-supported`](https://docs.ovok.com/errors/webhook-not-supported). ## What this means [#what-this-means] Ovok takes no notifications from this wearable provider. Only Withings, Polar and Suunto send them. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Remove the notification URL from the provider's portal. The provider's data is synced daily and on demand. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Webhook URLs](/wearables/set-up-providers#webhook-urls) - [Wearables webhooks](/wearables/api-reference#webhooks) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # WEBHOOK SECRET NOT USED Canonical page: https://docs.ovok.com/errors/webhook-secret-not-used **HTTP 422.** Stable Problem Details type: [`https://docs.ovok.com/errors/webhook-secret-not-used`](https://docs.ovok.com/errors/webhook-secret-not-used). ## What this means [#what-this-means] A `webhookSecret` was sent for a wearable provider that does not take one. Only Suunto signs its notifications with a secret the admin sets. Clients should branch on `type` and `status`, not on human-readable `detail` text. ## Troubleshooting [#troubleshooting] Remove `webhookSecret` from the request. Withings and Polar notifications are set up by Ovok itself; the other providers send no notifications. Compare the request with the relevant endpoint's documentation and confirm the authenticated project and environment. Record the request path and `traceId` before escalating; the identifier lets an administrator find server-side context without sharing credentials or patient data. ## Related endpoint guidance [#related-endpoint-guidance] Use these pages to check the route, project settings, and request requirements associated with this error: - [Set up wearable providers](/wearables/set-up-providers) - [Wearables API reference](/wearables/api-reference#provider-setup) ## Retry safely [#retry-safely] Correct the request, configuration, access or project state described above before retrying. Repeating an unchanged request will normally return the same error; for writes, check whether the first attempt changed state before sending it again. Follow endpoint-specific idempotency and concurrency guidance. Do not retry in a tight loop or use a broader permission or project setting to bypass the check. ## If the problem persists [#if-the-problem-persists] Share the HTTP status, problem `type`, request path, response timestamp, and `traceId` with your administrator or support contact. Remove access tokens, provider secrets, and sensitive patient data from the report. The [Error responses guide](/errors) explains the response fields, while the [machine-code registry](/errors/machine-codes) lists every endpoint-specific type audited for this release. # Docs for AI agents Canonical page: https://docs.ovok.com/working-with-ai-agents/docs-for-agents Ovok Docs publishes Markdown for AI tools alongside each rendered page: - Start with the [docs router for AI agents](/llms.txt). It points to the most useful topic pages without loading the whole documentation set. - The [exhaustive page manifest](/llms/manifest.json) lists every published page with its title, canonical URL, page-specific Markdown URL, section, source hash, and `lastUpdated` timestamp in UTC. It also lists topic downloads with their versions, page counts, and UTF-8 byte sizes. - Download a [topic bundle](/llms.txt) for focused context, such as [Authentication](/llms/topics/authentication.txt), [Access policies](/llms/topics/access-policies.txt), or [FHIR API references](/llms/topics/api.txt). Each topic has its own content-based version, so unrelated documentation changes do not invalidate that download. - For a focused task, fetch the page-specific Markdown URL, such as [Authentication](/authentication/llms.txt), [Access policies](/access-policies/llms.txt), or [Settings and features](/settings-and-features/llms.txt). The same pattern works for every docs page: `/path/to/page/llms.txt`. - Every page is also served as Markdown at `/path/to/page.md`, or at its own URL when the request sends `Accept: text/markdown`. - Use the [complete docs bundle](/llms-full.txt) only when broad context is needed. It contains every page and is intentionally the largest option; for most implementation tasks, start with the router and fetch only relevant pages. Bundle versions are SHA-256 identifiers of the exported text before its version line is inserted. Compare them to detect changed downloads. File sizes are not token counts; if a topic still exceeds your model's context budget, fetch only the page-specific Markdown you need. Page timestamps record source-content changes rather than rebuild or deployment times. The [Ovok MCP server](/working-with-ai-agents/mcp-server) points connected agents to the router too. For example, you can ask: “Read the Ovok docs index, then fetch the page-specific Markdown for authentication, FHIR resources, and settings that apply to this workflow. Use those docs as the source of truth and cite the relevant pages in your plan.” # Working With AI Agents Canonical page: https://docs.ovok.com/working-with-ai-agents AI coding agents can help you explore Ovok, plan an integration, set up a project and implement application code. They work best when you give them the context of your application and ask them to verify platform behavior against the current Ovok documentation. Building AI *into* your application at runtime, such as clinical summarization or agents acting on patient data, is a different topic; see [Build with AI on Ovok](/settings-and-features/features/ai) for Ovok's documented `$ai` feature. This section is about using AI to *develop* on Ovok. ## Three pieces [#three-pieces] | Piece | What it gives the agent | Page | | --- | --- | --- | | **Ovok skill** | Guidance: how to work on an Ovok app, what to verify, what to leave to a project admin. | [Install the Ovok skill](/working-with-ai-agents/ovok-skill) | | **Ovok MCP server** | Access: named tools that read and set up one project, as the admin who connected it. | [Connect the MCP server](/working-with-ai-agents/mcp-server) · [MCP tools](/working-with-ai-agents/mcp-tools) | | **AI-readable docs** | Context: Markdown for every page, topic bundles and a page manifest. | [Docs for AI agents](/working-with-ai-agents/docs-for-agents) | The skill and the docs work with any coding agent and need no Ovok access. The MCP server needs a project admin to approve it. ## Quick start [#quick-start] 1. Install the skill in your application repository: ```bash npx skills add Actimi/ovok-landing --skill ovok ``` 2. Connect the MCP server for the sandbox, then authenticate it with `/mcp` in Claude Code: ```bash claude mcp add --transport http ovok https://api.sandbox.ovok.com/mcp ``` 3. Ask for the work, with enough context. For example: “Use the `ovok` skill. Read the project with the Ovok MCP tools, then read the Ovok docs for authentication and access policies, and plan a practitioner login for this app. Don't change settings yet.” Then follow [Prompting and review](/working-with-ai-agents/prompting-and-review) to plan, build and check the result. # Connect the Ovok MCP server Canonical page: https://docs.ovok.com/working-with-ai-agents/mcp-server The [Ovok skill](/working-with-ai-agents/ovok-skill) guides an agent; the Ovok MCP server lets it act. Once a project admin connects it, Claude, or any MCP client, can read and set up that project through [named tools](/working-with-ai-agents/mcp-tools), as that admin. ## Server URL [#server-url] ```text https://api.sandbox.ovok.com/mcp ``` The server speaks MCP over Streamable HTTP (`POST /mcp`) and signs clients in with standard MCP OAuth: dynamic client registration and an authorization code with PKCE. It has no SSE stream. ## Add it to your client [#add-it-to-your-client] ### Claude Code [#claude-code] ```bash claude mcp add --transport http ovok https://api.sandbox.ovok.com/mcp ``` Then run `/mcp` in Claude Code and authenticate the `ovok` server. ### Claude and Claude Desktop [#claude-and-claude-desktop] Add a custom connector with the server URL, then select **Connect**. ### ChatGPT, VS Code and other clients [#chatgpt-vs-code-and-other-clients] Add a remote MCP server with the server URL. Any client that supports Streamable HTTP and MCP OAuth works the same way; you don't need to create a client ID or an API key. ## Sign in and approve [#sign-in-and-approve] The client opens the OVOK Console in your browser. Sign in, choose the project, check what is asking for access, and select **Allow**. - Only an admin of the project can connect it. The Super Admin project can't be connected. - The Console shows where the approval goes. If that isn't a known MCP client (Claude, ChatGPT or VS Code) or your own computer, the Console warns you, and you must confirm before allowing. - There is one level of access: the agent can use every [tool](/working-with-ai-agents/mcp-tools), on that one project. To work on another project, connect again and choose it. ## Limits and lifetime [#limits-and-lifetime] - The agent acts as you. Each tool follows the same rules as the matching API route, and it loses access as soon as you stop being an admin of the project. - The connection ends 90 days after you approve it, even if the client keeps refreshing its token. Connect again to continue. - Each admin may send 300 MCP messages a minute, and one address 3000. Each tool allows 60 calls a minute, except: - `invite_member` and `create_app`: 10 a minute; - `get_requests`, `get_failed_requests` and `get_request_details`: 30 a minute. - A call over a limit answers `429`. Wait a minute and try again. - MCP calls don't count toward your plan's API usage. - To disconnect, remove the server from your client. Tools change live settings, send invitation emails, create credentials and publish CMS content. Ask the agent to explain each change before it makes it, and review your client's tool-approval prompts. A secret from `create_app` appears in the conversation: store it in your secret manager and keep it out of code and logs. ## Troubleshooting [#troubleshooting] | What you see | Why | What to do | | --- | --- | --- | | The client asks you to sign in again | The connection reached its 90 days, or it was revoked. | Authenticate the server again. | | `403 insufficient_scope` on every call | You are no longer an admin of the project, or it is the Super Admin project. | Ask an admin to restore your role, or connect another project. | | `403 not_parent_project` from `get_usage_details` | The project is a sub-tenant; it bills to its parent. | Connect the parent project. | | `404 unknown_collection` from a CMS tool | The collection isn't one `get_cms_schema` lists. | Call `get_cms_schema` and use one of its slugs. | | `422` from a tool | An input failed validation. The answer names the field. | Fix the input. | | No CMS tools listed | The CMS isn't configured on this deployment. | Manage content in the Console. | # Ovok MCP tools Canonical page: https://docs.ovok.com/working-with-ai-agents/mcp-tools Every tool acts on the one project the connection was approved for, as the admin who approved it. Each calls the service behind the matching API route, so it follows that route's rules and answers its errors. The server tells the agent to read before it changes: `get_project` and `get_settings` first. Paged tools take `page` (from `0`) and `count` (`1`–`100`, default `20`). ## Project and settings [#project-and-settings] | Tool | Changes data | What it does | Inputs | | --- | --- | --- | --- | | `get_project` | No | Reads the project's ID, name and tenant code. | — | | `get_settings` | No | Reads every on/off setting, with its saved value (`overrides`, `null` when unset) and the value Ovok applies (`effectiveSettings`), and the text settings (`values`): app URLs and default access policies, with `warnings`. | — | | `set_setting` | Yes | Turns one on/off setting on or off, and answers every setting after the change, with `warnings`. | `key`, `enabled` | | `set_setting_value` | Yes | Sets one text setting, or clears it with `null`. App URLs are `https` URLs or app deep links; access policy settings are `AccessPolicy/` of a policy in this project. Answers every setting, with `warnings`. | `key`, `value` | The keys are the ones on [Settings and features](/settings-and-features). Some switches need another setting to work. `warnings` lists each switch that is on, saved or by default, but has no effect, as `{ setting, message }`; the message names the setting it needs. See [Defaults and dependencies](/settings-and-features#defaults-and-dependencies). ## Members and apps [#members-and-apps] | Tool | Changes data | What it does | Inputs | | --- | --- | --- | --- | | `list_members` | No | Lists the project's members, with their profile, access policy and admin flag. | `page`, `count` | | `invite_member` | Yes, sends email | Invites a practitioner by email. A new address gets an account and an email to set its password; `admin: true` makes them a project admin. | `email`, `firstName`, `lastName`, `admin`, optional `access` | | `list_apps` | No | Lists the project's client applications (OAuth clients), without their secrets. | `page`, `count`, optional `search`, `type` | | `create_app` | Yes | Creates a client application and shows its secret once: `default` for an app signing users in, `admin` for a server acting as a project admin, `social-login` with its Google or Apple sign-ins. | `type`, `name`, `description`, optional `socialLogins` | See [Invitations](/invitations) and [Authentication](/authentication) for what these create. ## Signals [#signals] | Tool | Changes data | What it does | Inputs | | --- | --- | --- | --- | | `get_signals` | No | Reads whether [Signals](/signals) is on for the project, which tenant it uses, and its counts of enrolled patients, alerts and observations. | — | ## Requests and usage [#requests-and-usage] Use these to debug an app: find the requests that failed, then read one in full. | Tool | Changes data | What it does | Inputs | | --- | --- | --- | --- | | `get_requests` | No | Lists the project's API requests on this environment, newest first: method, route, status, duration and `traceId`. Where request traces are sampled, it is a sample. The Console's own calls are left out. | `page`, `count`, optional `search`, `window` | | `get_failed_requests` | No | As `get_requests`, for requests answered `4xx` or `5xx`, or marked as an error. | `page`, `count`, optional `search`, `window` | | `get_request_details` | No | Reads one request in full, by its `traceId`: every step it ran (calls to the FHIR store, Redis and other services) in start order, with durations and errors. Looks back 7 days. | `traceId` | | `get_usage_details` | No | Reads the project's plan and this month's usage against its allowances (API requests, monitored patients, devices and sub-tenants), with its invoices. For a parent project; a sub-tenant answers `403 not_parent_project`. | — | `search` matches part of the method and route, in any case. `window` is `1h`, `24h` (the default) or `7d`. ## FHIR data [#fhir-data] These read and change the project's FHIR R4 data as the admin who approved the connection: their project, its linked projects and their access policy decide what each call reaches, as on the [FHIR API](/fhir-basics). Use them for data, such as patients, observations and devices; use the tools above for project setup. | Tool | Changes data | What it does | Inputs | | --- | --- | --- | --- | | `search_fhir` | No | Searches one resource type with FHIR search parameters, such as `name=Smith&_count=10`. Answers `resources`, `hasMore`, and `total` when you ask for `_total=accurate`. Search by `_id` to read one resource. | `resourceType`, optional `query` | | `create_fhir_resource` | Yes | Creates one resource and answers it with its ID. | `resource` | | `update_fhir_resource` | Yes | **Replaces** one resource: fields left out are deleted. Send the whole resource back with its `meta.versionId`, and the update answers `412` if someone changed it since. | `resource` (with `id`) | | `delete_fhir_resource` | Yes | Deletes one resource. It cannot be restored through Ovok, and resources that reference it are kept. | `resourceType`, `id` | - `query` is a query string without the leading `?`. A page holds at most 100 resources (`_count`); page on with `_offset`. - Each tool's description carries its warning, and the update and delete tools are marked destructive, so a client can ask you before it runs them. - `Project`, `ProjectMembership`, `User`, `UserSecurityRequest`, `Login`, `ClientApplication`, `Bot`, `JsonWebKey` and `DomainConfiguration` are refused with `422`. Use `create_app`, `invite_member` and the settings tools for project administration. - Writes to patients, devices and observations reach Ovok's apps and Signals as any write through the API does. ## CMS content [#cms-content] These manage the project's [CMS](/cms) content, as the Console does. They are offered only where the CMS is configured. | Tool | Changes data | What it does | Inputs | | --- | --- | --- | --- | | `get_cms_schema` | No | Lists the collections the project can write (legal pages, posts, translations, content types and items, media, release notes) with their fields, and the locales. Read it before writing a document. | — | | `list_cms_documents` | No | Lists the project's documents in one collection. | `collection`, `page`, `count`, optional `where`, `sort`, `locale`, `draft`, `depth` | | `get_cms_document` | No | Reads one document by ID. | `collection`, `id`, optional `locale`, `draft`, `depth` | | `create_cms_document` | Yes | Creates a document, its localized fields in `locale`. Answers a summary, not the document. | `collection`, `data`, optional `locale`, `draft`, `returnDocument` | | `update_cms_document` | Yes | Changes the fields given in `data`; the others are kept. Answers a summary, not the document. | `collection`, `id`, `data`, optional `locale`, `draft`, `returnDocument` | | `delete_cms_document` | Yes | Deletes one document. It cannot be undone. | `collection`, `id` | | `set_cms_translations` | Yes | Sets strings of one `translations` group in one locale, by key, and keeps every other key and locale. Creates the group if it does not exist. | `slug`, `locale`, optional `strings`, `remove`, `title`, `publish` | | `list_cms_api_keys` | No | Lists the project's [CMS API keys](/cms#api-keys): `id`, `name`, `prefix`, `createdAt` and `isDefault`. Never a key itself. | — | | `create_cms_api_key` | Yes | Creates a CMS API key and shows it once, in `key`. | `name` | | `revoke_cms_api_key` | Yes | Revokes a CMS API key. Apps sending it are refused at once. | `id` | - `collection` is a slug that `get_cms_schema` lists, such as `legal-pages`. Any other answers `404 unknown_collection`. - `where` filters as the Payload REST API does, such as `{ "slug": { "equals": "terms-and-conditions" } }`. `sort` is a field name, with `-` first for descending. - `locale` is a language tag such as `de`; `all` reads every locale. - `draft` reads or saves the draft, in collections that have drafts. - `depth` (`0`–`3`, default `0`) fills in related documents; `0` answers their IDs. - The project's tenant is set on new documents for you. - Publishing a legal page asks users to accept it again. - Media files are uploaded in the Console, not through MCP. ### Write answers [#write-answers] `create_cms_document` and `update_cms_document` answer a summary of the saved document, not the document itself: ```json { "id": 12, "slug": "welcome", "status": "draft", "updatedAt": "2026-10-18T09:00:00.000Z", "locale": "de", "note": "Saved. The document is not repeated here: read it with get_cms_document, or pass returnDocument: true." } ``` `locale` is `null` when the call named none, which writes the default locale. A rich-text body can be tens of kilobytes, so the full document can exceed an agent's tool-answer limit even when the write succeeded. Pass `returnDocument: true` to get the whole document, or read it with `get_cms_document`. ### Translations [#translations] `set_cms_translations` changes a [`translations` group](/cms/use-ovok-cms-with-i18n) key by key. Use it instead of `update_cms_document`, which replaces the group's whole `strings` list: rows left out are deleted, and a row sent without its `id` loses its text in the other locales. ```json { "slug": "sign-in", "locale": "de", "strings": { "title": "Anmelden", "errors.required": "Pflichtfeld" } } ``` It answers counts of keys, such as `{ "slug": "sign-in", "locale": "de", "created": 0, "updated": 1, "removed": 0, "unchanged": 1, "status": "published" }`. - **One locale a call.** `strings` sets each key's text in `locale`. Every other key, and every other locale of the keys you set, is kept. An empty text clears the key in that locale, so apps fall back to English. - **New keys start in English.** A key the group does not have yet can be created only in a call with `locale` `en`, the default locale. A call in another locale that names a new key writes nothing and answers `422 default_locale_first` with the keys. Write them in `en`, then call again for each other locale. - **New groups.** If no group has the `slug`, a call with `locale` `en` and a `title` creates it. Otherwise it answers `422 group_not_found`. - **Removing keys.** `remove` lists keys to delete from the group in every locale. It cannot be undone. A key cannot be in both `strings` and `remove`. - **Publishing.** `publish: true` publishes the group. `publish: false` makes it a draft, which takes it off every app at once. Without `publish`, a new group is a draft and an existing group keeps its status. Apps read published groups only. - **Keys** are letters, digits, `_`, `-` and `.`, as in the Console; a dot nests, as in `errors.required`. `__proto__`, `constructor` and `prototype` are refused. The `slug` is letters, digits, `_` and `-`, without dots. A call takes at most 1,000 keys. - **Concurrent edits.** The write applies only if the group is unchanged since the tool read it. If it changed, nothing is written and the call answers `409 translations_changed` with `retryable: true`. Call the tool again. A save that lands within milliseconds of the write can still be overwritten, so avoid editing the same group in the Console while an agent writes it. - **Refused groups.** If the CMS refuses the group, for example a row with no key, nothing is written and the call answers `422 cms_refused` with the CMS's `errors`. - **Duplicate groups.** If the project has two groups with the same `slug`, the call answers `409 duplicate_group`. Delete the extra one with `delete_cms_document`. ### CMS API keys [#cms-api-keys] `create_cms_api_key` answers the new key in `key`, once. Ovok stores only its hash, so it cannot be shown again: give it to the person who asked, to keep in a secret store or a server environment variable. A project holds at most 20 keys. `revoke_cms_api_key` takes an `id` from `list_cms_api_keys`, including `default`, and takes effect at once: apps that send the key are refused. See [API keys](/cms#api-keys). ## Errors [#errors] A refused call answers the matching route's status and body, such as `403`, `404` or `409`. Invalid inputs answer `422` with the failing fields. A `5xx` answers without internal details. Calls over a limit answer `429`; see [Limits and lifetime](/working-with-ai-agents/mcp-server#limits-and-lifetime). # Install the Ovok skill Canonical page: https://docs.ovok.com/working-with-ai-agents/ovok-skill The [Ovok skill](https://github.com/Actimi/ovok-landing/tree/main/skills/ovok) gives a coding agent a repeatable way to work with Ovok. ## What the skill does [#what-the-skill-does] It tells the agent to: - inspect your application repository, its `AGENTS.md` instructions, framework, and existing code patterns before making changes; - check the current Ovok docs and available source for the API route, FHIR resource, SDK method, request and response shape, and error behavior involved. For SDK methods, use the documentation and declarations shipped with the SDK version in the project; - identify project setup requirements, including authentication, access policies, feature switches, settings, and their prerequisites; - use the Console or the [Ovok MCP server](/working-with-ai-agents/mcp-server) for project administration, such as settings, members, client applications and CMS content, and use APIs or SDKs for application integrations; - preserve tenant and patient boundaries, keep secrets and clinical data out of client code and logs, and flag behavior it cannot verify; - report the implementation, setup a project administrator must complete, and any remaining assumptions. The skill is guidance for the coding agent. It does not sign in to Ovok, grant the agent access to a project, create credentials, or change project settings by itself. The agent can only inspect or change files and systems allowed by the tools and permissions in your development environment. To let an agent set up a project for you, [connect the Ovok MCP server](/working-with-ai-agents/mcp-server). ## Install it [#install-it] Install it from the repository where you plan to use your coding agent: ```bash npx skills add Actimi/ovok-landing --skill ovok ``` The Skills CLI detects the current coding agent. To choose Codex explicitly, run: ```bash npx skills add Actimi/ovok-landing --skill ovok --agent codex ``` The default installation is for the current project. To install it for your user account instead, add `--global`: ```bash npx skills add Actimi/ovok-landing --skill ovok --global ``` List installed skills to confirm it is available: ```bash npx skills ls ``` ## Use it [#use-it] Open your application repository in the agent. Skills-enabled agents may select the skill automatically for relevant work; you can also ask explicitly: “Use the `ovok` skill for this task.” The skill source is in the [Actimi/ovok-landing repository](https://github.com/Actimi/ovok-landing/tree/main/skills/ovok). # Prompting and review Canonical page: https://docs.ovok.com/working-with-ai-agents/prompting-and-review ## Give the agent enough context [#give-the-agent-enough-context] “Build something with Ovok” leaves important decisions open. Describe the product workflow and the people who will use it. Include: - **The user and their role:** for example, a patient recording a blood-pressure reading or a practitioner reviewing observations. - **The workflow:** what starts it, what the user does, and what should happen next. - **The data:** which clinical concepts, devices, or records are involved, and which system is authoritative. - **Access rules:** who may create, read, update, or share each record. - **The application:** its framework, existing authentication, and relevant repository conventions. - **The environment:** whether the work is a code example, sandbox integration, or production change. - **The expected result:** screens or API behavior to implement, plus how you will decide it is complete. For example: ```text Use the ovok skill. In this repository, add a practitioner view for reviewing a patient's recent blood-pressure observations. First inspect the app structure and repository instructions. Then check the current Ovok docs for authentication, the relevant FHIR resources and search parameters, and any project setup required for this workflow. Use the existing app patterns. Keep tokens and patient data out of browser logs. Before coding, summarize the endpoint and access-policy assumptions; after coding, list the files changed and any Console setup an admin still needs to do. Use sandbox URLs in examples. ``` You can ask the agent to explain or plan a workflow before it edits files. For example: “Map this user journey to Ovok resources and endpoints. Show the required settings, features, access policies, and failure cases, and cite the docs you used. Do not change code yet.” This is useful when the data model or permissions need review first. ## Example prompts with the MCP server [#example-prompts-with-the-mcp-server] With the [Ovok MCP server](/working-with-ai-agents/mcp-server) connected: - **Set up a project:** “Read the project and its settings. Tell me which settings this app needs, and why, before changing anything. Then create a `default` client application named ‘Web app’ and tell me where to store its secret.” - **Debug an app:** “Show the failed requests from the last hour. Pick the most common one, read its details, and explain the cause with the docs page that covers that route.” - **Manage content:** “Read the CMS schema, then add German translations for the `onboarding` group as a draft. Show me the draft before publishing.” - **Check usage:** “Read the plan and this month's usage, and tell me which allowance we will reach first.” ## A practical workflow [#a-practical-workflow] For a feature that uses Ovok, work through these steps with the agent: 1. **Map the user journey.** Identify the actors, project, records, and actions. Decide what the patient, practitioner, and application can each do. 2. **Confirm the Ovok contract.** Have the agent find the exact docs for [authentication](/authentication), [Access policies](/access-policies), [settings and features](/settings-and-features), [FHIR basics](/fhir-basics), [FHIR R4 resources](/api/fhir/r4), [Ovok primitives](/primitives), [Slim APIs](/slim-apis), and [Data ingestion](/data-ingestion). If the implementation uses an SDK, have it check the documentation and declarations shipped with the SDK version in the project. Authorization should be designed early: confirm both the authenticated identity and the AccessPolicy requirements for each operation. Ask it to distinguish standard FHIR behavior from Ovok-specific operations and to verify request, response, and error details. 3. **Check project setup.** Identify required feature switches, settings, access policies, app URLs, and other prerequisites. With the MCP server connected, the agent can read them with `get_settings`. The skill warns about common configuration traps: for example, a feature-list `PATCH` replaces the complete list, an unset setting may behave differently from the value returned by `GET`, and a setting does not replace an access policy. 4. **Separate project setup from code.** Project creation and administration (settings, email templates, CMS content, billing, memberships, and access configuration) belong in the [OVOK Console](https://ovok.com/console?ref=docs), or to an agent through the [MCP tools](/working-with-ai-agents/mcp-tools). FHIR requests and application behavior belong in your application code through documented APIs or SDKs. Ask the agent to list setup steps separately from code changes. 5. **Implement against the existing application.** Keep patient and project scope explicit. Put credentials on the server where required. Use the sandbox for example requests and test data; do not put production tokens or real patient data in prompts, fixtures, or logs. 6. **Review the result.** Check changed files, FHIR version, query parameters, resource references, permissions, and error handling. Complete any setup, then exercise the workflow with appropriate test accounts before using it with patients. `get_failed_requests` shows what the app's calls got wrong. ## Review AI-generated changes [#review-ai-generated-changes] Agents are fast and often right, but they hallucinate fields, mix FHIR versions, and produce plausible-but-wrong code. Treat everything an agent writes as a draft to review, not a finished answer. Apply extra scrutiny to anything that affects security or data exposure, especially access policies, `ProjectMembership` scopes, and PHI handling. Ask the agent to show the docs behind an endpoint or behavior it relies on. Review authorization and data access yourself, and test important cases, including unauthorized access, missing configuration, invalid input, and partial or failed writes. Do not treat a successful build as proof that a clinical workflow or permission model is correct. The skill also asks agents to keep product claims precise: Ovok is not described as a certified medical-device platform, and the regulatory status of an application depends on its own intended purpose. For Signals behavior, verify the current [Signals documentation](/signals) and your product's requirements. # RPM app Diary tab Canonical page: https://docs.ovok.com/example-rpm-app/app-tabs/diary Diary presents the readings and check-ins captured on this phone, including synthetic demo history, weight trends, ECG traces, timestamps, and questionnaire answers. ## What the history means [#what-the-history-means] The diary is a device-local view, not a complete cross-device history fetched from the server. Demo and Patient records use separate storage. The app keeps pending Patient entries visible and labels failed server writes **Needs sync**, with an explicit retry action. This distinction matters when testing: signing in does not upload demo history, and seeing an entry in the diary does not by itself prove the remote FHIR save succeeded. Check the displayed sync state and, for a sandbox test, verify the Patient resource in Ovok. **Explore the source:** [Diary.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/Diary.tsx) renders the history and filters; [care-store.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/care-store.tsx) owns the local state and save states; [model.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/model.ts) defines and validates diary entries. ## Try it [#try-it] Record one demo ECG and weight from [Home](/example-rpm-app/app-tabs/home), then open Diary. Inspect timestamps, trend presentation, and the synthetic-data label. Resetting demo history is available in [Settings](/example-rpm-app/app-tabs/settings). For the app's storage and retry behavior, read [Local data and sync](/example-rpm-app/integrations/local-data-and-sync). # RPM app Home tab Canonical page: https://docs.ovok.com/example-rpm-app/app-tabs/home Home is the daily starting point in Ovok Care. It brings the example's ECG task, weight entry, and short symptom check-in into one patient-facing flow. ## What the patient sees [#what-the-patient-sees] The screen presents the day's tasks and their completion state. In Demo mode, measurement results are synthetic and clearly kept local. With a signed-in Patient and a paired device, the app can receive supported device results and save them through the configured Ovok client. The Home screen is an example of product UI built around measurements; it does not interpret ECG waveforms, diagnose a condition, or set alert thresholds. Its short check-in is illustrative, not a validated clinical questionnaire. **Explore the source:** [Home.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/Home.tsx) lays out the daily tasks; [MeasurementSheet.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/MeasurementSheet.tsx) handles the guided measurement and check-in flow. ## Try it [#try-it] 1. Open **Home** in Demo mode. 2. Start the ECG demonstration and save its synthetic result. 3. Record a demo weight and complete the short check-in. 4. Open [Diary](/example-rpm-app/app-tabs/diary) to review what was recorded. For actual device pairing, see [Bluetooth measurements](/example-rpm-app/integrations/bluetooth). For server-backed saves, connect a sandbox project first. # RPM app Settings tab Canonical page: https://docs.ovok.com/example-rpm-app/app-tabs/settings Settings is where a person can change the app appearance, manage supported-device pairing, and sign in or out of a Patient account. Demo history can also be reset here. The app does not include project administration or patient registration. Configure a sandbox project separately, then use an existing authorized Patient account to test server-backed behavior. See [Connect a sandbox project](/example-rpm-app/sandbox-setup). **Explore the source:** [Settings.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/Settings.tsx) implements account and appearance controls; [bluetooth.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/bluetooth.tsx) supplies the device state and pairing actions. ## Try it [#try-it] - In Demo mode, switch appearance and reset synthetic history. - On a physical phone, inspect **Devices** and pair only a supported model. - With sandbox access, sign in using a Patient account and verify the active API origin shown in the sign-in form. Sign-out does not upload demo records or turn the app into a server-wide diary. Read [Diary](/example-rpm-app/app-tabs/diary) for the scope of its history. # RPM app Support tab Canonical page: https://docs.ovok.com/example-rpm-app/app-tabs/support Support collects the device instructions and practical troubleshooting shown by the example app. It helps a user prepare a supported device and understand what to check when a measurement cannot be captured. Bluetooth pairing requires a physical phone; the iOS simulator can run the demo UI but cannot pair the example devices. Always use the instructions supplied with the exact device model and check it against the [Ovok supported-device catalog](/native-sdk/guide/supported-devices). The page is not a substitute for manufacturer instructions or clinical guidance. The sample app does not interpret the ECG or provide emergency monitoring. **Explore the source:** [Support.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/Support.tsx) contains the in-app help, supported device notes, and troubleshooting text. ## Try it [#try-it] Open **Support** in the app to see the guidance available before pairing. For the full connection flow, see [Bluetooth measurements](/example-rpm-app/integrations/bluetooth). # Clinic workflow and FHIR records in the EHR example Canonical page: https://docs.ovok.com/example-rpm-app/ehr/clinic-workflow The EHR separates synthetic demo state from records returned by an Ovok sandbox. Sandbox requests use the signed-in Practitioner and remain subject to project AccessPolicies; a UI stage or care-team assignment does not grant backend access. ## Trace the implementation [#trace-the-implementation] 1. [`src/App.tsx`](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/src/App.tsx) coordinates the clinic workbench, selected Patient, and demo or sandbox mode. 2. [`src/lib/ovokClient.ts`](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/src/lib/ovokClient.ts) lazily creates the `@ovok/core` client using the configured sandbox URL and tenant code. 3. [`src/lib/fhir.ts`](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/src/lib/fhir.ts) maps the example's inputs to FHIR `Patient`, `CareTeam`, `CarePlan`, and `DeviceUseStatement` resources. 4. [`src/components/PatientRegistrationDialog.tsx`](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/src/components/PatientRegistrationDialog.tsx) collects registration details; [`src/components/PatientChart.tsx`](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/src/components/PatientChart.tsx) presents records accessible for the selected Patient. 5. [`src/components/SignalsSetup.tsx`](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/src/components/SignalsSetup.tsx) exposes read-only Signals settings and open alerts. ## Sandbox records [#sandbox-records] The app searches accessible Patients and their demographics, patient-scoped Observations, QuestionnaireResponses, CareTeams, CarePlans, DeviceUseStatements, and Consent status where available. Sandbox registration first checks for an accessible Patient with the submitted email, then creates a FHIR `Patient` and separately requests an invitation. The two writes are not atomic. Sandbox actions can create a `CareTeam`, an active CHF RPM `CarePlan`, and a `DeviceUseStatement` linking an accessible FHIR `Device` to the Patient. Creating one of these records does not grant access to the Patient or confirm that a device is available. Follow the [sandbox setup guide](/example-rpm-app/ehr/sandbox-setup) and the official [FHIR R4 reference](/api/fhir/r4) before adapting these operations. Signals is read-only in this app. It does not change project settings, acknowledge alerts, calculate risk scores, or recommend treatment. The EHR does not implement human messaging, subscriptions, or WebSocket updates. ## Synthetic demo and local relay [#synthetic-demo-and-local-relay] The demo workbench uses synthetic fixtures and session-only actions. In development, [`vite.config.ts`](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/vite.config.ts) exposes an in-memory relay for synthetic ECG, weight, and questionnaire readings shared with the companion examples. [`src/lib/demoRelay.ts`](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/src/lib/demoRelay.ts) validates relay payloads. The relay resets with the dev server, has no database or Ovok connection, and is absent from production builds; it is not a sandbox fallback or a realtime platform feature. ## Current boundaries [#current-boundaries] - The registration form does not collect legally binding signatures or create a Consent record. Consent status is read-only. - Intake questionnaire answers and clinical Conditions, allergies, medications, appointments, and task queues are not persisted as complete workflows. - Device assignment in sandbox does not implement inventory, compatibility checks, shipping, delivery, returns, or replacement. - Demo kit names and patient records are synthetic. The EHR is not for clinical use and is not certified medical software. See the repository's [capability matrix](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/docs/capability-matrix.md), [FHIR resource mapping](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/docs/fhir-resource-mapping.md), and [capability-gap report](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/docs/capability-gaps.md) for additional detail. # Run rpm-ehr-example-app Canonical page: https://docs.ovok.com/example-rpm-app/ehr/getting-started The EHR starts in a synthetic demo workspace. You can explore the clinic workbench without an Ovok account or sandbox configuration. ## Requirements [#requirements] - Node.js 24 or newer - npm 11.16.0, as pinned by the repository ## Run the standalone repository [#run-the-standalone-repository] ```sh git clone https://github.com/Ovok-Dev/rpm-ehr-example-app.git cd rpm-ehr-example-app npm ci npm run dev ``` Open the local URL printed by Vite. The EHR's development server uses port `5174` by default. **Explore the source:** [`src/main.tsx`](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/src/main.tsx) mounts the app; [`src/App.tsx`](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/src/App.tsx) coordinates the workbench and demo/sandbox modes; [`src/data/demo.ts`](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/src/data/demo.ts) supplies synthetic records. ## Run it from the monorepo [#run-it-from-the-monorepo] If you already cloned [`rpm-example-app`](https://github.com/Ovok-Dev/rpm-example-app), run these commands from its root instead: ```sh npm ci npm run ehr ``` The EHR runs at `http://localhost:5174`. Use the monorepo root lockfile and root scripts rather than installing from `apps/ehr`. ## Next [#next] - Connect authorized sandbox records with [Sandbox setup](/example-rpm-app/ehr/sandbox-setup). - Trace registration, FHIR records, and local demo behavior in [Clinic workflow](/example-rpm-app/ehr/clinic-workflow). - See how the three apps exchange sandbox records and synthetic demo readings in the [monorepo data flow](/example-rpm-app/monorepo/data-flow). # rpm-ehr-example-app Canonical page: https://docs.ovok.com/example-rpm-app/ehr [rpm-ehr-example-app](https://github.com/Ovok-Dev/rpm-ehr-example-app) is a standalone React, TypeScript, and Vite reference app for one-clinic CHF remote patient monitoring operations. It demonstrates how an EHR-style workflow can use Ovok FHIR records alongside the patient mobile app and clinician dashboard. The app opens in a synthetic demo. Connect a sandbox project only when you have an authorized Practitioner account and project setup. **This is an example, not clinical software:** demo people and readings are synthetic; the app is not certified medical software and does not provide medical advice or clinical decision support. ## What it demonstrates [#what-it-demonstrates] - A clinic workbench for patient intake, care-team assignment, monitoring enrollment, and device provisioning. - Practitioner sign-in through `@ovok/core`, including MFA, and paginated search of accessible Patients. - Patient registration in sandbox with a FHIR `Patient` create followed by a separate invitation request. - Patient charts with accessible measurements, QuestionnaireResponses, CareTeams, CarePlans, DeviceUseStatements, and Consent status. - Sandbox creation of a CareTeam, CHF RPM CarePlan, or DeviceUseStatement when the current account's AccessPolicy permits it. - Read-only Signals settings and open alerts. - Links to the companion RPM dashboard using an opaque Patient ID; the receiving app authenticates and checks access independently. ## Get started [#get-started] - [Run the EHR locally](/example-rpm-app/ehr/getting-started) using synthetic data. - [Connect an Ovok sandbox](/example-rpm-app/ehr/sandbox-setup) for authorized FHIR records. ## Follow the workflow [#follow-the-workflow] | Workflow | Guide | | --- | --- | | Intake, patient registration, charts, and supported sandbox writes | [Clinic workflow and FHIR records](/example-rpm-app/ehr/clinic-workflow) | | Ovok project setup and practitioner access | [Sandbox setup](/example-rpm-app/ehr/sandbox-setup) | | Local setup and demo mode | [Getting started](/example-rpm-app/ehr/getting-started) | The source tour links to the standalone [`rpm-ehr-example-app`](https://github.com/Ovok-Dev/rpm-ehr-example-app/tree/dev/src). Its [capability-gap report](https://github.com/Ovok-Dev/rpm-ehr-example-app/blob/dev/docs/capability-gaps.md) lists behavior that is intentionally absent or unverified. ## Related examples [#related-examples] The [RPM example monorepo](/example-rpm-app/monorepo) includes this EHR with the [patient mobile app](/example-rpm-app/mobile-app) and [clinician dashboard](/example-rpm-app/web-dashboard). The apps use Ovok for sandbox clinical records; the local relay shares synthetic demo measurements only. # Connect rpm-ehr-example-app to an Ovok sandbox Canonical page: https://docs.ovok.com/example-rpm-app/ehr/sandbox-setup Use sandbox mode after a project administrator has prepared a sandbox project, an authorized Practitioner account, and least-privilege AccessPolicies. The app uses `@ovok/core` against the FHIR R4 API; each request is still authorized by Ovok. ## Prepare the project [#prepare-the-project] 1. Create an Ovok account and a sandbox project in the [Ovok Console](https://ovok.com/console?ref=docs). For project setup, see [Create and configure a project](/authentication/project-setup). 2. Enable Practitioner sign-in and configure an AccessPolicy for only the FHIR reads and writes the example needs. Review [Practitioner login](/authentication/practitioner-login) and [Access Policies](/access-policies). 3. If you will try patient registration, configure patient invitations, patient sharing, the patient application URL, and the required policies. Follow [Invite a patient](/invitations/invite-a-patient). The tenant code identifies a project; it does not authorize requests or replace an AccessPolicy. ## Set public app configuration [#set-public-app-configuration] From the standalone repository root, create a local environment file: ```sh cp .env.example .env.local ``` Set the sandbox API origin and the tenant code for your project: ```dotenv VITE_OVOK_API_BASE_URL=https://api.sandbox.ovok.com VITE_OVOK_TENANT_CODE=your-sandbox-tenant-code ``` These `VITE_` values are bundled into browser code. Do not put a ClientApplication secret, service credential, access token, password, or patient information in them. Restart Vite after changing configuration. ## Sign in and verify access [#sign-in-and-verify-access] Open the EHR, choose **Connect sandbox**, and sign in with your own Practitioner account. The SDK may request an authenticator code. Search results and chart records are limited to what the signed-in Practitioner may access. A UI assignment or Patient ID link does not grant access. If a patient registration succeeds but the later invitation request fails, the Patient record may already exist: those are separate, non-atomic requests. The invitation response means only that the request was accepted for sending; it does not confirm delivery or patient acceptance. Do not retry Patient creation without checking the project first. Continue to the [FHIR workflow walkthrough](/example-rpm-app/ehr/clinic-workflow) for the records this example reads and writes. For the resource contract, see the [FHIR R4 documentation](/api/fhir/r4). # Get started with the example RPM app Canonical page: https://docs.ovok.com/example-rpm-app/getting-started [Ovok Care](https://github.com/Ovok-Dev/rpm-mobile-app) is a runnable React Native example for the Ovok SDK. This guide takes you from a fresh checkout to the app running in an iOS simulator, then explains the optional setup for signing in to an Ovok sandbox and connecting real devices. The app opens in **Demo** mode. Its example readings are synthetic, stay on the phone, and are never uploaded to a patient account. You do not need an Ovok account to run the demo. ## What you need [#what-you-need] For the documented iOS simulator path, have: - macOS with Node.js 24 or later; - Xcode with an iOS simulator installed; - CocoaPods available in your development environment; - Git and npm. The repository uses Expo SDK 57 and React Native 0.86. Its lockfile records the package versions used by the app. Use the checked-in lockfile with `npm ci`; do not install a separate Expo or React Native version globally. The app includes native Bluetooth dependencies, so run it as an Expo development build. **Expo Go is not sufficient.** A simulator can run the demo screens, but Bluetooth pairing requires a physical phone. ## 1. Clone the app and install dependencies [#1-clone-the-app-and-install-dependencies] Open a terminal and run: ```sh git clone https://github.com/Ovok-Dev/rpm-mobile-app.git cd rpm-mobile-app npm ci ``` `npm ci` installs the exact dependency tree from `package-lock.json`. If installation fails, check the Node.js version first, then remove `node_modules` and run `npm ci` again. Keep the lockfile; do not replace this step with `npm install` when following the example as published. **Explore the source:** [package.json](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/package.json) lists the scripts and pinned dependencies; [app.config.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/app.config.ts) declares the native app and Bluetooth configuration. ## 2. Build and launch the iOS app [#2-build-and-launch-the-ios-app] Start the native development build: ```sh npm run ios ``` Choose an installed iPhone simulator when prompted. On the first run, Expo generates the native iOS project, installs its native dependencies, builds the app, and starts Metro. The initial native build takes longer than later JavaScript refreshes. For subsequent development sessions, start Metro with: ```sh npm start ``` Open the installed **Ovok Care** development app in the simulator. When Metro is already using its default port, the README documents using another port for the native run, for example: ```sh npx expo run:ios --port 8091 ``` **Explore the source:** [App.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/App.tsx) assembles the app providers and four tabs; [app.config.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/app.config.ts) supplies Expo's native configuration. ## 3. Explore Demo mode [#3-explore-demo-mode] The app has four tabs: | Tab | Try it | | --- | --- | | **Home** | Record the synthetic ECG, enter a demo weight, and complete the short daily check-in. | | **Diary** | Review the example readings, weight trend, ECG trace, and answers. | | **Support** | Find device instructions and measurement troubleshooting. | | **Settings** | Switch appearance, reset demo history, or open the patient sign-in form. | The app seeds synthetic history so the diary is useful immediately. Demo records are stored separately from patient records, and the upload boundary rejects demo entries. Completing the demo does not create a patient, authenticate you, or send data to Ovok. **Explore the source:** [Home.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/Home.tsx) and [Diary.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/Diary.tsx) render the main experience; [model.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/model.ts), [care-store.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/care-store.tsx), and [storage.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/storage.ts) define records, demo/patient separation, and local persistence. ## Next steps [#next-steps] - [Connect this app to your sandbox project](/example-rpm-app/sandbox-setup) to sign in a Patient and save test data. - [Explore the app tabs](/example-rpm-app/app-tabs/home) to see how Home, Diary, Support, and Settings work. - Browse the [implementation examples](/example-rpm-app/integrations/fhir-persistence) for the FHIR write and [Bluetooth flow](/example-rpm-app/integrations/bluetooth). # Example RPM repositories Canonical page: https://docs.ovok.com/example-rpm-app There are four public repositories in the Ovok RPM example set. Each has a quick path to run it and a code tour that follows the implementation. Pick one app for a focused starting point, or clone the monorepo to run the patient, clinician, and clinic operations experiences together. | Repository | What it contains | Quick start | Code exploration | | --- | --- | --- | --- | | [**rpm-web-dashboard**](https://github.com/Ovok-Dev/rpm-web-dashboard) · Public · TypeScript | React clinician dashboard for patient records, measurements, trends, and read-only Signals status. | [Run the dashboard](/example-rpm-app/web-dashboard/getting-started) | [Follow the dashboard code](/example-rpm-app/web-dashboard/app-shell) | | [**rpm-mobile-app**](https://github.com/Ovok-Dev/rpm-mobile-app) · Public · TypeScript | Expo and React Native patient app for readings, check-ins, diary, device support, and settings. | [Run the mobile app](/example-rpm-app/getting-started) | [Follow the mobile code](/example-rpm-app/integrations/fhir-persistence) | | [**rpm-ehr-example-app**](https://github.com/Ovok-Dev/rpm-ehr-example-app) · Public · TypeScript | React clinic EHR reference app for patient intake, care-team assignment, CHF RPM enrollment, and device-use records. | [Run the EHR](/example-rpm-app/ehr/getting-started) | [Follow the clinic workflow](/example-rpm-app/ehr/clinic-workflow) | | [**rpm-example-app**](https://github.com/Ovok-Dev/rpm-example-app) · Public · TypeScript | Turborepo monorepo with the mobile app, clinician dashboard, and EHR, plus commands to run them together. | [Run the examples](/example-rpm-app/monorepo/getting-started) | [Explore the monorepo](/example-rpm-app/monorepo/workspaces) | ## Choose a starting point [#choose-a-starting-point] - Choose **rpm-mobile-app** to work on the Patient experience or native device flow. - Choose **rpm-web-dashboard** to work on clinician review in a browser. - Choose **rpm-ehr-example-app** to explore a clinic intake, care-team, and CHF RPM enrollment workflow. - Choose **rpm-example-app** when you want all three applications in one checkout and one coordinated development workflow. The focused repositories are useful when you only need one app. The monorepo keeps each application in a separate workspace. Sandbox records are shared through Ovok; only synthetic demo readings use the local development relay. ## Explore the mobile app [#explore-the-mobile-app] The patient app has four screens: [Home](/example-rpm-app/app-tabs/home), [Diary](/example-rpm-app/app-tabs/diary), [Support](/example-rpm-app/app-tabs/support), and [Settings](/example-rpm-app/app-tabs/settings). The [mobile app overview](/example-rpm-app/mobile-app) links its quick start, screen walkthroughs, and implementation pages. ## Start with Ovok SDKs [#start-with-ovok-sdks] These repositories demonstrate the SDKs in complete applications. For the reusable APIs themselves, continue to the [JavaScript SDK](/web-sdk) and [React Native SDK](/native-sdk) references. # Patient authentication in the RPM app Canonical page: https://docs.ovok.com/example-rpm-app/integrations/authentication Ovok Care signs in existing **Patient** accounts in one configured tenant. It does not create a project, administer settings, or provide a registration screen. A Console administrator account cannot be used as the app's Patient session. ## Configuration boundary [#configuration-boundary] The app's environment supplies a public API origin and tenant code. The project administrator separately enables patient sign-in and assigns appropriate patient-scoped permissions. The tenant code identifies the project; it is not a credential. The app prompts for Patient email and password and continues with a verification code when MFA is required. Do not place client secrets, administrator credentials, Patient passwords, or access tokens in the app's source or `EXPO_PUBLIC_` settings. See [Connect a sandbox project](/example-rpm-app/sandbox-setup) for the complete Console and local environment setup, and [Ovok authentication](/authentication) for the platform contract. **Explore the source:** [Settings.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/Settings.tsx) implements sign-in and MFA continuation; [ovok.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/ovok.ts) creates the shared client with the configured tenant and API origin. # Bluetooth measurements in the RPM app Canonical page: https://docs.ovok.com/example-rpm-app/integrations/bluetooth Bluetooth is optional. The iOS simulator can run the application and its synthetic demo, but discovering or pairing a device requires a physical phone with Bluetooth permission granted. The example configures the native SDK for two device declarations: | Device declaration | Example use | | --- | --- | | `IntegratedDevices.BP2` | ECG waveform and duration; a result may also include heart rate. | | `IntegratedDevices.F4` | Body weight in kilograms. | Use the exact model and the instructions in the [supported-device catalog](/native-sdk/guide/supported-devices). The app does not interpret a waveform or infer clinical status from a reading. ## Result path [#result-path] The app creates a Bluetooth manager for the authenticated physical-device workspace, mounts `BTProvider` with the accepted-device list, and handles normalized result events. It converts supported result types into app diary entries, then hands them to local persistence and the FHIR save flow. See [FHIR persistence](/example-rpm-app/integrations/fhir-persistence) and [local data and sync](/example-rpm-app/integrations/local-data-and-sync). **Explore the source:** [bluetooth.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/bluetooth.tsx) defines the SDK provider, allowed devices, and result handling; [device-readings.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/device-readings.ts) keeps received readings available for a local save retry; [app.config.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/app.config.ts) declares native Bluetooth configuration. # FHIR persistence in the RPM app Canonical page: https://docs.ovok.com/example-rpm-app/integrations/fhir-persistence The example uses the Ovok client for real Patient data while keeping Demo data local. Its persistence boundary is explicit: a demo entry is rejected, and a Patient entry can only be saved when the active client profile matches that Patient. ## What the app writes [#what-the-app-writes] - **Daily check-in:** the app builds a FHIR `QuestionnaireResponse` for the signed-in Patient and updates it using a stable resource ID. Retrying therefore targets the same response instead of creating a new ID on every attempt. - **Weight:** the app sends a typed body-weight measurement through `OvokClient.saveMeasurement()`. - **ECG:** the app sends the waveform, duration, optional heart rate, device details, and recorded time through the SDK's ECG measurement input. These are example data flows, not clinical interpretation. The check-in is illustrative, and the app does not make a diagnosis or calculate an alert threshold. The [FHIR R4 reference](/api/fhir/r4), [JavaScript SDK measurement docs](/web-sdk/core/measurements-and-health-data), and [React Native SDK measurement docs](/native-sdk/guide/components/measurement) explain the broader resource and SDK contracts. **Explore the source:** [ovok.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/ovok.ts) contains the FHIR resource construction and calls to `updateResource()` and `saveMeasurement()`; [care-store.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/care-store.tsx) controls when entries are persisted and synchronized. # Local data and sync in the RPM app Canonical page: https://docs.ovok.com/example-rpm-app/integrations/local-data-and-sync Ovok Care separates synthetic Demo entries from Patient entries. The demo stays on the phone and the upload function rejects it. A Patient entry is persisted locally before the app attempts the server write, so a temporary network failure can remain visible and retryable. ## What sync does and does not mean [#what-sync-does-and-does-not-mean] - **Demo:** stored locally; never uploaded. - **Patient entry:** saved to the local patient diary first, then sent through the configured Ovok client. - **Needs sync:** local data exists, but the server save has not succeeded. The app exposes a retry action. - **Diary history:** shows entries captured on this phone. It is not a complete server history across devices. - **Delivery:** sync is foreground-driven. This sample does not provide background monitoring or emergency response. These boundaries are part of the example's behavior, not guarantees for every Ovok application. Design retention, offline delivery, and patient handover policies for your own product. **Explore the source:** [care-store.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/care-store.tsx) handles local entries and sync states; [storage.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/storage.ts) separates demo storage and secure Patient storage; [device-readings.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/device-readings.ts) supports retry after a device reading arrives. For the remote write boundary, continue to [FHIR persistence](/example-rpm-app/integrations/fhir-persistence). For more general durable delivery patterns, see [JavaScript SDK offline measurements](/web-sdk/core/offline-measurements) and the [React Native SDK background sync guide](/native-sdk/guide/modules/background-sync). # rpm-mobile-app Canonical page: https://docs.ovok.com/example-rpm-app/mobile-app [rpm-mobile-app](https://github.com/Ovok-Dev/rpm-mobile-app) is the standalone patient-facing RPM example. It is built with Expo, React Native, TypeScript, `@ovok/core`, and `@ovok/native`. The app opens in a synthetic demo, so you can explore without an Ovok account. The four tabs are [Home](/example-rpm-app/app-tabs/home), [Diary](/example-rpm-app/app-tabs/diary), [Support](/example-rpm-app/app-tabs/support), and [Settings](/example-rpm-app/app-tabs/settings). Demo readings stay local and are not uploaded. ## Run it [#run-it] Start with [Run the mobile app](/example-rpm-app/getting-started) for the iOS simulator setup. To connect an authorized sandbox Patient account, continue to [Connect a sandbox project](/example-rpm-app/sandbox-setup). ## Explore the implementation [#explore-the-implementation] | Area | Start here | | --- | --- | | App structure and screens | [Home](/example-rpm-app/app-tabs/home), [Diary](/example-rpm-app/app-tabs/diary), [Support](/example-rpm-app/app-tabs/support), [Settings](/example-rpm-app/app-tabs/settings) | | Patient authentication and client setup | [Authentication integration](/example-rpm-app/integrations/authentication) | | FHIR-backed writes | [FHIR persistence](/example-rpm-app/integrations/fhir-persistence) | | Bluetooth discovery and readings | [Bluetooth measurements](/example-rpm-app/integrations/bluetooth) | | Local storage and retry | [Local data and sync](/example-rpm-app/integrations/local-data-and-sync) | For the standalone repository, run the [mobile quick start](/example-rpm-app/getting-started). To run this app alongside the clinician dashboard from one checkout, use [rpm-example-app](/example-rpm-app/monorepo). # Follow the RPM example data flow Canonical page: https://docs.ovok.com/example-rpm-app/monorepo/data-flow Each app connects to Ovok as needed: the mobile app saves readings, the EHR reads records and performs supported FHIR writes, and the dashboard reads practitioner data. Each authenticates independently. In local demo mode only, a development relay shares synthetic readings between the mobile app, EHR, and dashboard. ```mermaid flowchart LR device[Supported device] --> mobile[Patient mobile app] mobile -->|FHIR-backed measurement or response| ovok[Ovok] ehr -->|FHIR reads and supported writes| ovok ovok -->|Authorized patient records| ehr ovok -->|Patient-linked records| dashboard[Clinician dashboard] mobile -. synthetic demo only .-> relay[Local in-memory relay] relay -. synthetic demo only .-> ehr relay -. synthetic demo only .-> dashboard ``` The local relay is not an Ovok service, is unavailable in production builds, and does not carry sandbox records. It exists only to demonstrate synthetic readings across the three local applications. ## Patient write path [#patient-write-path] In the mobile workspace, [`src/bluetooth.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/mobile/src/bluetooth.tsx) receives supported device results. The app passes a validated diary entry into [`src/care-store.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/mobile/src/care-store.tsx), which persists it locally and then calls the write functions in [`src/ovok.ts`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/mobile/src/ovok.ts) when an authenticated Patient session is active. Demo records remain local. Patient saves use the signed-in profile and are kept separate from demo history. A failed write is surfaced as a retryable state; this example does not promise unattended background delivery. ## Practitioner read path [#practitioner-read-path] The dashboard's [`patientData.ts`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/dashboard/src/lib/patientData.ts) loads Patient measurements and QuestionnaireResponses through the SDK. [`PatientReviewPage.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/dashboard/src/components/PatientReviewPage.tsx) displays readings, timestamps, source labels, and recent activity. Sandbox access is enforced by the project and practitioner policy, not by a client-side relationship check. For separate app-specific setup and source tours, continue to the [mobile app](/example-rpm-app/monorepo/mobile-app), [clinician dashboard](/example-rpm-app/monorepo/web-dashboard), and [clinic EHR](/example-rpm-app/ehr). # Run the RPM example apps Canonical page: https://docs.ovok.com/example-rpm-app/monorepo/getting-started The monorepo is the quickest way to explore the patient mobile app, clinician dashboard, and clinic EHR together. It installs one workspace dependency tree and starts all three applications from the repository root. ## Requirements [#requirements] - Node.js 24 or newer - npm 11.16.0, as pinned by the repository - Xcode and an iOS simulator to build and run the mobile app on macOS - Android Studio and an emulator/device for the Android mobile build ## Install and start both apps [#install-and-start-both-apps] ```sh git clone https://github.com/Ovok-Dev/rpm-example-app.git cd rpm-example-app npm ci npm run dev ``` The command starts the Expo mobile server and both Vite web applications. Open the dashboard and EHR URLs printed by Vite, then launch the mobile app in an Expo development client. Expo Go does not include this app's native modules; Bluetooth pairing requires a physical phone. To start one app instead, use `npm run mobile`, `npm run dashboard`, or `npm run ehr`. To build the iOS app, use `npm run ios` on macOS with Xcode installed. **Explore the source:** the root [`package.json`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/package.json) defines workspace commands; [`turbo.json`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/turbo.json) configures task execution; each app has its own package in [`apps/mobile`](https://github.com/Ovok-Dev/rpm-example-app/tree/dev/apps/mobile), [`apps/dashboard`](https://github.com/Ovok-Dev/rpm-example-app/tree/dev/apps/dashboard), and [`apps/ehr`](https://github.com/Ovok-Dev/rpm-example-app/tree/dev/apps/ehr). ## Start with demo data [#start-with-demo-data] All three apps can be explored in their synthetic demo experiences without connecting a project. Sandbox configuration is app-specific; see [Workspaces and commands](/example-rpm-app/monorepo/workspaces), the [mobile sandbox setup](/example-rpm-app/sandbox-setup), [dashboard sandbox setup](/example-rpm-app/web-dashboard/sandbox-setup), and [EHR sandbox setup](/example-rpm-app/ehr/sandbox-setup) before connecting accounts. # rpm-example-app Canonical page: https://docs.ovok.com/example-rpm-app/monorepo [rpm-example-app](https://github.com/Ovok-Dev/rpm-example-app) is the combined example repository. It contains the patient-facing Expo app in `apps/mobile`, clinician dashboard in `apps/dashboard`, and clinic EHR in `apps/ehr`, managed as npm workspaces and orchestrated with Turborepo. The apps remain separate products with separate dependencies and user flows. They meet at the Ovok backend: the mobile example records patient readings and check-ins, the EHR supports intake and enrollment, and the dashboard reads patient-linked records for practitioner review. ## Get started [#get-started] [Install the workspace and run the examples](/example-rpm-app/monorepo/getting-started). Use the root `npm run dev` command to start all three development servers, or start one workspace when you are focused on a single app. ## Explore the repository [#explore-the-repository] | Topic | Guide | | --- | --- | | Workspace boundaries, scripts, and task graph | [Workspaces and commands](/example-rpm-app/monorepo/workspaces) | | Mobile screens, authentication, Bluetooth, and local saves | [Patient mobile app](/example-rpm-app/monorepo/mobile-app) | | Practitioner workspace, patient review, and Signals reads | [Clinician dashboard](/example-rpm-app/monorepo/web-dashboard) | | Clinic intake, care teams, and CHF RPM enrollment | [Clinic EHR](/example-rpm-app/ehr) | | How the applications use Ovok and share synthetic demo readings | [End-to-end data flow](/example-rpm-app/monorepo/data-flow) | Use the [standalone mobile repository](/example-rpm-app/mobile-app), [standalone dashboard repository](/example-rpm-app/web-dashboard), or [standalone EHR repository](/example-rpm-app/ehr) when you only need one application. # Explore the mobile app in the monorepo Canonical page: https://docs.ovok.com/example-rpm-app/monorepo/mobile-app The mobile workspace is under `apps/mobile`. Its screen and integration structure follows the standalone [rpm-mobile-app](/example-rpm-app/mobile-app) guide, while source links here point to the monorepo copy. | Responsibility | Source in rpm-example-app | | --- | --- | | Navigation, restored Patient identity, providers, and four tabs | [`apps/mobile/App.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/mobile/App.tsx) | | Home routine and measurement actions | [`apps/mobile/src/Home.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/mobile/src/Home.tsx) and [`MeasurementSheet.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/mobile/src/MeasurementSheet.tsx) | | Tenant client and FHIR-backed saves | [`apps/mobile/src/ovok.ts`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/mobile/src/ovok.ts) | | Device discovery and normalized readings | [`apps/mobile/src/bluetooth.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/mobile/src/bluetooth.tsx) | | Diary model, local persistence, and retry states | [`model.ts`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/mobile/src/model.ts), [`care-store.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/mobile/src/care-store.tsx), and [`storage.ts`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/mobile/src/storage.ts) | The app keeps demo data separate from Patient data. It saves Patient entries locally before attempting a server write, and exposes retry state when a sync fails. Continue to [End-to-end data flow](/example-rpm-app/monorepo/data-flow) to connect this write path to practitioner review. # Explore the dashboard in the monorepo Canonical page: https://docs.ovok.com/example-rpm-app/monorepo/web-dashboard The dashboard workspace is under `apps/dashboard`. It mirrors the standalone [rpm-web-dashboard](/example-rpm-app/web-dashboard) guide, with source links into this monorepo. | Responsibility | Source in rpm-example-app | | --- | --- | | React entry point and workspace state | [`apps/dashboard/src/App.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/dashboard/src/App.tsx) | | Responsive navigation and shell | [`AppShell.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/dashboard/src/components/AppShell.tsx) | | Patient directory and review | [`PatientsPage.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/dashboard/src/components/PatientsPage.tsx) and [`PatientReviewPage.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/dashboard/src/components/PatientReviewPage.tsx) | | SDK client and patient resource mapping | [`ovokClient.ts`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/dashboard/src/lib/ovokClient.ts) and [`patientData.ts`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/dashboard/src/lib/patientData.ts) | | Read-only project Signals status | [`SignalsPage.tsx`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/apps/dashboard/src/components/SignalsPage.tsx) | The dashboard starts in synthetic demo mode. In sandbox mode, it reads only the Patients and patient-linked records returned for the practitioner. For setup, see [Dashboard sandbox setup](/example-rpm-app/web-dashboard/sandbox-setup). # Workspaces and commands in rpm-example-app Canonical page: https://docs.ovok.com/example-rpm-app/monorepo/workspaces The monorepo keeps the mobile app, dashboard, and EHR in separate npm workspaces under `apps/*`. The root lockfile installs all three; each application owns its runtime and dependencies. ## Repository map [#repository-map] | Path | Responsibility | Source | | --- | --- | --- | | `apps/mobile` | Expo and React Native patient experience | [Mobile workspace](https://github.com/Ovok-Dev/rpm-example-app/tree/dev/apps/mobile) | | `apps/dashboard` | React and Vite clinician dashboard | [Dashboard workspace](https://github.com/Ovok-Dev/rpm-example-app/tree/dev/apps/dashboard) | | `apps/ehr` | React and Vite clinic EHR for intake, care teams, and CHF RPM enrollment | [EHR workspace](https://github.com/Ovok-Dev/rpm-example-app/tree/dev/apps/ehr) | | `package.json` | Root workspaces and combined commands | [Root package.json](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/package.json) | | `turbo.json` | Dev, check, and build task behavior | [Turborepo config](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/turbo.json) | There is no shared UI package in the root. Keep native and browser-specific code in the app that owns it; the apps use Ovok as their shared clinical backend. A separate local relay shares only synthetic demo measurements during development. ## Commands from the repository root [#commands-from-the-repository-root] | Command | Purpose | | --- | --- | | `npm run dev` | Start the mobile, dashboard, and EHR development servers. | | `npm run mobile` | Start the Expo development server. | | `npm run dashboard` | Start the Vite dashboard. | | `npm run ehr` | Start the Vite EHR. | | `npm run ios` / `npm run android` | Build and launch the mobile app on the selected platform. | | `npm run typecheck` | Type-check both workspaces. | | `npm test` | Run tests in the workspaces. | | `npm run build` | Build the dashboard and export the mobile JavaScript bundle. | | `npm run check` | Run type checks, tests, Expo dependency validation, and builds. | Turborepo defines these tasks in [`turbo.json`](https://github.com/Ovok-Dev/rpm-example-app/blob/dev/turbo.json). See the per-app guides for their environment and sandbox requirements. # Connect the RPM app to a sandbox project Canonical page: https://docs.ovok.com/example-rpm-app/sandbox-setup Use this page when the demo is running and you want to test Patient sign-in and server-backed saves. Demo mode does not require a project or account. ## Set up the project [#set-up-the-project] An Ovok project administrator should follow [project setup](/authentication/project-setup) and review [Access Policies](/access-policies). For this app: 1. Use a sandbox project and copy its tenant code. 2. Enable patient sign-in with [`PATIENT_LOGIN_ENABLED`](/settings-and-features/settings/patient-login-enabled). 3. Give the Patient AccessPolicy only the patient-scoped access needed for the Patient profile, Observation writes, and QuestionnaireResponse updates used by this app. 4. Enable [`transaction-bundles`](/settings-and-features/features/transaction-bundles) for SDK measurement saves. When changing the feature list, preserve other enabled entries because feature `PATCH` replaces the whole list. 5. Obtain an authorized Patient account in that tenant. The app signs in existing patients; it does not create projects or register patients. An Ovok Console or administrator account is not a Patient account. Do not put a ClientApplication secret in the mobile app. ## Configure the app [#configure-the-app] The example defaults to `https://api.sandbox.ovok.com` and tenant `public-example`. These values let the demo run; the tenant name does not grant permission to sign in. To use your own sandbox project: ```sh cp .env.example .env ``` Set the API origin and tenant for the same environment: ```dotenv EXPO_PUBLIC_OVOK_BASE_URL=https://api.sandbox.ovok.com EXPO_PUBLIC_TENANT_CODE=your-sandbox-tenant-code ``` Restart Metro after editing `.env`. Expo includes every `EXPO_PUBLIC_` value in the client bundle, so use these fields only for public configuration. Never place passwords, tokens, or client secrets in this file. ## Sign in and verify a save [#sign-in-and-verify-a-save] In Ovok Care, open **Settings → Sign in to your project** and enter the sandbox Patient credentials. If the account uses MFA, enter its verification code when prompted. Complete a test check-in and confirm its QuestionnaireResponse in the same sandbox Patient record. A server save failure remains visible as **Needs sync** and can be retried from the app. For current account behavior, see [patient login](/authentication/patient-login), [patient registration](/authentication/patient-registration), and the [`transaction-bundles` feature](/settings-and-features/features/transaction-bundles). **Explore the source:** [Settings.tsx](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/Settings.tsx) implements sign-in and MFA continuation; [ovok.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/ovok.ts) configures the SDK client and environment; [storage.ts](https://github.com/Ovok-Dev/rpm-mobile-app/blob/dev/src/storage.ts) supplies persistent client storage. ## Troubleshooting [#troubleshooting] | Problem | Check | | --- | --- | | Sign-in fails | Confirm API origin and tenant match, the account is a Patient in that tenant, patient sign-in is enabled, and the account has the expected AccessPolicy. See [authentication troubleshooting](/authentication/troubleshooting). | | QuestionnaireResponse save fails | Confirm the Patient can update the response resource and that the app is signed in to that Patient. | | Measurement shows **Needs sync** | Check connectivity and Patient write access; confirm `transaction-bundles` is enabled, then retry. | | The previous tenant still appears | Stop and restart Metro after changing `.env`. | # Explore the dashboard app shell Canonical page: https://docs.ovok.com/example-rpm-app/web-dashboard/app-shell The dashboard keeps its navigation small: Overview, Patients, Signals setup, and Support. It uses a single selected patient for the review screen and separates synthetic demo mode from sandbox mode. ## Follow the render path [#follow-the-render-path] 1. [`src/main.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/main.tsx) mounts the application. 2. [`src/App.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/App.tsx) owns the active page, workspace mode, selected patient, loaded review, and request states. 3. [`src/components/AppShell.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/components/AppShell.tsx) renders the sidebar navigation, environment indicator, and responsive app frame. 4. The selected page receives data and callbacks from `App`; the screen components remain focused on rendering and user interaction. The app starts in demo mode. A successful practitioner sign-in switches the data source to the sandbox project. Returning to demo clears the live review state rather than blending sandbox and synthetic records. ## Explore the screens [#explore-the-screens] - [`PatientsPage.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/components/PatientsPage.tsx) provides a searchable patient directory and selection callback. - [`PatientReviewPage.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/components/PatientReviewPage.tsx) renders the selected profile, measurement cards, and recent activity. - [`SupportPage.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/components/SupportPage.tsx) links out to the platform documentation and example guidance. Continue to [Patient data flow](/example-rpm-app/web-dashboard/patient-data) to trace how SDK results reach these screens. # Dashboard demo data and tests Canonical page: https://docs.ovok.com/example-rpm-app/web-dashboard/demo-and-tests The dashboard's demo workspace is the fastest way to learn the screens. Its patient profiles, ECG examples, questionnaire answers, and weight history are synthetic fixtures; they are not fetched from Ovok and must not be treated as patient data. ## Find the fixtures [#find-the-fixtures] - [`src/data/demo.ts`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/data/demo.ts) defines the synthetic patient reviews and sample history. - [`src/App.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/App.tsx) chooses demo records or sandbox results based on the current workspace mode. - [`src/lib/patientData.test.ts`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/lib/patientData.test.ts) tests resource-to-view mapping. - [`src/lib/weightUnits.test.ts`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/lib/weightUnits.test.ts) tests supported weight-unit conversion. ## Run the checks [#run-the-checks] ```sh npm test npm run build ``` `npm run check` runs both commands through the repository script. Keep new examples synthetic, preserve timestamps and source labels, and add a focused test when changing resource mapping or unit handling. # Run rpm-web-dashboard Canonical page: https://docs.ovok.com/example-rpm-app/web-dashboard/getting-started This quick start launches the synthetic dashboard locally. The demo workspace requires no Ovok account, environment variables, or sandbox data. ## Requirements [#requirements] - Node.js 24 or newer - npm ## Install and run [#install-and-run] ```sh git clone https://github.com/Ovok-Dev/rpm-web-dashboard.git cd rpm-web-dashboard npm ci npm run dev ``` Open the local URL printed by Vite. Use the **Overview**, **Patients**, **Signals setup**, and **Support** navigation to explore the synthetic workspace. **Explore the source:** [`src/main.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/main.tsx) mounts the React app; [`src/App.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/App.tsx) owns its page and workspace state; [`src/data/demo.ts`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/data/demo.ts) defines the synthetic records. ## Next [#next] - Connect real sandbox records with [Sandbox setup](/example-rpm-app/web-dashboard/sandbox-setup). - Follow the navigation and view composition in [App shell](/example-rpm-app/web-dashboard/app-shell). # rpm-web-dashboard Canonical page: https://docs.ovok.com/example-rpm-app/web-dashboard [rpm-web-dashboard](https://github.com/Ovok-Dev/rpm-web-dashboard) is the standalone browser-based clinician example. It uses React, Vite, TypeScript, and `@ovok/core` to review patient records and measurements from one Ovok project. The dashboard opens in a synthetic demo workspace. It includes a patient directory, a patient review with readings and recent activity, read-only Signals status, and support links. It does not pair devices; that workflow belongs to the companion mobile app. ## Get started [#get-started] - [Run the demo locally](/example-rpm-app/web-dashboard/getting-started) with Node.js and npm. No account or environment file is needed to explore the synthetic workspace. - [Connect a sandbox project](/example-rpm-app/web-dashboard/sandbox-setup) when you have an authorized practitioner account and project configuration. ## Explore the code [#explore-the-code] | Workflow | Implementation guide | | --- | --- | | Navigation, page state, and workspace modes | [App shell](/example-rpm-app/web-dashboard/app-shell) | | Patient search and patient-linked readings | [Patient data flow](/example-rpm-app/web-dashboard/patient-data) | | Read-only Signals view and support links | [Signals and support](/example-rpm-app/web-dashboard/signals-and-support) | | Synthetic fixtures and focused checks | [Demo data and tests](/example-rpm-app/web-dashboard/demo-and-tests) | Each walkthrough links to the corresponding TypeScript implementation in the public [rpm-web-dashboard repository](https://github.com/Ovok-Dev/rpm-web-dashboard/tree/main/src). # Follow patient data through the dashboard Canonical page: https://docs.ovok.com/example-rpm-app/web-dashboard/patient-data The dashboard reads from one Ovok project through `@ovok/core`. Its data path is intentionally narrow: list the Patients visible to the practitioner, load measurements and questionnaire responses for the selected Patient, normalize those resources for display, and keep source timestamps in the review. ## Trace the SDK boundary [#trace-the-sdk-boundary] 1. [`src/lib/ovokClient.ts`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/lib/ovokClient.ts) lazily constructs and reuses one `OvokClient`, using the sandbox origin and tenant as public configuration. 2. [`src/lib/patientData.ts`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/lib/patientData.ts) calls `searchResources("Patient", ...)` for the directory. 3. When a Patient is selected, `loadPatientReview()` requests that Patient's measurement history and QuestionnaireResponses. The mapper sorts by recorded/authored time and converts supported Observation codes and QuestionnaireResponse answers into view models. 4. [`src/App.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/App.tsx) owns loading, empty, and error states, then passes the resulting review to the screen. 5. [`src/components/MeasurementCards.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/components/MeasurementCards.tsx) and [`src/components/PatientReviewPage.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/components/PatientReviewPage.tsx) render the normalized information with timestamps and source labels. The app does not create a clinical interpretation from these values. It presents the measurements and questionnaire entries returned for the selected Patient. ## Follow a focused implementation [#follow-a-focused-implementation] The small [`patientData.test.ts`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/lib/patientData.test.ts) suite exercises the mapping from SDK results into the review model. Read it beside `patientData.ts` when adding a supported resource or changing a display mapping. Continue to [Signals and support](/example-rpm-app/web-dashboard/signals-and-support) for the separate project-status path. # Connect rpm-web-dashboard to a sandbox Canonical page: https://docs.ovok.com/example-rpm-app/web-dashboard/sandbox-setup The demo works without a project. Use sandbox mode only after an administrator has prepared a project and practitioner account. ## Configure the browser app [#configure-the-browser-app] From the repository root, copy the example environment file: ```sh cp .env.example .env.local ``` Set the sandbox API origin and the tenant code for the same project: ```dotenv VITE_OVOK_API_BASE_URL=https://api.sandbox.ovok.com VITE_OVOK_TENANT_CODE=your-sandbox-tenant-code ``` `VITE_` values are included in browser-delivered code. They are public configuration, not a place for client secrets, service credentials, passwords, tokens, or patient data. Restart Vite after changing the file. ## Prepare practitioner access [#prepare-practitioner-access] Ask a project administrator to configure practitioner sign-in and a least-privilege AccessPolicy for the dashboard's patient reads. If the Signals page is used, the policy also needs the documented Signals read capabilities. Follow [project setup](/authentication/project-setup), [practitioner login](/authentication/practitioner-login), [Access Policies](/access-policies), and the [Signals access-policy guide](/access-policies/signals). In the app, choose **Connect sandbox** and sign in with the practitioner account. The dashboard reads only records returned for that authenticated user; it does not silently replace failed sandbox requests with demo data. **Explore the source:** [`src/lib/ovokClient.ts`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/lib/ovokClient.ts) constructs the client from the public environment values; [`src/components/SignInDialog.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/components/SignInDialog.tsx) submits the practitioner login through the SDK. # Explore Signals and support in the dashboard Canonical page: https://docs.ovok.com/example-rpm-app/web-dashboard/signals-and-support The dashboard's Signals page is a read-only view for a connected project. It does not configure enrollment, change thresholds, or acknowledge alerts, and it does not call the Signals service directly. ## Trace the request [#trace-the-request] When the practitioner is in sandbox mode and opens **Signals setup**, [`src/App.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/App.tsx) requests project settings and a limited list of unacknowledged raw alerts through the existing `OvokClient`. It tracks each result independently so one failed request does not erase a successful result from the other request. [`src/components/SignalsPage.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/components/SignalsPage.tsx) renders the returned status, alert list, loading and error states, and a read-only indicator. The source links and UI point administrators to the current Ovok setup and [Signals authorization guidance](/access-policies/signals). ## Support links [#support-links] [`src/components/SupportPage.tsx`](https://github.com/Ovok-Dev/rpm-web-dashboard/blob/main/src/components/SupportPage.tsx) is a small navigation surface for documentation and companion-device instructions. Device pairing remains in the patient mobile app. For the platform contract, see [Signals](/signals) and [Working with Signals as a connected part of Ovok](/signals/connected-ovok). # FHIR Basics Canonical page: https://docs.ovok.com/fhir-basics To follow along, use a sample FHIR bundle in an Ovok project. For import instructions, refer to the **Import Sample Data** guide. ## Why FHIR? [#why-fhir] Ovok stores healthcare data using FHIR, a standard for representing and exchanging clinical information. Using FHIR can help your team: - **Interoperate with partners.** Hospitals, practices, laboratories, and other healthcare partners increasingly expose FHIR APIs. Using shared resource formats makes it easier to connect systems. - **Adapt as your product grows.** Healthcare workflows and partner requirements vary. FHIR models common clinical concepts so teams can extend integrations without replacing a proprietary data model each time. FHIR is powerful and can take time to learn. This page introduces the concepts you will encounter when working with FHIR data in Ovok. For the complete specification, see the [official FHIR R4 documentation](https://hl7.org/fhir/R4/). ## Storing data: resources [#storing-data-resources] A core data object in FHIR is called a [**Resource**](/fhir-elements/foundation/resource). You can think of a resource as a typed object in an application. FHIR defines resources for healthcare concepts such as [`Patient`](/api/fhir/r4/patient), [`Medication`](/api/fhir/r4/medication), [`Device`](/api/fhir/r4/device), [`Observation`](/api/fhir/r4/observation), [`Procedure`](/api/fhir/r4/procedure), [`CarePlan`](/api/fhir/r4/care-plan), and [`Encounter`](/api/fhir/r4/encounter). Each field in a resource is an [**Element**](/fhir-elements/complex/element). Elements use primitive types such as [`string`](/fhir-elements/primitive/string), [`decimal`](/fhir-elements/primitive/decimal), and [`date`](/fhir-elements/primitive/date), or complex types such as [`HumanName`](/fhir-elements/complex/human-name) and [`Address`](/fhir-elements/complex/address). Most resources also have an [`id`](/fhir-elements/foundation/resource): a server-assigned identifier that is unique within that server. Browse all types in [FHIR Elements](/fhir-elements) or all resources in [FHIR resources](/api/fhir/r4). ### Example [Patient](/api/fhir/r4/patient) [#example-patient] The example below shows a fictional Patient resource with [`name`](/api/fhir/r4/patient), [`telecom`](/api/fhir/r4/patient), and [`address`](/api/fhir/r4/patient) elements. It contains no real patient information.
Show the Patient resource ```json { "resourceType": "Patient", "id": "patient-berlin-001", "name": [ { "use": "official", "family": "Mustermann", "given": ["Johann"] } ], "telecom": [ { "system": "phone", "value": "+49 30 0000 0000", "use": "mobile" } ], "address": [ { "use": "home", "line": ["Musterstraße 1"], "city": "Berlin", "postalCode": "10115", "country": "DE" } ] } ```
## Linking data: references [#linking-data-references] Clinical data is often split across multiple resources. A [`MedicationRequest`](/api/fhir/r4/medication-request), for example, refers to the [`Patient`](/api/fhir/r4/patient) it is for, and a [`DiagnosticReport`](/api/fhir/r4/diagnostic-report) can refer to several [`Observation`](/api/fhir/r4/observation) resources. A FHIR [**Reference**](/fhir-elements/complex/reference) links one resource to another, much like a foreign key in a relational database. A reference can include: - [`reference`](/fhir-elements/complex/reference) — the resource type and id, such as `Patient/patient-berlin-001`; - [`display`](/fhir-elements/complex/reference) — a human-readable label for the referenced item; - [`type`](/fhir-elements/complex/reference) — the resource type, commonly used with logical references; - [`identifier`](/fhir-elements/complex/reference) — an identifier for the target when a direct resource reference is not available. In Ovok, you will usually use `reference` and may include `display` for readability. ### Example: link a [MedicationRequest](/api/fhir/r4/medication-request) to a [Patient](/api/fhir/r4/patient) and [Practitioner](/api/fhir/r4/practitioner) [#example-link-a-medicationrequest-to-a-patient-and-practitioner] This fictional prescription request refers to a patient and the practitioner who requested it. The medication and dosage are illustrative only; they are not treatment instructions.
Show the linked resources ```json { "resourceType": "MedicationRequest", "id": "medication-request-001", "status": "active", "intent": "order", "medicationCodeableConcept": { "text": "Paracetamol", "coding": [ { "system": "http://fhir.de/CodeSystem/bfarm/atc", "code": "N02BE01", "display": "Paracetamol" } ] }, "subject": { "reference": "Patient/patient-berlin-001", "display": "Johann Mustermann" }, "dosageInstruction": [ { "text": "Example only — follow the approved medication plan." } ], "requester": { "reference": "Practitioner/practitioner-001", "display": "Dr. Erika Beispiel" } } ```
## Searching resources: search parameters [#searching-resources-search-parameters] Ovok exposes REST and GraphQL interfaces for querying FHIR data. Search is based on supported parameters for each resource rather than arbitrary fields. See the [GraphQL guide](/graphql), the [FHIR resource reference](/api/fhir/r4) for resource-specific search parameters, and the [Primitives reference](/primitives) for Ovok operations. ## Describing coded values: [CodeableConcept](/fhir-elements/complex/codeable-concept) [#describing-coded-values-codeableconcept] Healthcare systems use codes to represent diagnoses, procedures, observations, medications, and other clinical concepts consistently. In Germany, common terminology systems include **ICD-10-GM** for diagnoses, **OPS** for procedures, **ATC** for medication classification, and **PZN** for pharmaceutical products. Many clinical measurements also use international code systems such as LOINC. FHIR's [CodeableConcept](/fhir-elements/complex/codeable-concept) can carry human-readable [`text`](/fhir-elements/complex/codeable-concept) and one or more [`coding`](/fhir-elements/complex/codeable-concept) entries. Each [`Coding`](/fhir-elements/complex/coding) identifies its [`system`](/fhir-elements/complex/coding) and [`code`](/fhir-elements/complex/coding). A single concept can therefore be represented in more than one system when a workflow requires it. ### Example [CodeableConcept](/fhir-elements/complex/codeable-concept) [#example-codeableconcept] This example represents paracetamol using its ATC code. Add a PZN coding when your workflow needs to identify a specific pharmaceutical product or pack; use the value supplied by your trusted product catalogue. See [`Medication`](/api/fhir/r4/medication) for the resource structure that can carry coded medication information.
Show the CodeableConcept ```json { "text": "Paracetamol", "coding": [ { "system": "http://fhir.de/CodeSystem/bfarm/atc", "code": "N02BE01", "display": "Paracetamol" } ] } ```
The `system` is an absolute URI that identifies the code system. For example, the German FHIR base profiles use `http://fhir.de/CodeSystem/bfarm/atc` for ATC and `http://fhir.de/CodeSystem/ifa/pzn` for PZN. The codes themselves are maintained by their respective publishers and should come from an appropriate terminology service or catalogue. ## Naming data: [Identifier](/fhir-elements/complex/identifier) [#naming-data-identifier] The same person or organisation can have identifiers in several systems. A [`Patient`](/api/fhir/r4/patient) may have an organisation-local patient id, a hospital case number for an [`Encounter`](/api/fhir/r4/encounter), and—when required for the workflow—a German health insurance identifier. FHIR represents an identifier with the [`Identifier`](/fhir-elements/complex/identifier) type. Its [`system`](/fhir-elements/complex/identifier) and [`value`](/fhir-elements/complex/identifier) identify the authority or namespace that issued it and the value assigned there. Use a stable URI for systems you own, and follow the relevant German FHIR profiles for nationally defined identifiers. Prefer the Ovok resource `id` for references inside Ovok. Store external identifiers only when the workflow needs them, and handle personal identifiers such as a health insurance number with appropriate access controls. ### Example: [Patient](/api/fhir/r4/patient) with identifiers from different systems [#example-patient-with-identifiers-from-different-systems] This example uses clearly fictional values. The KVID value is a placeholder, not a valid insurance number.
Show the Patient identifiers ```json { "resourceType": "Patient", "id": "patient-berlin-001", "name": [ { "use": "official", "family": "Mustermann", "given": ["Johann"] } ], "identifier": [ { "system": "https://clinic.example.de/identifiers/patient-id", "value": "PAT-EXAMPLE-001" }, { "system": "http://fhir.de/sid/gkv/kvid-10", "value": "EXAMPLE-KVID" } ] } ```
HL7 Deutschland documents the German FHIR conventions for [health insurance identifiers](https://ig.fhir.de/basisprofile-de/stable/ig-markdown-LebenslangeKrankenversichertennummer10-stelligeKVID-Identifier.html) and [medication code systems](https://ig.fhir.de/basisprofile-de/stable/ig-markdown-Medication-CodeSystem.html). Check the applicable profile before exchanging these identifiers with a partner. ## Restricting codes: [ValueSets](/api/fhir/r4/value-set) [#restricting-codes-valuesets] A [**ValueSet**](/api/fhir/r4/value-set) defines which codes are allowed for a particular use. Its [`compose`](/api/fhir/r4/value-set) element can select a subset from a larger code system—for example, the observation codes an application accepts for a vital-sign workflow. German projects may draw on systems such as ICD-10-GM, OPS, ATC, and PZN, alongside international systems such as LOINC. This example shows a small set of LOINC codes for common vital signs. The URI is illustrative; define and publish the canonical URL for your own ValueSet. ```json { "resourceType": "ValueSet", "url": "https://example.org/fhir/ValueSet/vital-signs", "name": "VitalSigns", "title": "Vital signs", "status": "active", "compose": { "include": [ { "system": "http://loinc.org", "concept": [ { "code": "8310-5", "display": "Body temperature" }, { "code": "8462-4", "display": "Diastolic blood pressure" }, { "code": "8480-6", "display": "Systolic blood pressure" }, { "code": "8867-4", "display": "Heart rate" }, { "code": "9279-1", "display": "Respiratory rate" } ] } ] } } ``` ## Listening for changes: [Subscriptions](/api/fhir/r4/subscription) [#listening-for-changes-subscriptions] FHIR's [`Subscription`](/api/fhir/r4/subscription) resource describes how an application can be notified when matching data changes. Its [`criteria`](/api/fhir/r4/subscription) selects resources using a FHIR search expression; its [`channel`](/api/fhir/r4/subscription) describes how notifications are delivered. Available channels and behavior depend on the FHIR version and the Ovok project configuration. An Ovok Bot can be used in a configured workflow to respond to data changes. See the [Primitives reference](/primitives) for supported subscription and bot operations. ## Further reading [#further-reading] - [Official FHIR R4 documentation](https://hl7.org/fhir/R4/) - [HL7 Deutschland FHIR Base Profiles](https://ig.fhir.de/basisprofile-de/stable/) - [FHIR resources](/api/fhir/r4) - [Ovok primitives](/primitives) # Get started Canonical page: https://docs.ovok.com/get-started

Ovok is a FHIR backend for medical apps. It stores your clinical data as FHIR R4, brings readings in from supported devices, and hands vital signs to Signals for alert decisions.

Your team builds the patient and clinician experience. Ovok runs the data, device and alerting layer underneath.

Create your first app →
Sandbox
Base URL
https://api.sandbox.ovok.com
FHIR path
/fhir/R4/
Create an app
pnpm create ovok my-app
## Start building [#start-building] Scaffold web and mobile apps connected to the sandbox with `create-ovok`. Create a project and turn on the sign-in your users need. Resources, references and searches, the way Ovok uses them. A patient app, a clinician dashboard and a clinic EHR, all public. The Ovok skill, the MCP server and the AI-readable docs. Build a remote-monitoring app from sign-in to alerts. ## How Ovok fits together [#how-ovok-fits-together] - **FHIR data.** Patients, devices, observations and the rest live as FHIR R4 resources, with focused routes for common monitoring workflows. - **Devices.** Readings from supported blood-pressure monitors, sleep radars, SpO₂ monitors, urine analysers and wearables arrive as observations you can read live or as history. - **Care operations.** Projects and sub-projects organise patients, devices, thresholds and teams. - **Alerts.** For patients enrolled in [Signals](/signals), an MDR Class IIa medical device, Ovok forwards eligible vital signs and brings the alert decisions back into your app. ## Choose your SDK [#choose-your-sdk] | SDK | Package | Use it for | | --- | --- | --- | | [JavaScript](/web-sdk) | `@ovok/core` | Web apps and TypeScript services | | [React Native](/native-sdk) | `@ovok/native` | Mobile apps, Bluetooth devices, health-data sync | | [Java](/java-sdk) | `com.ovok:ovok-sdk` | JVM services | | [Python](/python-sdk) | `ovok-sdk` | Services, scripts and data work | | [Flutter](/flutter-sdk) | `ovok_sdk` | Dart and Flutter apps | Every SDK speaks to the same API, so you can also call it directly: start with [authentication](/authentication) and the [FHIR resources](/api/fhir/r4). ## See also [#see-also] - [Create your first app](/get-started/quickstart) - [Access policies](/access-policies) - [Signals](/signals) - [Errors](/errors) # Create your first Ovok app Canonical page: https://docs.ovok.com/get-started/quickstart `create-ovok` sets up a Turborepo with a web app, a mobile app or both, already connected to your Ovok project. The web app signs a practitioner in and lists the project's patients, so you can see data flow end to end before you write any code. ## Set up [Console] [#set-up-console] You need: - Node.js 22 or newer and [pnpm](https://pnpm.io/installation). - An Ovok project and its tenant code. [Set up your project](/authentication/project-setup) shows where to find it. - A practitioner account in that project, to sign in to the web app. - For the mobile app, Xcode or Android Studio to build the development client. ## Create the workspace [Terminal] [#create-the-workspace-terminal] Run `create-ovok` with the name of your workspace folder: ```bash title="Terminal" pnpm create ovok my-app ``` It asks for the apps you want and your tenant code, then installs dependencies and makes the first git commit. The recommended setup creates a web app and a mobile app for iOS and Android, pointed at the sandbox. Flags answer the questions up front, which is useful in scripts: | Flag | Answers | | --- | --- | | `--platform web\|mobile\|mobile-web` | The apps to start with | | `--type ios\|android` | One mobile platform instead of both | | `--tenant {{TENANT_CODE}}` | Your Ovok tenant code | | `--base-url https://api.sandbox.ovok.com` | The Ovok API URL | | `--yes` | Every other question, with the recommended setup | | `--skip-install` | Leaves `pnpm install` to you | | `--disable-git` | Leaves the folder without a git repository | The result: - `apps/` holds the apps you chose. - `.env` sets `OVOK_BASE_URL` and `OVOK_TENANT_CODE` for every app. - `.mcp.json` registers the Ovok MCP server, so coding agents in the workspace can read your project. - Each app has an `AGENTS.md` with the Ovok rules for coding agents, and a `CLAUDE.md` that imports it. ## Start the web app [Client-side] [#start-the-web-app-client-side] ```bash title="Terminal" cd my-app pnpm dev ``` The web app creates one client for the whole app from `.env`: ```ts title="apps/web/src/ovok.ts" import { Ovok } from '@ovok/core/next'; export const ovok = new Ovok({ baseUrl: import.meta.env.OVOK_BASE_URL, tenantCode: import.meta.env.OVOK_TENANT_CODE, fhirPath: '/fhir/R4/', }); ``` Sign in with your practitioner's email and password. The app calls `ovok.auth.login` and then searches the project's `Patient` resources. ### Verify your integration [#verify-your-integration] You should see a list of up to 10 patients from your project, or an empty list in a new project. If you don't: 1. Check that `.env` has your tenant code and `https://api.sandbox.ovok.com`. 2. Check that the account is a practitioner in that project. 3. Look up the error the app shows in [Errors](/errors). ## Start the mobile app [Client-side] [#start-the-mobile-app-client-side] The mobile app runs in an Expo development client, which you build once per platform: ```bash title="Terminal" cd apps/mobile pnpm ios # or: pnpm android ``` After the first build, `pnpm dev` starts the bundler and the installed client reloads as you edit. ## Test your integration [#test-your-integration] 1. Start the web app and sign in as a practitioner. 2. Create a patient in the project, for example with the [Slim API](/slim-apis/patient/create-patient). 3. Sign in again and check the new patient appears. | Scenario | How to trigger it | Expected result | | --- | --- | --- | | Signed in | Valid practitioner email and password | The patient list | | Wrong password | Any other password | An error message; no list | | Second factor needed | An account with MFA on | A note to finish with `ovok.auth.verifyMfa` | ## Optional: Grow the workspace [Terminal] [#optional-grow-the-workspace-terminal] Add apps and shared code with the generators `create-ovok` installed: ```bash title="Terminal" pnpm turbo gen app # add a web or mobile app pnpm turbo gen package # add a shared package pnpm turbo gen agents # refresh the Ovok rules in every AGENTS.md ``` ## See also [#see-also] - [Set up your project](/authentication/project-setup) - [JavaScript SDK](/web-sdk) - [React Native SDK](/native-sdk) - [Build with AI agents](/working-with-ai-agents) # Step 6 · Build onboarding and authentication Canonical page: https://docs.ovok.com/guides/chf-remote-monitoring/build-onboarding-and-authentication An email-and-password patient flow with registration, sign-in, and a protected patient route group. The native forms call the configured Ovok client and activate the returned login; the app decides what to show before and after that flow. ## Before you begin [#before-you-begin] - The configured sandbox client and tenant code from step 2. - The providers from step 5. - `@ovok/native` authentication forms available below `OvokProvider` and the native `ThemeProvider`. ## Build it [Client-side] [#build-it-client-side] ### Add the sign-in screen [#add-the-sign-in-screen] Create `app/sign-in.tsx`: ~~~tsx import { SignIn, useSession } from "@ovok/native"; import { Redirect, useRouter } from "expo-router"; import { useTranslation } from "react-i18next"; import { ActivityIndicator, Alert, View } from "react-native"; import { ovokConfig } from "../src/config/ovok"; export default function SignInScreen() { const router = useRouter(); const { t } = useTranslation(); const { status } = useSession({ sessions: false }); if (status === "loading") return ; if (status === "authenticated") return ; return ( router.replace("/(patient)")} onError={() => Alert.alert(t("auth.signInFailed"), t("errors.tryAgain")) } > router.push("/register")} /> ); } ~~~ `SignIn.EmailForm` owns the standard credential and supported MFA exchange. Its `onSuccess` callback runs after the form activates the login. Do not store a second copy of the credentials or build a parallel authentication request. See [Native authentication](/native-sdk/guide/modules/auth) and [session management](/native-sdk/guide/components/auth/session). ### Add registration [#add-registration] Create `app/register.tsx`: ~~~tsx import { Register, useSession } from "@ovok/native"; import { Redirect, useRouter } from "expo-router"; import { useTranslation } from "react-i18next"; import { ActivityIndicator, Alert, View } from "react-native"; import { Text } from "react-native-paper"; import { ovokConfig } from "../src/config/ovok"; export default function RegisterScreen() { const router = useRouter(); const { t } = useTranslation(); const { status } = useSession({ sessions: false }); if (status === "loading") return ; if (status === "authenticated") return ; return ( router.replace("/(patient)")} onError={() => Alert.alert(t("auth.registrationFailed"), t("errors.tryAgain")) } onNextStep={(step) => { if (step.nextStep === "clinician-invite") { Alert.alert( t("auth.checkEmailTitle"), t("auth.checkEmailForInvitation"), ); } }} > router.push("/sign-in")} /> ); } ~~~ The optional `onNextStep` handles the configured business-email clinician-invite outcome. If that project setting is not used, remove the callback. The ordinary patient-registration path creates and activates the patient account through the SDK; do not create a duplicate Patient resource. ### Protect the patient route group [#protect-the-patient-route-group] Update `app/(patient)/_layout.tsx` so Bluetooth starts only after a patient is authenticated: ~~~tsx import { useSession } from "@ovok/native"; import { Redirect, Slot } from "expo-router"; import { ActivityIndicator } from "react-native"; import { BluetoothWorkspace } from "../../src/features/bluetooth/device-state"; export default function PatientLayout() { const { status } = useSession({ sessions: false }); if (status === "loading") return ; if (status !== "authenticated") return ; return ( ); } ~~~ Create `app/index.tsx` to choose the initial route: ~~~tsx import { useSession } from "@ovok/native"; import { Redirect } from "expo-router"; import { ActivityIndicator } from "react-native"; export default function IndexScreen() { const { status } = useSession({ sessions: false }); if (status === "loading") return ; return status === "authenticated" ? ( ) : ( ); } ~~~ Expo Router still registers these screens as routes, but signed-in users are immediately redirected away from sign-in and registration. The protected layout also redirects a signed-out user before mounting the Bluetooth provider. ### Add consent at the right point [#add-consent-at-the-right-point] Insert your product's approved consent and privacy step before registration or before entering the monitoring workflow, according to the intended purpose and the decisions made by your clinical and legal teams. The SDK does not supply consent language or decide when consent is legally required. Do not treat a generic checkbox as a substitute for your approved consent flow. ## Key decisions [#key-decisions] - Patient self-registration needs `PATIENT_REGISTRATION_ENABLED` enabled and a project default Patient AccessPolicy. Confirm both in [patient registration setup](/authentication/patient-registration) before testing. - Patient sign-in uses the sandbox tenant code. Keep it in public app configuration; it is not a password or secret. - The built-in forms manage their own supported MFA behavior. Your route guard uses `useSession`; it does not authorize individual FHIR operations. - A Patient profile is created by the registration workflow. Only add a separate profile-initialization step if your project requires additional fields and the current SDK supports that workflow. ## Verify your integration [#verify-your-integration] A signed-out person can register or sign in with the sandbox project, and a successful login opens the patient route group. A signed-in person cannot remain on the auth screens, and a signed-out person cannot mount the patient Bluetooth workspace. ## Troubleshooting [#troubleshooting] - **Registration returns a project configuration error:** confirm patient registration is enabled and the default Patient AccessPolicy exists. - **The form rejects a valid account:** verify the tenant code and API URL belong to the same sandbox project. - **The route stays on the loading indicator:** inspect `useSession`'s error state in a development-only diagnostic screen; do not treat a failed refresh as proof of a valid session. - **Registration shows an invitation message instead of entering the app:** check whether the project routes business-email registrations to clinician invitations and handle that next step intentionally. ## Next step [#next-step] Continue to [step 7: build the measurement screen](/guides/chf-remote-monitoring/build-the-measurement-screen). # Step 9 · Build Settings Canonical page: https://docs.ovok.com/guides/chf-remote-monitoring/build-settings A patient account screen that edits fields on the active Patient profile, links to device management, lets the patient switch app language, surfaces the product's approved privacy and consent information, and signs out through the SDK. ## Before you begin [#before-you-begin] - The authenticated route group and tabs from step 8. - `useSession` returning the active Patient profile. - CMS-backed i18next initialized in step 3. - A product-approved privacy and consent destination. ## Build it [Client-side] [#build-it-client-side] Create `app/(patient)/settings.tsx`: ~~~tsx import { LogoutButton, ProfileForm, useSession } from "@ovok/native"; import { LanguageSwitcher } from "@ovok/native/language-switcher"; import Constants from "expo-constants"; import { Link } from "expo-router"; import { useTranslation } from "react-i18next"; import { Alert, Linking, ScrollView } from "react-native"; import { Button, Card, Text } from "react-native-paper"; export default function SettingsScreen() { const { t, i18n } = useTranslation(); const { status, profile } = useSession({ sessions: false }); if (status === "loading") { return {t("settings.loading")}; } if (status !== "authenticated" || !profile) { return {t("auth.sessionUnavailable")}; } const fields = [ { name: "name[0].given", label: t("settings.firstName"), type: "text" as const, value: profile.name?.[0]?.given?.[0] ?? "", }, { name: "name[0].family", label: t("settings.lastName"), type: "text" as const, value: profile.name?.[0]?.family ?? "", }, ]; return ( {t("settings.title")} Alert.alert(t("settings.profileSaved")) } /> void i18n.changeLanguage(language)} > {t("languages.english")} {t("languages.german")} {t("settings.manageDevices")} {t("settings.privacyDescription")} {t("settings.consentDescription")} {t("settings.notificationsNotConfigured")} Alert.alert(t("settings.signOutFailed"), t("errors.tryAgain")) } /> {t("settings.appVersion", { version: Constants.expoConfig?.version ?? "—", })} ); } ~~~ Replace the privacy link with the privacy policy for your product, and connect the consent copy to the consent records or workflow your organization actually uses. The example link is only the public Actimi privacy page; it does not record consent. The profile form patches only the fields passed to it. Check the project's Patient AccessPolicy and product rules before exposing editable fields. `LogoutButton` ends the current Ovok session; the protected layout routes the signed-out person back to sign-in. This tutorial does not add notification toggles because no notification delivery channel has been configured. A settings control should reflect a real, supported capability. ## Key decisions [#key-decisions] - Profile fields are supplied from the loaded Patient profile; `ProfileForm` does not fetch initial values itself. See [ProfileForm](/native-sdk/guide/components/auth/profile). - Language selection changes the app's active i18next locale. The CMS hook fetches the matching published translation groups after the change. This tutorial keeps the choice in memory; persist it only if your app defines a preference-storage policy. - Device pairing belongs on the Devices screen, not in account identity fields. - A successful logout is followed by the auth guard; do not treat a rendered button callback as proof of server-side success. ## Verify your integration [#verify-your-integration] The Settings tab displays current profile fields, saves permitted edits, switches the CMS-backed app language between English and German, links to device management and privacy information, and signs the patient out. ## Troubleshooting [#troubleshooting] - **Profile values are blank:** confirm `useSession` has loaded the active Patient and the AccessPolicy permits the selected fields. - **A profile edit is refused:** check which Patient fields the policy and project allow the patient to update; remove unsupported fields from the form. - **Language changes but text does not:** make sure the corresponding CMS translation groups are published for that locale and environment, and the screen uses `useTranslation()` rather than hard-coded labels. - **Logout shows an error:** keep the user in the protected area until the auth state changes; show a retry path rather than assuming the request succeeded. ## Next step [#next-step] Continue to [step 10: complete localisation](/guides/chf-remote-monitoring/complete-localisation). # Step 8 · Build the Devices section Canonical page: https://docs.ovok.com/guides/chf-remote-monitoring/build-the-devices-section A Devices tab where the patient can discover and pair supported hardware, see the current connection and optional battery state, and remove a remembered device. Pairing state is stored locally; measurements continue to be saved separately through the flow from step 7. ## Before you begin [#before-you-begin] - `BTProvider` with the accepted BP2 and F4 declarations. - The `DeviceStateContext` connection and last-upload state from step 7. - `expo-secure-store` installed in step 1. ## Build it [Client-side] [#build-it-client-side] Update `app/(patient)/_layout.tsx` to use tabs in the authenticated area: ~~~tsx import { useSession } from "@ovok/native"; import { Redirect, Tabs } from "expo-router"; import { ActivityIndicator } from "react-native"; import { useTranslation } from "react-i18next"; import { BluetoothWorkspace } from "../../src/features/bluetooth/device-state"; export default function PatientLayout() { const { status } = useSession({ sessions: false }); const { t } = useTranslation(); if (status === "loading") return ; if (status !== "authenticated") return ; return ( ); } ~~~ Create `app/(patient)/devices.tsx`: ~~~tsx import { PairingFlow } from "@ovok/native/ui"; import * as SecureStore from "expo-secure-store"; import { useContext } from "react"; import { Alert, Linking, ScrollView, View } from "react-native"; import { Button, Card, Text } from "react-native-paper"; import { useTranslation } from "react-i18next"; import { DeviceStateContext } from "../../src/features/bluetooth/device-state"; const pairedDeviceStorage = { getItem: (key: string) => SecureStore.getItemAsync(key), setItem: (key: string, value: string) => SecureStore.setItemAsync(key, value), }; export default function DevicesScreen() { const { t, i18n } = useTranslation(); const deviceState = useContext(DeviceStateContext); return ( {t("devices.title")} {t("devices.intro")} {Object.entries(deviceState?.devices ?? {}).map(([id, device]) => ( {typeof device.batteryLevel === "number" && ( {t("devices.battery", { value: device.batteryLevel })} )} {device.hasError && {t("devices.connectionProblem")}} ))} {t("devices.lastUpload")} {deviceState?.lastSavedAt ? deviceState.lastSavedAt.toLocaleString(i18n.language) : t("devices.noRecentUpload")} ( {actions.status === "paired" ? ( ) : ( )} )} onError={() => Alert.alert(t("devices.pairingFailed"), t("errors.tryAgain")) } /> {t("devices.catalogPrompt")} ); } ~~~ The `PairingFlow` must render beneath the `BTProvider` from step 5. It owns discovery UI and reads the provider runtime; it does not create a second BLE manager. Its `forget()` action forgets the active device and removes the remembered ID. The SDK currently reports battery percentage only when the connected device exposes the supported battery service. The catalog contains artwork, device details, and image credits; use those assets and credits through the [supported-device catalog](/native-sdk/guide/components/bt-management/supported-devices) rather than copying manufacturer images into this app. Follow the device's supplied instructions for the actual measurement procedure. ## Key decisions [#key-decisions] - The pairing ID is saved locally by `PairingFlow`; it is not an account credential or FHIR resource. - This tutorial stores only the last successful upload timestamp in memory. It resets when this app session ends; it is not a durable per-device sync history. - Do not display Bluetooth peripheral IDs to patients or log them. - Bluetooth pairing and measurement are separate states. A paired device is not proof that a reading was saved. ## Verify your integration [#verify-your-integration] The authenticated patient can see discovered supported devices, start pairing, see paired status, and forget the current device. Connected devices show status and battery only when the runtime provides it; successful measurement upload time is shown separately. ## Troubleshooting [#troubleshooting] - **The list is empty:** use a physical phone, grant Bluetooth permission, wake the device, and keep the app open while discovery runs. - **The device appears but pairing fails:** check Bluetooth is enabled, device is not connected to another phone, and follow the model-specific instructions in the catalog or device packaging. - **Battery is absent:** the device may not expose a battery level; do not invent or estimate one. - **A pair action remains pending:** inspect `PairingFlow.onError` in development and verify that only one provider owns this scan. - **Last upload disappears after restart:** this page intentionally reports app-session state only. A durable sync history needs an app-owned persisted record or a server query. ## Next step [#next-step] Continue to [step 9: build Settings](/guides/chf-remote-monitoring/build-settings). # Step 7 · Build the measurement screen Canonical page: https://docs.ovok.com/guides/chf-remote-monitoring/build-the-measurement-screen A patient dashboard for blood pressure, ECG, pulse when supplied, body weight, connection state, and recent saved readings. The flow is: device reading → normalized SDK result → authenticated Patient association → Ovok measurement save → FHIR-backed query → screen refresh. ## Before you begin [#before-you-begin] - The authenticated route group from step 6. - `BTProvider` mounted once in `BluetoothWorkspace` from step 5. - `acceptedDevices` containing `IntegratedDevices.BP2` and `IntegratedDevices.F4`. - `transaction-bundles` enabled in the sandbox project. ## Build it [Client-side] [#build-it-client-side] ### Save BP2 and scale readings from the provider event [#save-bp2-and-scale-readings-from-the-provider-event] Replace `src/features/bluetooth/device-state.tsx` with this version. It keeps the provider in one place and saves the blood-pressure, ECG, and body-weight result categories: ~~~tsx import { MeasurementTypeKey, useClient, } from "@ovok/core"; import { useSession } from "@ovok/native"; import { BTProvider } from "@ovok/native/bt-management"; import { BleManager } from "react-native-ble-plx"; import * as React from "react"; import { acceptedDevices } from "./accepted-devices"; type DeviceInfo = { name: string; status: string; batteryLevel?: number; hasError?: boolean; }; type DeviceState = { devices: Record; saveState: "idle" | "saving" | "saved" | "error"; lastSavedAt: Date | null; }; export const DeviceStateContext = React.createContext(null); const bleManager = new BleManager(); export function BluetoothWorkspace({ children, }: React.PropsWithChildren) { const client = useClient(); const { profile } = useSession({ sessions: false }); const [devices, setDevices] = React.useState({}); const [saveState, setSaveState] = React.useState("idle"); const [lastSavedAt, setLastSavedAt] = React.useState(null); return ( { setDevices((current) => ({ ...current, [deviceData.id]: { ...current[deviceData.id], name: deviceData.model || deviceData.localName || "", status, hasError: false, }, })); }} onConnectionEvent={({ deviceData, batteryLevel }) => { if (typeof batteryLevel !== "number") return; setDevices((current) => ({ ...current, [deviceData.id]: { ...current[deviceData.id], name: deviceData.model || deviceData.localName || "", status: current[deviceData.id]?.status ?? "Disconnected", batteryLevel, }, })); }} onError={({ deviceData }) => { if (!deviceData) return; setDevices((current) => ({ ...current, [deviceData.id]: { ...current[deviceData.id], name: deviceData.model || deviceData.localName || "", status: current[deviceData.id]?.status ?? "Disconnected", hasError: true, }, })); }} onResult={({ deviceData, data }) => { if ( data.measurementTypeKey !== MeasurementTypeKey.bloodPressure && data.measurementTypeKey !== MeasurementTypeKey.ecg && data.measurementTypeKey !== MeasurementTypeKey.bodyWeight ) { return; } if (!profile?.id) { setSaveState("error"); return; } setSaveState("saving"); void client .saveMeasurement({ patientId: profile.id, device: deviceData, measurement: data, effectiveDateTime: data.recordedAt ?? new Date(), }) .then(() => { setLastSavedAt(new Date()); setSaveState("saved"); }) .catch(() => setSaveState("error")); }} > {children} ); } ~~~ `onResult` is an immediate callback; the provider does not wait for this save. This foreground tutorial reports the outcome in the app and does not promise offline delivery. If your product must retain readings through process death or network loss, implement the documented [React Native SDK background delivery flow](/native-sdk/guide/modules/background-sync) and its durable storage acknowledgement separately. The device's `recordedAt` is used when supplied. Otherwise the app uses the time it received the reading. `bodyWeight` is saved in kilograms. The BP2 reports ECG as a separate `ecg` result with its waveform samples in `diagramPoints`; the typed measurement API saves those samples, duration, optional heart rate, and optional device-reported result label. See the [ECG](/web-sdk/core/measurements/ecg), [blood-pressure](/web-sdk/core/measurements/blood-pressure), and [body-weight](/web-sdk/core/measurements/body-weight) references. ### Build the dashboard [#build-the-dashboard] Create `app/(patient)/index.tsx`: ~~~tsx import { MeasurementTypeKey, useObservations, type BloodPressureMeasurement, type BodyWeightMeasurement, } from "@ovok/core"; import { useSession } from "@ovok/native"; import { EcgStripViewer } from "@ovok/native/ui"; import { useEffect, useContext } from "react"; import { ActivityIndicator, ScrollView, View } from "react-native"; import { Button, Card, Text } from "react-native-paper"; import { useTranslation } from "react-i18next"; import { DeviceStateContext } from "../../src/features/bluetooth/device-state"; const readingTypes = [ MeasurementTypeKey.bloodPressure, MeasurementTypeKey.ecg, MeasurementTypeKey.bodyWeight, ] as const; const previewMeasurements: (BloodPressureMeasurement | BodyWeightMeasurement)[] = __DEV__ ? [ { measurementTypeKey: MeasurementTypeKey.bloodPressure, systolic: 121, diastolic: 79, heartRate: 68, recordedAt: new Date(), }, { measurementTypeKey: MeasurementTypeKey.bodyWeight, bodyWeight: 72.4, recordedAt: new Date(), }, ] : []; function PatientReadings({ patientId }: { patientId: string }) { const { t, i18n } = useTranslation(); const deviceState = useContext(DeviceStateContext); const { measurements, loading, error, refetch, } = useObservations({ types: readingTypes, patientId, count: 20, sort: "-date", }); useEffect(() => { if (deviceState?.lastSavedAt) void refetch(); }, [deviceState?.lastSavedAt, refetch]); if (loading) return ; if (error) { return ( {t("readings.loadFailed")} ); } if (measurements.length === 0) { if (!__DEV__) return {t("readings.empty")}; } const showingPreview = __DEV__ && measurements.length === 0; const visibleMeasurements = showingPreview ? previewMeasurements : measurements; return ( {showingPreview && {t("readings.preview")}} {visibleMeasurements.map((measurement, index) => { const time = measurement.recordedAt?.toLocaleString(i18n.language); const title = measurement.measurementTypeKey === MeasurementTypeKey.bloodPressure ? t("readings.bloodPressure") : measurement.measurementTypeKey === MeasurementTypeKey.bodyWeight ? t("readings.bodyWeight") : t("readings.ecg"); return ( {measurement.measurementTypeKey === MeasurementTypeKey.bloodPressure ? ( <> {t("readings.bloodPressureValue", { systolic: measurement.systolic ?? "—", diastolic: measurement.diastolic ?? "—", })} {t("readings.pulseValue", { value: measurement.heartRate ?? "—", })} ) : measurement.measurementTypeKey === MeasurementTypeKey.bodyWeight ? ( {t("readings.weightValue", { value: measurement.bodyWeight ?? "—", })} ) : ( <> {measurement.heartRate != null && ( {t("readings.pulseValue", { value: measurement.heartRate })} )} {measurement.diagnosticResult && ( {t("readings.ecgDeviceResult", { value: measurement.diagnosticResult, })} )} {measurement.diagramPoints?.length && measurement.duration && measurement.duration > 0 ? ( ) : ( {t("readings.ecgWaveformUnavailable")} )} {t("readings.ecgDisclaimer")} )} ); })} ); } export default function MeasurementScreen() { const { t } = useTranslation(); const { status, profile } = useSession({ sessions: false }); const deviceState = useContext(DeviceStateContext); if (status === "loading") return ; if (status !== "authenticated" || !profile?.id) { return {t("auth.sessionUnavailable")}; } const connected = Object.values(deviceState?.devices ?? {}).some( (device) => device.status === "Connected" || device.status === "Measuring", ); return ( {t("readings.title")} {connected ? t("devices.connected") : t("devices.notConnected")} {t("readings.devicePrompt")} {deviceState?.saveState === "saving" && {t("readings.saving")}} {deviceState?.saveState === "saved" && {t("readings.saved")}} {deviceState?.saveState === "error" && ( {t("readings.saveFailed")} )} ); } ~~~ The person starts a blood-pressure measurement or ECG recording with the BP2's physical controls and takes a weight reading by standing on the scale. This provider integration does not expose a `startMeasurement()` command. Do not add a fake start button. During development, the dashboard shows two clearly labelled in-memory blood-pressure and weight samples only when the server has no readings; it never passes those fixtures to `saveMeasurement()`. Do not synthesize ECG traces or use sample readings to validate device behavior or clinical workflows. See [useObservations](/web-sdk/core/hooks/use-observations) for query filters and return states. ## Key decisions [#key-decisions] - The patient route is already authenticated; `patientId` is still passed explicitly so the query is scoped to that Patient. - A blood-pressure reading can contain an optional heart-rate value. Render it as unavailable when the monitor did not provide it; do not derive it. - The BP2's ECG `diagramPoints` are waveform samples in millivolts. `EcgStripViewer` only presents the supplied trace; it does not decode, analyze, or diagnose it. - A device-reported ECG label is shown as source data. It is not an Ovok interpretation or a diagnosis. - The app refreshes after a successful save. A visible “saved” state means the immediate request completed; this sample has no durable offline queue. - Do not interpret readings or assign alert thresholds in this UI. Alert decisions and care escalation belong to the configured clinical workflow. ## Verify your integration [#verify-your-integration] With a paired device, blood-pressure, ECG, or weight data arrives through `BTProvider.onResult`, the app saves it to the authenticated Patient, and the dashboard refreshes from Ovok. ECG recordings with valid waveform samples and timing appear in `EcgStripViewer`. Without a device, the dashboard still shows its connection, empty, loading, and error states. ## Troubleshooting [#troubleshooting] - **The provider sees a reading but it is not saved:** check that the result type is blood pressure, ECG, or body weight, then check the current Patient session, API environment, AccessPolicy, and `transaction-bundles` feature. - **The ECG waveform is missing:** the viewer needs a non-empty `diagramPoints` array and a positive `duration`; show the source metadata and unavailable state instead of fabricating samples. - **Weight looks off:** confirm the UI says kilograms and never treats the value as pounds. - **A reading disappears when the app closes before upload:** this sample uses immediate foreground writes. Add and validate the SDK's opt-in durable background delivery before promising queued or background uploads. - **Pulse is blank:** the BP2 may not include heart rate in a particular result; the app correctly leaves it unavailable. ## Next step [#next-step] Continue to [step 8: build the Devices section](/guides/chf-remote-monitoring/build-the-devices-section). # Step 4 · Choose connected devices Canonical page: https://docs.ovok.com/guides/chf-remote-monitoring/choose-connected-devices A small, explicit device allowlist for the tutorial. The SDK catalog is the source of truth for supported models, measurement types, product artwork, image credits, and any manual links it publishes. ## Before you begin [#before-you-begin] - The Expo project and English locale. - A product scope that collects blood pressure, heart rate when supplied by the BP2, and body weight. ## Build it [Client-side] [#build-it-client-side] The current supported-device catalog contains these entries: | Catalog entry | Catalog ID | Runtime declaration | Measurements used here | | --- | --- | --- | --- | | Viatom BP2 | catalog-viatom-bp2 | IntegratedDevices.BP2 | Blood pressure and ECG; heart rate when the reading includes it | | Viatom F4 / LeScale | catalog-viatom-f4-lescale | IntegratedDevices.F4 | Body weight | Add src/features/bluetooth/accepted-devices.ts: ~~~ts import { IntegratedDevices } from "@ovok/native/bt-management"; export const acceptedDevices = [ IntegratedDevices.BP2, IntegratedDevices.F4, ] as const; ~~~ These are two different identifiers: the catalog ID is metadata for finding the catalog entry; IntegratedDevices.BP2 and IntegratedDevices.F4 are the runtime declarations passed to BTProvider. Do not substitute the catalog IDs into acceptedDevices. Open the [full supported-device catalog](/native-sdk/guide/components/bt-management/supported-devices) to review the catalog's current images and credits, supported measurements, and any available device instructions. The catalog can change independently of this tutorial. ## Key decisions [#key-decisions] - BP2 reports blood pressure and ECG as distinct normalized measurements. The app stores both; an ECG result may include a waveform, duration, heart rate, and a device-reported diagnostic label. - BP2's normalized blood-pressure result can include heartRate. Do not rename that field in the API payload; the patient UI may label it “Pulse”. - The F4 / LeScale contributes bodyWeight in kilograms. The measurement save API expects kilograms and does not convert pounds. - Read the instructions supplied with the exact device model. Do not copy manufacturer instructions or artwork into your app unless you have rights to do so. ## Verify your integration [#verify-your-integration] The app has one stable accepted-device array containing BP2 and F4. The catalog shows the correct measurement types and current links for each supported entry. ## Troubleshooting [#troubleshooting] - **A device appears in the catalog but cannot be passed to Bluetooth:** check the entry's acceptedDevices value and use the SDK runtime enum, not the catalog ID. - **The BP2 ECG card has no waveform:** confirm the result includes `diagramPoints` and a positive `duration`; the screen cannot render a waveform without valid samples and timing. - **Weight has the wrong unit:** confirm the app displays and saves kilograms; add an explicit unit conversion only if your product receives a different unit from another supported source. ## Next step [#next-step] Continue to [step 5: initialise Ovok and Bluetooth](/guides/chf-remote-monitoring/initialise-ovok-and-bluetooth). # Step 10 · Complete localisation with Ovok CMS Canonical page: https://docs.ovok.com/guides/chf-remote-monitoring/complete-localisation The finished app loads all patient-facing UI text from published Ovok CMS `translations` documents. English and German values are authored in the Console; no app translation JSON files are created or bundled. Changing language with the Settings screen makes the React Native SDK fetch the matching CMS locale and update i18next. ## Before you begin [#before-you-begin] - CMS enabled for the sandbox project and `LocalizationGate` mounted in the root layout. - English text in the `app` translation group from step 3. - `useTranslation()` in the onboarding, measurement, device, and Settings screens. - `LanguageSwitcher` in Settings with `en` and `de` options. ## Build it [Client-side] [#build-it-client-side] ### Publish one `translations` document for each group [#publish-one-translations-document-for-each-group] In the Ovok Console, open the sandbox project's CMS and add the groups below to the built-in `translations` collection. Each row is one i18next key. Enter the English and German value for every key, then publish each group to `staging`. | Document `slug` | Keys to add | | --- | --- | | `app` | `title`, `welcome`, `description` | | `common` | `continue`, `retry` | | `auth` | `signInFailed`, `registrationFailed`, `checkEmailTitle`, `checkEmailForInvitation`, `sessionUnavailable` | | `errors` | `tryAgain` | | `tabs` | `home`, `devices`, `settings` | | `readings` | `title`, `devicePrompt`, `saving`, `saved`, `saveFailed`, `loadFailed`, `empty`, `preview`, `timeUnavailable`, `bloodPressure`, `bodyWeight`, `ecg`, `bloodPressureValue`, `pulseValue`, `weightValue`, `ecgDeviceResult`, `ecgWaveformUnavailable`, `ecgDisclaimer` | | `devices` | `title`, `intro`, `connected`, `notConnected`, `supportedDevice`, `battery`, `connectionProblem`, `lastUpload`, `noRecentUpload`, `addTitle`, `addDescription`, `noneNearby`, `pair`, `pairingCodePrompt`, `pairingCode`, `pairing`, `paired`, `remembered`, `pairingFailed`, `remove`, `catalogPrompt`, `openCatalog`, `status.Connected`, `status.Disconnected`, `status.Measuring`, `status.LowBattery`, `pairStatus.idle`, `pairStatus.pairing`, `pairStatus.code-required`, `pairStatus.paired`, `pairStatus.error` | | `settings` | `title`, `loading`, `profile`, `firstName`, `lastName`, `profileSaved`, `language`, `devices`, `manageDevices`, `privacyAndConsent`, `privacyDescription`, `privacyPolicy`, `consentDescription`, `notificationsNotConfigured`, `signOut`, `signOutFailed`, `appVersion` | | `profile` | `save`, `form.error.network`, `form.error.generic` | | `languages` | `english`, `german` | | `sign-in` | `title`, `subtitle`, `email`, `password`, `button`, `forgot-password`, `dont-have-account`, `mfa.code`, `mfa.verify`, `errors.invalid-credentials`, `errors.unavailable`, `errors.network`, `errors.generic`, `form.email.invalid`, `form.email.required`, `form.password.required`, `form.password.min` | | `register` | `title`, `subtitle`, `name`, `surname`, `email`, `password`, `password-confirm`, `button`, `already-have-account`, `errors.network`, `errors.generic`, `form.email.invalid`, `form.email.required`, `form.confirm-password.required`, `form.confirm-password.mismatch`, `form.password.special-character`, `form.password.min`, `form.password.number`, `form.password.lowercase`, `form.password.uppercase`, `form.password.no-spaces`, `form.password.max`, `form.name.required`, `form.name.min`, `form.name.max`, `form.surname.required`, `form.surname.min`, `form.surname.max`, `clinician-invite.title`, `clinician-invite.message` | The dots in a key create nested i18next paths. For example, `status.Connected` in the `devices` group becomes `devices.status.Connected`. Keep group slugs free of dots. Here is a small example of the values to enter in the `readings` document: | Key | English (`en`) | German (`de`) | | --- | --- | --- | | `title` | Your readings | Ihre Messwerte | | `ecg` | ECG recording | EKG-Aufzeichnung | | `ecgDeviceResult` | Device-reported result: {{value}} | Vom Gerät gemeldetes Ergebnis: {{value}} | | `ecgWaveformUnavailable` | Waveform is not available for this recording. | Für diese Aufzeichnung ist keine Kurve verfügbar. | | `ecgDisclaimer` | Device data for review; not a diagnosis. | Gerätedaten zur Prüfung; keine Diagnose. | | `bloodPressure` | Blood pressure | Blutdruck | | `bodyWeight` | Body weight | Körpergewicht | Keep the i18next interpolation variable names `value`, `systolic`, and `diastolic` intact when translating interpolated strings. Use the clinical/product team's approved German wording for the rest of the catalog. ### Add translations for the React Native SDK authentication forms [#add-translations-for-the-react-native-sdk-authentication-forms] The `sign-in` and `register` groups intentionally use the React Native SDK's group names. A tenant group with one of these slugs replaces the shared group as a whole. Add every key listed above that the forms use; otherwise omitted shared keys will no longer be available from that group. The SDK's built-in English strings remain the final fallback if a CMS group or key is missing. Do not translate authentication errors into a promise that the account exists or that a login succeeded. Keep the meaning of the SDK-provided messages and validation requirements. ### Change language from the app [#change-language-from-the-app] The Settings screen already calls `i18n.changeLanguage(language)`. `useCmsTranslations` observes the active i18next language, requests the matching CMS locale, and merges that response into the `translation` namespace. The app does not fetch each group itself and does not need locale files or an API key. Use the CMS language codes in the switcher: `en` and `de`. If the app requests a regional tag such as `de-DE`, the React Native SDK maps it to the CMS locale `de`. The selection in this tutorial is in memory; persist it only if the application defines where patient language preferences belong. The CMS returns published content only. A missing German value falls back to English field by field. The collection is public by default and the request includes the app's tenant code, so never store PHI, secrets, or tenant configuration as translation content. Published edits normally become visible after about a minute and may remain cached for several more minutes; see [CMS caching](/cms#caching). ### Localize operating-system permission text separately [#localize-operating-system-permission-text-separately] App screens and the Ovok authentication components use CMS-backed i18next text. iOS and Android system permission prompts are native platform UI and cannot be changed by CMS or an over-the-air text update. Localize the iOS Bluetooth usage description in the native app configuration for each supported system language and rebuild the app. Localize the in-app explanation shown before Android's permission prompt through CMS. ## Key decisions [#key-decisions] - Store application translations in CMS, not in local JSON or other bundled translation catalogs. - Publish every group in the same sandbox environment the app requests (`staging` here). - A group named `sign-in` or `register` replaces the shared group whole; keep the full set of keys required by the SDK forms. - Missing CMS translation values fall back to English. A CMS outage is different: the root `LocalizationGate` shows its retry state rather than rendering a screen full of untranslated keys. - CMS translations are public tenant content. Never place patient-specific or otherwise confidential information in them. - The CMS hook refetches on language changes, but cached published content can take several minutes to update after an edit. - The ECG viewer shows device waveform samples and a source-reported label. Translating its surrounding UI does not add clinical interpretation. ## Verify your integration [#verify-your-integration] On launch, the app waits for its first CMS translation response. Sign-in, registration, onboarding feedback, blood-pressure/ECG/weight cards, device pairing, and Settings use published English or German text. Choosing another language in Settings triggers a CMS locale read and updates the UI without shipping a new native binary. ## Troubleshooting [#troubleshooting] - **The app stays on the translation loading screen:** confirm CMS is enabled and each required group is published to sandbox `staging` for the configured tenant code. - **One section displays raw keys:** check that a translation document's slug matches the group name, that the key spelling matches the `t()` call, and that the group is published. - **Sign-in or registration labels are missing:** make sure your `sign-in` or `register` group contains the full set of required keys; each tenant group replaces the shared group whole. - **German falls back to English:** verify the German values are set on the published CMS strings and the app selects `de`. - **A recent edit has not appeared:** allow for CMS and CDN caching, then retry the translation request. - **System permission copy is still English:** update native localized permission resources and rebuild; the CMS cannot change OS-owned prompts. ## Tutorial complete [#tutorial-complete] You now have an Expo patient app that registers and authenticates through Ovok, pairs the supported BP2 and F4 devices, saves blood-pressure, ECG, and weight readings, loads recent observations, renders available ECG waveform samples, manages paired hardware and profile settings, and loads its English and German UI text from Ovok CMS. Continue with the deeper references for [React Native SDK](/native-sdk/guide/overview), [Bluetooth](/native-sdk/guide/modules/bt-management), [supported devices](/native-sdk/guide/supported-devices), [authentication](/authentication), [Access Policies](/access-policies), [ECG measurements](/web-sdk/core/measurements/ecg), [blood pressure](/web-sdk/core/measurements/blood-pressure), [body weight](/web-sdk/core/measurements/body-weight), [CMS](/cms), and [CMS-backed i18n](/cms/use-ovok-cms-with-i18n). # Step 3 · Configure localisation with Ovok CMS Canonical page: https://docs.ovok.com/guides/chf-remote-monitoring/configure-localisation An i18next setup that reads the app's published strings from Ovok CMS. Translation content lives in the Console, not in JSON files bundled with the app. When a translator updates a published value, the app can receive it without a new native release. ## Before you begin [#before-you-begin] - The Expo app and `ovokConfig` from steps 1–2. - Ovok CMS enabled for the sandbox project. - `i18next` and `react-i18next` installed in step 1. ## Build it [Client-side] [#build-it-client-side] ### Add the first translation group in Ovok Console [#add-the-first-translation-group-in-ovok-console] In the Console, open the sandbox project's CMS and create a document in the built-in `translations` collection: | Field | Value | | --- | --- | | `slug` | `app` | | `status` | `published` | | `strings` | Add `title`, `welcome`, and `description` keys with English values. | For example, the `welcome` key can have the English value `Welcome`. The CMS document stores localized values; it is not a file in the app. The `translations` collection is open by default, so the app needs its tenant code but no CMS API key. Publish this document to the sandbox `staging` environment, which is the environment used below. See [Use Ovok CMS with i18n](/cms/use-ovok-cms-with-i18n) for the Console fields and fallback rules. ### Initialize i18next without local translation resources [#initialize-i18next-without-local-translation-resources] Create `src/localization/i18n.ts`: ~~~ts import "@ovok/native/auth"; import i18n from "i18next"; import { initReactI18next } from "react-i18next"; export const localizationReady = i18n .use(initReactI18next) .init({ lng: "en", fallbackLng: "en", supportedLngs: ["en", "de"], interpolation: { escapeValue: false }, react: { useSuspense: false }, }); export default i18n; ~~~ There is intentionally no `resources` option and no `locales/en.json`: the CMS supplies app strings. Importing `@ovok/native/auth` registers the SDK's built-in English auth copy. When the CMS hook loads a matching group such as `sign-in`, its published values can replace those defaults. ### Load CMS strings and gate the first screen [#load-cms-strings-and-gate-the-first-screen] Create `src/localization/localization-gate.tsx`: ~~~tsx import * as React from "react"; import { ActivityIndicator, View } from "react-native"; import { Button, Text } from "react-native-paper"; import { useCmsTranslations } from "@ovok/native/cms"; import { ovokConfig } from "../config/ovok"; import { localizationReady } from "./i18n"; function CmsTranslations({ children }: React.PropsWithChildren) { const { data, loading, error, reload } = useCmsTranslations({ tenantCode: ovokConfig.tenantCode, environment: "staging", }); if (error) { return ( App language content could not be loaded. ); } if (loading || !data) return ; return children; } export function LocalizationGate({ children }: React.PropsWithChildren) { const [ready, setReady] = React.useState(false); React.useEffect(() => { void localizationReady.then(() => setReady(true)); }, []); if (!ready) return ; return {children}; } ~~~ `useCmsTranslations` reads the current i18next language, fetches the published CMS translation groups for it, and merges them into the `translation` namespace. Passing `tenantCode` allows this request before sign-in. It refetches when the language changes. The inline error and retry text are a bootstrap fallback for a CMS outage; they are not the app's translation catalog. In step 5, place `LocalizationGate` inside `OvokProvider` and the app `ThemeProvider`, around the Expo Router stack. The gate waits for i18next and the first CMS response before showing screens that use translated text. Use the starter group in a screen: ~~~tsx import { useTranslation } from "react-i18next"; import { Text } from "react-native"; export function WelcomeScreen() { const { t } = useTranslation(); return {t("app.welcome")}; } ~~~ ## Key decisions [#key-decisions] - Keep application copy in the project's CMS `translations` collection. Do not add app translation JSON files. - Use bare CMS language codes such as `en` and `de`. The CMS accepts every ISO 639-1 language, but the Ovok SDKs read only `de`, `en`, `fr`, and `es`. The app's allowed language list should match languages actually published for its tenant. - A draft group is not delivered. Publish the group in the same environment the app requests. - CMS text is public content. Never put patient data, secrets, or private project configuration in translation values. - The system Bluetooth permission prompt is native platform copy, not CMS content. Step 10 explains where that text must be localized. ## Verify your integration [#verify-your-integration] The app initializes i18next without bundled translation dictionaries, loads the published `app` group from the sandbox CMS, and renders `app.welcome` from the CMS response. ## Troubleshooting [#troubleshooting] - **The app stays on the loading screen:** confirm CMS is enabled, the `app` group is published, and its tenant/environment match the app configuration. - **The screen shows `app.welcome`:** check that the group slug is `app` and the key is `welcome`; confirm the document is published. - **The CMS request returns an unknown tenant:** use the tenant code from the same sandbox project and allow time for a newly created tenant code to become available. - **The language changes but text does not:** make sure a published group exists for the selected language. Missing CMS values fall back to English field by field. ## Next step [#next-step] Continue to [step 4: choose connected devices](/guides/chf-remote-monitoring/choose-connected-devices). # Step 2 · Create and configure the Ovok project Canonical page: https://docs.ovok.com/guides/chf-remote-monitoring/create-and-configure-the-ovok-project A sandbox project that can register and authenticate patients and accept measurement writes from the app. This step is done in Ovok Console; the app receives only the sandbox API URL and public tenant code. ## Before you begin [#before-you-begin] - The native Expo project from step 1. - Access to the [Ovok Console](https://ovok.com/console?ref=docs) and permission to create or configure a project. ## Build it [Console] [#build-it-console] ### Configure in Ovok Console [#configure-in-ovok-console] 1. Create a project for the sandbox app, or select an existing sandbox project. 2. Record the project's tenant code for the app. The code must belong to the sandbox environment used in this guide. 3. Enable patient sign-in by ensuring PATIENT_LOGIN_ENABLED is not set to false. See [Patient login](/settings-and-features/settings/patient-login-enabled). 4. Set PATIENT_REGISTRATION_ENABLED to true if patients will create accounts from the app. Registration also requires a project default Patient AccessPolicy. See [Patient registration](/settings-and-features/settings/patient-registration-enabled) and [project setup](/authentication/project-setup). 5. Set a least-privilege default Patient AccessPolicy for newly registered accounts. It must grant only the resource and operation access this app needs, including the approved Patient profile and Observation workflows. Follow [Access policies](/access-policies); do not paste a permissive example policy into a real project. 6. Confirm that the transaction-bundles feature is enabled. It is enabled for new projects by default, but older projects may not have it. The feature makes supported multi-resource writes atomic. See [Transaction bundles](/settings-and-features/features/transaction-bundles). 7. Decide whether the project should send a patient welcome email. If so, map the PATIENT_WELCOME template and complete the email provider setup. This is optional for the tutorial's email/password flow; see the [template catalogue](/email-templates/template-catalogue) and [email setup](/email-templates/set-up-email). 8. Enable Ovok CMS for the project. The tutorial stores app translations in the CMS `translations` collection; publish them to the sandbox's `staging` environment. The collection is open by default, so the mobile app reads published translations using its tenant code without an API key. See [Enable the CMS](/cms#enable-the-cms) and [Use Ovok CMS with i18n](/cms/use-ovok-cms-with-i18n). Do not enable practitioner registration or invitations for this patient-only tutorial unless your product needs them. ### Configure in the app [#configure-in-the-app] Put the sandbox values in your local environment file: ~~~dotenv EXPO_PUBLIC_OVOK_BASE_URL=https://api.sandbox.ovok.com EXPO_PUBLIC_TENANT_CODE=the-tenant-code-from-your-sandbox-project ~~~ Create src/config/ovok.ts: ~~~ts const baseUrl = process.env.EXPO_PUBLIC_OVOK_BASE_URL ?? "https://api.sandbox.ovok.com"; const tenantCode = process.env.EXPO_PUBLIC_TENANT_CODE; if (!tenantCode) { throw new Error("Set EXPO_PUBLIC_TENANT_CODE to the sandbox project code."); } export const ovokConfig = { baseUrl, tenantCode }; ~~~ The React Native app will use these values when it creates one OvokClient in step 5. The app config does not contain patient passwords or credentials. ## Key decisions [#key-decisions] - Patient registration creates the account and Patient profile through the supported authentication flow. Do not create a second Patient resource after signup. - The default AccessPolicy is project configuration, not an app-side permission check. It controls what the authenticated Patient can access. - Atomic transactions depend on the project feature. A successful measurement write should be treated as complete only after the SDK confirms the save. - A Patient app URL is only needed when a project sends links that should open the app. This tutorial does not use password-reset, invitation, or social-login links, so it does not invent a redirect or deep-link setting. ## Verify your integration [#verify-your-integration] The project can accept sandbox patient registration and sign-in, has the intended Patient AccessPolicy, has transaction bundles enabled, and has CMS available for published translations. The app has a sandbox URL and tenant code in local configuration. ## Troubleshooting [#troubleshooting] - **Registration is refused:** confirm patient registration is enabled, the tenant code belongs to this project, and a default Patient AccessPolicy exists. - **Login is refused:** confirm the account belongs to this tenant and patient login is enabled. - **Writes are not atomic:** check the project feature list for transaction-bundles. - **The app cannot load its text:** confirm CMS is enabled and the translation groups are published in the sandbox `staging` environment for this tenant. - **Welcome email is absent:** this is expected until the template is mapped and the provider is ready. - **The app points at the wrong environment:** confirm the API URL and tenant code are both from the sandbox project. ## Next step [#next-step] Continue to [step 3: configure localisation](/guides/chf-remote-monitoring/configure-localisation). # Step 1 · Create the React Native app Canonical page: https://docs.ovok.com/guides/chf-remote-monitoring/create-the-react-native-app An Expo Router app that compiles for iOS and Android and contains the native dependencies needed for Ovok authentication, persistent client storage, and Bluetooth LE. ## Before you begin [#before-you-begin] - Node.js installed. - Xcode for iOS, Android Studio for Android, or both. - A development device or simulator for building. Bluetooth pairing itself must be tested on a physical phone. The current @ovok/native example uses Expo SDK 57, React Native 0.86.3, React 19.2.3, Android API 26 minimum, and iOS deployment target 16.4. Treat those as the repository example's compatibility baseline, not as a promise for every Expo combination. Match native package versions to the Expo SDK in your project; see the [React Native SDK installation guide](/native-sdk/guide/how-to/installation). ## Build it [Terminal] [#build-it-terminal] Create an Expo Router tabs project and install the two Ovok packages: ~~~bash npx create-expo-app@latest ovok-bp-rpm --template tabs cd ovok-bp-rpm npm install @ovok/core@^0.4.27 @ovok/native@^1.10.6 formik yup i18next react-i18next npx expo install react-native-ble-plx react-native-permissions expo-secure-store expo-crypto expo-standard-web-crypto expo-dev-client expo-constants react-native-gesture-handler react-native-keyboard-controller react-native-paper react-native-safe-area-context react-native-svg @expo-google-fonts/dm-sans expo-build-properties ~~~ The minimum Ovok SDK versions validated for this tutorial are `@ovok/core` 0.4.27 and `@ovok/native` 1.10.6. Keep your lockfile and verify peer compatibility when upgrading. Expo installs should use npx expo install so native packages match your Expo SDK. The authentication forms also use Formik and Yup, while localization uses i18next and react-i18next. ### Bootstrap the Ovok runtime before Expo Router [#bootstrap-the-ovok-runtime-before-expo-router] Create index.js in the project root: ~~~js const { polyfillOvokWebAPIs } = require("@ovok/native/polyfills"); polyfillOvokWebAPIs(); require("expo-router/entry"); ~~~ Set the app package's entry point to this file: ~~~json { "main": "index.js" } ~~~ Keep this file in CommonJS form. The initializer must run before Expo Router imports screens or the client. ### Configure the Bluetooth plugin [#configure-the-bluetooth-plugin] Replace the generated app config with an app.config.ts based on this shape. Keep your real bundle identifiers from the Expo project: ~~~ts import type { ExpoConfig } from "expo/config"; const config: ExpoConfig = { name: "Ovok BP RPM", slug: "ovok-bp-rpm", plugins: [ "expo-router", [ "@ovok/native", { bluetooth: { bluetoothAlwaysPermission: "Allow this app to connect to supported health devices.", }, }, ], ["react-native-permissions", { iosPermissions: ["Bluetooth"] }], [ "expo-build-properties", { ios: { deploymentTarget: "16.4" }, android: { minSdkVersion: 26 }, }, ], "expo-secure-store", ], ios: { bundleIdentifier: "com.example.ovokbprpm" }, android: { package: "com.example.ovokbprpm" }, }; export default config; ~~~ The Ovok plugin configures the Bluetooth usage description and Android Bluetooth permissions for this foreground flow. The permissions plugin enables the iOS Bluetooth permission handler. Do not add background Bluetooth configuration: this tutorial only scans while the signed-in app is open. See the [Bluetooth provider reference](/native-sdk/guide/components/bt-management/bt-provider). ### Add public sandbox configuration [#add-public-sandbox-configuration] Create .env.example and keep a local .env or .env.local out of version control: ~~~dotenv EXPO_PUBLIC_OVOK_BASE_URL=https://api.sandbox.ovok.com EXPO_PUBLIC_TENANT_CODE=replace-with-your-sandbox-project-code ~~~ Expo embeds EXPO_PUBLIC_ values in the client bundle. Use them for public environment configuration only; never put passwords, private keys, or server credentials there. Step 2 will fill in the sandbox project's actual tenant code. ### Build a native development app [#build-a-native-development-app] Expo Go does not contain the Bluetooth native module. Generate and compile a development build: ~~~bash npx expo prebuild npx expo run:ios # or npx expo run:android ~~~ Run Bluetooth testing on physical iOS and Android devices. Simulators can help compile and exercise non-Bluetooth screens, but they do not replace a real BLE scan, permission, pairing, or measurement test. ## Key decisions [#key-decisions] - The app opts into foreground Bluetooth only. Do not add HealthKit, Health Connect, social sign-in, notifications, or background service plugins for this tutorial. - The Bluetooth permission prompt needs a plain explanation that matches the app's actual use. - Email/password authentication does not need an OAuth redirect URL. A deep-link scheme is only needed if you later add a flow that returns the patient to the app through a link. ## Verify your integration [#verify-your-integration] The Expo app compiles into a native development build on at least one target platform. Starting the app shows the template screen without a runtime error. ## Troubleshooting [#troubleshooting] - **Module not found for BLE:** install react-native-ble-plx and react-native-permissions, then rebuild the native app. - **Permission is missing after editing app config:** rerun Prebuild and create a new development build. OTA JavaScript updates cannot add native permissions. - **Expo Go opens instead of the development app:** launch the custom development build produced by expo run. - **iOS Bluetooth permission is blank:** confirm the Ovok plugin's bluetoothAlwaysPermission text and the permissions plugin configuration, then rebuild. ## Next step [#next-step] Continue to [step 2: create and configure the Ovok project](/guides/chf-remote-monitoring/create-and-configure-the-ovok-project). # Monitor blood pressure at home Canonical page: https://docs.ovok.com/guides/chf-remote-monitoring Build a patient-facing remote-monitoring app in ten runnable steps. You use Expo, React Native, `@ovok/native` and `@ovok/core` to sign a patient in, pair two supported devices, save their measurements and show recent readings. By the end, the app: - registers and signs a patient in with Ovok's native authentication forms - discovers and pairs a supported blood-pressure monitor and a supported scale - receives normalised blood-pressure, ECG, heart-rate and body-weight readings - saves them as Ovok measurements and reads them back - shows connection, loading, empty, success and error states - lets the patient manage paired devices, profile details, language and sign-out The waveform and any device-reported label are source data, not a diagnosis. The app doesn't interpret readings or set alert thresholds; agree care pathways and escalation with the clinical team running the service. ## Set up [Console] [#set-up-console] You need: - Node.js and a package manager your Expo project supports. - Xcode for iOS builds, or Android Studio for Android builds. - An Ovok sandbox project. Step 2 configures it. - A [supported](/native-sdk/guide/supported-devices) blood-pressure monitor and scale for the Bluetooth steps. Without hardware you can still build every screen, using test fixtures that never write to a patient record. ## Build the app [#build-the-app] 1. [Create the React Native app](/guides/chf-remote-monitoring/create-the-react-native-app) 2. [Create and configure the Ovok project](/guides/chf-remote-monitoring/create-and-configure-the-ovok-project) 3. [Configure localisation](/guides/chf-remote-monitoring/configure-localisation) 4. [Choose connected devices](/guides/chf-remote-monitoring/choose-connected-devices) 5. [Initialise Ovok and Bluetooth](/guides/chf-remote-monitoring/initialise-ovok-and-bluetooth) 6. [Build onboarding and authentication](/guides/chf-remote-monitoring/build-onboarding-and-authentication) 7. [Build the measurement screen](/guides/chf-remote-monitoring/build-the-measurement-screen) 8. [Build the Devices section](/guides/chf-remote-monitoring/build-the-devices-section) 9. [Build Settings](/guides/chf-remote-monitoring/build-settings) 10. [Complete localisation](/guides/chf-remote-monitoring/complete-localisation) Each step builds on the last in the same project and file paths, and ends with what you should see and how to fix what you don't. ## How a reading flows [#how-a-reading-flows] The phone discovers a device over Bluetooth. The device produces a reading and the native SDK normalises it. Your app attaches the blood-pressure, ECG or weight reading to the signed-in patient and calls `OvokClient.saveMeasurement()`. Ovok stores the FHIR Observation resources, and the app refreshes `useObservations()` to render the stored values, including a waveform for ECG. ## Test your integration [#test-your-integration] 1. Sign in as a test patient in the sandbox project. 2. Pair the monitor and the scale from the Devices section. 3. Take one reading on each device and check it appears on the measurement screen. | Scenario | How to trigger it | Expected result | | --- | --- | --- | | Blood pressure saved | Take a reading on the paired monitor | Systolic, diastolic and heart rate appear in the history | | ECG saved | Record an ECG on the monitor | The waveform renders from the stored observation | | Weight saved | Step on the paired scale | The weight appears in the history | | No hardware | Use the step 7 test fixtures | Screens render; nothing is written to the patient | | Signed out | Sign out in Settings | The app returns to onboarding | ## Troubleshooting [#troubleshooting] - **It takes longer than an hour:** the estimate excludes native toolchain setup, sandbox access and device availability. - **A referenced API has changed:** check the [React Native SDK](/native-sdk) and [JavaScript SDK](/web-sdk) reference pages, which follow the current release. - **You're moving to production:** keep this tutorial's sandbox credentials and configuration out of the production project. ## See also [#see-also] - [React Native SDK installation](/native-sdk/guide/how-to/installation) - [Bluetooth module](/native-sdk/guide/modules/bt-management) - [Supported devices](/native-sdk/guide/supported-devices) - [Measurements and health data](/web-sdk/core/measurements-and-health-data) - [Access policies](/access-policies) # Step 5 · Initialise Ovok and Bluetooth Canonical page: https://docs.ovok.com/guides/chf-remote-monitoring/initialise-ovok-and-bluetooth One persistent OvokClient for the sandbox project and one foreground Bluetooth runtime that discovers only the two devices selected in step 4. ## Before you begin [#before-you-begin] - src/config/ovok.ts from step 2. - acceptedDevices from step 4. - The native development build from step 1. ## Build it [Client-side] [#build-it-client-side] ### Create the client once [#create-the-client-once] Create src/client/ovok-client.ts: ~~~ts import { OvokClient } from "@ovok/core"; import { ExpoClientStorage } from "@ovok/native/polyfills"; import { ovokConfig } from "../config/ovok"; export const ovokClient = new OvokClient({ baseUrl: ovokConfig.baseUrl, fhirUrlPath: "/fhir/R4/", storage: new ExpoClientStorage(), }); ~~~ The client stays at module scope so screens share the same session and storage. The FHIR path includes the trailing slash. See [Core client configuration](/web-sdk/core/client-configuration). ### Compose the app providers [#compose-the-app-providers] Update app/_layout.tsx: ~~~tsx import { OvokProvider } from "@ovok/core"; import { DEFAULT_COLORS, DEFAULT_MULTIPLIERS, ThemeProvider, } from "@ovok/native/theme"; import { Stack } from "expo-router"; import { SafeAreaProvider } from "react-native-safe-area-context"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { KeyboardProvider } from "react-native-keyboard-controller"; import { LocalizationGate } from "../src/localization/localization-gate"; import { ovokClient } from "../src/client/ovok-client"; export default function RootLayout() { return ( ); } ~~~ The native auth and themed UI components render below both OvokProvider and the SDK ThemeProvider. The keyboard and gesture providers support the native form components. ### Mount Bluetooth in the signed-in patient area [#mount-bluetooth-in-the-signed-in-patient-area] Create src/features/bluetooth/device-state.tsx: ~~~tsx import { BTProvider } from "@ovok/native/bt-management"; import { BleManager } from "react-native-ble-plx"; import * as React from "react"; import { acceptedDevices } from "./accepted-devices"; type DeviceState = { devices: Record< string, { name: string; status: string; batteryLevel?: number; hasError?: boolean } >; }; export const DeviceStateContext = React.createContext(null); const bleManager = new BleManager(); export function BluetoothWorkspace({ children, }: React.PropsWithChildren) { const [devices, setDevices] = React.useState({}); return ( { setDevices((current) => ({ ...current, [deviceData.id]: { ...current[deviceData.id], name: deviceData.model || deviceData.localName || "", status, }, })); }} onConnectionEvent={({ deviceData, batteryLevel }) => { if (typeof batteryLevel === "number") { setDevices((current) => ({ ...current, [deviceData.id]: { ...current[deviceData.id], name: deviceData.model || deviceData.localName || "", status: current[deviceData.id]?.status ?? "Disconnected", batteryLevel, }, })); } }} onError={({ deviceData }) => { if (deviceData) { setDevices((current) => ({ ...current, [deviceData.id]: { ...current[deviceData.id], name: deviceData.model || deviceData.localName || "", status: current[deviceData.id]?.status ?? "Disconnected", hasError: true, }, })); } }} > {children} ); } ~~~ Add app/(patient)/_layout.tsx: ~~~tsx import { Slot } from "expo-router"; import { BluetoothWorkspace } from "../../src/features/bluetooth/device-state"; export default function PatientLayout() { return ( ); } ~~~ Keep patient routes inside app/(patient). The workspace exists only after authentication, so Bluetooth permission is not requested on the sign-in screen. The app can read state with React.useContext(DeviceStateContext) from a screen beneath this layout. ## Key decisions [#key-decisions] - BTProvider owns discovery and connection lifecycle while mounted. Do not create a new BleManager during a component render. - The provider reports normalized result data; it does not save readings or choose the Patient. Step 7 adds the explicit save operation after the authenticated Patient is known. - Device IDs may be local Bluetooth identifiers. Keep them as internal map keys and do not display or log them. - Battery level is optional and only reported when the device exposes it. ## Verify your integration [#verify-your-integration] After a patient enters the patient route group, the app requests Bluetooth permission and the runtime can discover compatible BP2 and F4 devices. The permission state and connection errors are available to child screens. ## Troubleshooting [#troubleshooting] - **Permission dialog never appears:** check the iOS Bluetooth plugin entries or Android manifest generated by Prebuild, then rebuild. - **No devices appear in a simulator:** use a physical phone; a simulator cannot emulate the actual BLE devices. - **Repeated scans or connection instability:** confirm there is only one mounted BluetoothWorkspace and one BleManager. - **Permission is granted but scan fails:** check that Bluetooth is switched on and that the app was rebuilt after native config changes. ## Next step [#next-step] Continue to [step 6: build onboarding and authentication](/guides/chf-remote-monitoring/build-onboarding-and-authentication). # Guides Canonical page: https://docs.ovok.com/guides Use these walkthroughs to turn a care idea into a patient and clinician experience on Ovok. Each guide starts with a product workflow, then maps it to project setup, app screens, FHIR data, device readings, and the clinician view. ## Example guides [#example-guides] ## A shared foundation [#a-shared-foundation] Each example follows the same foundation: create a project, shape the patient workflow, build the app against Ovok APIs, store clinical data as FHIR resources, and give care teams a clear view of the information they need. For Patients enrolled in [Signals](/signals), Ovok forwards eligible vital-sign readings according to the documented forwarding behavior and surfaces the resulting decisions. Do not infer which measurements are forwarded; check [Data Ingestion](/data-ingestion). Non-clinical products can opt out. These are implementation guides, not clinical protocols. Set thresholds, care pathways, and escalation rules with the responsible clinical team before using them with patients. # Step 7 · Add medication reminders Canonical page: https://docs.ovok.com/guides/medication-reminder/add-medication-reminders ## What we are building [#what-we-are-building] Device-local notifications for supported occurrences. The phone schedules and presents them; Ovok supplies the FHIR plan but does not schedule these reminders. ## What you should already have [#what-you-should-already-have] - Future `scheduledAt` occurrences from step 6. - `expo-notifications` installed and configured in step 1. - A CMS translation group with generic notification title/body strings. ## The implementation [#the-implementation] Create `src/features/medication/reminders.ts`; the examples in this step use the occurrence builder from step 6. Install a foreground handler once near app startup. On Android, create a notification channel before requesting permission so the Android 13 prompt can be shown. ```ts import * as Notifications from "expo-notifications"; import * as React from "react"; import * as SecureStore from "expo-secure-store"; import { useFocusEffect } from "expo-router"; import { buildOccurrencesForDay } from "./today-schedule"; import { loadMedicationPlan } from "./medication-plan"; import { useTranslation } from "react-i18next"; type MedicationPlan = Awaited>; export const reminderPreferenceKey = "ovok-medication-reminders-enabled"; Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldPlaySound: false, shouldSetBadge: false, shouldShowBanner: true, shouldShowList: true, }), }); export async function requestReminderPermission(channelName: string) { await Notifications.setNotificationChannelAsync("medication-reminders", { name: channelName, importance: Notifications.AndroidImportance.DEFAULT, }); const existing = await Notifications.getPermissionsAsync(); if (existing.granted || existing.ios?.status === Notifications.IosAuthorizationStatus.PROVISIONAL) return true; const requested = await Notifications.requestPermissionsAsync(); return requested.granted || requested.ios?.status === Notifications.IosAuthorizationStatus.PROVISIONAL; } ``` Ask at a moment when the patient understands the benefit, and leave reminders off when permission is denied. Keep the lock-screen content generic: ```ts export async function scheduleOccurrence(occurrence: { occurrenceKey: string; scheduledAt: Date; }, copy: { title: string; body: string }) { return Notifications.scheduleNotificationAsync({ content: { title: copy.title, body: copy.body, data: { kind: "medication-reminder", occurrenceKey: occurrence.occurrenceKey }, }, trigger: { type: Notifications.SchedulableTriggerInputTypes.DATE, date: occurrence.scheduledAt, }, }); } ``` Do not put the medication name, dose, diagnosis, or instructions in the notification body. Store the returned notification identifier so the app can cancel it when the plan changes or the patient disables reminders. ### Reconcile after a plan or timezone change [#reconcile-after-a-plan-or-timezone-change] When the plan is refreshed, the patient changes reminder preferences, or the app returns to the foreground, replace only this app's medication notifications. Build occurrences for the next seven device-local calendar days rather than scheduling an unbounded future: ```ts export function occurrencesForNextSevenDays(plan: MedicationPlan) { return Array.from({ length: 7 }, (_, offset) => { const day = new Date(); day.setDate(day.getDate() + offset); return buildOccurrencesForDay(plan, day); }).flat(); } ``` Serialize reconciliations so a simultaneous plan refresh and app-resume event cannot race and schedule duplicates: ```ts let reconcileQueue: Promise = Promise.resolve(); export function reconcileMedicationReminders( occurrences: Array<{ occurrenceKey: string; scheduledAt: Date }>, copy: { title: string; body: string }, ) { reconcileQueue = reconcileQueue.catch(() => undefined).then(async () => { const existing = await Notifications.getAllScheduledNotificationsAsync(); const ours = existing.filter((item) => item.content.data?.kind === "medication-reminder"); await Promise.all( ours.map((item) => Notifications.cancelScheduledNotificationAsync(item.identifier)), ); const now = Date.now(); for (const occurrence of occurrences) { if (occurrence.scheduledAt.getTime() <= now) continue; await scheduleOccurrence(occurrence, copy); } }); return reconcileQueue; } ``` Ask for permission only after the patient turns reminders on in Settings. For plan changes and app resume, read permission without prompting and reconcile the next seven days. This hook runs from the authenticated Today route; `enabled` is the app preference added in step 10: ```tsx export function useMedicationReminderSchedule(plan: MedicationPlan) { const { t } = useTranslation(); const [error, setError] = React.useState(); useFocusEffect(React.useCallback(() => { let current = true; setError(undefined); void (async () => { try { const enabled = await SecureStore.getItemAsync(reminderPreferenceKey) === "true"; const permission = await Notifications.getPermissionsAsync(); if (!current) return; const allowed = permission.granted || permission.ios?.status === Notifications.IosAuthorizationStatus.PROVISIONAL; const occurrences = enabled && allowed ? occurrencesForNextSevenDays(plan) : []; await reconcileMedicationReminders(occurrences, { title: t("medication.reminderTitle"), body: t("medication.reminderBody"), }); } catch (reason) { if (current) setError(reason instanceof Error ? reason : new Error(String(reason))); } })(); return () => { current = false; }; }, [plan, t])); return { error }; } ``` Call `requestReminderPermission(t("medication.notificationChannel"))` from the explicit enable action in Settings. The hook reads the preference whenever Today gains focus and rebuilds future reminders when the plan or locale changes, so a timezone change is picked up when the patient returns to the app. Surface its `error` as `t("medication.reminderScheduleError")`. The notification's `data` marker lets reconciliation leave unrelated app notifications alone. If the process stops partway through, the next run removes the partial set and rebuilds it from the plan. This example assumes one active patient account; when switching accounts, remove the previous account's local reminders before scheduling the new one. Connect the hook to the authenticated Today screen and show a recoverable state if reconciliation fails: ```tsx const { error: reminderError } = useMedicationReminderSchedule(plan); {reminderError && ( {t("medication.reminderScheduleError")} )} ``` The device's local clock and timezone determine how `Date` triggers are interpreted. Recompute future occurrences when the timezone changes. Delivery and restoration after a device restart depend on the operating system, its settings, permission state, and platform scheduling behavior; test both platforms on real devices. Do not use this mechanism for urgent or clinically critical alerts. The React Native SDK's `showPushNotification()` helper presents an immediate notification for a background measurement. It does not schedule medication reminders; use the local Expo Notifications API above. ## Important Ovok decisions [#important-ovok-decisions] - Local reminders can fire without a network connection after the OS has accepted them. - No reminder delivery or acknowledgement is written to FHIR. Only the explicit patient action in step 8 creates an adherence record. - A delivered notification does not prove that a dose was taken. ## Expected result [#expected-result] With permission granted, the device presents a generic reminder at a scheduled local time. Re-running reconciliation does not leave duplicate tutorial reminders, and plan changes cancel obsolete notifications. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **Android 13 permission prompt does not appear:** create the notification channel before calling `requestPermissionsAsync()`. - **No alert appears in foreground:** confirm the global notification handler returns a presentation behavior. - **Reminder time shifts after travel:** recalculate upcoming occurrences using the new device timezone when the app resumes. - **Reminder says too much on the lock screen:** remove health details from both title and body; keep them inside the authenticated app. ## Previous / Next [#previous--next] Previous: [step 6: build the Today screen](/guides/medication-reminder/build-the-today-screen) · Continue to [step 8: record medication adherence](/guides/medication-reminder/record-medication-adherence). # Step 9 · Build History and Medication Details Canonical page: https://docs.ovok.com/guides/medication-reminder/build-history-and-medication-details ## What we are building [#what-we-are-building] A medication details view backed by its `MedicationRequest`, and an adherence history backed by the Patient's `MedicationAdministration` records. ## What you should already have [#what-you-should-already-have] - The Patient's medication plan and `MedicationAdministration` reports from steps 5 and 8. - A patient AccessPolicy that allows reading/searching those resources. - CMS strings for the details and history screens. ## The implementation [#the-implementation] ### Medication details [#medication-details] Render fields that exist in the source request. For the tutorial plan, show the medication concept text or referenced Medication display, each dosage instruction, the explicit schedule, and `boundsPeriod` start/end when present. Show the request status and source information separately from adherence history. ```tsx import { Text, View } from "react-native"; import { useTranslation } from "react-i18next"; type MedicationRequestView = { id?: string; status?: string; medicationCodeableConcept?: { text?: string }; medicationReference?: { display?: string }; dosageInstruction?: Array<{ doseAndRate?: Array<{ doseQuantity?: { value?: number; unit?: string } }>; text?: string; timing?: { repeat?: { boundsPeriod?: { start?: string; end?: string } } }; }>; }; export function MedicationDetails({ request }: { request: MedicationRequestView }) { const { t } = useTranslation(); const name = request.medicationCodeableConcept?.text ?? request.medicationReference?.display ?? t("medication.unknownName"); return ( {name} {t("medication.requestStatus", { status: request.status })} {(request.dosageInstruction ?? []).map((dosage, index) => ( {dosage.doseAndRate?.[0]?.doseQuantity && ( {t("medication.dose", { value: dosage.doseAndRate[0].doseQuantity.value, unit: dosage.doseAndRate[0].doseQuantity.unit })} )} {dosage.text && {dosage.text}} {dosage.timing?.repeat?.boundsPeriod?.start && ( {t("medication.startDate", { date: dosage.timing.repeat.boundsPeriod.start })} )} {dosage.timing?.repeat?.boundsPeriod?.end && ( {t("medication.endDate", { date: dosage.timing.repeat.boundsPeriod.end })} )} ))} ); } ``` `MedicationRequestView` is the subset of FHIR fields this view reads; the server resource remains the source of truth. Do not synthesize a dose or schedule when the corresponding elements are absent. Create `src/app/(patient)/medications/[requestId].tsx` to load the selected request from the authenticated Patient's plan and render that component: ```tsx import { useLocalSearchParams } from "expo-router"; import { useTranslation } from "react-i18next"; import { ActivityIndicator, Text } from "react-native"; import { useMedicationPlan } from "../../../features/medication/use-medication-plan"; import { MedicationDetails } from "../../../features/medication/medication-details"; export default function MedicationDetailsScreen() { const { requestId } = useLocalSearchParams<{ requestId: string }>(); const { plan, loading, error } = useMedicationPlan(); const { t } = useTranslation(); if (loading) return ; if (error) return {t("medication.loadError")}; const request = plan.find((item) => item.id === requestId); if (!request) return {t("medication.notInPlan")}; return ; } ``` In each Today card, link to the route using the request id returned by Ovok: Import `Pressable` from `react-native`, `useRouter` from `expo-router`, and create `const router = useRouter()` in the Today screen. The route snippet below uses those values: ```tsx {item.request.id && ( router.push({ pathname: "/(patient)/medications/[requestId]", params: { requestId: item.request.id }, })}> {t("medication.viewDetails")} )} ``` ### Load all history pages [#load-all-history-pages] The Native/Core FHIR client exposes `searchResourcePages()` as an async generator. It follows the server's paging links; append each returned page rather than assuming the first page is the whole history: ```tsx import { useClient } from "@ovok/core"; import * as React from "react"; export type MedicationAdministrationView = { id?: string; status?: string; effectiveDateTime?: string; request?: { reference?: string }; medicationCodeableConcept?: { text?: string }; medicationReference?: { display?: string }; identifier?: Array<{ system?: string; value?: string }>; }; export function useMedicationHistory(patientId: string) { const client = useClient(); const [events, setEvents] = React.useState([]); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(); const [revision, setRevision] = React.useState(0); const reload = React.useCallback(() => setRevision((value) => value + 1), []); React.useEffect(() => { let current = true; setEvents([]); setError(undefined); if (!patientId) { setLoading(false); return () => { current = false; }; } setLoading(true); void (async () => { try { const loaded: MedicationAdministrationView[] = []; for await (const page of client.searchResourcePages("MedicationAdministration", { subject: `Patient/${patientId}`, _count: "50", })) { loaded.push(...page); } if (current) setEvents(loaded); } catch (reason) { if (current) setError(reason instanceof Error ? reason : new Error(String(reason))); } finally { if (current) setLoading(false); } })(); return () => { current = false; }; }, [client, patientId, revision]); return { events, loading, error, reload }; } ``` Sort the loaded events by `effectiveDateTime` for display. Each record's `request.reference` links it back to the plan; its identifier links it to the scheduled occurrence. Use the FHIR `effective-time` search parameter for server-side date filtering when needed, after confirming it in the current project's [CapabilityStatement](/api/fhir/r4/capability-statement). Display a clear label such as **Patient reported** next to Taken and Skipped. For a date range, show a Missed row only when the app can match a supported scheduled occurrence to no adherence event after the product-approved cutoff. Do not write or present that derived state as a clinical judgment. Create `src/app/(patient)/history.tsx` for a simple local 7-day / 30-day / all filter. This view shows only events linked to requests in the current plan and uses neutral labels for statuses the tutorial did not create: ```tsx import { useSession } from "@ovok/native"; import { useTranslation } from "react-i18next"; import { Pressable, ScrollView, Text, View } from "react-native"; import { useState } from "react"; import { occurrenceIdentifierSystem } from "../../features/medication/adherence"; import { useMedicationHistory } from "../../features/medication/history"; export default function HistoryScreen() { const { status, profile } = useSession({ sessions: false }); const patientId = profile?.resourceType === "Patient" ? profile.id : ""; const { events, loading, error } = useMedicationHistory(patientId); const { t, i18n } = useTranslation(); const [days, setDays] = useState(30); const cutoff = days === null ? 0 : Date.now() - days * 24 * 60 * 60 * 1000; const visible = events .filter((event) => event.identifier?.some((item) => item.system === occurrenceIdentifierSystem)) .filter((event) => days === null || Date.parse(event.effectiveDateTime ?? "") >= cutoff) .slice() .sort((a, b) => Date.parse(b.effectiveDateTime ?? "") - Date.parse(a.effectiveDateTime ?? "")); if (status === "loading" || loading) return {t("medication.loading")}; if (error) return {t("medication.loadError")}; return ( {t("medication.historyTitle")} setDays(7)}>{t("medication.filter7Days")} setDays(30)}>{t("medication.filter30Days")} setDays(null)}>{t("medication.filterAll")} {visible.length === 0 && {t("medication.noHistory")}} {visible.map((event, index) => { const label = event.status === "completed" ? t("medication.taken") : event.status === "not-done" ? t("medication.skipped") : t("medication.recordedStatus", { status: event.status ?? "unknown" }); const medicationName = event.medicationCodeableConcept?.text ?? event.medicationReference?.display ?? t("medication.unknownName"); return ( {medicationName} {label} · {t("medication.patientReported")} {!!event.effectiveDateTime && {new Intl.DateTimeFormat(i18n.language, { dateStyle: "medium", timeStyle: "short" }).format(new Date(event.effectiveDateTime))}} ); })} ); } ``` ### Connect History to Today [#connect-history-to-today] Export the occurrence identifier system from step 8. In the Today screen, read history for the authenticated Patient, index reports by that identifier, pass the matching event to `doseStatus()`, and give the action component a reload callback: ```tsx import { AdherenceActions } from "../../features/medication/adherence-actions"; import { occurrenceIdentifierSystem } from "../../features/medication/adherence"; import { useMedicationHistory } from "../../features/medication/history"; const { patient } = useMedicationPlan(); const { events, reload: reloadHistory } = useMedicationHistory(patient?.id ?? ""); const eventsByOccurrence = new Map( events.flatMap((event) => { const occurrence = event.identifier?.find((item) => item.system === occurrenceIdentifierSystem)?.value; return occurrence ? [[occurrence, event] as const] : []; }), ); // Inside each Today card: const status = doseStatus(item.scheduledAt, eventsByOccurrence.get(item.occurrenceKey)); ``` Add the hook and `AdherenceActions` imports to the Today route. The cached local outbox in step 10 adds its pending state separately; do not mix unsynced reports with server-confirmed History entries. ## Important Ovok decisions [#important-ovok-decisions] - Details come from `MedicationRequest`; adherence events come from `MedicationAdministration`. Do not overwrite the plan with a patient's action. - `status: completed` means the patient reported taking that occurrence in this tutorial; it does not mean the platform verified it. - `status: not-done` is the patient's skipped report. A missed row is derived from the schedule and absence of a record. - Show only fields that are present. The app must not infer a medicine's identity or dose from a free-text string. ## Expected result [#expected-result] The details screen presents the underlying plan without rewriting it, and History loads every matching FHIR page and labels adherence as patient-reported. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **History stops after one page:** use `searchResourcePages()` and iterate until it completes; `searchResources()` is a single result set and may not include older records. - **History includes another Patient's data:** verify the Patient search filter and AccessPolicy. The server-side policy must enforce the boundary even if a client omits its filter. - **An event is detached from its medication.** ensure every event has the source `MedicationRequest` reference and the same occurrence identifier used by the Today screen. - **The UI treats status as clinical truth:** label events as patient reports and do not translate them into care advice. ## Previous / Next [#previous--next] Previous: [step 8: record medication adherence](/guides/medication-reminder/record-medication-adherence) · Continue to [step 10: offline behavior, Settings, and localisation](/guides/medication-reminder/offline-settings-and-localisation). # Step 6 · Build the Today screen Canonical page: https://docs.ovok.com/guides/medication-reminder/build-the-today-screen ## What we are building [#what-we-are-building] A patient-facing schedule grouped into Morning, Afternoon, Evening, and Night, with a clear status for each supported occurrence. ## What you should already have [#what-you-should-already-have] - The authenticated Patient and `MedicationRequest[]` from step 5. - The local time and localisation rules from step 4. ## The implementation [#the-implementation] Create `src/features/medication/today-schedule.ts`. Only turn explicit daily `Timing.repeat.timeOfDay` values into reminder rows. This parser accepts a one-day period, matching frequency and `timeOfDay` count, and optional FHIR day-of-week/bounds fields. Other repeat patterns are skipped instead of guessed. ```ts import { atDeviceLocalTime } from "../../localization/schedule-time"; import { loadMedicationPlan } from "./medication-plan"; export function buildOccurrencesForDay(plan: Awaited>, day = new Date()) { const date = [day.getFullYear(), String(day.getMonth() + 1).padStart(2, "0"), String(day.getDate()).padStart(2, "0")].join("-"); const weekday = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"][day.getDay()]; return plan.flatMap((request) => (request.dosageInstruction ?? []).flatMap((dosage, dosageIndex) => { const repeat = dosage.timing?.repeat; if (!repeat?.timeOfDay?.length) return []; if (repeat.periodUnit !== "d" || repeat.period !== 1) return []; if (repeat.frequency !== undefined && repeat.frequency !== repeat.timeOfDay.length) return []; if ( repeat.frequencyMax !== undefined || repeat.periodMax !== undefined || repeat.duration !== undefined || repeat.durationMax !== undefined || repeat.count !== undefined || repeat.countMax !== undefined || repeat.boundsDuration !== undefined || repeat.boundsRange !== undefined || repeat.offset !== undefined || repeat.when?.length ) return []; if (repeat.dayOfWeek?.length && !repeat.dayOfWeek.includes(weekday)) return []; if (repeat.boundsPeriod?.start && date < repeat.boundsPeriod.start) return []; if (repeat.boundsPeriod?.end && date > repeat.boundsPeriod.end) return []; return repeat.timeOfDay.flatMap((time) => { const scheduledAt = atDeviceLocalTime(day, time); if (!scheduledAt || !request.id) return []; const medicationName = request.medicationCodeableConcept?.text ?? request.medicationReference?.display; const doseText = dosage.doseAndRate?.[0]?.doseQuantity ? `${dosage.doseAndRate[0].doseQuantity.value ?? ""} ${dosage.doseAndRate[0].doseQuantity.unit ?? ""}`.trim() : undefined; const occurrenceKey = `${request.id}:${dosageIndex}:${date}:${time}`; return [{ occurrenceKey, medicationName, doseText, instruction: dosage.text, request, scheduledAt, }]; }); }), ); } ``` `loadMedicationPlan` is the shared loader from step 5. For multiple days, call the same function with each local calendar date. If your plan uses a more complex FHIR Timing pattern, render its text and mark the schedule as unsupported until its interpretation has been reviewed. For each occurrence, derive state from the most recent matching `MedicationAdministration` identifier: ```ts type DoseStatus = "upcoming" | "due" | "taken" | "skipped" | "missed"; export function doseStatus( scheduledAt: Date, event: { status?: string } | undefined, now = new Date(), missedAfterMs?: number, ): DoseStatus { if (event?.status === "completed") return "taken"; if (event?.status === "not-done") return "skipped"; if (now < scheduledAt) return "upcoming"; if (missedAfterMs !== undefined && now.getTime() > scheduledAt.getTime() + missedAfterMs) { return "missed"; } return "due"; } ``` `missedAfterMs` is an application rule, not an Ovok or FHIR value. Choose its value with the product and clinical owners. If no approved cutoff exists, leave the occurrence as “Due” or “No response recorded”; do not present a guessed grace period as a clinical fact. The stable occurrence key uses the local calendar date and source `timeOfDay`, so rescheduling after a timezone change does not create a second report identifier for the same scheduled row. Build the screen in `src/app/(patient)/index.tsx` with loading, error, and empty states. Group rows by device-local time; all labels come from CMS translations: ```tsx import { useTranslation } from "react-i18next"; import { ActivityIndicator, ScrollView, StyleSheet, Text, View } from "react-native"; import { useMedicationPlan } from "../../features/medication/use-medication-plan"; import { formatScheduleTime } from "../../localization/schedule-time"; import { buildOccurrencesForDay, doseStatus } from "../../features/medication/today-schedule"; const periods = ["morning", "afternoon", "evening", "night"] as const; function periodFor(date: Date) { const hour = date.getHours(); if (hour < 12) return "morning"; if (hour < 17) return "afternoon"; if (hour < 21) return "evening"; return "night"; } export default function TodayScreen() { const { plan, loading, error } = useMedicationPlan(); const { t, i18n } = useTranslation(); if (loading) return ; if (error) return {t("medication.loadError")}; if (plan.length === 0) return {t("medication.emptyPlan")}; const occurrences = buildOccurrencesForDay(plan); return ( {t("medication.todayTitle")} {periods.map((period) => { const group = occurrences.filter((item) => periodFor(item.scheduledAt) === period); if (group.length === 0) return null; return ( {t(`medication.${period}`)} {group.map((item) => { const status = doseStatus(item.scheduledAt, undefined); return ( {item.medicationName ?? t("medication.unknownName")} {item.doseText && {item.doseText}} {formatScheduleTime(item.scheduledAt, i18n.language)} {item.instruction && {item.instruction}} {t(`medication.${status}`)} {status === "missed" && {t("medication.missedMessage")}} ); })} ); })} {occurrences.length === 0 && {t("medication.noSupportedSchedule")}} ); } const styles = StyleSheet.create({ screen: { padding: 20, gap: 20 }, title: { fontSize: 28, fontWeight: "700" }, group: { gap: 10 }, groupTitle: { fontSize: 18, fontWeight: "600" }, card: { borderWidth: 1, borderColor: "#d9d2e5", borderRadius: 14, padding: 16, gap: 8 }, name: { fontSize: 17, fontWeight: "600" }, }); ``` Step 8 adds patient actions; step 9 connects matching `MedicationAdministration` records so saved Taken and Skipped events replace the no-event status. The code passes `undefined` while that history integration is not yet in place. If a production request uses `medicationReference` without a `display`, resolve the referenced `Medication` through the FHIR client under the same Patient policy before rendering its name; the sample plan uses `medicationCodeableConcept.text`. ## Important Ovok decisions [#important-ovok-decisions] - No data means “no record,” not “not taken.” - The card displays the original source text. It does not translate or rewrite medication instructions unless a reviewed localization workflow provides an approved value. - `MedicationRequest.status` and event status are separate: an active request can have a taken or skipped occurrence. ## Expected result [#expected-result] The Today screen shows the three synthetic medicines grouped by local time, omits requests outside their `boundsPeriod`, and distinguishes an unrecorded occurrence from a saved patient report. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **The card has no scheduled time:** the request may not contain supported `timeOfDay` values. Do not parse `Dosage.text` to guess. - **The wrong weekday appears:** FHIR day codes are lowercase `mon` through `sun`; compare them with the device-local weekday. - **“Missed” appears too early:** verify the app's explicitly approved `missedAfterMs` policy. Ovok does not supply this cutoff. ## Previous / Next [#previous--next] Previous: [step 5: initialise Ovok and authentication](/guides/medication-reminder/initialise-ovok-and-authentication) · Continue to [step 7: add medication reminders](/guides/medication-reminder/add-medication-reminders). # Step 2 · Create and configure the Ovok project Canonical page: https://docs.ovok.com/guides/medication-reminder/create-and-configure-the-ovok-project ## What we are building [#what-we-are-building] A sandbox project where a synthetic patient can authenticate, read only their own medication plan and adherence history, and create their own patient-reported adherence events. ## What you should already have [#what-you-should-already-have] - The Expo app from step 1. - Project owner or administrator access to the Ovok Console. - A synthetic patient account and synthetic medication data only. ## The implementation [#the-implementation] ### Ovok Console configuration [#ovok-console-configuration] In the Console, create or select the sandbox project and record its tenant code. Use the sandbox API host from the app's `.env` file. Configure only the project capabilities the tutorial uses: 1. Enable patient sign-in and, only if patients will create their own test accounts, [`PATIENT_REGISTRATION_ENABLED`](/settings-and-features/settings/patient-registration-enabled). Self-registration also requires the project’s `defaultPatientAccessPolicy`; configure it in the Console. There is no project-settings key for this field, and registration fails until it exists. If a project administrator provisions the synthetic patient, leave self-registration off. 2. Configure an [AccessPolicy](/access-policies) for the patient workflow. It must scope access to the authenticated Patient and permit the specific interactions this tutorial uses: read/search `MedicationRequest`, read/search `MedicationAdministration`, and create `MedicationAdministration`. Assign it as the default patient policy only if new patients should receive it. Do not grant broad project-wide access just to make a tutorial request succeed. Test the policy with a patient account, not an administrator account. 3. Confirm the live CapabilityStatement advertises `MedicationAdministration` conditional create. Step 8 writes one resource per request, so it does not need the all-or-nothing `transaction-bundles` feature. If you later group multiple clinical writes into one transaction, enable and verify that feature first. 4. Enable the CMS for the project and publish the tutorial's `translations` groups to the sandbox environment used by the app. The [CMS/i18n guide](/cms/use-ovok-cms-with-i18n) explains the collection and publication flow. 5. Patient self-registration does not require a custom email template. If the product should send a welcome message, map the `PATIENT_WELCOME` template; configure invitation or password-reset templates only when those flows are enabled. See the [authentication setup guide](/authentication/project-setup) and [email template docs](/email-templates). The medication resources are standard FHIR resources. There is no medication-specific feature switch in this tutorial. Check the project's live [`CapabilityStatement`](/api/fhir/r4/capability-statement) for resource interactions and search parameters; API availability does not grant a patient permission to use them. ### Mobile application configuration [#mobile-application-configuration] Put the sandbox host and tenant code in the public Expo configuration created in step 1. Do not embed an administrator account, API key, or privileged token in the app. The application signs in as the patient and uses that patient's access policy for all resource requests. The tutorial uses email/password sign-in. It does not configure social login, OAuth callbacks, or app links. Add deep links only if you introduce a verified email or password-reset link flow and follow the corresponding authentication documentation. ## Important Ovok decisions [#important-ovok-decisions] - The patient app reads an existing plan; it must not let a patient create or alter a prescription. A project administrator or authorised clinical workflow creates the synthetic `MedicationRequest` used in the sandbox exercise. - The AccessPolicy is the security boundary. Filtering a resource list in React Native is not authorization. - No migration is required. The app reads FHIR resources directly and does not install a medication schema or custom profile. ## Expected result [#expected-result] You have a sandbox tenant code, a patient-only account, a tested AccessPolicy, and the CMS ready for published translation strings. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **The endpoint is in the CapabilityStatement but returns 403:** the authenticated patient AccessPolicy does not allow that resource interaction or scope. Do not switch to a privileged token in the client. - **A conditional create is rejected:** check the resource's CapabilityStatement interactions and the conditional-create query in the Bundle entry. - **Patient registration is disabled:** use an already provisioned synthetic patient or enable the registration setting for this sandbox project only. - **CMS strings are missing:** verify the tenant code, locale, publication state, and environment match the app configuration. ## Previous / Next [#previous--next] Previous: [step 1: create the React Native app](/guides/medication-reminder/create-the-react-native-app) · Continue to [step 3: model the medication plan](/guides/medication-reminder/model-the-medication-plan). # Step 1 · Create the React Native app Canonical page: https://docs.ovok.com/guides/medication-reminder/create-the-react-native-app ## What we are building [#what-we-are-building] An Expo Router app that compiles for iOS and Android and has the native modules needed for Ovok authentication, local notifications, and encrypted offline storage. ## What you should already have [#what-you-should-already-have] - Node.js and a package manager. - Xcode for iOS builds and/or Android Studio for Android builds. - Access to a development device or simulator. ## The implementation [#the-implementation] Create an Expo tabs app and install the Ovok packages. The minimum versions validated for this tutorial are `@ovok/core` 0.4.27 and `@ovok/native` 1.10.6; use the React Native SDK installation guide for platform compatibility requirements. ```bash npx create-expo-app@latest ovok-medication-reminder --template tabs cd ovok-medication-reminder npm install @ovok/core@^0.4.27 @ovok/native@^1.10.6 formik yup i18next react-i18next npm install iconsax-react-nativejs npx expo install @expo-google-fonts/dm-sans @gorhom/bottom-sheet react-native-ble-plx react-native-permissions react-native-reanimated expo-notifications expo-sqlite expo-secure-store expo-crypto expo-standard-web-crypto expo-dev-client expo-constants @react-native-community/netinfo react-native-safe-area-context react-native-gesture-handler react-native-keyboard-controller react-native-paper react-native-svg ``` Keep the Expo SDK version compatible with the [React Native SDK installation guide](/native-sdk/guide/how-to/installation). `npx expo install` selects the native package versions for that Expo SDK. Check the React Native SDK guide's current iOS deployment target and Android minimum SDK before building; those values follow the supported SDK baseline and can change. This tutorial does not use Bluetooth, HealthKit, or Health Connect, so do not add those permissions or plugins. ### Run Ovok's web platform polyfills first [#run-ovoks-web-platform-polyfills-first] Create `index.js` in the project root and make it the app entry in `package.json`: ```js const { polyfillOvokWebAPIs } = require("@ovok/native/polyfills"); polyfillOvokWebAPIs(); require("expo-router/entry"); ``` ```json { "main": "index.js" } ``` The polyfills must run before the client or screens import Ovok. ### Configure native plugins [#configure-native-plugins] Add the notification, secure storage, and SQLCipher plugins to `app.config.ts`. Keep the bundle identifiers generated for your application: ```ts import type { ExpoConfig } from "expo/config"; const config: ExpoConfig = { name: "Ovok Medication Reminder", slug: "ovok-medication-reminder", plugins: [ "expo-router", "expo-notifications", "expo-secure-store", ["expo-sqlite", { useSQLCipher: true }], ], ios: { bundleIdentifier: "com.example.ovokmedication" }, android: { package: "com.example.ovokmedication" }, }; export default config; ``` On iOS, local notifications require the patient's permission; step 7 requests it at the point the app explains reminders. On Android, create the notification channel before requesting runtime permission, also covered in step 7. The tutorial does not configure push credentials, background remote notifications, or exact-alarm permissions. Let the operating system control delivery timing. A notification is a reminder, not a clinical alert. ### Add public sandbox configuration [#add-public-sandbox-configuration] Create `.env.example`, copy it to `.env.local`, and keep that local file out of version control: ```dotenv EXPO_PUBLIC_OVOK_BASE_URL=https://api.sandbox.ovok.com EXPO_PUBLIC_TENANT_CODE=replace-with-your-sandbox-tenant-code ``` Expo embeds `EXPO_PUBLIC_` values in the application bundle. Store only public environment configuration here—never passwords, access tokens, or server credentials. ### Build a development app [#build-a-development-app] SQLCipher is configured at build time and is not available in Expo Go. Create a development build after adding the plugins: ```bash npx expo prebuild npx expo run:ios # or npx expo run:android ``` Local notifications can be previewed in Expo Go, but the encrypted database configuration requires your own native development build. Rebuild after changing a config plugin; an OTA JavaScript update cannot change native permissions or database libraries. ## Important Ovok decisions [#important-ovok-decisions] - The app uses an email/password patient flow. It does not need an OAuth redirect URI unless you later add an authentication flow that returns through a link. - `expo-notifications` schedules device-local notifications. It does not send a medication schedule to Ovok. - SQLCipher protects the app-owned offline cache/outbox at rest. It does not replace access control, device security, or a privacy review. ## Expected result [#expected-result] The blank Expo app launches in a custom development build, and its native configuration includes Expo Notifications and SQLCipher. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **Expo cannot resolve a native package:** run `npx expo install --fix`, then rebuild. - **The SQLite plugin appears configured but the app opens an ordinary database:** confirm `useSQLCipher: true` is in the evaluated Expo config and rebuild the native app. - **Notifications do not appear while the app is open:** install the notification handler in step 7; Expo does not present foreground notifications by default without one. ## Previous / Next [#previous--next] Start: [Medication Reminder tutorial overview](/guides/medication-reminder) · Continue to [step 2: create and configure the Ovok project](/guides/medication-reminder/create-and-configure-the-ovok-project). # Build a Medication Reminder App with Ovok in 30 Minutes Canonical page: https://docs.ovok.com/guides/medication-reminder Build a patient-facing medication reminder app in ten steps with Expo, React Native, `@ovok/native`, `@ovok/core`, and FHIR R4. The finished tutorial app signs a patient in, reads the patient's medication plan, shows today's scheduled doses, schedules private local reminders, records patient-reported taken or skipped events, and shows history. The title is a target for an experienced developer who already has an Ovok sandbox project. Native builds, Console configuration, clinical review, and device-specific testing can take longer. ## What you will build [#what-you-will-build] - A patient app that reads active `MedicationRequest` resources for the authenticated Patient. - A Today screen that displays only schedule details explicitly represented in the request. - Local notifications scheduled by the mobile app with Expo Notifications. Ovok does not schedule these device reminders. - `MedicationAdministration` resources for occurrence-level patient reports. “Missed” is calculated by the app and is not written as a clinical administration event. - A paginated adherence history and an encrypted local cache/outbox for offline use. - Localised interface text loaded from the project's Ovok CMS translations, not bundled translation JSON files. The sandbox CapabilityStatement currently advertises read, create, update, delete, history, and search interactions for `Medication`, `MedicationRequest`, `MedicationStatement`, `MedicationAdministration`, and `MedicationDispense`. Capabilities and project permissions can differ by environment; check your own [`/fhir/R4/metadata` CapabilityStatement](/api/fhir/r4/capability-statement) before relying on an interaction. ## Before you start [#before-you-start] - An Ovok sandbox project and a synthetic patient account. - A development machine with Node.js, Xcode for iOS builds, and/or Android Studio for Android builds. - Familiarity with React Native, TypeScript, and Expo Router. - A project owner or administrator who can configure the sandbox AccessPolicy and project features. This is a software implementation tutorial, not prescribing guidance. Use synthetic records only. Do not create, change, or discontinue a real medication plan from this patient app. The application displays instructions supplied by the plan and does not advise whether or how to take a medicine. ## Tutorial map [#tutorial-map] 1. [Create the React Native app](/guides/medication-reminder/create-the-react-native-app) 2. [Create and configure the Ovok project](/guides/medication-reminder/create-and-configure-the-ovok-project) 3. [Model the medication plan](/guides/medication-reminder/model-the-medication-plan) 4. [Set up localisation and time handling](/guides/medication-reminder/set-up-localisation-and-time-handling) 5. [Initialise Ovok and authentication](/guides/medication-reminder/initialise-ovok-and-authentication) 6. [Build the Today screen](/guides/medication-reminder/build-the-today-screen) 7. [Add medication reminders](/guides/medication-reminder/add-medication-reminders) 8. [Record medication adherence](/guides/medication-reminder/record-medication-adherence) 9. [Build History and Medication Details](/guides/medication-reminder/build-history-and-medication-details) 10. [Offline behavior, Settings, and localisation](/guides/medication-reminder/offline-settings-and-localisation) ## FHIR model at a glance [#fhir-model-at-a-glance] `MedicationRequest` is the plan or order, including the medication, Patient reference, status, and dosage instructions. `Medication` can hold a separately reusable medication definition, but a request can also carry a `medicationCodeableConcept`; this tutorial uses a text-only synthetic concept to keep the example small. `MedicationStatement` records a statement about medication use over a period. For this tutorial's individual reminder occurrences, the app creates a `MedicationAdministration` with `completed` or `not-done` status and identifies the Patient as the reporter/performer. That record is a patient report, not independent verification. There is no Ovok medication-plan hook, reminder scheduler, or generic offline FHIR write queue in the SDK. The app uses the current FHIR client methods for resources, Expo Notifications for local device reminders, and its own SQLCipher-backed cache/outbox for this example. The SDK's built-in offline queue is for measurements; it does not queue medication resources. ## Expected result [#expected-result] At the end, the app displays the sandbox patient's active medication schedule, can deliver already-scheduled reminders without network access, records taken/skipped reports to Ovok when online, and keeps pending reports in an encrypted local outbox until they can sync. The app never recommends a dose or tells a patient how to compensate for a missed dose. ## Reference documentation [#reference-documentation] - [React Native SDK overview](/native-sdk/guide/overview) · [Authentication](/authentication) · [Access Policies](/access-policies) - [FHIR R4 MedicationRequest](/api/fhir/r4/medication-request) · [MedicationAdministration](/api/fhir/r4/medication-administration) · [MedicationStatement](/api/fhir/r4/medication-statement) - [Project features and settings](/settings-and-features) · [Use Ovok CMS with i18n](/cms/use-ovok-cms-with-i18n) ## Next step [#next-step] Start with [step 1: create the React Native app](/guides/medication-reminder/create-the-react-native-app). # Step 5 · Initialise Ovok and authentication Canonical page: https://docs.ovok.com/guides/medication-reminder/initialise-ovok-and-authentication ## What we are building [#what-we-are-building] One persisted Ovok client, patient sign-in and registration screens, and a protected patient area that reads the authenticated Patient's plan. ## What you should already have [#what-you-should-already-have] - The tenant code and sandbox API URL from step 2. - The CMS loader from step 4. - Published sandbox `MedicationRequest` test records created by an authorized operator. ## The implementation [#the-implementation] ### Configure one client [#configure-one-client] Create `src/config/ovok.ts`: ```ts export const ovokConfig = { baseUrl: process.env.EXPO_PUBLIC_OVOK_BASE_URL!, tenantCode: process.env.EXPO_PUBLIC_TENANT_CODE!, }; ``` Create `src/client/ovok-client.ts`: ```ts import { OvokClient } from "@ovok/core"; import { ExpoClientStorage } from "@ovok/native/polyfills"; import { ovokConfig } from "../config/ovok"; export const ovokClient = new OvokClient({ baseUrl: ovokConfig.baseUrl, fhirUrlPath: "/fhir/R4/", storage: new ExpoClientStorage(), }); ``` The client owns the active login and persisted SDK session. Keep one instance at module scope. See [Core client configuration](/web-sdk/core/client-configuration). The current Expo template keeps routes in `src/app`; mount the providers in `src/app/_layout.tsx`: ```tsx import { OvokProvider } from "@ovok/core"; import { DEFAULT_COLORS, DEFAULT_MULTIPLIERS, ThemeProvider as OvokThemeProvider } from "@ovok/native"; import { I18nextProvider } from "react-i18next"; import { Slot } from "expo-router"; import { SafeAreaProvider } from "react-native-safe-area-context"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { KeyboardProvider } from "react-native-keyboard-controller"; import { LocalizationGate } from "../localization/localization-gate"; import i18n from "../localization/i18n"; import { ovokClient } from "../client/ovok-client"; export default function RootLayout() { return ( ); } ``` The React Native SDK auth forms need the SDK theme provider and the native keyboard/gesture setup. The provider values above match the current [React Native SDK app shell](/native-sdk/guide/how-to/app-shell); `ThemeProvider` also requires `@expo-google-fonts/dm-sans`, installed in step 1. Protect the patient route group in `src/app/(patient)/_layout.tsx`. Keep an offline session available—the React Native SDK reports `isAuthenticated` for a persisted offline session—while still requiring a Patient profile: ```tsx import { useSession } from "@ovok/native"; import { Redirect, Slot } from "expo-router"; import { ActivityIndicator } from "react-native"; export default function PatientLayout() { const { status, isAuthenticated, profile } = useSession({ sessions: false }); if (status === "loading") return ; if (!isAuthenticated || profile?.resourceType !== "Patient") return ; return ; } ``` The registration form is the account and Patient initialization path for this tutorial. Do not follow a successful registration by creating a second `Patient` resource in the app. ### Use the React Native SDK authentication forms [#use-the-react-native-sdk-authentication-forms] Create `src/app/sign-in.tsx` with the supported patient form and `src/app/register.tsx` with the registration form below. Replace the Expo starter routes with these screens and the authenticated `src/app/(patient)/` route group so each URL resolves to one flow: ```tsx import { SignIn, useSession } from "@ovok/native"; import { Redirect, useRouter } from "expo-router"; import { ActivityIndicator, View } from "react-native"; import { ovokConfig } from "../config/ovok"; export default function SignInScreen() { const router = useRouter(); const { status, isAuthenticated } = useSession({ sessions: false }); if (status === "loading") return ; if (isAuthenticated) return ; return ( router.replace("/(patient)")} > ); } ``` For the sandbox's patient registration screen, use `Register.EmailForm` with the same `tenantCode` and route to the patient area from `onSuccess`. Use the SDK's form rather than sending passwords through a custom FHIR request. See [Native authentication](/native-sdk/guide/modules/auth), [patient registration](/authentication/patient-registration), and [patient login](/authentication/patient-login). ### Load the signed-in Patient's plan [#load-the-signed-in-patients-plan] Put the loader in `src/features/medication/medication-plan.ts` so Today, Details, and History screens share one query and step 6 can infer its resource type: ```ts import type { OvokClient } from "@ovok/core"; export async function loadMedicationPlan(client: OvokClient, patientId: string) { const requests: Awaited> = []; for await (const page of client.searchResourcePages("MedicationRequest", { subject: `Patient/${patientId}`, status: "active", _count: "100", })) { requests.push(...page); } return requests; } ``` Create `src/features/medication/use-medication-plan.ts`. Derive the Patient from the active React Native SDK session and load the plan with that id: ```tsx import { useClient } from "@ovok/core"; import { useSession } from "@ovok/native"; import * as React from "react"; import { loadMedicationPlan } from "./medication-plan"; export function useMedicationPlan() { const client = useClient(); const { status, isAuthenticated, profile } = useSession({ sessions: false }); const patientId = profile?.resourceType === "Patient" ? profile.id : undefined; const [plan, setPlan] = React.useState>>([]); const [error, setError] = React.useState(); const [loading, setLoading] = React.useState(true); React.useEffect(() => { if (status === "loading") return; if (!isAuthenticated || !patientId) { setPlan([]); setError(undefined); setLoading(false); return; } let current = true; setLoading(true); setError(undefined); setPlan([]); void loadMedicationPlan(client, patientId) .then((resources) => { if (current) setPlan(resources); }) .catch((reason: unknown) => { if (current) setError(reason instanceof Error ? reason : new Error(String(reason))); }) .finally(() => { if (current) setLoading(false); }); return () => { current = false; }; }, [client, isAuthenticated, status, patientId]); return { plan, patient: patientId ? profile : undefined, loading, error }; } ``` Keep the Patient type check; do not assume every authenticated account is a Patient. See [Native authentication](/native-sdk/guide/modules/auth) for the current session and form APIs. ### Add patient registration [#add-patient-registration] When self-registration is enabled for the sandbox, the React Native SDK form creates and activates the Patient account. It does not require a second client-side `Patient` create: ```tsx import { Register, useSession } from "@ovok/native"; import { Redirect, useRouter } from "expo-router"; import { useTranslation } from "react-i18next"; import { ActivityIndicator, Alert, View } from "react-native"; import { ovokConfig } from "../config/ovok"; export default function RegisterScreen() { const router = useRouter(); const { t } = useTranslation(); const { status, isAuthenticated } = useSession({ sessions: false }); if (status === "loading") return ; if (isAuthenticated) return ; return ( router.replace("/(patient)")} onError={() => Alert.alert(t("register.registrationFailed"), t("register.tryAgain"))} > router.push("/sign-in")} /> ); } ``` If your sandbox uses pre-provisioned Patients instead, omit self-registration and use the test account. For production, protect the patient route group with the session state and send signed-out users to the sign-in route. The protected route group created earlier is `src/app/(patient)/_layout.tsx`: ```tsx import { useSession } from "@ovok/native"; import { Redirect, Slot } from "expo-router"; import { ActivityIndicator } from "react-native"; export default function PatientLayout() { const { status, isAuthenticated, profile } = useSession({ sessions: false }); if (status === "loading") return ; if (!isAuthenticated || profile?.resourceType !== "Patient") { return ; } return ; } ``` ## Important Ovok decisions [#important-ovok-decisions] - The authenticated profile supplies the Patient id. Do not accept a patient id from a route parameter as the authorization context. - The search includes `subject` and `status`; the AccessPolicy from step 2 must independently enforce the patient scope. - React Native SDK forms own the authentication exchange. The app only chooses navigation and displays loading/error states. ## Expected result [#expected-result] The sandbox patient can sign in, enter a protected patient area, and read only their active `MedicationRequest` resources. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **`profile` is missing or not a Patient:** wait for `useSession` to finish, then route non-patient account types away from patient screens. - **401 or 403 on search:** check base URL/FHIR path, login state, and the patient AccessPolicy. Do not test with an administrator token and assume the policy works. - **Authentication works but plan is empty:** verify the synthetic request's subject reference and active status. ## Previous / Next [#previous--next] Previous: [step 4: set up localisation and time handling](/guides/medication-reminder/set-up-localisation-and-time-handling) · Continue to [step 6: build the Today screen](/guides/medication-reminder/build-the-today-screen). # Step 3 · Model the medication plan Canonical page: https://docs.ovok.com/guides/medication-reminder/model-the-medication-plan ## What we are building [#what-we-are-building] A small synthetic plan expressed as FHIR R4 `MedicationRequest` resources, ready for the patient app to read. ## What you should already have [#what-you-should-already-have] - The sandbox project and patient access policy from step 2. - A synthetic Patient resource created through an authorized sandbox or clinical setup flow. - Permission to create the sample plan as a project administrator or another authorized test operator. ## The implementation [#the-implementation] ### Choose the FHIR resources [#choose-the-fhir-resources] Ovok does not expose a separate medication-plan API. Use the FHIR resource that matches each fact: | Need | Resource | Use in this tutorial | | --- | --- | --- | | A prescribed or intended plan with dose instructions | [`MedicationRequest`](/api/fhir/r4/medication-request) | The app reads active requests for the signed-in Patient. | | A reusable coded or detailed medication definition | [`Medication`](/api/fhir/r4/medication) | Optional. A request may instead use `medicationCodeableConcept`. | | A statement that a patient is or was taking medication over a period | [`MedicationStatement`](/api/fhir/r4/medication-statement) | Not used for each individual reminder occurrence. | | One occurrence reported as completed or not done | [`MedicationAdministration`](/api/fhir/r4/medication-administration) | Used in step 8 for patient-reported taken/skipped events. | The CapabilityStatement at `GET /fhir/R4/metadata` advertises create, read, update, delete, history, and search interactions for these medication resources in the current sandbox. Always check the target environment before deploying. ### Create synthetic requests outside the patient app [#create-synthetic-requests-outside-the-patient-app] Create the following requests in the sandbox using an authorized setup tool. Do not put an administrator token in the mobile app. This is non-clinical sample data; replace nothing here with a real medication or prescribing instruction. ```json { "resourceType": "MedicationRequest", "status": "active", "intent": "order", "medicationCodeableConcept": { "text": "Demo medicine A" }, "subject": { "reference": "Patient/REPLACE_WITH_SYNTHETIC_PATIENT_ID" }, "authoredOn": "2026-10-07T09:00:00Z", "dosageInstruction": [ { "text": "Demo instructions only.", "timing": { "repeat": { "frequency": 1, "period": 1, "periodUnit": "d", "timeOfDay": ["08:00:00"], "boundsPeriod": { "start": "2026-10-07", "end": "2026-11-06" } } } } ] } ``` Create two more active `MedicationRequest` resources for the same synthetic Patient: one with `frequency: 2` and `timeOfDay: ["08:00:00", "20:00:00"]`, and one with `frequency: 1`, `timeOfDay: ["18:30:00"]`, and its own neutral `dosageInstruction.text`. Give each resource a different `medicationCodeableConcept.text` and a different server-assigned resource id. These examples demonstrate one daily dose, two daily doses, and an instruction such as “Demo instructions only; meal context supplied by the test plan.” They are not recommendations. The sample `authoredOn`, `boundsPeriod.start`, and `boundsPeriod.end` values are illustrative. Before creating the sample requests, update the start/end dates to a current test window so they remain active during your walkthrough. `MedicationRequest.medication[x]` and `subject` are required. The `dosageInstruction` carries the display text and timing. `timeOfDay` is a FHIR `time`, so it has no UTC offset. The tutorial interprets this simple example as the patient's local wall-clock time; step 4 defines that product decision and its limitations. ### Read the plan with the FHIR client [#read-the-plan-with-the-fhir-client] Once step 5 has created the `client` and authenticated patient profile, the app reads only active requests belonging to that Patient: ```ts const plan = await loadMedicationPlan(client, patient.id); ``` `loadMedicationPlan` is implemented in step 5 using the client's paginated search method. Keep the `subject` filter in the request and let the AccessPolicy enforce the same boundary server-side. ## Important Ovok decisions [#important-ovok-decisions] - `MedicationRequest.status` describes the request's lifecycle. Only `active` requests are included in this simple Today view; cancelled, stopped, completed, or entered-in-error requests must not be shown as current. - A `Medication` resource is optional when the request has a usable `medicationCodeableConcept`. Do not create duplicate Medication resources simply to display a text label. - A `MedicationStatement` is not a dose-by-dose adherence log. The tutorial uses one `MedicationAdministration` per reported occurrence and makes clear it is patient-reported. - `Dosage.timing` can express more than this tutorial's daily `timeOfDay` subset. The app must not guess a reminder time from `when`, `frequency`, or free text. Unsupported timing needs an explicit product/clinical interpretation before scheduling. ## Expected result [#expected-result] The sandbox contains three synthetic `MedicationRequest` resources linked to one test Patient, and the authenticated patient search returns only that patient's active requests. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **No requests are returned:** verify the `subject` reference is exactly `Patient/{id}`, the request is `active`, and the user is signed in as that patient. - **The plan displays a misleading schedule:** inspect the source `Dosage.timing`. The tutorial supports explicit local `timeOfDay` entries; it does not parse free-text instructions into times. - **A write returns 403:** create the sample plan through an authorized setup identity. The patient app should not receive a privilege that lets it prescribe or edit the plan. ## Previous / Next [#previous--next] Previous: [step 2: create and configure the Ovok project](/guides/medication-reminder/create-and-configure-the-ovok-project) · Continue to [step 4: set up localisation and time handling](/guides/medication-reminder/set-up-localisation-and-time-handling). # Step 10 · Offline behavior, Settings, and localisation Canonical page: https://docs.ovok.com/guides/medication-reminder/offline-settings-and-localisation ## What we are building [#what-we-are-building] An encrypted local cache for the current plan and a durable outbox for adherence reports. We will also finish the patient Settings screen and add a second CMS locale. ## What you should already have [#what-you-should-already-have] - The running Expo development build and SQLCipher plugin from step 1. - `expo-sqlite`, `expo-secure-store`, `expo-crypto`, and `@react-native-community/netinfo` installed. - The plan loader, adherence Bundle builder, local reminders, and CMS/i18next setup from earlier steps. ## The implementation [#the-implementation] ### Open an encrypted local database [#open-an-encrypted-local-database] Create `src/features/medication/offline-storage.ts`: Create the encryption key once, keep it in the operating system's secure storage, and apply it before issuing any SQL query. This database stores the last downloaded plan and any unsent patient reports: ```ts import * as Crypto from "expo-crypto"; import * as SecureStore from "expo-secure-store"; import * as SQLite from "expo-sqlite"; const databaseName = "ovok-medication.db"; const keyName = "ovok-medication-db-key"; export async function openMedicationDatabase() { let key = await SecureStore.getItemAsync(keyName); if (!key) { key = Array.from(await Crypto.getRandomBytesAsync(32), (byte) => byte.toString(16).padStart(2, "0")).join(""); await SecureStore.setItemAsync(keyName, key); } const db = await SQLite.openDatabaseAsync(databaseName); await db.execAsync(`PRAGMA key = '${key}'`); await db.execAsync(` CREATE TABLE IF NOT EXISTS plan_cache ( patient_id TEXT NOT NULL, request_id TEXT NOT NULL, resource_json TEXT NOT NULL, updated_at TEXT NOT NULL, PRIMARY KEY (patient_id, request_id) ); CREATE TABLE IF NOT EXISTS plan_cache_state ( patient_id TEXT PRIMARY KEY NOT NULL, synced_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS history_cache ( patient_id TEXT NOT NULL, event_id TEXT NOT NULL, resource_json TEXT NOT NULL, PRIMARY KEY (patient_id, event_id) ); CREATE TABLE IF NOT EXISTS history_cache_state ( patient_id TEXT PRIMARY KEY NOT NULL, synced_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS translation_cache ( locale TEXT PRIMARY KEY NOT NULL, tree_json TEXT NOT NULL, fetched_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS adherence_outbox ( patient_id TEXT NOT NULL, occurrence_key TEXT NOT NULL, bundle_json TEXT NOT NULL, sync_state TEXT NOT NULL DEFAULT 'pending', created_at TEXT NOT NULL, PRIMARY KEY (patient_id, occurrence_key) ); `); return db; } ``` `key` contains only hex characters generated by the app. Never interpolate user input into SQL. Keep the Patient id on every row so one signed-in account cannot flush another account's pending events. ### Cache the plan and queue reports [#cache-the-plan-and-queue-reports] After a successful plan search, atomically replace that Patient's cache with the returned plan. Before sending a Taken or Skipped report, persist the Bundle created in step 8: ```ts export async function cacheMedicationPlan(db: SQLite.SQLiteDatabase, patientId: string, requests: Array<{ id?: string }>) { const syncedAt = new Date().toISOString(); await db.withTransactionAsync(async () => { await db.runAsync("DELETE FROM plan_cache WHERE patient_id = ?", patientId); await db.runAsync( `INSERT INTO plan_cache_state (patient_id, synced_at) VALUES (?, ?) ON CONFLICT(patient_id) DO UPDATE SET synced_at = excluded.synced_at`, patientId, syncedAt, ); for (const request of requests) { if (!request.id) throw new Error("A server medication request has no id and cannot be cached."); await db.runAsync( `INSERT INTO plan_cache (patient_id, request_id, resource_json, updated_at) VALUES (?, ?, ?, ?)`, patientId, request.id, JSON.stringify(request), syncedAt, ); } }); } export async function readCachedMedicationPlan(db: SQLite.SQLiteDatabase, patientId: string) { const snapshot = await db.getFirstAsync<{ synced_at: string }>( "SELECT synced_at FROM plan_cache_state WHERE patient_id = ?", patientId, ); if (!snapshot) return undefined; const rows = await db.getAllAsync<{ resource_json: string }>( `SELECT resource_json, updated_at FROM plan_cache WHERE patient_id = ? ORDER BY updated_at DESC`, patientId, ); return { requests: rows.map((row) => JSON.parse(row.resource_json) as T), syncedAt: snapshot.synced_at, }; } export async function cacheMedicationHistory(db: SQLite.SQLiteDatabase, patientId: string, events: Array<{ id?: string }>) { const syncedAt = new Date().toISOString(); await db.withTransactionAsync(async () => { await db.runAsync("DELETE FROM history_cache WHERE patient_id = ?", patientId); await db.runAsync( `INSERT INTO history_cache_state (patient_id, synced_at) VALUES (?, ?) ON CONFLICT(patient_id) DO UPDATE SET synced_at = excluded.synced_at`, patientId, syncedAt, ); for (const event of events) { if (!event.id) throw new Error("A server medication report has no id and cannot be cached."); await db.runAsync( "INSERT INTO history_cache (patient_id, event_id, resource_json) VALUES (?, ?, ?)", patientId, event.id, JSON.stringify(event), ); } }); } export async function readCachedMedicationHistory(db: SQLite.SQLiteDatabase, patientId: string) { const snapshot = await db.getFirstAsync<{ synced_at: string }>( "SELECT synced_at FROM history_cache_state WHERE patient_id = ?", patientId, ); if (!snapshot) return undefined; const rows = await db.getAllAsync<{ resource_json: string }>( "SELECT resource_json FROM history_cache WHERE patient_id = ?", patientId, ); return { events: rows.map((row) => JSON.parse(row.resource_json) as T), syncedAt: snapshot.synced_at, }; } export async function cacheCmsTranslations( db: SQLite.SQLiteDatabase, locale: string, tree: Record, ) { await db.runAsync( `INSERT INTO translation_cache (locale, tree_json, fetched_at) VALUES (?, ?, ?) ON CONFLICT(locale) DO UPDATE SET tree_json = excluded.tree_json, fetched_at = excluded.fetched_at`, locale, JSON.stringify(tree), new Date().toISOString(), ); } export async function readCachedCmsTranslations(db: SQLite.SQLiteDatabase, locale: string) { const row = await db.getFirstAsync<{ tree_json: string }>( "SELECT tree_json FROM translation_cache WHERE locale = ?", locale, ); return row ? JSON.parse(row.tree_json) as Record : undefined; } export async function queueAdherenceBundle( db: SQLite.SQLiteDatabase, patientId: string, occurrenceKey: string, bundle: unknown, ) { await db.runAsync( `INSERT OR IGNORE INTO adherence_outbox (patient_id, occurrence_key, bundle_json, created_at) VALUES (?, ?, ?, ?)`, patientId, occurrenceKey, JSON.stringify(bundle), new Date().toISOString(), ); } ``` Read one queued report when the Today screen mounts so the UI can restore its local pending state after an app restart: ```ts export async function readQueuedAdherenceReport( db: SQLite.SQLiteDatabase, patientId: string, occurrenceKey: string, ) { const row = await db.getFirstAsync<{ bundle_json: string; sync_state: string }>( `SELECT bundle_json, sync_state FROM adherence_outbox WHERE patient_id = ? AND occurrence_key = ?`, patientId, occurrenceKey, ); if (!row) return undefined; const bundle = JSON.parse(row.bundle_json) as { entry?: Array<{ resource?: { status?: string } }>; }; const status = bundle.entry?.[0]?.resource?.status; if (status !== "completed" && status !== "not-done") return undefined; return { action: status === "completed" ? "taken" as const : "skipped" as const, syncState: row.sync_state, }; } ``` Update the plan cache only after the FHIR search succeeds. If the search fails, call `readCachedMedicationPlan()` for the authenticated Patient and mark it **Last synced** with its timestamp; do not describe stale data as current. The phone's already-scheduled local reminders can still fire offline. Replace the step 5 plan hook with this version. It falls back only to the signed-in Patient's cache, and exposes the source and last-sync time so the screen can distinguish stale data: ```tsx import { useClient } from "@ovok/core"; import { useSession } from "@ovok/native"; import * as React from "react"; import { loadMedicationPlan } from "./medication-plan"; import { cacheMedicationPlan, openMedicationDatabase, readCachedMedicationPlan } from "./offline-storage"; type MedicationPlan = Awaited>; export function useMedicationPlan() { const client = useClient(); const { status, isAuthenticated, profile } = useSession({ sessions: false }); const patientId = profile?.resourceType === "Patient" ? profile.id : undefined; const [plan, setPlan] = React.useState([]); const [loading, setLoading] = React.useState(true); const [error, setError] = React.useState(); const [cacheError, setCacheError] = React.useState(); const [source, setSource] = React.useState<"server" | "cache">("server"); const [lastSyncedAt, setLastSyncedAt] = React.useState(); React.useEffect(() => { if (status === "loading") return; if (!isAuthenticated || !patientId) { setPlan([]); setLoading(false); setError(undefined); setCacheError(undefined); setSource("server"); setLastSyncedAt(undefined); return; } let current = true; setLoading(true); setError(undefined); setCacheError(undefined); setPlan([]); setSource("server"); setLastSyncedAt(undefined); void (async () => { try { const fresh = await loadMedicationPlan(client, patientId); if (!current) return; const syncedAt = new Date().toISOString(); setPlan(fresh); setSource("server"); setLastSyncedAt(syncedAt); try { const db = await openMedicationDatabase(); await cacheMedicationPlan(db, patientId, fresh); } catch (cacheReason) { if (current) setCacheError(cacheReason instanceof Error ? cacheReason : new Error(String(cacheReason))); } } catch (reason) { const serverError = reason instanceof Error ? reason : new Error(String(reason)); try { const db = await openMedicationDatabase(); const cached = await readCachedMedicationPlan(db, patientId); if (!current) return; if (cached) { setPlan(cached.requests); setSource("cache"); setLastSyncedAt(cached.syncedAt); } else { setError(serverError); } } catch (cacheReason) { if (current) { setError(serverError); setCacheError(cacheReason instanceof Error ? cacheReason : new Error(String(cacheReason))); } } } finally { if (current) setLoading(false); } })(); return () => { current = false; }; }, [client, isAuthenticated, patientId, status]); return { plan, patient: patientId ? profile : undefined, loading, error, cacheError, source, lastSyncedAt }; } ``` In Today, show **Last synced** with `lastSyncedAt` when `source === "cache"`. Do not present cached data as current, or replace it with an empty plan when the server request fails. Render the cache timestamp and a recoverable warning when a fresh online plan could not be cached: ```tsx const { source, lastSyncedAt, cacheError } = useMedicationPlan(); const { t, i18n } = useTranslation(); {source === "cache" && lastSyncedAt && ( {t("medication.lastSynced", { date: new Intl.DateTimeFormat(i18n.language, { dateStyle: "medium", timeStyle: "short" }) .format(new Date(lastSyncedAt)), })} )} {source === "server" && cacheError && ( {t("medication.offlineCacheError")} )} ``` ### Keep confirmed history available offline [#keep-confirmed-history-available-offline] Replace the Step 9 `useMedicationHistory` implementation in `src/features/medication/history.ts`. Keep its `MedicationAdministrationView` type and `reload()` contract. Cache only this tutorial's occurrence reports, not every MedicationAdministration returned by the Patient search: ```tsx import { useClient } from "@ovok/core"; import * as React from "react"; import { occurrenceIdentifierSystem } from "./adherence"; import { cacheMedicationHistory, openMedicationDatabase, readCachedMedicationHistory } from "./offline-storage"; export function useMedicationHistory(patientId: string) { const client = useClient(); const [events, setEvents] = React.useState([]); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(); const [cacheError, setCacheError] = React.useState(); const [source, setSource] = React.useState<"server" | "cache">("server"); const [lastSyncedAt, setLastSyncedAt] = React.useState(); const [revision, setRevision] = React.useState(0); const reload = React.useCallback(() => setRevision((value) => value + 1), []); React.useEffect(() => { let current = true; setEvents([]); setError(undefined); setCacheError(undefined); if (!patientId) { setLoading(false); return () => { current = false; }; } setLoading(true); void (async () => { try { const loaded: MedicationAdministrationView[] = []; for await (const page of client.searchResourcePages("MedicationAdministration", { subject: `Patient/${patientId}`, _count: "50", })) loaded.push(...page); const ownReports = loaded.filter((event) => event.identifier?.some((item) => item.system === occurrenceIdentifierSystem), ); const syncedAt = new Date().toISOString(); if (current) { setEvents(ownReports); setSource("server"); setLastSyncedAt(syncedAt); } try { const db = await openMedicationDatabase(); await cacheMedicationHistory(db, patientId, ownReports); } catch (reason) { if (current) setCacheError(reason instanceof Error ? reason : new Error(String(reason))); } } catch (reason) { const serverError = reason instanceof Error ? reason : new Error(String(reason)); try { const db = await openMedicationDatabase(); const cached = await readCachedMedicationHistory(db, patientId); if (!current) return; if (cached) { setEvents(cached.events); setSource("cache"); setLastSyncedAt(cached.syncedAt); } else { setError(serverError); } } catch (cacheReason) { if (current) { setError(serverError); setCacheError(cacheReason instanceof Error ? cacheReason : new Error(String(cacheReason))); } } } finally { if (current) setLoading(false); } })(); return () => { current = false; }; }, [client, patientId, revision]); return { events, loading, error, cacheError, source, lastSyncedAt, reload }; } ``` In the Step 9 History screen, update the hook result and display the cache timestamp when `source === "cache"`: ```tsx const { events, loading, error, cacheError, source, lastSyncedAt } = useMedicationHistory(patientId); {source === "cache" && lastSyncedAt && ( {t("medication.lastSynced", { date: new Intl.DateTimeFormat(i18n.language, { dateStyle: "medium", timeStyle: "short" }) .format(new Date(lastSyncedAt)), })} )} {source === "server" && cacheError && ( {t("medication.offlineCacheError")} )} ``` Keep local outbox reports on Today as **Pending sync**; do not mix them into server-confirmed history. ### Flush the outbox safely [#flush-the-outbox-safely] Sync only after the same Patient is authenticated. Delete a queued row only after the server returns a successful response for its transaction entry: ```ts import { readOvokError, type OvokClient } from "@ovok/core"; import { buildAdherenceBundle, type DoseOccurrence, type PatientReport } from "./adherence"; export async function flushAdherenceOutbox( db: SQLite.SQLiteDatabase, client: OvokClient, authenticatedPatientId: string, ) { const rows = await db.getAllAsync<{ occurrence_key: string; bundle_json: string }>( `SELECT occurrence_key, bundle_json FROM adherence_outbox WHERE patient_id = ? AND sync_state = 'pending' ORDER BY created_at`, authenticatedPatientId, ); for (const row of rows) { const bundle = JSON.parse(row.bundle_json) as Parameters[0]; let response: Awaited>; try { response = await client.executeBatch(bundle); } catch (reason) { const { status } = readOvokError(reason); if (status !== undefined && status >= 400 && status < 500) { await db.runAsync( `UPDATE adherence_outbox SET sync_state = 'needs-attention' WHERE patient_id = ? AND occurrence_key = ?`, authenticatedPatientId, row.occurrence_key, ); } throw reason; } const status = response.entry?.[0]?.response?.status; const code = Number(status?.slice(0, 3)); if (code >= 400 && code < 500) { await db.runAsync( `UPDATE adherence_outbox SET sync_state = 'needs-attention' WHERE patient_id = ? AND occurrence_key = ?`, authenticatedPatientId, row.occurrence_key, ); throw new Error(`Adherence report needs attention for ${row.occurrence_key}: ${status}`); } if (!status || !/^2\d\d/.test(status)) { throw new Error(`Adherence sync did not succeed for ${row.occurrence_key}: ${status ?? "missing response status"}`); } await db.runAsync( "DELETE FROM adherence_outbox WHERE patient_id = ? AND occurrence_key = ?", authenticatedPatientId, row.occurrence_key, ); } } ``` The Taken/Skipped handler now stores first and sends second: ```ts export async function recordPatientReport( db: SQLite.SQLiteDatabase, client: OvokClient, patientId: string, occurrence: DoseOccurrence, report: PatientReport, isOnline: boolean, ) { const bundle = buildAdherenceBundle(patientId, occurrence, report); await queueAdherenceBundle(db, patientId, occurrence.occurrenceKey, bundle); if (!isOnline) return "pending-sync" as const; await flushAdherenceOutbox(db, client, patientId); return "synced" as const; } ``` In `AdherenceActions` from step 8, add `syncState` state and replace its online-only `submitAdherenceReport()` call with the durable write. The action is queued before the network request; restore that same action when the route regains focus: ```tsx import NetInfo from "@react-native-community/netinfo"; import { useFocusEffect } from "expo-router"; import { openMedicationDatabase, readQueuedAdherenceReport, recordPatientReport } from "./offline-storage"; const [syncState, setSyncState] = useState(); useFocusEffect(React.useCallback(() => { let current = true; void (async () => { if (!profile?.id) return; try { const db = await openMedicationDatabase(); const queued = await readQueuedAdherenceReport(db, profile.id, occurrence.occurrenceKey); if (!current) return; if (queued) { setAttemptedAction(queued.action); setSavedAction(queued.action); setSyncState(queued.syncState); } else { setSyncState(undefined); } } catch { if (current) setError(true); } })(); return () => { current = false; }; }, [profile?.id, occurrence.occurrenceKey])); async function submit(action: PatientReport["action"]) { if (!profile?.id || attemptedAction) return; setAttemptedAction(action); let db: Awaited> | undefined; try { db = await openMedicationDatabase(); const network = await NetInfo.fetch(); const isOnline = network.isConnected === true && network.isInternetReachable !== false; const result = await recordPatientReport(db, client, profile.id, occurrence, { action, reportedAt: new Date(), }, isOnline); setSavedAction(action); setSyncState(result === "pending-sync" ? "pending" : undefined); if (result === "synced") onSaved?.(); } catch { try { const queued = db ? await readQueuedAdherenceReport(db, profile.id, occurrence.occurrenceKey) : undefined; if (queued) { setSavedAction(queued.action); setSyncState(queued.syncState); } else { setError(true); setAttemptedAction(undefined); } } catch { setError(true); } } } ``` Render the restored state before the buttons: `syncState === "pending"` uses `t("medication.pendingSync")`, and `syncState === "needs-attention"` uses `t("medication.syncError")`. Keep the action locked while either state exists. When a reconnect flush succeeds, reload History; its server event becomes the confirmed state. A local queued report is never labelled **Saved to Ovok**. In `AdherenceActions`, show those states before the local `savedAction` state so an offline report is not presented as a confirmed server record: ```tsx if (existingAction) return {t("medication.patientReported")}: {t(`medication.${existingAction}`)}; if (syncState === "pending") return {t("medication.pendingSync")}; if (syncState === "needs-attention") return {t("medication.syncError")}; if (savedAction) return {t("medication.patientReported")}: {t(`medication.${savedAction}`)}; ``` If the request fails, keep the queue row and display **Pending sync** or **Needs attention** according to the failure. Do not show **Saved to Ovok** until a successful response. The transaction's conditional create means retrying the same occurrence remains safe. Watch connectivity and app-resume events from the authenticated patient area: ```ts import NetInfo from "@react-native-community/netinfo"; import { AppState } from "react-native"; export function watchForReconnect(sync: () => Promise, onError: (error: Error) => void) { let running = false; const runIfOnline = async () => { if (running) return; running = true; try { const state = await NetInfo.fetch(); if (state.isConnected && state.isInternetReachable !== false) { await sync(); } } catch (reason) { onError(reason instanceof Error ? reason : new Error(String(reason))); } finally { running = false; } }; void runIfOnline(); const stopNetworkListener = NetInfo.addEventListener((state) => { if (state.isConnected && state.isInternetReachable !== false) void runIfOnline(); }); const appStateListener = AppState.addEventListener("change", (state) => { if (state === "active") void runIfOnline(); }); return () => { stopNetworkListener(); appStateListener.remove(); }; } ``` Call `watchForReconnect(async () => { await flushAdherenceOutbox(db, client, patientId); await reloadHistory(); }, showSyncError)` only after the session confirms that `patientId` is the authenticated Patient. Keep processing sequentially. On a network error, leave the row pending; on a 4xx response, mark it `needs-attention`, show a sync error, and stop automatic retries until the app or support workflow resolves it. Conditional create in step 8 makes an uncertain retry idempotent. Create `src/features/medication/use-medication-reconnect-sync.ts`. Mount this hook from the authenticated patient layout so it can flush while the app is open. It owns its listener cleanup and reloads History after the server confirms a queued report: ```tsx import { useClient } from "@ovok/core"; import { useSession } from "@ovok/native"; import * as React from "react"; import { flushAdherenceOutbox, openMedicationDatabase, watchForReconnect } from "./offline-storage"; import { useMedicationHistory } from "./history"; export function useMedicationReconnectSync() { const client = useClient(); const { isAuthenticated, profile } = useSession({ sessions: false }); const patientId = profile?.resourceType === "Patient" ? profile.id : undefined; const { reload: reloadHistory } = useMedicationHistory(patientId ?? ""); const [syncError, setSyncError] = React.useState(); React.useEffect(() => { if (!isAuthenticated || !patientId) return; let current = true; let stop = () => {}; void openMedicationDatabase() .then((db) => { if (!current) return; stop = watchForReconnect(async () => { await flushAdherenceOutbox(db, client, patientId); reloadHistory(); if (current) setSyncError(undefined); }, (error) => { if (current) setSyncError(error); }); }) .catch((reason: unknown) => { if (current) setSyncError(reason instanceof Error ? reason : new Error(String(reason))); }); return () => { current = false; stop(); }; }, [client, isAuthenticated, patientId, reloadHistory]); return { syncError }; } ``` Ovok's built-in offline queue is for measurements, not generic FHIR resources. This plan cache and adherence outbox are application-owned. SQLCipher reduces exposure at rest; it does not replace a threat model, device lock policy, retention rules, consent, or account isolation. Never flush one Patient's data while another Patient is signed in. ### Finish Settings [#finish-settings] Create `src/app/(patient)/settings.tsx`. This small screen uses the Native session for account state, persists only local preferences, and lets the CMS hook fetch the chosen locale. Add a real privacy/consent route owned by your product; the tutorial does not invent an Ovok consent API. ```tsx import Constants from "expo-constants"; import * as SecureStore from "expo-secure-store"; import { useSession } from "@ovok/native"; import { useTranslation } from "react-i18next"; import { useEffect, useState } from "react"; import { Pressable, Switch, Text, View } from "react-native"; import i18n from "../../localization/i18n"; import { ovokConfig } from "../../config/ovok"; import { occurrencesForNextSevenDays, reconcileMedicationReminders, reminderPreferenceKey, requestReminderPermission } from "../../features/medication/reminders"; import { useMedicationPlan } from "../../features/medication/use-medication-plan"; const languagePreferenceKey = "ovok-app-language"; export default function SettingsScreen() { const { plan } = useMedicationPlan(); const { profile, logout } = useSession({ sessions: false }); const { t } = useTranslation(); const [remindersEnabled, setRemindersEnabled] = useState(false); const [reminderMessage, setReminderMessage] = useState(); useEffect(() => { void SecureStore.getItemAsync(reminderPreferenceKey).then((value) => setRemindersEnabled(value === "true")); }, []); async function setReminderPreference(enabled: boolean) { try { if (enabled && !(await requestReminderPermission(t("medication.notificationChannel")))) { setReminderMessage(t("settings.notificationsDenied")); return; } await SecureStore.setItemAsync(reminderPreferenceKey, String(enabled)); setRemindersEnabled(enabled); await reconcileMedicationReminders(enabled ? occurrencesForNextSevenDays(plan) : [], { title: t("medication.reminderTitle"), body: t("medication.reminderBody"), }); setReminderMessage(undefined); } catch { setReminderMessage(t("medication.reminderScheduleError")); } } async function setLanguage(language: "en" | "de") { await SecureStore.setItemAsync(languagePreferenceKey, language); await i18n.changeLanguage(language); } async function signOut() { try { await reconcileMedicationReminders([], { title: t("medication.reminderTitle"), body: t("medication.reminderBody"), }); } catch { setReminderMessage(t("medication.reminderScheduleError")); } await logout(); } return ( {t("settings.title")} {t("settings.profile")}: {profile?.id ?? "—"} {t("settings.language")} void setLanguage("en")}>{t("settings.english")} void setLanguage("de")}>{t("settings.german")} {t("settings.reminders")} void setReminderPreference(value)} /> {!!reminderMessage && {reminderMessage}} {t("settings.privacyAndConsent")} {t("settings.appInformation")}: {Constants.expoConfig?.version ?? "—"} {ovokConfig.baseUrl} void signOut()}> {t("settings.signOut")} ); } ``` When the patient returns to Today, `useMedicationReminderSchedule()` reads the saved preference and rebuilds or cancels this app's local reminders. Pending adherence reports remain keyed to the Patient id; the reconnect worker only queries the currently authenticated Patient. The settings screen does not edit prescriptions or offer clinical advice. Do not add dose changes, interaction checking, or medication advice to Settings. ### Add German through the Ovok CMS [#add-german-through-the-ovok-cms] In the same published CMS `translations` groups used in step 4, add German (`de`) values for every user-facing key. Do not add `en.json` or `de.json` files. The React Native SDK's `useCmsTranslations({ tenantCode })` merges published CMS translations into the app's shared i18next instance. Use `i18n.changeLanguage("de")` for the app language control, and format dates using the selected language while preserving the schedule-time rule from step 4. Create or update these German values in the same CMS translation groups. Keep all group slugs, keys, and `{{...}}` interpolation names unchanged. ### `medication` German values [#medication-german-values] | Key | German value | | --- | --- | | `todayTitle` | Heutige Medikamente | | `loading` | Wird geladen… | | `loadError` | Diese Informationen konnten nicht geladen werden. Bitte versuchen Sie es erneut. | | `emptyPlan` | Für dieses Konto ist kein aktiver Medikamentenplan verfügbar. | | `noSupportedSchedule` | Es sind noch keine unterstützten Angaben zum Zeitplan verfügbar. | | `morning` | Morgen | | `afternoon` | Nachmittag | | `evening` | Abend | | `night` | Nacht | | `upcoming` | Bevorstehend | | `due` | Fällig | | `taken` | Eingenommen | | `skipped` | Ausgelassen | | `missed` | Nicht erfasst | | `missedMessage` | Für diese Dosis wurde keine Einnahme erfasst. | | `unknownName` | Kein Medikamentenname angegeben | | `requestStatus` | Planstatus: `{{status}}` | | `dose` | `{{value}}` `{{unit}}` | | `startDate` | Beginn: `{{date}}` | | `endDate` | Ende: `{{date}}` | | `notificationChannel` | Erinnerungen | | `reminderTitle` | Erinnerung | | `reminderBody` | Sie haben eine geplante Erinnerung. Öffnen Sie die App, um Details anzusehen. | | `reminderScheduleError` | Erinnerungen konnten nicht aktualisiert werden. Öffnen Sie die Einstellungen und versuchen Sie es erneut. | | `saving` | Ihre Rückmeldung wird gespeichert… | | `markTaken` | Als eingenommen markieren | | `markSkipped` | Als ausgelassen markieren | | `patientReported` | Vom Patienten gemeldet | | `reportError` | Diese Rückmeldung konnte nicht gespeichert werden. Bitte versuchen Sie es erneut. | | `retryReport` | Erneut senden | | `historyTitle` | Medikamentenverlauf | | `filterAll` | Gesamter Zeitraum | | `filter7Days` | Letzte 7 Tage | | `filter30Days` | Letzte 30 Tage | | `noHistory` | Keine Medikamentenmeldungen in diesem Zeitraum. | | `recordedStatus` | Erfasster Status: `{{status}}` | | `viewDetails` | Details ansehen | | `notInPlan` | Dieses Medikament ist nicht im aktuellen Plan enthalten. | | `lastSynced` | Zuletzt synchronisiert: `{{date}}` | | `offlineCacheError` | Diese Informationen konnten nicht für die Offline-Nutzung gespeichert werden. Beim nächsten Mal sind sie möglicherweise ohne Verbindung nicht verfügbar. | | `pendingSync` | Ihre Rückmeldung ist auf diesem Gerät gespeichert und wartet auf die Synchronisierung. | | `syncError` | Für eine gespeicherte Rückmeldung ist eine Aktion erforderlich, bevor sie synchronisiert werden kann. | ### `settings` German values [#settings-german-values] | Key | German value | | --- | --- | | `title` | Einstellungen | | `profile` | Patienten-ID | | `language` | Sprache | | `english` | Englisch | | `german` | Deutsch | | `reminders` | Erinnerungen | | `privacyAndConsent` | Datenschutz und Einwilligungen | | `signOut` | Abmelden | | `appInformation` | App-Informationen | | `notificationsDenied` | Benachrichtigungen sind deaktiviert. Sie können sie in den Geräteeinstellungen ändern. | Set `register.registrationFailed` to **Ihr Konto konnte nicht erstellt werden.** and `register.tryAgain` to **Prüfen Sie Ihre Angaben und versuchen Sie es erneut.** Translate every React Native SDK sign-in and registration key used by the app; the [sign-in reference](/native-sdk/guide/components/auth/sign-in) and [registration reference](/native-sdk/guide/components/auth/register) list the full current key sets. The CMS applies English fallback one string at a time while German translations are incomplete. The translations collection is open tenant content. Store only UI strings there—never medication plans, Patient names, PHI, or credentials. The hook keeps translations in memory; if the app cold-starts without a network connection, the CMS cannot provide a newly requested language. The root gate below restores the saved locale before the CMS hook runs, then step 10's encrypted cache supplies a previously fetched translation bundle when offline. Keep the CMS as the editable source of truth; the encrypted local copy is only a cache. See [Use Ovok CMS with i18n](/cms/use-ovok-cms-with-i18n) for the CMS schema, fallback behavior, caching, and the documented HTTP loading option. Replace the `LocalizationGate` from step 4 so the saved language is selected before `CmsTranslations` reads the CMS: ```tsx import * as React from "react"; import * as SecureStore from "expo-secure-store"; import { ActivityIndicator } from "react-native"; import i18n, { localizationReady } from "./i18n"; const languagePreferenceKey = "ovok-app-language"; export function LocalizationGate({ children }: React.PropsWithChildren) { const [ready, setReady] = React.useState(false); React.useEffect(() => { let current = true; void (async () => { try { await localizationReady; const language = await SecureStore.getItemAsync(languagePreferenceKey); if (language === "en" || language === "de") await i18n.changeLanguage(language); } catch { // Keep the initialized English language if local preference storage is unavailable. } finally { if (current) setReady(true); } })(); return () => { current = false; }; }, []); if (!ready) return ; return {children}; } ``` Replace the `CmsTranslations` body from step 4 with this offline-aware version. It still loads and publishes through Ovok CMS; SQLite only caches the most recently fetched public translation tree for each locale: ```tsx import * as React from "react"; import { ActivityIndicator, Button, Text, View } from "react-native"; import { useTranslation } from "react-i18next"; import { useCmsLocale, useCmsTranslations } from "@ovok/native/cms"; import { ovokConfig } from "../config/ovok"; import { cacheCmsTranslations, openMedicationDatabase, readCachedCmsTranslations } from "../features/medication/offline-storage"; export function CmsTranslations({ children }: React.PropsWithChildren) { const locale = useCmsLocale(); const { i18n } = useTranslation(); const { data, loading, error, reload } = useCmsTranslations({ tenantCode: ovokConfig.tenantCode, environment: "staging", }); const [ready, setReady] = React.useState(false); const [cached, setCached] = React.useState(false); React.useEffect(() => { let current = true; setReady(false); setCached(false); if (loading) return () => { current = false; }; void (async () => { try { const db = await openMedicationDatabase(); if (!error && data) { await cacheCmsTranslations(db, locale, data); if (current) setReady(true); return; } if (error) { const tree = await readCachedCmsTranslations(db, locale); if (tree) { i18n.addResourceBundle(locale, "translation", tree, true, false); await i18n.changeLanguage(locale); if (current) setCached(true); } if (current) setReady(true); return; } if (current) setReady(true); } catch { if (current) setReady(true); } })(); return () => { current = false; }; }, [data, error, i18n, loading, locale]); if (loading || !ready) return ; if ((error || !data) && !cached) { return ( App language content is unavailable. Connect to the internet and try again. ); } if (loading || !data) return ; return children; } export function LocalizationGate({ children }: React.PropsWithChildren) { const [ready, setReady] = React.useState(false); React.useEffect(() => { void localizationReady.then(() => setReady(true)); }, []); if (!ready) return ; return {children}; } ``` `useCmsTranslations` is called once near the root, below the `I18nextProvider` added in step 5. It observes the active locale and refetches when the user changes languages. The retry text above is a bootstrap fallback; it is not a replacement for the app's CMS strings. The authentication module import registers the React Native SDK's built-in auth strings so missing CMS keys still have the SDK's English fallback. ### Define one schedule-time rule [#define-one-schedule-time-rule] FHIR `Timing.repeat.timeOfDay` is a local clock time without a timezone offset. For this tutorial, interpret it in the device's current timezone and preserve that wall-clock value when the user travels. Display times with `Intl.DateTimeFormat`; do not convert the plan's `timeOfDay` to UTC and write it back. Create `src/localization/schedule-time.ts` for the device-local time rule: ```ts export function atDeviceLocalTime(day: Date, fhirTime: string): Date | undefined { const [hour, minute, seconds = "0"] = fhirTime.split(":"); const second = Number(seconds.split(".")[0]); const result = new Date( day.getFullYear(), day.getMonth(), day.getDate(), Number(hour), Number(minute), second, 0, ); // A wall-clock time inside the spring DST gap does not exist on this date. if ( result.getHours() !== Number(hour) || result.getMinutes() !== Number(minute) || result.getSeconds() !== second ) { return undefined; } return result; } export function formatScheduleTime(date: Date, locale: string): string { return new Intl.DateTimeFormat(locale, { hour: "numeric", minute: "2-digit", }).format(date); } ``` This tutorial's three sample times avoid the DST spring gap. A repeated wall-clock time in the autumn overlap is resolved by the device runtime; if your care workflow needs a specific “first” or “second” occurrence, choose and test that rule explicitly. When the app returns to the foreground, compare `Intl.DateTimeFormat().resolvedOptions().timeZone` with the last scheduled zone and rebuild future local notifications if it changed. The app cannot promise to react to a timezone change while it is not running. Only schedule explicit daily `timeOfDay` entries with the simple daily `period` used in the sample plan. `dayOfWeek` and `boundsPeriod` also affect whether an occurrence is due. If a request uses a more complex `Timing` pattern, do not silently approximate it; show the supplied instructions and have the product owner define the schedule interpretation. ## Important Ovok decisions [#important-ovok-decisions] - CMS translations hold public interface text only; patient-specific content remains in FHIR and is rendered at runtime. - Localisation changes display formatting. It does not change the meaning or timezone interpretation of a stored schedule. - A timezone change triggers a local reschedule; it does not alter `MedicationRequest`. ## Expected result [#expected-result] The app can render English labels from published CMS translations and has a helper that maps supported FHIR local times to device-local `Date` values without silently moving a non-existent DST time. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **The app shows translation keys:** check CMS publication, tenant code, locale, and that `CmsTranslations` uses the same i18next instance as React screens. - **A schedule appears one hour off:** confirm that code treats `timeOfDay` as local wall-clock time and does not parse it as UTC. - **An occurrence disappears on a DST transition:** the helper intentionally returns no instant for a nonexistent local time. Define a product-approved handling rule rather than shifting it silently. ## Previous / Next [#previous--next] Previous: [step 3: model the medication plan](/guides/medication-reminder/model-the-medication-plan) · Continue to [step 5: initialise Ovok and authentication](/guides/medication-reminder/initialise-ovok-and-authentication). # Step 5 · Add the FINDRISC Questionnaire Canonical page: https://docs.ovok.com/guides/type-2-diabetes/add-the-findrisc-questionnaire ## What we are building [#what-we-are-building] A server-published FHIR `Questionnaire` rendered by the React Native SDK, with a local scoring function that accepts only the exact reviewed canonical URL and version. The saved `QuestionnaireResponse` remains the source record for patient answers. ## What you should already have [#what-you-should-already-have] - The sandbox project and Questionnaire identifiers from steps 1–2. - A copy of the approved classic eight-item FINDRISC Questionnaire, obtained through an authorized source. - Clinical-owner approval for its suitability, answer order, linkIds, score mapping, result categories, and patient-facing wording. The [official Finnish Diabetes Association guidance](https://diabetes.fi/lahteet-ja-kayttoohjeet-kansansairauksien-riskitesti/) describes the instrument’s use, eligibility, risk bands, and source. It distinguishes FINDRISC from its newer nine-question combined risk-test flow. The original instrument publication is [Lindström and Tuomilehto, Diabetes Care 2003](https://doi.org/10.2337/diacare.26.3.725). The current guide does not establish a license to reproduce question wording, answer labels, or translations: obtain permission or confirm an applicable license before distributing that material. Use approved translations only. ## The implementation [#the-implementation] ### Publish the Questionnaire as FHIR [#publish-the-questionnaire-as-fhir] Publish the approved artifact as a FHIR `Questionnaire` in the sandbox using your governed FHIR content workflow. Do not paste the risk instrument into this docs page or convert it to a custom app-only format. The resource owner must preserve the exact item text, answer options, order, and any approved translations. For this tutorial’s local scorer, the approved classic eight-item resource must use these stable, app-mapped `linkId` values: | `linkId` used by the app | Reviewed score sequence by answer-option order | | --- | --- | | `age` | `0, 2, 3, 4` | | `bmi` | `0, 1, 3` | | `waist` | `0, 3, 4` | | `physicalActivity` | `0, 2` | | `fruitVegetableIntake` | `0, 1` | | `bloodPressureMedication` | `0, 2` | | `historyOfHighGlucose` | `0, 5` | | `familyDiabetesHistory` | `0, 3, 5` | The values above are scoring points, not question or answer text. The clinical owner must verify that this exact resource/version and its option order implement the selected FINDRISC version. Do not infer that answer order from a translation or from a resource title. See the canonical [`Questionnaire`](/api/fhir/r4/questionnaire) and [`QuestionnaireResponse`](/api/fhir/r4/questionnaire-response) references. ### Understand the FHIR lifecycle [#understand-the-fhir-lifecycle] ```text FHIR Questionnaire ↓ (optional, only for approved FHIR prefill) POST /fhir/R4/Questionnaire/:id/$populate ↓ render in QuestionnaireForm ↓ FHIR QuestionnaireResponse ↓ local reviewed FINDRISC score mapping ↓ (optional, only when Questionnaire is configured for extraction) POST /fhir/R4/QuestionnaireResponse/:id/$extract ``` `$populate` is for answers that can be validly prefilled from the active Patient’s FHIR data. It does not infer diet, activity, prior high glucose, or family history. The SDK’s `client.populateQuestionnaire(questionnaireId, parameters?)` calls the current operation; the operation resolves the subject from the authenticated session. See [populate a Questionnaire](/primitives/populate-questionnaire). `$extract` is not a FINDRISC scoring API. Use it only if the approved Questionnaire is configured with the supported standard extraction metadata and the extracted Observation semantics are clinically appropriate. The React Native SDK form can perform that extraction during its managed submission flow. See [extract Observations](/primitives/extract-observations). ### Add the scoring function [#add-the-scoring-function] Create `src/features/findrisc/scoring.ts`. It maps the selected FHIR answer back to its exact `answerOption` and uses the reviewed option index. It fails if a required item is missing, repeated, has an unexpected number of options, or belongs to another Questionnaire version. ```ts export const FINDRISC_POINTS = { age: [0, 2, 3, 4], bmi: [0, 1, 3], waist: [0, 3, 4], physicalActivity: [0, 2], fruitVegetableIntake: [0, 1], bloodPressureMedication: [0, 2], historyOfHighGlucose: [0, 5], familyDiabetesHistory: [0, 3, 5], } as const; export type FindriscLinkId = keyof typeof FINDRISC_POINTS; export type FindriscCategory = | "low" | "slightly-increased" | "moderate" | "high" | "very-high"; type QuestionnaireItem = { linkId: string; answerOption?: object[]; item?: QuestionnaireItem[]; }; type ResponseItem = { linkId: string; answer?: object[]; item?: ResponseItem[]; }; type QuestionnaireShape = { resourceType: "Questionnaire"; id?: string; url?: string; version?: string; item?: QuestionnaireItem[]; }; type QuestionnaireResponseShape = { resourceType: "QuestionnaireResponse"; questionnaire?: string; status?: string; item?: ResponseItem[]; }; type ReviewedInstrument = { url: string; version: string }; function flatten( items: T[] | undefined, output = new Map(), ): Map { for (const item of items ?? []) { if (output.has(item.linkId)) { throw new Error(`Duplicate Questionnaire linkId: ${item.linkId}`); } output.set(item.linkId, item); flatten(item.item, output); } return output; } function valueX(record: object): [string, unknown] { const values = Object.entries(record).filter(([key]) => /^value[A-Z]/.test(key)); if (values.length !== 1) throw new Error("Expected one FHIR value[x] field."); const value = values[0]; if (!value) throw new Error("Expected one FHIR value[x] field."); return [value[0], value[1]]; } function stable(value: unknown): unknown { if (Array.isArray(value)) return value.map(stable); if (value && typeof value === "object") { return Object.fromEntries( Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map( ([key, entry]) => [key, stable(entry)], ), ); } return value; } function sameValue(left: unknown, right: unknown): boolean { return JSON.stringify(stable(left)) === JSON.stringify(stable(right)); } export function classifyFindrisc(score: number): FindriscCategory { if (!Number.isInteger(score) || score < 0 || score > 26) { throw new RangeError("FINDRISC score must be an integer from 0 to 26."); } if (score <= 6) return "low"; if (score <= 11) return "slightly-increased"; if (score <= 14) return "moderate"; if (score <= 20) return "high"; return "very-high"; } export function scoreFindrisc( questionnaire: QuestionnaireShape, response: QuestionnaireResponseShape, reviewed: ReviewedInstrument, ) { if ( questionnaire.url !== reviewed.url || questionnaire.version !== reviewed.version || !questionnaire.id || response.questionnaire !== `Questionnaire/${questionnaire.id}` || response.status !== "completed" ) { throw new Error("The response does not match the reviewed completed Questionnaire."); } const questions = flatten(questionnaire.item); const answers = flatten(response.item); let total = 0; for (const [linkId, points] of Object.entries(FINDRISC_POINTS)) { const question = questions.get(linkId); const answer = answers.get(linkId); const options = question?.answerOption ?? []; if (!question || !answer || options.length !== points.length) { throw new Error(`Questionnaire content does not match reviewed item ${linkId}.`); } if (!answer.answer || answer.answer.length !== 1) { throw new Error(`Expected one completed answer for ${linkId}.`); } const [selectedType, selectedValue] = valueX(answer.answer[0]); const optionIndex = options.findIndex((option) => { const [optionType, optionValue] = valueX(option); return selectedType === optionType && sameValue(selectedValue, optionValue); }); if (optionIndex < 0) throw new Error(`Answer is not an option for ${linkId}.`); const score = points[optionIndex]; if (score === undefined) throw new Error(`No reviewed score exists for ${linkId}.`); total += score; } return { total, category: classifyFindrisc(total) }; } ``` The sequences and categories correspond to the classic 0–26 FINDRISC version: 0–6 low, 7–11 slightly increased, 12–14 moderate, 15–20 high, and 21–26 very high. They must not be applied to the newer nine-question combined risk-test form. The official Finnish instructions identify the assessment as an estimate of future risk, not a diagnosis. ### Test score bands and fail-closed behavior [#test-score-bands-and-fail-closed-behavior] Create `src/features/findrisc/scoring.test.ts`: ```ts import { classifyFindrisc, FINDRISC_POINTS, scoreFindrisc, } from "./scoring"; const reviewed = { url: "https://example.org/reviewed-classic-findrisc", version: "1.0.0", }; const questionnaire = { resourceType: "Questionnaire" as const, id: "findrisc-classic", ...reviewed, item: Object.entries(FINDRISC_POINTS).map(([linkId, points]) => ({ linkId, answerOption: points.map((_, index) => ({ valueString: `${linkId}:${index}`, })), })), }; function completedResponse(useMaximumOptions: boolean) { return { resourceType: "QuestionnaireResponse" as const, questionnaire: `Questionnaire/${questionnaire.id}`, status: "completed", item: Object.entries(FINDRISC_POINTS).map(([linkId, points]) => { const index = useMaximumOptions ? points.length - 1 : 0; return { linkId, answer: [{ valueString: `${linkId}:${index}` }], }; }), }; } describe("FINDRISC category boundaries", () => { it.each([ [0, "low"], [6, "low"], [7, "slightly-increased"], [11, "slightly-increased"], [12, "moderate"], [14, "moderate"], [15, "high"], [20, "high"], [21, "very-high"], [26, "very-high"], ] as const)("classifies %i as %s", (score, expected) => { expect(classifyFindrisc(score)).toBe(expected); }); it.each([-1, 27, 1.5])("rejects out-of-range score %s", (score) => { expect(() => classifyFindrisc(score)).toThrow(RangeError); }); it("uses the expected total range for the eight-item score map", () => { const items = Object.values(FINDRISC_POINTS); expect(items.reduce((sum, points) => sum + Math.min(...points), 0)).toBe(0); expect(items.reduce((sum, points) => sum + Math.max(...points), 0)).toBe(26); }); it.each([ [false, 0, "low"], [true, 26, "very-high"], ] as const)("scores the approved FHIR answer map", (maximum, total, category) => { expect( scoreFindrisc(questionnaire, completedResponse(maximum), reviewed), ).toEqual({ total, category }); }); it("fails closed when the reviewed Questionnaire version changes", () => { expect(() => scoreFindrisc( { ...questionnaire, version: "unreviewed" }, completedResponse(false), reviewed, ), ).toThrow("reviewed completed Questionnaire"); }); }); ``` The boundary cases exercise every displayed category edge; the synthetic FHIR fixture exercises option matching at the minimum and maximum scores without reproducing clinical question text. Before release, also verify every answer option in the approved Questionnaire against the clinical owner’s signed-off mapping. Do not publish clinical labels in test fixtures or CMS translations unless the content license permits it. ## Important Ovok decisions [#important-ovok-decisions] - Ovok stores and renders the FHIR Questionnaire and QuestionnaireResponse; the score mapping belongs to this application because the current Ovok API does not calculate FINDRISC. - No custom FHIR extension is invented for score calculation. The scorer reads the standard FHIR answer and answerOption values and matches canonical URL, version, resource ID, completion state, and stable linkIds. - `$extract` is optional and separate from scoring. Do not extract the score as a glucose Observation or imply it is a diagnosis. - The saved QuestionnaireResponse is authoritative for answers. Recalculate a displayed result using the same reviewed mapping rather than silently storing a second competing score resource. ## Expected result [#expected-result] The approved Questionnaire is available to the Patient app, the scorer compiles against standard FHIR-shaped data, and Jest verifies all category boundaries and the 0–26 range. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **The form renders but scoring fails:** compare resource URL, version, ID, `linkId`s, answer count, and answerOption order against the signed-off artifact. - **A Questionnaire version changes:** do not keep using the old scoring map. Review and approve a new map before displaying a score. - **The response was saved but no Observation was extracted:** extraction is optional and requires supported Questionnaire metadata and project configuration; it is not needed for a risk score. - **The total exceeds 26 or is fractional:** reject it as invalid app data. Do not clamp or round a score. - **A localized instrument has reordered choices:** use a validated instrument translation with its own verified option mapping; do not assume translated order is unchanged. ## Previous / Next [#previous--next] [Previous: choose the glucose device](/guides/type-2-diabetes/choose-the-glucose-device) · [Next: initialise Ovok, auth, and Bluetooth](/guides/type-2-diabetes/initialise-ovok-auth-and-bluetooth) # Step 9 · Build screening results and history Canonical page: https://docs.ovok.com/guides/type-2-diabetes/build-results-and-history ## What we are building [#what-we-are-building] A result view that shows the latest reviewed FINDRISC category and latest glucose measurement separately, plus a history list that preserves each resource’s date and provenance. ## What you should already have [#what-you-should-already-have] - Saved completed QuestionnaireResponses from step 7. - Saved blood-glucose Observations from step 8. - The reviewed local scoring function from step 5. ## The implementation [#the-implementation] ### Query the Patient’s questionnaire history [#query-the-patients-questionnaire-history] Create `app/(patient)/history.tsx`: ```tsx import { MeasurementTypeKey, useCurrentPatientProfile, useObservations, usePatientQuestionnaireResponses, usePatientQuestionnaires, } from "@ovok/core"; import { Text, View } from "react-native"; import { ovokConfig } from "../../src/config/ovok"; import { scoreFindrisc } from "../../src/features/findrisc/scoring"; const glucoseTypes = [MeasurementTypeKey.bloodGlucose] as const; export default function HistoryScreen() { const { data: current } = useCurrentPatientProfile(); const patientId = current?.profile.id; const { data: forms, loading: formsLoading } = usePatientQuestionnaires({ _id: ovokConfig.questionnaireId, }); const questionnaire = forms?.find( (form) => form.id === ovokConfig.questionnaireId, ); const { data: responses = [], loading: responsesLoading } = usePatientQuestionnaireResponses({ ...(patientId ? { patient: `Patient/${patientId}` } : {}), questionnaire: `Questionnaire/${ovokConfig.questionnaireId}`, _sort: "-authored", _count: 50, }); const { measurements, loading: glucoseLoading, error: glucoseError, } = useObservations({ types: glucoseTypes, patientId, count: 50, sort: "-date", }); const assessments = questionnaire?.url === ovokConfig.questionnaireUrl && questionnaire.version === ovokConfig.questionnaireVersion ? responses.flatMap((response) => { try { return [ { response, score: scoreFindrisc(questionnaire, response, { url: ovokConfig.questionnaireUrl, version: ovokConfig.questionnaireVersion, }), }, ]; } catch { return []; } }) : []; const latestAssessment = assessments[0]; const latestGlucose = measurements[0]; return ( Screening results {formsLoading || responsesLoading ? ( Loading assessment history… ) : latestAssessment ? ( FINDRISC: {latestAssessment.score.total} · {latestAssessment.score.category} ·{" "} {latestAssessment.response.authored ?? "Date unavailable"} ) : ( No completed FINDRISC assessment is available. )} Blood-glucose measurements {glucoseLoading ? ( Loading readings… ) : glucoseError ? ( Readings could not be loaded. ) : latestGlucose ? ( {latestGlucose.bloodGlucose ?? "Value unavailable"} mg/dL ·{" "} {latestGlucose.recordedAt?.toISOString() ?? "Time unavailable"} ) : ( No blood-glucose readings are available. )} Assessment history {assessments.map(({ response, score }) => ( FINDRISC · {score.total} · {score.category} · {response.authored ?? "Date unavailable"} ))} Measurement history {measurements.map((reading, index) => ( Blood glucose · {reading.bloodGlucose ?? "Value unavailable"} mg/dL ·{" "} {reading.recordedAt?.toISOString() ?? "Time unavailable"} ))} ); } ``` The questionnaire history uses the typed Patient hook, scoped to the signed-in Patient and questionnaire. `useObservations` maps supported blood-glucose Observations to typed measurements. It returns the original resources too when a view needs FHIR metadata; see [`useObservations`](/web-sdk/core/hooks/use-observations). The example uses the SDK’s mapped `recordedAt` when available and otherwise says the time is unavailable. Replace ISO timestamps with a locale-aware date formatter from your UI. For long histories, add date filters and FHIR pagination rather than silently showing an incomplete list. ### Keep the result language neutral [#keep-the-result-language-neutral] The result card may say: > FINDRISC is a risk assessment. It does not diagnose diabetes. A blood-glucose reading is shown separately and is not interpreted here. Translate this app-owned copy through Ovok CMS. If a particular validated instrument release includes different approved result language, use the authorized wording and clinical review for that release. Do not add risk probabilities or follow-up advice from a different version of the questionnaire. ## Important Ovok decisions [#important-ovok-decisions] - A FINDRISC QuestionnaireResponse and a glucose Observation are separate FHIR records with separate meaning and provenance. - Recompute each assessment with the matching reviewed questionnaire version. If it cannot be verified, omit the score and retain the response for review. - Do not combine the score and glucose into a new “diabetes score.” - A single glucose value in this UI does not diagnose diabetes. - The current example requests up to 50 records. Implement pagination if a deployment can exceed that limit. ## Expected result [#expected-result] The patient sees the latest FINDRISC result and glucose reading as separate cards, plus a history list whose rows identify the source type and date. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **An old assessment has no score:** confirm its Questionnaire reference and version; do not score it with a newer map. - **No glucose reading appears after a successful save:** confirm `patientId` is the active Patient’s ID and the `Observation` policy allows that Patient to read their own record. - **The history is truncated:** add paging or date bounds; do not present the first 50 records as “all history.” - **A glucose number is displayed without its unit:** render `mg/dL` adjacent to the numeric value. - **The app suggests a diagnosis or treatment action:** remove that logic; this tutorial presents risk and measurement data without clinical interpretation. ## Previous / Next [#previous--next] [Previous: connect TeleBGM and save readings](/guides/type-2-diabetes/connect-telebgm-and-save-readings) · [Next: settings, localisation, and validation](/guides/type-2-diabetes/settings-localisation-and-validation) # Step 7 · Build the screening home and Questionnaire flow Canonical page: https://docs.ovok.com/guides/type-2-diabetes/build-the-screening-home ## What we are building [#what-we-are-building] A patient-facing home with two independent cards: one for FINDRISC and one for blood glucose. The Questionnaire card launches the approved FHIR resource through `QuestionnaireForm`; the glucose card remains optional for screening completion. ## What you should already have [#what-you-should-already-have] - Authentication and the protected Patient area from step 6. - A published, reviewed Questionnaire with matching URL, version, ID, linkIds, and answerOption ordering. - The scoring function from step 5. ## The implementation [#the-implementation] ### Load the approved Questionnaire and latest assessment [#load-the-approved-questionnaire-and-latest-assessment] Create `app/(patient)/assessment.tsx`: ```tsx import { usePatientQuestionnaires } from "@ovok/core"; import { QuestionnaireForm } from "@ovok/native/questionnaire-response-form"; import { useState } from "react"; import { ActivityIndicator, Text, View } from "react-native"; import { ovokConfig } from "../../src/config/ovok"; import { scoreFindrisc } from "../../src/features/findrisc/scoring"; export default function AssessmentScreen() { const [notice, setNotice] = useState(); const [result, setResult] = useState>(); const { data: questionnaires, loading, error, reload, } = usePatientQuestionnaires({ _id: ovokConfig.questionnaireId }); const questionnaire = questionnaires?.find( (item) => item.id === ovokConfig.questionnaireId, ); if (loading) return ; if (error) { return Questionnaire unavailable. Tap to retry.; } if (!questionnaire) { return The approved screening form is not available in this project.; } if ( questionnaire.url !== ovokConfig.questionnaireUrl || questionnaire.version !== ovokConfig.questionnaireVersion ) { return The screening form needs review before it can be used.; } return ( { try { setResult( scoreFindrisc(questionnaire, response, { url: ovokConfig.questionnaireUrl, version: ovokConfig.questionnaireVersion, }), ); setNotice("Assessment saved."); } catch { setResult(undefined); setNotice("The saved form needs review before a score can be shown."); } }} onError={() => setNotice("The assessment could not be saved. Try again.")} > {notice ? {notice} : null} {result ? ( FINDRISC score: {result.total}. Category: {result.category}. ) : null} ); } ``` `QuestionnaireForm` supports paged sections, required validation, previous/next navigation, and SDK-managed `QuestionnaireResponse` creation. In this mode, the SDK associates the response with the active Patient and saves it. The callback fires after the save. Read the [QuestionnaireResponseForm guide](/native-sdk/guide/components/questionnaire-response-form) for rendering and submission behavior. The current form persists the completed response; do not promise that an unfinished form resumes after the app is closed. If cross-session drafts are a product requirement, design and verify a separate FHIR draft workflow before adding it. ### Compose the independent home cards [#compose-the-independent-home-cards] Create `app/(patient)/index.tsx`: ```tsx import { useCurrentPatientProfile, usePatientQuestionnaireResponses, } from "@ovok/core"; import { Link } from "expo-router"; import { Text, View } from "react-native"; import { ovokConfig } from "../../src/config/ovok"; export default function ScreeningHome() { const { data: current } = useCurrentPatientProfile(); const patientId = current?.profile.id; const { data: responses, loading } = usePatientQuestionnaireResponses({ ...(patientId ? { patient: `Patient/${patientId}` } : {}), questionnaire: `Questionnaire/${ovokConfig.questionnaireId}`, _sort: "-authored", _count: 1, }); const latest = responses?.[0]; return ( Diabetes risk screening Check your Type 2 diabetes risk {loading ? "Loading assessment status" : latest?.status === "completed" ? "Completed" : "Not started"} Blood glucose Connect a supported meter or view recent readings. ); } ``` Use CMS strings for the labels in the final UI. The two cards intentionally have no dependency: a Patient may complete FINDRISC without pairing a meter. ## Important Ovok decisions [#important-ovok-decisions] - Keep the questionnaire’s exact approved content and translations in its FHIR resource, not in screen code or CMS UI groups. - SDK-managed submission creates a completed QuestionnaireResponse. The response is stored before the score is rendered. - A QuestionnaireResponse without a matching reviewed canonical URL and version is saved data, but this app does not display a score for it. - `$populate` may prefill only fields supported by the approved Questionnaire and correctly sourced Patient data. It must not fill lifestyle answers or family history. - `$extract` is optional and never calculates this risk score. ## Expected result [#expected-result] The home screen clearly shows an assessment entry point and a separate glucose entry point. A Patient can navigate the approved FHIR form, answer required questions, save a QuestionnaireResponse, and see the reviewed app-owned score. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **Questionnaire is hidden:** check the project ID, Patient read permission, and Questionnaire status/access. - **Submit succeeds but no score appears:** inspect the saved response’s Questionnaire reference and compare its linkIds and answer options with the reviewed map. - **The form reloads without the previous draft:** the current managed form flow does not promise cross-session draft recovery. - **The app forces glucose before the questionnaire:** remove the dependency; the two cards represent separate data sources. - **An unsupported answer type renders incorrectly:** check the current [Questionnaire form renderer support](/native-sdk/guide/components/questionnaire-response-form) and keep the Questionnaire within supported FHIR answer types. ## Previous / Next [#previous--next] [Previous: initialise Ovok, auth, and Bluetooth](/guides/type-2-diabetes/initialise-ovok-auth-and-bluetooth) · [Next: connect TeleBGM and save readings](/guides/type-2-diabetes/connect-telebgm-and-save-readings) # Step 4 · Choose the glucose device Canonical page: https://docs.ovok.com/guides/type-2-diabetes/choose-the-glucose-device ## What we are building [#what-we-are-building] A single-device BLE allowlist for this tutorial: **TeleBGM Gen1 BLE**. The runtime declaration is `IntegratedDevices.BGM`; the catalog display name is not the Bluetooth identifier. ## What you should already have [#what-you-should-already-have] - The Expo native development build from step 1. - Access to the current [Supported Device Catalog](/native-sdk/guide/supported-devices). - A compatible meter and test strips for controlled sandbox testing. ## The implementation [#the-implementation] The current catalog lists TeleBGM Gen1 BLE for blood-glucose measurements. The current native runtime maps it to `IntegratedDevices.BGM` and a blood-glucose measurement type. The device contributes a normalized numeric `bloodGlucose` value. Its SDK measurement may include `recordedAt`; do not assume the field is present. Create `src/features/bluetooth/accepted-devices.ts`: ```ts import { IntegratedDevices } from "@ovok/native/bt-management"; export const acceptedDevices = [IntegratedDevices.BGM] as const; ``` Pass this stable array to the single `BTProvider` in step 6. The tutorial does not use a catalog label as an identifier, scan for every device, or claim TeleBGM provides meal context, fasting status, a diagnostic interpretation, or battery level. ## Important Ovok decisions [#important-ovok-decisions] - The Bluetooth runtime declaration is the SDK enum, `IntegratedDevices.BGM`. Keep the human-readable “TeleBGM Gen1 BLE” label in UI copy only. - The meter reports a glucose measurement. It does not establish whether the patient was fasting or had eaten. - If your product needs measurement context, collect it as a separate, explicit application workflow and only store it through a reviewed FHIR representation. - The typed API expects blood glucose in **mg/dL**. It does not convert from mmol/L. See [Blood glucose measurements](/web-sdk/core/measurements/blood-glucose). - Other supported glucose devices are listed in the [full catalog](/native-sdk/guide/supported-devices). Substitution requires checking their actual declarations, normalization, and test behavior. ## Expected result [#expected-result] The project has one allowlisted tutorial device and the native SDK’s current catalog and runtime agree that it produces blood-glucose data. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **Using the catalog name in `acceptedDevices`:** use `IntegratedDevices.BGM` from the native SDK. - **The device is not discovered:** use a physical phone, confirm Bluetooth permission, and ensure the meter is awake and advertising. - **The reading is presented as mmol/L:** this tutorial’s stored API value is mg/dL. Do not relabel a value or convert it without a product-wide unit policy. - **A screen shows “fasting” based on the time:** remove that inference. Neither time-of-day nor this BLE result supplies meal context. ## Previous / Next [#previous--next] [Previous: configure localisation](/guides/type-2-diabetes/configure-localisation) · [Next: add the FINDRISC Questionnaire](/guides/type-2-diabetes/add-the-findrisc-questionnaire) # Step 3 · Configure localisation with Ovok CMS Canonical page: https://docs.ovok.com/guides/type-2-diabetes/configure-localisation ## What we are building [#what-we-are-building] An i18next instance that reads application interface text from the Ovok CMS `translations` collection. The Questionnaire remains a governed FHIR clinical artifact; it is not copied into CMS strings or casually machine-translated. ## What you should already have [#what-you-should-already-have] - The app and `ovokConfig` from steps 1–2. - Ovok CMS enabled for the sandbox project. - `i18next` and `react-i18next` installed. ## The implementation [#the-implementation] ### Publish an English translation group in Console [#publish-an-english-translation-group-in-console] In the sandbox CMS, create and publish a `translations` document with slug `screening`. Add app-owned keys for navigation, status, errors, buttons, and screen labels. Use the same groups for all later steps, or add one per screen if that is easier for translators to maintain. Publish English strings to the sandbox `staging` environment before opening the app. The `translations` collection is public by default, so the app uses its tenant code; do not put patient data or secrets in this collection. See [Use Ovok CMS with i18n](/cms/use-ovok-cms-with-i18n) for Console fields, locale fallback, and caching. ### Initialize i18next with no bundled UI dictionary [#initialize-i18next-with-no-bundled-ui-dictionary] Create `src/localization/i18n.ts`: ```ts import "@ovok/native/auth"; import i18n from "i18next"; import { initReactI18next } from "react-i18next"; export const localizationReady = i18n.use(initReactI18next).init({ lng: "en", fallbackLng: "en", supportedLngs: ["en", "de"], interpolation: { escapeValue: false }, react: { useSuspense: false }, }); export default i18n; ``` There is no local app translation JSON. Importing the auth module registers native English auth labels; the CMS supplies app-specific labels and can override SDK groups when published. ### Load published CMS translations at the app root [#load-published-cms-translations-at-the-app-root] Create `src/localization/cms-translations.tsx`: ```tsx import { useCmsTranslations } from "@ovok/native/cms"; import { ovokConfig } from "../config/ovok"; export function CmsTranslations() { useCmsTranslations({ tenantCode: ovokConfig.tenantCode, environment: "staging", }); return null; } ``` Mount `` once under `OvokProvider` and the initialized i18next instance, as part of the root layout in step 6. The hook merges published groups into i18next and reloads when the language changes. Pass the tenant code because this first load happens before patient sign-in. Use translated UI copy in screens: ```tsx import { useTranslation } from "react-i18next"; import { Text } from "react-native"; export function ScreeningTitle() { const { t } = useTranslation("translation", { keyPrefix: "screening" }); return {t("title", "Diabetes risk screening")}; } ``` The second argument is a runtime fallback for an unpublished key during development. It is not a translation catalog; publish the final text in the CMS. ## Important Ovok decisions [#important-ovok-decisions] - CMS stores app-owned interface text. The licensed FINDRISC Questionnaire carries its own approved clinical wording and answer options. - Publish the translation group in the same sandbox environment the app requests. A draft or a different environment is not delivered. - The UI language may use a regional tag such as `de-DE`; the CMS reads a supported base locale such as `de`. - Native permission prompts are platform configuration strings. They are not automatically replaced by CMS content. ## Expected result [#expected-result] The root app can mount the CMS hook, and app screens can resolve `screening.*` keys from published CMS translations with English fallback. ## Common errors and troubleshooting [#common-errors-and-troubleshooting] - **Text shows its key:** check the `screening` group slug, key name, published status, tenant, and environment. - **CMS load fails before sign-in:** ensure the hook receives `tenantCode`. - **German labels still show English:** add and publish the German group; set i18next to the locale you published. - **FINDRISC text differs from the approved instrument:** do not fix it in CMS. Restore the approved Questionnaire version and review it with the content owner. ## Previous / Next [#previous--next] [Previous: create and configure the Ovok project](/guides/type-2-diabetes/create-and-configure-the-ovok-project) · [Next: choose the glucose device](/guides/type-2-diabetes/choose-the-glucose-device) # Step 8 · Connect TeleBGM and save glucose readings Canonical page: https://docs.ovok.com/guides/type-2-diabetes/connect-telebgm-and-save-readings ## What we are building [#what-we-are-building] A Devices screen that discovers TeleBGM Gen1 BLE and remembers its pairing, plus a measurement path from the SDK’s normalized result to the authenticated Patient’s FHIR-backed observation history. ## What you should already have [#what-you-should-already-have] - The single-device `BTProvider` in the authenticated Patient route group. - `IntegratedDevices.BGM` in `acceptedDevices`. - A physical TeleBGM Gen1 BLE meter and the package configuration from step 1. ## The implementation [#the-implementation] ### Add the discovery and pair screen [#add-the-discovery-and-pair-screen] Create `app/(patient)/devices.tsx`: ```tsx import { IntegratedDevices, useNearbyDevices, usePairedDevices } from "@ovok/native/bt-management"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { useState } from "react"; import { Button, Text, View } from "react-native"; export default function DevicesScreen() { const { devices, pair } = useNearbyDevices(); const remembered = usePairedDevices({ storage: AsyncStorage, autoPair: true }); const [message, setMessage] = useState(); const meters = devices.filter( (device) => device.deviceData.name === IntegratedDevices.BGM, ); async function connect(deviceId: string) { setMessage("Connecting to TeleBGM…"); try { const device = await pair(deviceId); if (!device) throw new Error("The meter is no longer available."); await remembered.pair(device); setMessage("TeleBGM is connected."); } catch { setMessage("Could not connect. Check Bluetooth and try again."); } } async function remove(deviceId: string) { await remembered.forget(deviceId); setMessage("The remembered meter was removed."); } return ( Devices TeleBGM Gen1 BLE measures blood glucose. {meters.length === 0 ? ( Turn on the meter and keep it nearby while this screen is open. ) : ( meters.map((device) => ( TeleBGM Gen1 BLE · {device.status ?? "Available"} {remembered.paired.includes(device.id) ? ( ); } ``` Localize the button label and error keys for your app. `setRateLimitFormError` stores an absolute `rateLimitUntil` timestamp in Formik status, sets the `submit` error to `auth.rate-limit`, and returns the parsed details. ## Recognized response shapes [#recognized-response-shapes] `getRateLimitDetails(error)` recognizes `code: "rate_limit"`, `status: 429`, and `response.status: 429`. It returns a message key and retry delay. A positive `retryAfterMs` from `@ovok/core`'s rate-limit error is used when present; otherwise `DEFAULT_RATE_LIMIT_RETRY_MS` is `60_000`. Unrecognized errors return `undefined`, so your form should handle them normally. The built-in sign-in, registration, and password-reset forms use the same server delay for their submit cooldown. A wrong password answers 401 (older servers answered 400); both show the invalid-credentials message. A password the server refuses, such as one shorter than 12 characters or a common one, answers 422 and its message is shown on the password field. Field errors come from `@ovok/core`'s `readOvokError`, so each one has a `path`; update `@ovok/core` to read the field errors of newer servers. Their `onError` callback receives the parsed `SignInError`, including `retryAfterMs` when the server provides it. `useRateLimitCooldown(until)` takes the absolute timestamp from Formik status, returns remaining milliseconds, and updates once per second while active. It returns `0` when no cooldown remains. ## Session state [#session-state] `useSession` exposes the current auth status, profile, sessions, refresh operations, logout, and session revocation. It does not protect routes or choose where the app navigates. It also exposes `switching` during account changes and `reason: "session-ended"` when the active login ends unexpectedly. See [Session Management](/native-sdk/guide/components/auth/session/) for its lifecycle, error behavior, and backend requirements. ## Related guides [#related-guides] - [Sign-in](/native-sdk/guide/components/auth/sign-in/) - [Registration](/native-sdk/guide/components/auth/register/) - [Password reset](/native-sdk/guide/components/auth/reset-password/) # Auth Components Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth The auth module provides UI and hooks for sign-in, registration, password recovery, profile editing, and session management. Its client-backed components use the native `Ovok` client from the nearest `OvokProvider` from `@ovok/core/next/react`. Your app owns routes, post-auth navigation, and the policies that determine who may sign in or edit an account. ## Choose a guide [#choose-a-guide] | Feature | What it covers | | --- | --- | | [Sign-in](/native-sdk/guide/components/auth/sign-in/) | Email and password, Google and Apple sign-in, MFA verification, and screen composition | | [Registration](/native-sdk/guide/components/auth/register/) | Account creation, registration form components, and examples | | [Password reset](/native-sdk/guide/components/auth/reset-password/) | Password recovery form and its component parts | | [Profile form](/native-sdk/guide/components/auth/profile/) | Editing the signed-in user's Patient profile | | [Session management](/native-sdk/guide/components/auth/session/) | Current profile state and server-side sessions | | [Logout button](/native-sdk/guide/components/auth/logout-button/) | Ending the current authenticated session | | [Delete account button](/native-sdk/guide/components/auth/delete-account-button/) | Confirming account deletion and handling its result | | [Auth hooks and rate limits](/native-sdk/guide/components/auth/hooks/) | Session hooks and rate-limit helpers for custom forms | Each guide links to the component-level reference for its form parts and props. You can also open any feature from the **Auth Components** sidebar section. ## Integration model [#integration-model] Mount auth components below the providers described in the [app shell guide](/native-sdk/guide/how-to/app-shell). Built-in forms submit through the active client. When you supply a custom `onSubmit`, that handler replaces the component's default request and session behavior; the host app must provide those pieces itself. Keep the tenant code in public app configuration and pass it to the native client. It is client-visible configuration, not a credential. If a form still accepts `tenantCode`, use the same value as the client. Configure Google and Apple native packages only when the app offers those providers; see the [installation guide](/native-sdk/guide/how-to/installation). ## Next steps [#next-steps] - Follow the [authentication integration guide](/native-sdk/guide/modules/auth) to connect routes, callbacks, MFA, and account controls. - Use the [public API map](/native-sdk/guide/public-api) to find the auth exports. # Logout Button Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/logout-button `LogoutButton` is a ready-made sign-out action for account settings. It calls `client.auth.logout()` on the active native `Ovok` client, signs out of Google when needed, and notifies mounted auth hooks to refresh. Your app owns navigation and any unsaved-work confirmation. ## Add the button [#add-the-button] ```tsx import { LogoutButton } from "@ovok/native"; import { Alert } from "react-native"; export function AccountActions() { return ( Alert.alert("Couldn't sign out", "Check your connection and try again.") } /> ); } ``` Render the button below [`OvokProvider`](/native-sdk/guide/how-to/app-shell). The default variant is `"row"`, which renders a settings-list row. Use `variant="button"` for a full-width React Native Paper button. The button variant accepts a custom `Button` component; both variants accept inherited settings-row props such as `disabled`, `style`, and `testID`. ## Handle request outcomes [#handle-request-outcomes] `onPress` runs when the user presses the action and before the logout request. `onError` receives a request error. There is a callback behavior to account for in the current implementation: `onSuccess` runs in the `finally` path, so it also runs after `onError`. Do not use it as proof that the server accepted the logout. For success-dependent navigation, track the request outcome in app-owned code or use an auth-state gate. The control prevents duplicate logout requests while busy. Use its `loading` and `disabled` props to coordinate it with the rest of the settings screen. ## Related guides [#related-guides] - [Session management](/native-sdk/guide/components/auth/session/) for custom session controls - [Delete account](/native-sdk/guide/components/auth/delete-account-button/) for account deletion # Profile Form Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/profile `ProfileForm` edits selected fields on the active Patient resource. The host app chooses which fields to show and supplies their current values. On submit, the default behavior patches only changed values through the active native `Ovok` client. ## Configure fields from profile data [#configure-fields-from-profile-data] Show the form only after the signed-in profile has loaded. Pass the current values from that profile; `ProfileForm` does not fetch initial field values on its own. ```tsx import { ProfileForm } from "@ovok/native"; import * as Yup from "yup"; import { Alert } from "react-native"; const fields = [ { name: "name[0].given", label: "First name", type: "text" as const, value: "Alex", validation: Yup.string().trim().required("Enter your first name"), }, { name: "name[0].family", label: "Last name", type: "text" as const, value: "Morgan", }, { name: "birthDate", label: "Date of birth", type: "date" as const, value: "1990-01-01", }, ]; export function EditProfileScreen() { return ( Alert.alert("Profile saved", "Your changes are up to date.")} /> ); } ``` Replace the example values with the loaded Patient values. `name` is a path on the Patient resource. Supported field types are `text`, `date`, and `select`; select fields also take `options: { label, value }[]`. Each field can include a Yup `validation`, `disabled`, and `testID` value. ## Save behavior [#save-behavior] The default submit handler compares values with the provided initial values, creates patch operations for changed fields, updates the active Patient, and refetches the profile. It then calls `onSuccess` with the updated Patient. `onError(error)` receives a failed default save or a rejected custom `onSubmit`; it receives the original error, including available status, code, or request-ID details. Default-save failures also show the form's generic or network submit error. `onSuccess` is called only after the save and profile refresh succeed. Errors thrown by `onSuccess` are application callback errors, not save failures, and are not sent to `onError`. Pass `onSubmit(values, helpers)` to own persistence. A custom submitter replaces the default patch; your handler must set form errors and refresh app data as needed. The custom and default submission modes are mutually exclusive. The form reinitializes when its `fields` values change. If refreshed profile data arrives while a user is editing, this resets unsaved changes. Decide when to refresh or remount the form, and only expose fields your product and backend allow users to edit. ## Related guides [#related-guides] - [Session management](/native-sdk/guide/components/auth/session/) for profile and session state - [Authentication integration guide](/native-sdk/guide/modules/auth) # Register.EmailForm Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/components/form The email form components provide a complete registration interface with validation, error handling, and customization options. ## Components Overview [#components-overview] The Register.EmailForm module includes several components that work together to create a complete registration form: - **[Register.EmailForm.Inputs](/native-sdk/guide/components/auth/register/components/form/inputs)**: Name, surname, email, and password input fields - **[Register.EmailForm.RegisterButton](/native-sdk/guide/components/auth/register/components/form/register-button)**: Submit button with loading states - **[Register.EmailForm.Spacing](/native-sdk/guide/components/auth/register/components/form/spacing)**: Layout spacing component ## Quick Usage [#quick-usage] ### Complete Form [#complete-form] The easiest way to implement email registration: ```tsx import { Register } from "@ovok/native"; import React from "react"; const QuickRegistrationForm = () => { return ( console.log("Registration successful:", response) } onError={(error) => console.error("Registration failed:", error)} > ); }; export default QuickRegistrationForm; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Form Validation [#form-validation] The form uses Yup and Formik for validation with these default rules: - **Name**: Required, 2-25 characters - **Surname**: Required, 2-25 characters - **Email**: Valid email format, required - **Password**: Minimum 8 characters, maximum 64 characters, required - **Password Confirmation**: Must match password ### Custom Validation [#custom-validation] ```tsx import * as Yup from "yup"; const customValidations = { name: Yup.string() .required("Name is required") .min(3, "Name must be at least 3 characters"), email: Yup.string() .email("Invalid email format") .required("Email is required"), password: (existingRule) => existingRule .min(10, "Minimum 10 characters") .matches(/[A-Z]/, "Must contain uppercase letter") .matches(/[0-9]/, "Must contain a number"), }; ; ``` ## Error Handling [#error-handling] The form provides comprehensive error handling: - **Validation Errors**: Field-level validation messages - **Network Errors**: API call failures - **Registration Errors**: Existing email, invalid data - **General Errors**: Unexpected errors ```tsx const handleError = (error) => { switch (error.code) { case "email_already_exists": // Show specific error for existing email break; case "network_error": // Show network error message break; default: // Show general error message } }; ``` ## Custom Form Handling [#custom-form-handling] For custom registration logic, use the `onSubmit` prop: ```tsx import React from "react"; import { Register } from "@ovok/native"; export const CustomRegistration = () => { const handleCustomSubmit = async (values, formikHelpers) => { try { // Custom registration logic const result = await myCustomRegisterAPI(values); // Handle success console.log("Registration successful:", result); } catch (error) { // Handle errors formikHelpers.setFieldError("submit", "Registration failed"); } }; return ( ); }; ``` ## Features [#features] - **Built-in Validation**: Yup and Formik-based validation with custom rules support - **Loading States**: Automatic loading indicators during submission - **Error Display**: User-friendly error messages - **Password Confirmation**: Automatic password matching validation - **Pre-filled Data**: Support for default values - **Theme Integration**: Consistent styling with app theme - **Accessibility boundary**: Forward input props and provide app-owned labels, hints, and announcements where required - **TypeScript**: Full type safety throughout ## Form Fields [#form-fields] ### Required Fields [#required-fields] - **Name**: User's first name - **Surname**: User's last name - **Email**: Valid email address - **Password**: Secure password - **Password Confirm**: Password confirmation (when not pre-filled) ### Conditional Fields [#conditional-fields] Fields are conditionally rendered based on `defaultValues`. If a field has a default value, it won't be shown in the form. ## Password Security [#password-security] The form includes password visibility toggles for both password and password confirmation fields, using eye/eye-slash icons for better user experience. # Register.EmailForm.Inputs Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/components/form/inputs The inputs component provides all form fields needed for user registration including name, surname, email, password, and password confirmation. ## Usage [#usage] ### Basic Implementation [#basic-implementation] ```tsx import { Register } from "@ovok/native"; import React from "react"; const BasicInputs = () => { return ( ); }; export default BasicInputs; ``` ### With Default Values [#with-default-values] When default values are provided, corresponding fields are hidden: ```tsx import { Register } from "@ovok/native"; import React from "react"; const defaultValues = { name: "John", surname: "Doe", email: "john@example.com", }; const PreFilledInputs = () => { return ( {/* Only password and password confirmation fields will show */} ); }; export default PreFilledInputs; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Form Fields [#form-fields] ### Name Field [#name-field] - **Label**: Uses `"register.name"` translation - **Validation**: Required, 2-25 characters - **Conditional**: Hidden if `defaultValues.name` is provided ### Surname Field [#surname-field] - **Label**: Uses `"register.surname"` translation - **Validation**: Required, 2-25 characters - **Conditional**: Hidden if `defaultValues.surname` is provided ### Email Field [#email-field] - **Label**: Uses `"sign-in.email"` translation - **Type**: Email keyboard - **Auto Capitalize**: None - **Validation**: Valid email format, required - **Conditional**: Hidden if `defaultValues.email` is provided ### Password Field [#password-field] - **Label**: Uses `"sign-in.password"` translation - **Type**: Secure text entry with visibility toggle - **Max Length**: 64 characters - **Icon**: Eye/EyeSlash toggle for visibility - **Validation**: Required, 8-64 characters - **Conditional**: Hidden if `defaultValues.password` is provided ### Password Confirmation Field [#password-confirmation-field] - **Label**: Uses `"register.password-confirm"` translation - **Type**: Secure text entry with visibility toggle - **Max Length**: 64 characters - **Icon**: Eye/EyeSlash toggle for visibility - **Validation**: Must match password - **Conditional**: Hidden if `defaultValues.passwordConfirm` OR `defaultValues.password` is provided ## Features [#features] - **Conditional Rendering**: Fields are automatically hidden when default values are provided - **Password Visibility**: Toggle icons for password fields - **Input Validation**: Real-time validation with error messages - **Keyboard Types**: Appropriate keyboard types for each field - **Theme Integration**: Consistent styling with app theme - **Accessibility**: Proper labels and hints for screen readers - **Auto Capitalize**: Disabled for email field ## Styling [#styling] ### Default Layout [#default-layout] The container uses vertical layout with theme-based spacing: ```tsx { gap: theme.spacing(4), // Default gap between fields } ``` ## Validation [#validation] Each field has built-in validation rules: - **Name/Surname**: Minimum 2, maximum 25 characters - **Email**: Valid email format with regex validation - **Password**: Minimum 8, maximum 64 characters - **Password Confirmation**: Must match the password field Validation errors are displayed below each field automatically. # Register.EmailForm.RegisterButton Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/components/form/register-button The register button component handles form submission with loading states and error display. ## Usage [#usage] ### Basic Implementation [#basic-implementation] ```tsx import { Register } from "@ovok/native"; import React from "react"; const BasicRegisterButton = () => { return ( ); }; export default BasicRegisterButton; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Button States [#button-states] ### Normal State [#normal-state] - Displays "Register" text (from `"register.button"` translation) - Full width button with contained mode - Uses theme's primary color ### Loading State [#loading-state] - Shows loading spinner - Button is disabled during submission - Text remains visible alongside spinner ### Error State [#error-state] - Button returns to normal state - Error message appears below button - Uses theme's error color for helper text ## Features [#features] - **Auto Loading**: Automatically shows loading state during form submission - **Error Display**: Shows validation and submission errors below button - **Theme Integration**: Uses theme colors and typography - **Full Width**: Button spans the full width of its container - **Accessibility**: Proper button semantics and error announcements - **TypeScript**: Full type safety for all props ## Default Styles [#default-styles] ### Button Styles [#button-styles] ```tsx const styles = { button: { width: "100%", }, buttonText: { fontFamily: "DMSans_700Bold", fontSize: 16, color: theme.colors.onPrimary, }, }; ``` ## Error Handling [#error-handling] The button automatically displays errors from: 1. **Form Validation**: Field-level validation errors 2. **Submission Errors**: API or network errors 3. **General Errors**: Unexpected errors during registration Error messages are shown using the `HelperText` component with error styling. ## Localization [#localization] The button text uses the translation key `"register.button"`. Make sure this key is defined: ```json { "register": { "button": "Create Account" } } ``` ## Accessibility [#accessibility] - Proper button role for screen readers - Loading state announcements - Error message accessibility - Keyboard navigation support - Touch target meets minimum size requirements ## Test IDs [#test-ids] The component provides several test IDs for testing: - `${testID}-container`: Button container - `${testID}-button`: The button element - `${testID}-helper-text`: Error text (when visible) Default `testID` is `"register-button"`. ## Form Integration [#form-integration] The button automatically integrates with the form context: - Accesses form submission state - Triggers form validation and submission - Displays form-level errors - Manages loading states during async operations No additional configuration is needed when used within `Register.EmailForm`. # Register.EmailForm.Spacing Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/components/form/spacing The spacing component provides flexible layout spacing for form elements. This component is shared with the sign-in module. ## Usage [#usage] ### Basic Spacing [#basic-spacing] ```tsx import { Register } from "@ovok/native"; import React from "react"; const FormWithSpacing = () => { return ( ); }; export default FormWithSpacing; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Features [#features] - **Theme-based Spacing**: Uses theme spacing system for consistency - **Flexible Heights**: Percentage-based or custom height values - **Layout Control**: Helps create proper visual hierarchy - **Responsive**: Adapts to different screen sizes through theme # Register.Header.Description Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/components/header/description The description component displays subtitle text for the registration page. ## Usage [#usage] ### Default Description [#default-description] ```tsx import { Register } from "@ovok/native"; import React from "react"; const DefaultDescription = () => { return ; }; export default DefaultDescription; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Default Styles [#default-styles] ```tsx const styles = { fontSize: 16, fontFamily: "DMSans_400Regular", lineHeight: 24, color: colors.onSurfaceDisabled, // From theme }; ``` ## Features [#features] - **Default Content**: Uses `"register.subtitle"` translation key - **Custom Content**: Supports custom description text via children - **Typography**: Consistent font family and line height - **Theme Colors**: Uses theme's disabled text color for subtle appearance - **Accessibility**: Proper text semantics for screen readers ## Localization [#localization] The default description uses the translation key `"register.subtitle"`. Make sure this key is defined in your translation files: ```json { "register": { "subtitle": "Fill in your details to create your account" } } ``` # Register.Header Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/components/header The header component provides title and description sections for the registration interface. ## Usage [#usage] ### Default Header [#default-header] ```tsx import { Register } from "@ovok/native"; import React from "react"; const DefaultHeader = () => { return ( ); }; export default DefaultHeader; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Sub-components [#sub-components] - **[Register.Header.Title](/native-sdk/guide/components/auth/register/components/header/title)**: Registration page title - **[Register.Header.Description](/native-sdk/guide/components/auth/register/components/header/description)**: Registration page description ## Features [#features] - **Flexible Layout**: Customizable container with theme-aware spacing - **Default Content**: Built-in translated title and description - **Custom Content**: Support for custom title and description text - **Theme Integration**: Consistent spacing using app theme - **Accessibility**: Proper heading hierarchy for screen readers ## Layout [#layout] The header uses a vertical layout with theme-based spacing between title and description components. The default gap is `theme.spacing(4)`. ## Localization [#localization] Default content uses these translation keys: - Title: `"register.title"` - Description: `"register.subtitle"` # Register.Header.Title Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/components/header/title The title component displays the main heading for the registration page. ## Usage [#usage] ### Default Title [#default-title] ```tsx import React from "react"; import { Register } from "@ovok/native"; const DefaultTitle = () => { return ; }; export default DefaultTitle; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Default Styles [#default-styles] ```tsx const styles = { fontSize: 24, fontFamily: "DMSans_700Bold", fontWeight: "600", lineHeight: 38.4, }; ``` ## Features [#features] - **Default Content**: Uses `"register.title"` translation key - **Custom Content**: Supports custom title text via children - **Typography**: Consistent font family and sizing - **Accessibility**: Proper heading semantics for screen readers - **Theme Integration**: Works with app's typography system ## Localization [#localization] The default title uses the translation key `"register.title"`. Make sure this key is defined in your translation files: ```json { "register": { "title": "Create Account" } } ``` # Register Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/components/register The main Register component provides a complete registration interface with keyboard-aware scrolling and safe area handling. ## Usage [#usage] ### Basic Implementation [#basic-implementation] ```tsx import { Register } from "@ovok/native"; import React from "react"; const RegistrationScreen = () => { return ( ); }; export default RegistrationScreen; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Features [#features] - **Keyboard Awareness**: Automatically adjusts for keyboard appearance - **Safe Area Support**: Handles device safe areas (notches, home indicators) - **Scroll Behavior**: Smooth scrolling with customizable indicators - **Keyboard Toolbar**: Built-in keyboard toolbar for input navigation - **Theme Integration**: Consistent spacing and styling with app theme ## Sub-components [#sub-components] - **Register.Header**: Title and description section - **Register.EmailForm**: Email registration form components - **Register.RegisterWithSeparator**: "Or register with" separator - **Register.SocialLogins**: Social authentication options - **Register.Footer**: Footer content and login link - **Register.LoginLink**: Link to redirect to sign-in ## Accessibility [#accessibility] - Proper keyboard navigation support - Screen reader compatibility - Focus management during keyboard interactions - Accessible scroll behavior # Basic Usage Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/examples/basic-usage Learn how to implement basic user registration functionality with the Register component. ## Simple Registration [#simple-registration] The most straightforward way to add registration to your app: ```tsx import React from "react"; import { Register } from "@ovok/native"; import { useRouter } from "expo-router"; export const BasicRegistration = () => { const router = useRouter(); const handleSuccess = (response) => { console.log("Registration successful:", response); // Navigate to welcome screen or dashboard router.push("/welcome"); }; const handleError = (error) => { console.error("Registration failed:", error); // Show error notification }; return ( router.push("/sign-in")} /> ); }; ``` ## With Social Registration [#with-social-registration] Add social login options to your registration flow: ```tsx import React from "react"; import { Register } from "@ovok/native"; import { useRouter } from "expo-router"; export const SocialRegistration = () => { const router = useRouter(); const handleEmailSuccess = (response) => { console.log("Email registration successful:", response); router.push("/welcome"); }; const handleSocialSuccess = (response) => { console.log("Social registration successful:", response); router.push("/welcome"); }; const handleError = (error) => { console.error("Registration failed:", error); }; return ( Continue with Google Continue with Apple router.push("/sign-in")} /> ); }; ``` ## Minimal Registration [#minimal-registration] A compact registration form with just the essentials: ```tsx import React from "react"; import { Register } from "@ovok/native"; export const MinimalRegistration = () => { const handleSuccess = (response) => { // Handle registration success }; const handleError = (error) => { // Handle registration error }; return ( Sign Up ); }; ``` ## Registration with Navigation [#registration-with-navigation] Integration with navigation libraries: ```tsx import React from "react"; import { Register } from "@ovok/native"; import { useNavigation } from "@react-navigation/native"; export const NavigationRegistration = () => { const navigation = useNavigation(); const handleSuccess = (response) => { // Store user data // Navigate to main app navigation.navigate("Dashboard"); }; const handleError = (error) => { // Show error message Alert.alert("Registration Failed", error.message); }; const navigateToSignIn = () => { navigation.navigate("SignIn"); }; return ( ); }; ``` ## Error Handling [#error-handling] Comprehensive error handling for registration: ```tsx import React from "react"; import { Alert } from "react-native"; import { Register } from "@ovok/native"; export const ErrorHandlingRegistration = () => { const handleSuccess = (response) => { Alert.alert("Success", "Account created successfully!"); }; const handleError = (error) => { let errorMessage = "Registration failed. Please try again."; // Handle specific error types if (error.message?.includes("email")) { errorMessage = "This email is already registered."; } else if (error.message?.includes("network")) { errorMessage = "Network error. Check your connection."; } else if (error.message?.includes("validation")) { errorMessage = "Please check your input and try again."; } Alert.alert("Registration Failed", errorMessage); }; return ( ); }; ``` ## Key Features [#key-features] - **Auto Validation**: Built-in form validation with real-time feedback - **Loading States**: Automatic loading indicators during submission - **Error Handling**: Comprehensive error display and handling - **Accessibility**: Add app-owned labels, hints, roles, and announcements for the screen-reader experience required by your product - **Theme Integration**: Consistent styling with your app theme - **Social Auth**: Optional Google and Apple registration - **Navigation**: Easy integration with navigation libraries ## Next Steps [#next-steps] - [Custom Styling](/native-sdk/guide/components/auth/register/examples/custom-styling) - Learn how to customize the appearance - [Custom Validation](/native-sdk/guide/components/auth/register/examples/custom-validation) - Add custom validation rules - [Pre-filled Data](/native-sdk/guide/components/auth/register/examples/pre-filled-data) - Handle registration with existing data # Custom Styling Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/examples/custom-styling Learn how to customize the appearance of registration components to match your app's design. ## Theme Customization [#theme-customization] Override theme colors and styles: ```tsx import React from "react"; import { Register } from "@ovok/native"; export const ThemedRegistration = () => { return ( console.log("Success:", response)} onError={(error) => console.error("Error:", error)} > ); }; ``` ## Material Design Styling [#material-design-styling] Apply Material Design principles: ```tsx import React from "react"; import { Register } from "@ovok/native"; export const MaterialRegistration = () => { return ( console.log("Success:", response)} onError={(error) => console.error("Error:", error)} > ); }; ``` ## iOS-Style Design [#ios-style-design] Create an iOS-inspired registration interface: ```tsx import React from "react"; import { Register } from "@ovok/native"; export const IOSRegistration = () => { return ( console.log("Success:", response)} onError={(error) => console.error("Error:", error)} > ); }; ``` ## Dark Mode Support [#dark-mode-support] Implement dark mode styling: ```tsx import React from "react"; import { useColorScheme } from "react-native"; import { Register } from "@ovok/native"; export const DarkModeRegistration = () => { const colorScheme = useColorScheme(); const isDark = colorScheme === "dark"; const colors = { background: isDark ? "#121212" : "#FFFFFF", surface: isDark ? "#1E1E1E" : "#F5F5F5", primary: isDark ? "#BB86FC" : "#6200EE", text: isDark ? "#FFFFFF" : "#000000", textSecondary: isDark ? "#B3B3B3" : "#666666", inputBackground: isDark ? "#2C2C2C" : "#FFFFFF", border: isDark ? "#373737" : "#E0E0E0", }; return ( console.log("Success:", response)} onError={(error) => console.error("Error:", error)} > ); }; ``` ## Custom Card Layout [#custom-card-layout] Create a card-based registration interface: ```tsx import React from "react"; import { View, StyleSheet } from "react-native"; import { Register } from "@ovok/native"; export const CardRegistration = () => { return ( console.log("Success:", response)} onError={(error) => console.error("Error:", error)} tenantCode="your-tenant-code" > ); }; const styles = StyleSheet.create({ container: { backgroundColor: "#F0F0F0", }, content: { padding: 20, justifyContent: "center", minHeight: "100%", }, card: { backgroundColor: "#FFFFFF", borderRadius: 16, padding: 24, shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 8, elevation: 4, }, header: { alignItems: "center", marginBottom: 32, }, title: { fontSize: 24, fontWeight: "700", color: "#1A1A1A", }, description: { fontSize: 16, color: "#666666", textAlign: "center", marginTop: 8, }, inputs: { gap: 20, }, input: { backgroundColor: "#FAFAFA", }, button: { backgroundColor: "#007AFF", borderRadius: 12, marginTop: 24, }, buttonContent: { paddingVertical: 4, }, footer: { marginTop: 24, alignItems: "center", }, }); ``` ## Styling Features [#styling-features] - **Theme Integration**: Works with your app's theme system - **Component-level Styling**: Style individual components - **Input Customization**: Full control over input field appearance - **Dark Mode Support**: Built-in support for dark/light modes - **Layout Flexibility**: Customize spacing, alignment, and structure - **Material Design**: Easy Material Design implementation - **iOS Guidelines**: Support for iOS design principles ## Best Practices [#best-practices] 1. **Consistency**: Maintain consistent styling across your app 2. **Accessibility**: Ensure proper contrast ratios and touch targets 3. **Responsive**: Design for different screen sizes 4. **Theme Support**: Use theme variables for better maintainability 5. **Platform Guidelines**: Follow platform-specific design guidelines ## Next Steps [#next-steps] - [Custom Validation](/native-sdk/guide/components/auth/register/examples/custom-validation) - Add custom validation styling - [Pre-filled Data](/native-sdk/guide/components/auth/register/examples/pre-filled-data) - Style forms with default values # Custom Validation Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/examples/custom-validation Learn how to implement custom validation rules for the registration form. ## Custom Validation Rules [#custom-validation-rules] Override default validation with custom Yup schemas: ```tsx import React from "react"; import * as Yup from "yup"; import { Register } from "@ovok/native"; export const CustomValidationRegistration = () => { const customValidations = { name: Yup.string() .required("First name is required") .min(3, "Name must be at least 3 characters") .max(20, "Name cannot exceed 20 characters") .matches(/^[a-zA-Z\s]+$/, "Name can only contain letters"), surname: Yup.string() .required("Last name is required") .min(2, "Last name must be at least 2 characters") .max(30, "Last name cannot exceed 30 characters"), email: Yup.string() .email("Please enter a valid email address") .required("Email is required") .matches( /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, "Please enter a valid email format", ), password: (existingRule) => existingRule .min(10, "Password must be at least 10 characters") .matches(/[A-Z]/, "Password must contain at least one uppercase letter") .matches(/[a-z]/, "Password must contain at least one lowercase letter") .matches(/[0-9]/, "Password must contain at least one number") .matches( /[^A-Za-z0-9]/, "Password must contain at least one special character", ), passwordConfirm: (existingRule) => existingRule.required("Please confirm your password"), }; return ( Create Strong Account Please follow our security requirements console.log("Success:", response)} onError={(error) => console.error("Error:", error)} > ); }; ``` ## Domain-specific Validation [#domain-specific-validation] Validation rules for specific business requirements: ```tsx import React from "react"; import * as Yup from "yup"; import { Register } from "@ovok/native"; export const BusinessValidationRegistration = () => { // Custom validation for business domains const allowedDomains = ["company.com", "partner.org", "client.net"]; const customValidations = { email: Yup.string() .email("Invalid email format") .required("Corporate email is required") .test("domain", "Please use a corporate email address", (value) => { if (!value) return false; const domain = value.split("@")[1]; return allowedDomains.includes(domain); }), name: Yup.string() .required("Full name is required") .min(2, "Name too short") .test("full-name", "Please enter your full name", (value) => { return value && value.trim().split(" ").length >= 2; }), password: (existingRule) => existingRule .min(12, "Corporate password must be at least 12 characters") .matches(/[A-Z]{2,}/, "Must contain at least 2 uppercase letters") .matches(/[0-9]{2,}/, "Must contain at least 2 numbers") .matches(/[!@#$%^&*]/, "Must contain special characters (!@#$%^&*)") .test("no-common", "Password is too common", (value) => { const commonPasswords = ["password123", "123456789", "qwerty123"]; return !commonPasswords.includes(value?.toLowerCase()); }), }; return ( Corporate Registration Please use your corporate email address console.log("Corporate registration:", response) } onError={(error) => console.error("Registration error:", error)} > ); }; ``` ## Async Validation [#async-validation] Validate against server data (email uniqueness, etc.): ```tsx import React from "react"; import * as Yup from "yup"; import { Register } from "@ovok/native"; export const AsyncValidationRegistration = () => { // Mock API function to check email availability const checkEmailAvailability = async (email: string) => { // Simulate API call const response = await fetch(`/api/check-email?email=${email}`); const data = await response.json(); return data.available; }; const customValidations = { email: Yup.string() .email("Invalid email format") .required("Email is required") .test( "email-available", "This email is already registered", async (value) => { if (!value || !Yup.string().email().isValidSync(value)) { return true; // Let email format validation handle this } try { const isAvailable = await checkEmailAvailability(value); return isAvailable; } catch (error) { // If API fails, allow the form to proceed console.warn("Email availability check failed:", error); return true; } }, ), name: Yup.string() .required("Username is required") .min(3, "Username must be at least 3 characters") .matches( /^[a-zA-Z0-9_]+$/, "Username can only contain letters, numbers, and underscores", ) .test("username-available", "This username is taken", async (value) => { if (!value || value.length < 3) return true; try { const response = await fetch(`/api/check-username?username=${value}`); const data = await response.json(); return data.available; } catch (error) { return true; } }), }; return ( console.log("Success:", response)} onError={(error) => console.error("Error:", error)} > ); }; ``` ## Password Strength Validation [#password-strength-validation] Advanced password requirements with visual feedback: ```tsx import React from "react"; import * as Yup from "yup"; import { Register } from "@ovok/native"; export const StrongPasswordRegistration = () => { const customValidations = { password: (existingRule) => existingRule .min(8, "Password must be at least 8 characters") .test( "password-strength", "Password does not meet requirements", (value) => { if (!value) return false; const requirements = [ { test: /.{8,}/, message: "At least 8 characters" }, { test: /[A-Z]/, message: "One uppercase letter" }, { test: /[a-z]/, message: "One lowercase letter" }, { test: /[0-9]/, message: "One number" }, { test: /[^A-Za-z0-9]/, message: "One special character" }, ]; return requirements.every((req) => req.test.test(value)); }, ), passwordConfirm: (existingRule) => existingRule .required("Please confirm your password") .test("passwords-match", "Passwords do not match", function (value) { return value === this.parent.password; }), }; return ( Secure Registration Create a strong password to protect your account console.log("Success:", response)} onError={(error) => console.error("Error:", error)} > ); }; ``` ## International Validation [#international-validation] Support for international names and addresses: ```tsx import React from "react"; import * as Yup from "yup"; import { Register } from "@ovok/native"; export const InternationalRegistration = () => { const customValidations = { name: Yup.string() .required("Name is required") .min(1, "Name is required") .max(50, "Name is too long") // Support international characters .matches(/^[\p{L}\p{M}\s\-'\.]+$/u, "Name contains invalid characters"), surname: Yup.string() .required("Surname is required") .min(1, "Surname is required") .max(50, "Surname is too long") .matches( /^[\p{L}\p{M}\s\-'\.]+$/u, "Surname contains invalid characters", ), email: Yup.string() .email("Invalid email format") .required("Email is required") // Support international domain names .matches( /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, "Please enter a valid email address", ), }; return ( International Registration Welcome users from around the world console.log("Success:", response)} onError={(error) => console.error("Error:", error)} > ); }; ``` ## Validation Features [#validation-features] - **Real-time Validation**: Validation occurs as the user types - **Custom Error Messages**: Provide specific, helpful error messages - **Async Validation**: Check against server data for uniqueness - **Password Strength**: Complex password requirements - **International Support**: Unicode character support for global users - **Business Rules**: Domain-specific validation requirements ## Best Practices [#best-practices] 1. **Clear Error Messages**: Use descriptive, actionable error messages 2. **Progressive Validation**: Start with basic rules, add complexity as needed 3. **User-Friendly**: Balance security with usability 4. **Performance**: Be mindful of async validation performance 5. **Accessibility**: Ensure error messages are accessible to screen readers ## Next Steps [#next-steps] - [Custom Styling](/native-sdk/guide/components/auth/register/examples/custom-styling) - Style validation states and error messages - [Pre-filled Data](/native-sdk/guide/components/auth/register/examples/pre-filled-data) - Handle validation with default values # Pre-filled Data Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register/examples/pre-filled-data Learn how to handle registration with pre-existing data and partial user information. ## Basic Pre-filled Registration [#basic-pre-filled-registration] Use default values to pre-populate form fields: ```tsx import React from "react"; import { View, Text } from "react-native"; import { Register } from "@ovok/native"; export const PreFilledRegistration = () => { const existingUserData = { name: "John", surname: "Doe", email: "john.doe@example.com", }; return ( Complete Your Registration Just add a password to finish setting up your account console.log("Registration completed:", response) } onError={(error) => console.error("Registration failed:", error)} > {/* Only password fields will be shown since other fields are pre-filled */} ); }; ``` ## Social Login Flow [#social-login-flow] Handle registration after social authentication: ```tsx import React from "react"; import { Register } from "@ovok/native"; export const SocialRegistrationCompletion = () => { // Data received from social login (Google, Apple, etc.) const socialUserData = { name: "Jane", surname: "Smith", email: "jane.smith@gmail.com", // No password needed for social login password: "social_auth_token", }; return ( Welcome, Jane! Your account has been created successfully { console.log("Social registration completed:", response); // Navigate to dashboard }} onError={(error) => console.error("Error:", error)} > {/* No input fields will be shown since all required data is provided */} {/* Show completion message or additional setup options */} Your account is ready to use! ); }; ``` ## Partial Data Flow [#partial-data-flow] Handle cases where only some information is available: ```tsx import React from "react"; import { Register } from "@ovok/native"; export const PartialDataRegistration = () => { // Email from invitation or previous step const partialData = { email: "invited.user@company.com", }; return ( Complete Your Profile Please provide your details to finish registration console.log("Profile completed:", response)} onError={(error) => console.error("Error:", error)} > {/* Email field will be hidden, name/surname/password fields will show */} ); }; ``` ## Dynamic Data Loading [#dynamic-data-loading] Load user data asynchronously and pre-fill the form: ```tsx import React, { useState, useEffect } from "react"; import { Register } from "@ovok/native"; import { ActivityIndicator, View } from "react-native"; export const DynamicPreFilledRegistration = ({ userId, }: { userId: string; }) => { const [userData, setUserData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const loadUserData = async () => { try { // Fetch user data from API const response = await fetch(`/api/users/${userId}/profile`); const data = await response.json(); setUserData({ name: data.firstName, surname: data.lastName, email: data.emailAddress, }); } catch (error) { console.error("Failed to load user data:", error); setUserData({}); // Empty object to show all fields } finally { setLoading(false); } }; loadUserData(); }, [userId]); if (loading) { return ( ); } return ( Update Your Information Please verify and complete your details console.log("Updated successfully:", response)} onError={(error) => console.error("Update failed:", error)} > ); }; ``` ## Password-only Registration [#password-only-registration] For cases where only password is needed: ```tsx import React from "react"; import { Register } from "@ovok/native"; export const PasswordOnlyRegistration = () => { const completeUserData = { name: "Michael", surname: "Johnson", email: "michael.johnson@company.com", }; return ( Set Your Password Create a secure password for your account: {completeUserData.email} console.log("Password set:", response)} onError={(error) => console.error("Error:", error)} > {/* Only password and password confirmation fields will show */} ); }; ``` ## Editable Pre-filled Data [#editable-pre-filled-data] Allow users to edit pre-filled information: ```tsx import React, { useState } from "react"; import { Register } from "@ovok/native"; import { View, TouchableOpacity, Text } from "react-native"; export const EditablePreFilledRegistration = () => { const [allowEdit, setAllowEdit] = useState(false); const defaultData = { name: "Sarah", surname: "Wilson", email: "sarah.wilson@email.com", }; // Don't pass defaultValues if editing is allowed const formDefaultValues = allowEdit ? {} : defaultData; return ( Confirm Your Details Review your information and set a password {!allowEdit && ( Your Information: Name: {defaultData.name} {defaultData.surname} Email: {defaultData.email} setAllowEdit(true)} style={{ marginTop: 12 }} > Edit Information )} console.log("Registration completed:", response) } onError={(error) => console.error("Error:", error)} > ); }; ``` ## Form State Management [#form-state-management] Handle complex pre-filled data scenarios: ```tsx import React, { useMemo } from "react"; import { Register } from "@ovok/native"; interface UserProfile { firstName?: string; lastName?: string; emailAddress?: string; hasPassword?: boolean; } export const StateBasedRegistration = ({ profile, }: { profile: UserProfile; }) => { const defaultValues = useMemo(() => { const values: any = {}; if (profile.firstName) values.name = profile.firstName; if (profile.lastName) values.surname = profile.lastName; if (profile.emailAddress) values.email = profile.emailAddress; // If user already has a password, don't require password confirmation if (profile.hasPassword) { values.password = "existing_password"; values.passwordConfirm = "existing_password"; } return values; }, [profile]); const getHeaderContent = () => { const missingFields = []; if (!profile.firstName) missingFields.push("name"); if (!profile.lastName) missingFields.push("surname"); if (!profile.emailAddress) missingFields.push("email"); if (!profile.hasPassword) missingFields.push("password"); if (missingFields.length === 0) { return { title: "Welcome Back!", description: "Your account is ready to use.", }; } return { title: "Complete Your Profile", description: `Please provide your ${missingFields.join(", ")} to continue.`, }; }; const headerContent = getHeaderContent(); return ( {headerContent.title} {headerContent.description} console.log("Profile updated:", response)} onError={(error) => console.error("Error:", error)} > ); }; ``` ## Features [#features] - **Conditional Fields**: Fields are automatically hidden when default values are provided - **Flexible Data**: Support for partial, complete, or dynamic data - **Social Integration**: Handle social login data seamlessly - **State Management**: Complex logic for different user states - **Validation**: Maintains validation rules even with pre-filled data - **User Experience**: Smooth flow for different registration scenarios ## Field Visibility Rules [#field-visibility-rules] | Default Value Provided | Field Visibility | | ------------------------------- | ---------------------------- | | `name` | Name field hidden | | `surname` | Surname field hidden | | `email` | Email field hidden | | `password` | Password field hidden | | `passwordConfirm` OR `password` | Password confirmation hidden | ## Best Practices [#best-practices] 1. **Clear Communication**: Tell users why fields are pre-filled 2. **Edit Options**: Allow users to modify pre-filled data when appropriate 3. **Validation**: Maintain proper validation even with default values 4. **Loading States**: Show loading indicators when fetching data 5. **Error Handling**: Handle cases where data loading fails 6. **Security**: Don't pre-fill sensitive data inappropriately ## Next Steps [#next-steps] - [Basic Usage](/native-sdk/guide/components/auth/register/examples/basic-usage) - Learn fundamental registration patterns - [Custom Validation](/native-sdk/guide/components/auth/register/examples/custom-validation) - Add validation for pre-filled data # Registration Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/register Use `Register` to compose an account-creation screen. Its default email flow submits to the active native `Ovok` client, activates the returned login, and publishes a session change. Your app owns the next route and any onboarding that follows. ## Add a registration screen [#add-a-registration-screen] Render the screen below [`OvokProvider`](/native-sdk/guide/how-to/app-shell) and the SDK `ThemeProvider`. Pass a tenant code from public app configuration. ```tsx import { Register } from "@ovok/native"; import { useRouter } from "expo-router"; import { Alert } from "react-native"; export function RegisterScreen() { const router = useRouter(); const tenantCode = process.env.EXPO_PUBLIC_TENANT_CODE; if (!tenantCode) { throw new Error("Set EXPO_PUBLIC_TENANT_CODE for this app environment"); } return ( router.replace("/welcome")} onError={() => Alert.alert("Registration failed", "Review your details or try again.") } > router.push("/sign-in")} /> ); } ``` Change the paths to match your navigation. The default form collects name, surname, email, password, and password confirmation. `defaultValues` can prefill fields when your flow already knows some of those values. ## Customize validation or submission [#customize-validation-or-submission] Pass `customValidations` to extend the built-in Yup validation. Use `onSubmit` when your app owns registration; it replaces the SDK's default `client.auth.register` request and automatic active-login setup. In that mode, handle errors, session updates, and navigation in your implementation. `onSubmit` cannot be combined with the default-flow `onSuccess` and `onError` callbacks. The shared Google and Apple buttons are available through `Register.SocialLogins`. Configure the native provider packages before rendering them; see [installation](/native-sdk/guide/how-to/installation) and the [registration examples](/native-sdk/guide/components/auth/register/examples/basic-usage). ## Related references [#related-references] - [Registration form and props](/native-sdk/guide/components/auth/register/components/form/) - [Inputs](/native-sdk/guide/components/auth/register/components/form/inputs) and [submit button](/native-sdk/guide/components/auth/register/components/form/register-button) - [Authentication integration guide](/native-sdk/guide/modules/auth) # ResetPassword.Form Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/reset-password/components/form Form container component that handles password reset validation, submission, and state management using Formik and Yup. ## Usage [#usage] ### Default Form [#default-form] ```tsx import { ResetPassword } from "@ovok/native"; const DefaultForm = () => { return ( ); }; export default DefaultForm; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Sub-Components [#sub-components] ### ResetPassword.Form.Inputs [#resetpasswordforminputs] Input fields for email and account type selection. - **Email Field**: Text input with email validation - **Account Type**: Dropdown selector for Patient/Practitioner/Carer - **[Documentation](/native-sdk/guide/components/auth/reset-password/components/form/inputs)**: Complete Inputs component guide ### ResetPassword.Form.Button [#resetpasswordformbutton] Submit button with loading states and error display. - **Loading States**: Shows spinner during submission - **Error Display**: Shows validation and submission errors - **[Documentation](/native-sdk/guide/components/auth/reset-password/components/form/reset-password-button)**: Complete Button component guide ### ResetPassword.Form.Spacing [#resetpasswordformspacing] Flexible spacing component for form layout. - **Flexible Growth**: Expands to fill available space - **Layout Helper**: Pushes button to bottom of container - **[Documentation](/native-sdk/guide/components/auth/reset-password/components/form/spacing)**: Complete Spacing component guide # ResetPassword.Form.Inputs Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/reset-password/components/form/inputs Input fields component containing email address input and account type selector for the password reset form. ## Usage [#usage] ### Default Inputs [#default-inputs] ```tsx import { ResetPassword } from "@ovok/native"; import React from "react"; const DefaultInputs = () => { return ( {}} onError={() => {}}> ); }; export default DefaultInputs; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Default Styles [#default-styles] The inputs container uses these default styles: ```tsx const defaultStyles = { gap: theme.spacing(4), // 16px gap between fields }; ``` ## Localization [#localization] The component uses these translation keys: ```json { "reset-password": { "email": "Email Address", "account-type": "Account Type", "patient": "Patient", "practitioner": "Practitioner" }, "sign-in": { "form": { "email": { "invalid": "Please enter a valid email address", "required": "Email address is required" } } } } ``` # ResetPassword.Form.Button Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/reset-password/components/form/reset-password-button Submit button component for the password reset form with loading states, error display, and proper form integration. ## Usage [#usage] ### Default Button [#default-button] ```tsx import { ResetPassword } from "@ovok/native"; import React from "react"; const DefaultButton = () => { return ( ); }; export default DefaultButton; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Button States [#button-states] ### Normal State [#normal-state] Default state when form is ready for submission: ```tsx // Button is enabled and ready ``` ### Loading State [#loading-state] During form submission with loading indicator: ```tsx // Button shows loading spinner ``` ### Error State [#error-state] When form has validation or submission errors: ```tsx {t(errors.submit)} ``` ## Default Styles [#default-styles] ### Button Styles [#button-styles] ```tsx const buttonStyles = { width: "100%", // Full width mode: "contained", // Filled button style }; ``` ### Text Styles [#text-styles] ```tsx const textStyles = { fontFamily: "DMSans_700Bold", fontSize: 16, color: theme.colors.onPrimary, }; ``` ## Localization [#localization] The button uses this translation key: ```json { "reset-password": { "reset-password": "Reset Password" } } ``` Error messages use these keys: ```json { "sign-in": { "form": { "email": { "invalid": "Please enter a valid email address", "required": "Email address is required" } } } } ``` # ResetPassword.Form.Spacing Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/reset-password/components/form/spacing Flexible spacing component that creates layout space between form elements and pushes the submit button to the bottom of the container. ## Usage [#usage] ### Default Spacing [#default-spacing] ```tsx import { ResetPassword } from "@ovok/native"; import React from "react"; const DefaultSpacing = () => { return ( ); }; export default DefaultSpacing; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). # ResetPassword.Header.Description Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/reset-password/components/header/description The description component for the password reset header, providing instructional text to guide users through the reset process. ## Usage [#usage] ### Default Description [#default-description] ```tsx import { ResetPassword } from "@ovok/native"; const DefaultDescription = () => { return ; }; export default DefaultDescription; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Default Styles [#default-styles] The description uses these default styles: ```tsx const defaultStyles = { fontSize: 16, fontFamily: "DMSans_400Regular", lineHeight: 24, color: colors.onSurfaceDisabled, // Muted text color }; ``` ## Features [#features] ### Typography [#typography] Uses consistent secondary typography: ```tsx // Default font: DMSans_400Regular // Size: 16px // Line height: 24px (1.5 ratio) // Color: Muted/disabled surface color ``` ### Localization [#localization] Automatically uses translation key: ```tsx // Default translation key: "reset-password.subtitle" // Fallback: Displays translation key if not found ``` ### Theme Integration [#theme-integration] Uses theme colors for consistent appearance: ```tsx // Uses theme.colors.onSurfaceDisabled by default // Provides appropriate contrast with background ``` ## Localization Keys [#localization-keys] ```json { "reset-password": { "subtitle": "Enter your email address and we'll send you instructions to reset your password." } } ``` # ResetPassword.Header Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/reset-password/components/header Header section component containing title and description for the password reset flow. ## Usage [#usage] ### Default Header [#default-header] ```tsx import { ResetPassword } from "@ovok/native"; import React from "react"; const DefaultHeader = () => { return ( ); }; export default DefaultHeader; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Sub-Components [#sub-components] ### ResetPassword.Header.Title [#resetpasswordheadertitle] Displays the main title for the reset password screen. - **Default**: Uses `"reset-password.title"` translation - **Customizable**: Can override with custom text - **[Documentation](/native-sdk/guide/components/auth/reset-password/components/header/title)**: Complete Title component guide ### ResetPassword.Header.Description [#resetpasswordheaderdescription] Displays descriptive text explaining the reset process. - **Default**: Uses `"reset-password.subtitle"` translation - **Customizable**: Can override with custom text - **[Documentation](/native-sdk/guide/components/auth/reset-password/components/header/description)**: Complete Description component guide ## Default Styles [#default-styles] The header uses these default styles: ```tsx const defaultStyles = { gap: theme.spacing(4), // 16px gap between title and description }; ``` ## Features [#features] ### Localization Support [#localization-support] Uses translation keys for default content: ```tsx // Default translations used: // - "reset-password.title" // - "reset-password.subtitle" ``` # ResetPassword.Header.Title Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/reset-password/components/header/title The title component for the password reset header, displaying the main heading text. ## Usage [#usage] ### Default Title [#default-title] ```tsx import { ResetPassword } from "@ovok/native"; import React from "react"; const DefaultTitle = () => { return ; }; export default DefaultTitle; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Default Styles [#default-styles] The title uses these default styles: ```tsx const defaultStyles = { fontSize: 24, fontFamily: "DMSans_700Bold", fontWeight: "600", lineHeight: 38.4, }; ``` ## Features [#features] ### Typography [#typography] Uses consistent typography from the design system: ```tsx // Default font: DMSans_700Bold // Size: 24px // Line height: 38.4px (1.6 ratio) // Weight: 600 (semi-bold) ``` ### Localization [#localization] Automatically uses translation key: ```tsx // Default translation key: "reset-password.title" // Fallback: Displays translation key if not found ``` ### Theme Integration [#theme-integration] Inherits text color from theme: ```tsx // Uses theme.colors.onSurface by default // Can be overridden with style prop ``` ## Localization Keys [#localization-keys] ```json { "reset-password": { "title": "Reset Password" } } ``` # ResetPassword Container Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/reset-password/components/reset-password The main container component that provides keyboard awareness, safe area handling, and scrolling functionality for the password reset flow. ## Usage [#usage] ### Basic Usage [#basic-usage] ```tsx import { ResetPassword } from "@ovok/native"; import React from "react"; const BasicResetPasswordContainer = () => { return ( console.log("Success:", response)} onError={(error) => console.error("Error:", error)} > ); }; export default BasicResetPasswordContainer; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Features [#features] ### Keyboard Awareness [#keyboard-awareness] Automatically adjusts content when keyboard appears: ```tsx {/* Form content automatically scrolls above keyboard */} ``` ### Safe Area Support [#safe-area-support] Handles device notches and home indicators: ```tsx // Automatically applies safe area padding: // - paddingBottom: bottom safe area // - paddingLeft: left safe area (landscape) // - paddingRight: right safe area (landscape) ``` ### Keyboard Toolbar [#keyboard-toolbar] Includes keyboard toolbar for enhanced input experience: ```tsx // Automatically includes: // - Done button to dismiss keyboard // - Navigation arrows for field switching // - Consistent toolbar styling ``` ## Sub-Components [#sub-components] ### ResetPassword.Header [#resetpasswordheader] Header section containing title and description. - **[ResetPassword.Header](/native-sdk/guide/components/auth/reset-password/components/header/)** - Complete header component - **[ResetPassword.Header.Title](/native-sdk/guide/components/auth/reset-password/components/header/title)** - Title component - **[ResetPassword.Header.Description](/native-sdk/guide/components/auth/reset-password/components/header/description)** - Description component ### ResetPassword.Form [#resetpasswordform] Form section with validation and submission handling. - **[ResetPassword.Form](/native-sdk/guide/components/auth/reset-password/components/form/)** - Complete form component - **[ResetPassword.Form.Inputs](/native-sdk/guide/components/auth/reset-password/components/form/inputs)** - Input fields - **[ResetPassword.Form.Button](/native-sdk/guide/components/auth/reset-password/components/form/reset-password-button)** - Submit button - **[ResetPassword.Form.Spacing](/native-sdk/guide/components/auth/reset-password/components/form/spacing)** - Layout spacing ## Default Styles [#default-styles] The container uses these default styles: ```tsx const defaultStyles = { // Scroll view showsVerticalScrollIndicator: false, bottomOffset: 75, // Safe area padding (automatic) paddingBottom: bottom, // from useSafeAreaInsets() paddingLeft: left, paddingRight: right, // Content container contentContainerStyle: { flexGrow: 1, gap: theme.spacing(6), padding: theme.spacing(6), }, }; ``` ## Layout Structure [#layout-structure] ```tsx {" "} {/* Main container */} {" "} {/* Safe area handling */} {" "} {/* Your content */}
{/* Keyboard toolbar */} ``` ## Best Practices [#best-practices] 1. **Content Organization**: Use proper spacing between sections 2. **Keyboard Handling**: Set appropriate `bottomOffset` for your content 3. **Safe Area**: Let the component handle safe area automatically 4. **Performance**: Use `keyboardShouldPersistTaps="handled"` for better UX 5. **Accessibility**: Ensure proper focus management in child components # Password Reset Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/reset-password Use `ResetPassword` to collect an email address and request account recovery through the active native `Ovok` client. The SDK validates the form and handles loading, field errors, and supported rate limits. Your app owns the confirmation copy, support path, and navigation back to sign-in. ## Compose a recovery screen [#compose-a-recovery-screen] Render the screen below [`OvokProvider`](/native-sdk/guide/how-to/app-shell) and the SDK `ThemeProvider`. ```tsx import { ResetPassword } from "@ovok/native"; import { Alert } from "react-native"; export function PasswordResetScreen() { return ( Alert.alert( "Check your email", "If the account can be recovered, instructions will be sent.", ) } onError={() => Alert.alert( "Request failed", "Try again. If the problem continues, contact support.", ) } > ); } ``` When `type` is omitted, the form defaults to `Patient` and shows the account type selector, which also offers `Carer` (`RelatedPerson`). Pass `type="Patient"`, `type="Practitioner"` or `type="RelatedPerson"` to lock the form to one account type and hide the selector. ## Use neutral confirmation copy [#use-neutral-confirmation-copy] The built-in success callback currently receives a generic confirmation message. Keep the user-facing response neutral so the screen does not reveal whether an email address is registered. For custom recovery behavior, pass `onSubmit`; it replaces the default `client.auth.resetPassword` request. ## Related references [#related-references] - [Form and callbacks](/native-sdk/guide/components/auth/reset-password/components/form/) - [Email and account-type inputs](/native-sdk/guide/components/auth/reset-password/components/form/inputs) - [Submit button](/native-sdk/guide/components/auth/reset-password/components/form/reset-password-button) - [Authentication integration guide](/native-sdk/guide/modules/auth) # Session Management Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/session Use `useSession` when an account screen needs the active profile or the user's server-side sessions. It reads the active native `Ovok` client; your app still owns route protection and the destination after sign-in or sign-out. ## Read session state [#read-session-state] Render the hook below [`OvokProvider`](/native-sdk/guide/how-to/app-shell). This example checks loading and errors before rendering a signed-out state. ```tsx import { useSession } from "@ovok/native"; import { Button, Text } from "react-native-paper"; export function SecurityStatus() { const { status, reason, activeAccountId, patientId, sessions, loading, switching, error, refresh, } = useSession({ sessions: true, refreshOnForeground: true }); if (loading) return Loading account…; if (error) { return ( <> We couldn't refresh your account state. ); } if (status === "signed-out") { return ( {reason === "session-ended" ? "Your session ended. Sign in again." : "Sign in to view account security."} ); } return ( <> Account: {activeAccountId} Patient: {patientId} Active sessions: {sessions.length} {switching && Updating account…} ); } ``` The hook returns `status` (`loading`, `authenticated`, `offline`, or `signed-out`), `isAuthenticated`, `activeAccountId`, `patientId` when the active profile is a Patient, saved `accounts`, `profile`, normalized `sessions`, `loading`, `switching`, `reason`, `error`, `refresh`, `refreshSessions`, `switchAccount`, `removeAccount`, `logout`, and `revokeSessions`. `offline` means the saved login is still present but profile refresh failed; it remains authenticated. The hook retries when connectivity returns. `reason` is `"session-ended"` when the client clears an active login unexpectedly; it is absent after a user-requested logout. ## Refresh and revoke sessions [#refresh-and-revoke-sessions] `sessions` and `refreshOnForeground` both default to `true`. Set `sessions: false` when a screen only needs profile state. Set `refreshOnForeground: false` if the host already refreshes on app resume. The hook also refreshes when a mounted auth component publishes a session change; call `refresh()` after a custom auth flow that does not publish that event. `activeAccountId` identifies the selected saved account. When it changes, `profile` is cleared until a profile can be matched to that account; if the identity cannot be confirmed, `profile` and `patientId` are undefined. A failed refresh will not expose the previous account's profile. `switchAccount()` and `removeAccount()` preserve the current `status` while they run. Use `switching` to disable account controls or show local progress; do not replace the screen or navigator based on it. Removing an inactive account does not change the active session. Account switching, saved accounts, and the `session-ended` reason use the `@ovok/core/next` session methods and the native client's secure storage. Use `revokeSessions("other")` to sign out other sessions. The server owns the session inventory and revocation policy. The returned session fields are `id`, `authMethod`, `remoteAddress`, and `lastUpdated` when the backend provides them. When the saved session remains present after a profile refresh failure, the hook reports `status: "offline"` and exposes the failure as `error`. It reports `signed-out` only when there is no current session. Its `logout()` method ends the local session even when the server request fails; catch the returned promise if the result affects navigation. ## Use the provided session list [#use-the-provided-session-list] `` renders the loading and empty states, lists available sessions, and offers **Sign out of other devices** when more than one session is present. It creates its own `useSession` hook; use the list on its own or build a custom list from one hook instance rather than mounting both and fetching sessions twice. The session list calls `client.auth.sessions.list()` and the action calls `client.auth.sessions.revoke("other")` on the active next client. ## Related guides [#related-guides] - [Auth hooks and rate limits](/native-sdk/guide/components/auth/hooks/) - [Logout button](/native-sdk/guide/components/auth/logout-button/) # SignIn Container Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/container The main container component that wraps all sign-in related functionality. It provides a scrollable interface with keyboard handling and safe area support, serving as the foundation for building complete sign-in experiences. > **SDK-first — do NOT hand-roll an auth form.** When your build needs sign-in, render `` + `` from `@ovok/native`. The component ships the entire form (email + password inputs, Formik/Yup validation, submit handler, error states, social-login buttons, "Forgot password" link, and the MFA step) and reads theme tokens via `useAppTheme()` automatically. A hand-rolled `` + `` clone has none of that and locks you out of future SDK upgrades. If you're tempted to write your own form because "I just need email + password", you don't — `` IS that. ## Quick Start Example [#quick-start-example] ```tsx import { SignIn, useAppTheme } from "@ovok/native"; import React from "react"; import { useTranslation } from "react-i18next"; import { StyleSheet } from "react-native"; // Static styles outside component const styles = StyleSheet.create({ container: { flex: 1, }, }); const LoginScreen = () => { const { t } = useTranslation(); const theme = useAppTheme(); return ( {t("auth.signIn.title")} {t("auth.signIn.description")} { // Handle successful authentication }} onError={(error) => { // Handle authentication error }} > ); }; export default LoginScreen; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Child Components [#child-components] - [SignIn.Header](/native-sdk/guide/components/auth/sign-in/header/) - Header section with title and description - [SignIn.EmailForm](/native-sdk/guide/components/auth/sign-in/form/) - Email/password form components and authentication logic - [SignIn.RegisterLink](/native-sdk/guide/components/auth/sign-in/register-link) - Link for navigating to registration - [SignIn.SocialLogins](/native-sdk/guide/components/auth/sign-in/social-logins/) - Social authentication options (Google, Apple) ## Related Components [#related-components] - [SignIn.Header](/native-sdk/guide/components/auth/sign-in/header/) - Header section with title and description - [SignIn.EmailForm](/native-sdk/guide/components/auth/sign-in/form/) - Email/password form components and authentication logic - [SignIn.RegisterLink](/native-sdk/guide/components/auth/sign-in/register-link) - Link for navigating to registration - [SignIn.SocialLogins](/native-sdk/guide/components/auth/sign-in/social-logins/) - Social authentication options (Google, Apple) # SignIn.Footer Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/footer Footer component that displays localized text with interactive site URL links for additional sign-in information. ## Quick Example [#quick-example] ```tsx import { SignIn } from "@ovok/native"; import React from "react"; const FooterExample = () => { return ; }; export default FooterExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Localization [#localization] The component uses this translation key: ```json { "sign-in": { "footer": "If you haven't purchased a telemonitoring package yet, visit actimi.com" } } ``` - `sign-in.footer` - Footer text with interactive site URL component ## Component Behavior [#component-behavior] The component uses react-i18next Trans component to render localized text with an interactive `` component that handles URL navigation. ## Styling [#styling] ### Theme Variables Used [#theme-variables-used] - `theme.colors.onSurfaceVariant` - Text color for the footer content ## Related Components [#related-components] - [SignIn](/native-sdk/guide/components/auth/sign-in/) - Main sign-in component container - [SignIn.Header](/native-sdk/guide/components/auth/sign-in/header/) - Header components for titles and descriptions - [SignIn.EmailForm](/native-sdk/guide/components/auth/sign-in/form/) - Email form components for authentication # SignIn.EmailForm.ForgotPassword Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/form/forgot-password Forgot password link component that provides navigation to password recovery functionality. Offers customizable styling, accessibility support, and seamless integration with the sign-in form layout. ## Quick Start Example [#quick-start-example] ```tsx import { SignIn, useAppTheme } from "@ovok/native"; import React from "react"; import { StyleSheet } from "react-native"; // Static styles outside component const styles = StyleSheet.create({ form: { flex: 1, }, forgotPasswordContainer: { alignSelf: "flex-end", }, }); const ForgotPasswordExample = () => { const theme = useAppTheme(); const handleForgotPassword = () => { console.log("Navigate to forgot password screen"); // Navigate to forgot password screen }; return ( ); }; export default ForgotPasswordExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Localization [#localization] The component uses this translation key: ```json { "sign-in": { "forgot-password": "Forgot password?" } } ``` - `sign-in.forgot-password` - Default link text displayed when no children provided ## Styling [#styling] ### Theme Variables Used [#theme-variables-used] The SignIn.EmailForm.ForgotPassword uses these theme values by default that can be changed globally: - **`theme.colors.primary`** - Link text color when styled with theme integration - **`theme.spacing()`** - Spacing values for positioning and margins - Inherits text styling from react-native-paper Text component ## Related Components [#related-components] - [SignIn.EmailForm](/native-sdk/guide/components/auth/sign-in/form/) - Email form provider that manages form state - [SignIn.EmailForm.Inputs](/native-sdk/guide/components/auth/sign-in/form/inputs) - Email and password input fields - [SignIn.EmailForm.SigninButton](/native-sdk/guide/components/auth/sign-in/form/signin-button) - Form submit button # SignIn.EmailForm Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/form Complete email/password authentication interface combining all form elements with validation, error handling, and customization options. Provides compound components for building flexible sign-in forms with built-in authentication logic. ## Prerequisites [#prerequisites] Before using the Sign-In module, you must configure your `ovokClient` with a valid tenant code. ### Obtaining Your Tenant Code [#obtaining-your-tenant-code] To get your organization's tenant code, use the Ovok API to receive organization codes via email: ```bash curl -X POST https://api.ovok.com/organizations/code/email \ -H "Content-Type: application/json" \ -d '{"email": "your-email@example.com"}' ``` For detailed API documentation, refer to the [Ovok API Reference](https://docs.ovok.com/reference/organizationcodecontroller_sendemailoforganizations). ### Configuring Your Client [#configuring-your-client] Once you receive your tenant code, update your `ovokClient` configuration in `app/_layout.tsx`: ```tsx import { Ovok } from "@ovok/native/next"; import * as SecureStore from "expo-secure-store"; const ovokClient = new Ovok({ baseUrl: "https://api.example.com", tenantCode: "your-tenant-code-here", secureStore: SecureStore, }); ``` ## Quick Start Example [#quick-start-example] ```tsx import { SignIn, useAppTheme } from "@ovok/native"; import React from "react"; import { Alert, StyleSheet } from "react-native"; // Static styles outside component const styles = StyleSheet.create({ form: { flex: 1, }, }); const LoginScreen = () => { const theme = useAppTheme(); const handleSuccess = () => Alert.alert("Signed in"); const handleError = (error: Error) => Alert.alert("Sign-in failed", error.message); return ( ); }; export default LoginScreen; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Child Components [#child-components] - **[SignIn.EmailForm.Inputs](/native-sdk/guide/components/auth/sign-in/form/inputs)** - Email and password input fields with validation - **[SignIn.EmailForm.SigninButton](/native-sdk/guide/components/auth/sign-in/form/signin-button)** - Submit button with loading states and error display - **[SignIn.EmailForm.ForgotPassword](/native-sdk/guide/components/auth/sign-in/form/forgot-password)** - Forgot password link component - **[SignIn.EmailForm.Spacing](/native-sdk/guide/components/auth/sign-in/form/spacing)** - Layout spacing component for consistent vertical spacing ## Localization [#localization] The SignIn.EmailForm component uses these translation keys that should be defined in your localization files: ```json { "sign-in": { "email": "Email", "password": "Password", "button": "Sign In", "forgot-password": "Forgot password?", "form": { "email": { "invalid": "Invalid email address", "required": "Email is required" }, "password": { "required": "Password is required" } } } } ``` ### Translation Key Usage [#translation-key-usage] - `sign-in.email` - Email input field label - `sign-in.password` - Password input field label - `sign-in.button` - Submit button text - `sign-in.forgot-password` - Forgot password link text - `sign-in.form.email.invalid` - Email validation error message - `sign-in.form.email.required` - Required email field error - `sign-in.form.password.required` - Required password field error The SDK registers English defaults for these keys without overwriting your own translations. ## Common Patterns [#common-patterns] ### With Custom Validation [#with-custom-validation] ```tsx import { SignIn, useAppTheme } from "@ovok/native"; import React from "react"; import { StyleSheet } from "react-native"; import * as Yup from "yup"; // Static styles outside component const styles = StyleSheet.create({ form: { flex: 1, }, }); const customValidations = { email: (existingRule: Yup.StringSchema) => existingRule .email("Invalid email address") .matches(/@ovok\.com$/, "Email must be from ovok.com domain"), }; export const CustomValidationLoginForm = () => { const theme = useAppTheme(); return ( ); }; ``` ## Related Components [#related-components] - [SignIn](/native-sdk/guide/components/auth/sign-in/) - Main sign-in component container - [SignIn.Header](/native-sdk/guide/components/auth/sign-in/header/) - Header components for titles and descriptions - [SignIn.SocialLogins](/native-sdk/guide/components/auth/sign-in/social-logins/) - Social authentication components # SignIn.EmailForm.Inputs Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/form/inputs Email and password input fields with validation, error display, and theme integration. Provides form inputs with built-in validation and password visibility toggle functionality. ## Quick Start Example [#quick-start-example] ```tsx import { SignIn, useAppTheme } from "@ovok/native"; import { StyleSheet } from "react-native"; // Static styles outside component const styles = StyleSheet.create({ form: { flex: 1, }, }); const InputsExample = () => { const theme = useAppTheme(); return ( ); }; export default InputsExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Localization [#localization] The component uses these translation keys: ```json { "sign-in": { "email": "Email", "password": "Password" } } ``` - `sign-in.email` - Label for email input field - `sign-in.password` - Label for password input field ## Input Features [#input-features] ### Email Input [#email-input] - **Keyboard Type**: Email keyboard layout (`keyboardType="email-address"`) - **Auto-capitalization**: Disabled for email addresses (`autoCapitalize="none"`) - **Auto-correction and auto-complete**: Not set by the SDK; pass these through `inputProps` when needed. - **Validation**: Email format validation ### Password Input [#password-input] - **Secure Entry**: Password text hidden by default (`secureTextEntry={true}`) - **Visibility Toggle**: Eye icon to show/hide password using [TextInput.Icon](https://callstack.github.io/react-native-paper/docs/components/TextInput/#textinputicon) - **Maximum Length**: 64 characters (`maxLength={64}`) - **Auto-complete**: Not set by the SDK; pass the desired password-manager hint through `inputProps`. - **Validation**: Required field validation > For additional input customization options, refer to the [React Native Paper TextInput props documentation](https://callstack.github.io/react-native-paper/docs/components/TextInput/#props). ## Validation Display [#validation-display] - **When errors appear**: Validation errors appear after a field value changes or the form is submitted; autofocus and blur alone do not show an untouched required-field error - **Error Styling**: Input borders change to error color - **Error Messages**: Displayed below inputs after validation is relevant - **Form Integration**: Connected to overall form validation state ## Input Behavior [#input-behavior] - **Auto-focus**: Email field receives focus on component mount; this does not mark it as edited or show a required error - **Tab Navigation**: Password field focused after email completion - **Form Submission**: Enter key on password field submits form - **Error Handling**: Validation errors prevent form submission The SDK applies the email field's focus behavior, the password field's `Next` action, and the final field's `Done` submit action after spreading `inputProps`. Those flow-critical values cannot be overridden through `inputProps`; use a custom form when the keyboard sequence must differ. ## Best Practices [#best-practices] 1. **Theme Integration**: Use theme values for consistent styling 2. **Accessibility**: Ensure proper labels and hints for screen readers 3. **Validation**: Provide clear, actionable error messages 4. **User Experience**: Let users toggle password visibility 5. **Form Flow**: Design logical tab navigation between fields ## Features [#features] - **Form Integration**: Seamless integration with EmailForm context - **Theme Integration**: Consistent styling with app theme - **Validation**: Built-in email and password validation - **Accessibility boundary**: Supply app-owned labels, hints, and announcements through the input props when the default field labels are not sufficient - **Password Toggle**: Show/hide password functionality - **Error Display**: Clear validation error messages ## Related Components [#related-components] - [SignIn.EmailForm](/native-sdk/guide/components/auth/sign-in/form/) - Parent form component that provides context - [SignIn.EmailForm.SigninButton](/native-sdk/guide/components/auth/sign-in/form/signin-button) - Submit button component - [SignIn.EmailForm.ForgotPassword](/native-sdk/guide/components/auth/sign-in/form/forgot-password) - Forgot password link component # SignIn.EmailForm.SigninButton Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/form/signin-button Submit button component that handles form submission with loading states, validation, and error display. Provides automatic form submission, loading indicators, and comprehensive error handling with accessibility support. ## Quick Start Example [#quick-start-example] ```tsx import { SignIn, useAppTheme } from "@ovok/native"; import React from "react"; import { StyleSheet } from "react-native"; // Static styles outside component const styles = StyleSheet.create({ form: { flex: 1, }, }); const SignInButtonExample = () => { const theme = useAppTheme(); return ( ); }; export default SignInButtonExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Localization [#localization] The component uses this translation key: ```json { "sign-in": { "button": "Sign In" } } ``` - `sign-in.button` - Default button text displayed on the submit button ## Styling [#styling] ### Theme Variables Used [#theme-variables-used] The SignIn.EmailForm.SigninButton uses these theme values by default that can be changed globally: - **`theme.colors.onPrimary`** - Button text color - **`theme.colors.primary`** - Button background color (inherited from react-native-paper Button) - **`theme.colors.error`** - Error text color for validation messages ## Related Components [#related-components] - [SignIn.EmailForm](/native-sdk/guide/components/auth/sign-in/form/) - Email form provider that manages button state - [SignIn.EmailForm.Inputs](/native-sdk/guide/components/auth/sign-in/form/inputs) - Input fields for email and password - [SignIn.EmailForm.ForgotPassword](/native-sdk/guide/components/auth/sign-in/form/forgot-password) - Password recovery link # SignIn.EmailForm.Spacing Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/form/spacing Layout spacing component that provides flexible vertical spacing using flex-based layout. ## Quick Example [#quick-example] ```tsx import { SignIn, useAppTheme } from "@ovok/native"; import React from "react"; import { StyleSheet } from "react-native"; // Static styles outside component const styles = StyleSheet.create({ customSpacing: { backgroundColor: "transparent", }, container: { flexGrow: 1, }, }); const SpacingExample = () => { const theme = useAppTheme(); return ( ); }; export default SpacingExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Component Behavior [#component-behavior] The component uses `flex: percentage` to create proportional spacing in flex layouts. Higher percentage values create more space relative to other flex items. ## Styling [#styling] ### Theme Variables Used [#theme-variables-used] - No specific theme variables used by default - Inherits styling capabilities from React Native View component ## Related Components [#related-components] - [SignIn.EmailForm](/native-sdk/guide/components/auth/sign-in/form/) - Email form provider that manages layout - [SignIn.EmailForm.Inputs](/native-sdk/guide/components/auth/sign-in/form/inputs) - Email and password input fields - [SignIn.EmailForm.SigninButton](/native-sdk/guide/components/auth/sign-in/form/signin-button) - Form submit button # SignIn.Header.Description Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/header/description Description component for the sign-in header section that provides contextual information with localization support. ## Quick Example [#quick-example] ```tsx import { SignIn } from "@ovok/native"; import React from "react"; const DescriptionExample = () => { return ( Enter your credentials to continue ); }; export default DescriptionExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Localization [#localization] The component uses the following translation keys: ```json { "sign-in": { "subtitle": "Log in to your account to start using Actimi products." } } ``` ### Default Behavior [#default-behavior] When no `children` prop is provided, the component automatically displays the localized subtitle: ```tsx ``` This renders the value of `t("sign-in.subtitle")` which defaults to "Log in to your account to start using Actimi products." ## Related Components [#related-components] - [SignIn.Header](/native-sdk/guide/components/auth/sign-in/header/) - Header container component - [SignIn.Header.Title](/native-sdk/guide/components/auth/sign-in/header/title) - Title text component - [SignIn](/native-sdk/guide/components/auth/sign-in/) - Main sign-in component # SignIn.Header Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/header Container component for the header section of the sign-in screen that provides structured layout for title and description elements. ## Quick Example [#quick-example] ```tsx import { SignIn } from "@ovok/native"; import React from "react"; const HeaderExample = () => { return ( Welcome Back Sign in to your account ); }; export default HeaderExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Child Components [#child-components] - [SignIn.Header.Title](/native-sdk/guide/components/auth/sign-in/header/title) - Title text component - [SignIn.Header.Description](/native-sdk/guide/components/auth/sign-in/header/description) - Description text component ## Related Components [#related-components] - [SignIn](/native-sdk/guide/components/auth/sign-in/) - Main sign-in component # SignIn.Header.Title Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/header/title Title component for the sign-in header section that displays the main heading with localization support. ## Quick Example [#quick-example] ```tsx import { SignIn } from "@ovok/native"; import React from "react"; const TitleExample = () => { return ( Welcome Back ); }; export default TitleExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Localization [#localization] The component uses the following translation keys: ```json { "sign-in": { "title": "Sign In" } } ``` ### Default Behavior [#default-behavior] When no `children` prop is provided, the component automatically displays the localized title: ```tsx ``` This renders the value of `t("sign-in.title")` which defaults to "Sign In". ## Related Components [#related-components] - [SignIn.Header](/native-sdk/guide/components/auth/sign-in/header/) - Header container component - [SignIn.Header.Description](/native-sdk/guide/components/auth/sign-in/header/description) - Description text component - [SignIn](/native-sdk/guide/components/auth/sign-in/) - Main sign-in component # Sign-In Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in Use `SignIn` to compose an email sign-in screen from SDK components. The default email form calls `client.auth.login()` on the active native `Ovok` client and activates the returned login. Your app decides where a successful user goes and how sign-in errors are presented. ## Add a patient sign-in screen [#add-a-patient-sign-in-screen] Render the screen below [`OvokProvider`](/native-sdk/guide/how-to/app-shell) and the SDK `ThemeProvider`. Patient sign-in uses the tenant configured on the native client; pass the same tenant code to the existing form prop. ```tsx import { SignIn } from "@ovok/native"; import { useRouter } from "expo-router"; import { Alert } from "react-native"; export function SignInScreen() { const router = useRouter(); const tenantCode = process.env.EXPO_PUBLIC_TENANT_CODE; if (!tenantCode) { throw new Error("Set EXPO_PUBLIC_TENANT_CODE for this app environment"); } return ( router.replace("/home")} onError={() => Alert.alert("Sign-in failed", "Check your details or try again.") } > router.push("/register")} /> ); } ``` Use your app's route names in place of `/home` and `/register`. For practitioner sign-in, set `loginType="Practitioner"`; the form's tenant code is optional for that variant. For carer (RelatedPerson) sign-in, set `loginType="RelatedPerson"` with the tenant code. Carers have no register route: their account is made when they accept a record-share invite (see [Invites and carers](/native-sdk/guide/how-to/invites-and-carers)). ## Add MFA or social sign-in [#add-mfa-or-social-sign-in] With the default client-backed form, an MFA response changes `SignIn.EmailForm.Inputs` to the verification-code input. The SDK verifies that code, activates the login, and then calls `onSuccess`. Use a compatible `@ovok/core` release that supports MFA responses. An `onSubmit` callback replaces the default submission path. If you provide one, your implementation owns credential verification, MFA, active-login storage, and session updates. The default `onSuccess` and `onError` callbacks cannot be combined with that custom submitter. Google and Apple buttons are optional. Add them inside `SignIn.SocialLogins` only after completing the native provider setup in [installation](/native-sdk/guide/how-to/installation). See the [social login reference](/native-sdk/guide/components/auth/sign-in/social-logins/) for provider props, and [Sign in on the web](/native-sdk/guide/components/auth/sign-in/social-logins/#sign-in-on-the-web) for React Native Web. ## Related references [#related-references] - [Sign-in container](/native-sdk/guide/components/auth/sign-in/container) - [Email form](/native-sdk/guide/components/auth/sign-in/form/), [inputs](/native-sdk/guide/components/auth/sign-in/form/inputs), and [submit button](/native-sdk/guide/components/auth/sign-in/form/signin-button) - [Authentication integration guide](/native-sdk/guide/modules/auth) # SignIn.RegisterLink Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/register-link `SignIn.RegisterLink` renders the localized “don't have an account?” sentence and calls `onPress` when the registration link is pressed. ## Example [#example] ```tsx import { SignIn } from "@ovok/native"; router.push("/register")} />; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). # SignIn.SocialLogins.AppleLogin Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/social-logins/apple-login Apple authentication button component that handles Sign in with Apple integration and availability checking. ## Quick Example [#quick-example] ```tsx import { SignIn, useAppTheme } from "@ovok/native"; import React from "react"; import { Alert, StyleSheet } from "react-native"; // Static styles outside component const styles = StyleSheet.create({ appleButton: { alignItems: "center", }, }); const AppleLoginExample = () => { const theme = useAppTheme(); const handleAppleSuccess = () => Alert.alert("Signed in"); const handleAppleError = (error: Error) => Alert.alert("Sign-in failed", error.message); return ( Continue with Apple ); }; export default AppleLoginExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Component Behavior [#component-behavior] The component checks Apple Sign-In availability on mount and handles the OAuth flow when available. Until `AppleAuthentication.isAvailableAsync()` resolves, and on platforms where it resolves `false`, the component renders `null` including no fallback for its children. Render your own placeholder if the app needs one. ## On the web [#on-the-web] On React Native Web the button opens Sign in with Apple JS in a popup for `appleServicesId`, with `appleRedirectUri` as the Return URL (default: the site's origin). Without `appleServicesId` it renders nothing on the web. Use an `internalId` that names an Ovok entry for the Services ID, because the web's tokens have it as their audience. `expo-apple-authentication` is not loaded; see [Sign in on the web](/native-sdk/guide/components/auth/sign-in/social-logins/#sign-in-on-the-web). ## Styling [#styling] ### Theme Variables Used [#theme-variables-used] - No specific theme variables used by default - Inherits styling capabilities from TouchableOpacity ## Child Components [#child-components] - **SignIn.SocialLogins.AppleLogin.Icon** - Apple logo icon component - **SignIn.SocialLogins.AppleLogin.Text** - Text component with typography variant support ## Related Components [#related-components] - [SignIn.SocialLogins](/native-sdk/guide/components/auth/sign-in/social-logins/) - Social logins container - [SignIn.SocialLogins.GoogleLogin](/native-sdk/guide/components/auth/sign-in/social-logins/google-login) - Google authentication button # SignIn.SocialLogins.GoogleLogin Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/social-logins/google-login Google authentication button component that handles OAuth integration with automatic Google Sign-In configuration. ## Quick Example [#quick-example] ```tsx import { SignIn, useAppTheme } from "@ovok/native"; import React from "react"; import { Alert, StyleSheet } from "react-native"; // Static styles outside component const styles = StyleSheet.create({ googleButton: { alignItems: "center", }, }); const GoogleLoginExample = () => { const theme = useAppTheme(); const handleGoogleSuccess = () => Alert.alert("Signed in"); const handleGoogleError = (error: Error) => Alert.alert("Sign-in failed", error.message); return ( Continue with Google ); }; export default GoogleLoginExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Component Behavior [#component-behavior] The component configures Google Sign-In on mount and remains disabled until `GoogleSignin.configure()` succeeds. If configuration throws, the button stays disabled for that mount and does not call `onError`; validate the client IDs before rendering it. ## On the web [#on-the-web] On React Native Web the button signs in through a redirect to Google and back, using `googleWebClientId` and `googleRedirectUri` (default `/oauth/google.html`). `googleIosClientId` is ignored, and nothing from `@react-native-google-signin/google-signin` is loaded. The app serves the return page, which the SDK exports as `GOOGLE_RETURN_PAGE_HTML`; see [Sign in on the web](/native-sdk/guide/components/auth/sign-in/social-logins/#sign-in-on-the-web). ## Styling [#styling] ### Theme Variables Used [#theme-variables-used] - `theme.spacing(2)` - Gap spacing between icon and text elements - `theme.spacing(2)` - Vertical padding for button - Dynamic background/border colors based on theme.dark property ## Child Components [#child-components] - **SignIn.SocialLogins.GoogleLogin.Icon** - Google logo icon component - **SignIn.SocialLogins.GoogleLogin.Text** - Text component with typography variant support ## Related Components [#related-components] - [SignIn.SocialLogins](/native-sdk/guide/components/auth/sign-in/social-logins/) - Social logins container - [SignIn.SocialLogins.AppleLogin](/native-sdk/guide/components/auth/sign-in/social-logins/apple-login) - Apple authentication button # SignIn.SocialLogins Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/social-logins Container component that groups social login buttons with consistent horizontal layout and spacing. ## Provider requirement [#provider-requirement] The social-login buttons use the SDK theme for spacing, colors and typography. Render them inside the SDK `ThemeProvider` (usually imported as `ThemeProvider as OvokThemeProvider`) and the `OvokProvider` from `@ovok/core/next/react`, as shown in the installation guide. A cancelled Apple prompt is treated as a cancellation and does not call `onError`; successful login sessions retain both the FHIR reference and its display value. ## Prerequisites [#prerequisites] Before using social login components, you need to complete the following setup steps: ### Google Login Setup [#google-login-setup] 1. **Get Google Credentials**: Obtain your Google client ID and iOS URL scheme from [Google Cloud Console](https://console.cloud.google.com/). For further information please follow [this guide](https://react-native-google-signin.github.io/docs/setting-up/get-config-file?firebase-or-not=cloud-console#ios) 2. **Configure App**: Update your `app.config.js` or `app.json` with the Google Sign-In plugin: ```javascript // app.config.js export default { expo: { plugins: [ [ "@react-native-google-signin/google-signin", { iosUrlScheme: "com.googleusercontent.apps.YOUR_CLIENT_ID", }, ], ], }, }; ``` For detailed Google Sign-In configuration, see the [Installation Guide](/native-sdk/guide/how-to/installation). ### Apple Login Setup [#apple-login-setup] Apple authentication requires the Apple authentication plugin and a native rebuild. See the [Installation Guide](/native-sdk/guide/how-to/installation). ### Ovok Dashboard Configuration [#ovok-dashboard-configuration] Both Google and Apple login methods require configuration in the [Ovok Dashboard](https://dashboard.ovok.com/): 1. **Navigate** to the Ovok Dashboard 2. **Update or Create** a ClientApplication with the following extension configuration: ```json { "extension": [ { "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-internal-id", "valueString": "google-web-app-id", "extension": [ { "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-client-id", "valueString": "605727522930-c06g9o9f4t906fqt9bkg6sncdn4lb504.apps.googleusercontent.com" }, { "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-provider-type", "valueString": "google" } ] } ] } ``` **Configuration Values:** - **`external-auth-internal-id`**: Custom identifier for matching (use this value in the `internalId` prop) - **`external-auth-client-id`**: - For Google: Your Google client ID from Google Cloud Console - For Apple: Your app's bundle identifier, or the Services ID for the web entry - **`external-auth-provider-type`**: Set to `"google"` or `"apple"` ### Native client configuration [#native-client-configuration] After configuring the ClientApplication in the Ovok Dashboard, pass its ID as `clientId` to the native client: ```tsx // app/_layout.tsx import { Ovok } from "@ovok/native/next"; import * as SecureStore from "expo-secure-store"; const ovokClient = new Ovok({ baseUrl: "https://api.example.com", tenantCode: "your-tenant", secureStore: SecureStore, clientId: "YOUR_CLIENT_APPLICATION_ID", }); ``` **Important:** Replace `YOUR_CLIENT_APPLICATION_ID` with the actual ClientApplication ID from your Ovok Dashboard configuration. ## Sign in on the web [#sign-in-on-the-web] On React Native Web the same buttons work with no extra setup in the bundle. The SDK ships web versions of `GoogleLogin` and `AppleLogin` (`.web` platform files), so a web bundle never loads `@react-native-google-signin/google-signin` or `expo-apple-authentication`. The buttons look and compose as on a phone; the web needs these props in addition: | Button | Web prop | Meaning | | --- | --- | --- | | `GoogleLogin` | `googleWebClientId` | The Google **Web application** client ID. `googleIosClientId` is ignored. | | `GoogleLogin` | `googleRedirectUri` | Optional. The page Google returns to; defaults to `/oauth/google.html` on your site. | | `AppleLogin` | `appleServicesId` | The Apple **Services ID**. Without it the button renders nothing on the web. | | `AppleLogin` | `appleRedirectUri` | Optional. A Return URL of the Services ID; defaults to your site's origin. | ### Google on the web [#google-on-the-web] Google signs the user in with an OpenID Connect redirect in the same tab: the page goes to Google, Google returns to a static page of yours, and that page sends the tab back to the sign-in screen. Keep `GoogleLogin` on that screen: when it mounts, it takes Google's answer, checks that it answers this tab's own request, and signs in. **1. Authorize the redirect URI.** In the [Google Cloud Console](https://console.cloud.google.com/), open the OAuth client of type **Web application** and add the return page to **Authorized redirect URIs**, for example `https://app.example.com/oauth/google.html` (and `http://localhost:8081/oauth/google.html` for local development). **2. Serve the return page as a static file.** The SDK exports its HTML as `GOOGLE_RETURN_PAGE_HTML`, and `@ovok/native/auth/google-return-page` loads in plain Node, so a build step can write it into the folder your app serves, such as Expo's `public/`: ```js // scripts/write-google-return-page.cjs const { mkdirSync, writeFileSync } = require("node:fs"); const { GOOGLE_RETURN_PAGE_HTML } = require("@ovok/native/auth/google-return-page"); mkdirSync("public/oauth", { recursive: true }); writeFileSync("public/oauth/google.html", GOOGLE_RETURN_PAGE_HTML); ``` Run it before the web build, for example as `"prebuild:web": "node scripts/write-google-return-page.cjs"`. To serve the page somewhere else, register that URL and pass it as `googleRedirectUri`. **3. Point Ovok at the Web client.** The `external-auth-client-id` of the Google entry is the Web client ID, and its `external-auth-internal-id` is the `internalId` you pass to `GoogleLogin`. The page keeps Google's answer in the tab's `sessionStorage` and replaces itself with the screen the user left, so the ID token never stays in the address bar or the history. The button accepts the answer only when its `state` and its token's `nonce` match the request this tab made, and it clears both from storage either way. ### Apple on the web [#apple-on-the-web] Apple signs the user in with Sign in with Apple JS in a popup. The button loads Apple's script when it mounts, so the popup opens straight from the tap. **1. Create a Services ID.** In the [Apple Developer account](https://developer.apple.com/account/resources/identifiers/list/serviceId), create a **Services ID** and enable Sign in with Apple for it. Under **Configure**, choose the primary App ID and add your domain and the Return URL, for example `app.example.com` and `https://app.example.com`. The Return URL is `appleRedirectUri`, which defaults to the site's origin. Apple does not accept `localhost`, so test on an HTTPS domain registered for the Services ID. **2. Add a separate Ovok entry for the Services ID.** Apple's web tokens have the Services ID as their audience, while the iOS app's tokens have its bundle ID, so one entry cannot verify both. Add the entry to the ClientApplication's `extension` array, and pass its `internalId` to `AppleLogin` on the web: ```json { "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-internal-id", "valueString": "apple-web", "extension": [ { "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-client-id", "valueString": "com.example.web" }, { "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-provider-type", "valueString": "apple" } ] } ``` A closed popup and a declined authorization are cancellations and do not call `onError`. Apple sends the name and email only the first time a user signs in with your app. ### One screen for every platform [#one-screen-for-every-platform] ```tsx import { Platform } from "react-native"; ``` `useSocialSignIn` has no web flow and rejects on the web; render the buttons instead. ## Quick Example [#quick-example] ```tsx import { SignIn, useAppTheme } from "@ovok/native"; import React from "react"; import { Alert, StyleSheet } from "react-native"; // Static styles outside component const styles = StyleSheet.create({ socialContainer: { alignItems: "center", }, }); const SocialLoginSection = () => { const theme = useAppTheme(); const handleSuccess = () => Alert.alert("Signed in"); const handleError = (error: Error) => Alert.alert("Sign-in failed", error.message); return ( Continue with Google Continue with Apple ); }; export default SocialLoginSection; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Component Behavior [#component-behavior] The component uses horizontal layout with `flexDirection: "row"`, `justifyContent: "center"`, and `flexWrap: "wrap"` to center social login buttons and allow wrapping on smaller screens. ## Styling [#styling] ### Theme Variables Used [#theme-variables-used] - `theme.spacing(6)` - Gap spacing between child components used by default ## Child Components [#child-components] - [SignIn.SocialLogins.GoogleLogin](/native-sdk/guide/components/auth/sign-in/social-logins/google-login) - Google authentication button - [SignIn.SocialLogins.AppleLogin](/native-sdk/guide/components/auth/sign-in/social-logins/apple-login) - Apple authentication button ## Related Components [#related-components] - [SignIn](/native-sdk/guide/components/auth/sign-in/) - Main sign-in component container - [SignIn.LoginWithSeparator](/native-sdk/guide/components/auth/sign-in/social-logins/login-with-separator) - Visual separator component # SignIn.LoginWithSeparator Canonical page: https://docs.ovok.com/native-sdk/guide/components/auth/sign-in/social-logins/login-with-separator Visual separator component that divides email login from social login options with localized separator text. ## Quick Example [#quick-example] ```tsx import { SignIn, useAppTheme } from "@ovok/native"; import React from "react"; const SeparatorExample = () => { const theme = useAppTheme(); return ( ); }; export default SeparatorExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/auth` API reference](/native-sdk/reference/auth). ## Localization [#localization] The component uses this translation key: ```json { "sign-in": { "or-login-with": "Or sign in with" } } ``` - `sign-in.or-login-with` - Separator text displayed between email form and social logins ## Component Behavior [#component-behavior] The component renders a horizontal layout with two flex lines and centered text, using theme spacing for consistent gap between elements. ## Styling [#styling] ### Theme Variables Used [#theme-variables-used] - `theme.spacing(4)` - Gap spacing between separator elements - `theme.colors.onSurfaceDisabled` - Default text color - `theme.colors.outlineVariant` - Default line color ## Related Components [#related-components] - [SignIn](/native-sdk/guide/components/auth/sign-in/) - Main sign-in component container - [SignIn.SocialLogins](/native-sdk/guide/components/auth/sign-in/social-logins/) - Social logins container # Background sync APIs Canonical page: https://docs.ovok.com/native-sdk/guide/components/background-sync The `@ovok/native/background-sync` subpath exports Android background controls, Health Connect headless task helpers, background-safe client storage, and local notification helpers. Import from this subpath so an app can use these APIs without loading the package's root UI barrel. ~~~ts import { registerAndroidHealthConnectBackgroundTask, runAndroidHealthConnectSync, scheduleAndroidHealthConnectSync, } from "@ovok/native/background-sync"; ~~~ The full end-to-end setup, native configuration, and delivery behavior are in the [background sync guide](/native-sdk/guide/modules/background-sync). ## Android Bluetooth foreground service [#android-bluetooth-foreground-service] `AndroidBluetoothForegroundService` is a React wrapper for apps that own the BLE manager and scan lifecycle outside `BTProvider`: ~~~tsx import { AndroidBluetoothForegroundService } from "@ovok/native/background-sync"; reportBluetoothError(error)} > ; ~~~ | Prop | Type | Description | | --- | --- | --- | | `enabled` | `boolean` | Starts the Android service while true; stops it on false or unmount. | | `options` | `AndroidBluetoothForegroundServiceOptions` | Optional notification title/body and battery-optimization request. | | `onError` | `(event: ErrorCallback) => void` | Receives service or permission request failures. | | `children` | `ReactNode` | Content rendered inside the wrapper. | This component is an alternative to the provider-managed foreground service. Do not mount it for a scan already owned by `BTProvider.backgroundSync`; there should be one service owner per scan. On non-Android platforms the wrapper renders its children and does not start a native service. The module also exports `startAndroidBluetoothForegroundService` and `stopAndroidBluetoothForegroundService` for imperative lifecycle control. These functions are Android-only and are no-ops on other platforms. ## Android Health Connect headless work [#android-health-connect-headless-work] | API | Purpose | | --- | --- | | `registerAndroidHealthConnectBackgroundTask(task, taskName?)` | Register the JS entry point at app startup. The default task name is `ANDROID_HEALTH_CONNECT_BACKGROUND_TASK`. | | `runAndroidHealthConnectSync(options)` | Run one import without mounting `AndroidHealthSync`. Requires a restored `client`, `patientId`, and `dataToSync` mapping. | | `scheduleAndroidHealthConnectSync(options?)` | Schedule periodic WorkManager work. `intervalMinutes` defaults to 15 and values below 15 are raised to 15. | | `cancelAndroidHealthConnectSync()` | Cancel scheduled periodic work. | | `ANDROID_HEALTH_CONNECT_BACKGROUND_TASK` | Default task name: `OvokHealthConnectBackgroundSync`. | The registered callback receives `{ reason?: string }`. If scheduling uses a custom `taskName`, registration must use the same value. Calls are no-ops on non-Android platforms. WorkManager may defer execution and requires network connectivity. `AndroidHealthConnectBackgroundSyncOptions` contains `intervalMinutes`, `taskName`, `notificationTitle`, and `notificationBody`. `AndroidHealthConnectSyncRunOptions` contains `client`, `patientId`, `dataToSync`, and optional `chunkSize`, `onError`, and `onProgress`. These types are exported from this subpath. Use [`AndroidHealthSync`](/native-sdk/guide/components/data-sync/android/health-sync/) for a foreground React import, and the [Health Connect authorization provider](/native-sdk/guide/components/data-sync/android/health-connect-authorization-provider/) to request foreground and optional background-read access. ## Battery optimization helpers [#battery-optimization-helpers] | API | Purpose | | --- | --- | | `isAndroidBatteryOptimizationIgnored()` | Read whether Android currently exempts the app from Doze optimizations. | | `requestAndroidBatteryOptimizationExemption()` | Open Android's consent/settings flow when it can be shown. The result can be `false` while consent is pending or has not been granted; re-check after the app resumes. | The request is explicit opt-in and does not grant an exemption itself. The helper returns `true` on non-Android platforms. ## Background-safe client storage [#background-safe-client-storage] `createBackgroundSafeClientStorage` adapts a SecureStore-compatible implementation for hosts still using that standalone storage adapter. The native next `Ovok` client accepts `secureStore` directly and uses `SecureStoreStorage` for its session and account-scoped health cursors: ~~~ts import { Ovok } from "@ovok/native/next"; import * as SecureStore from "expo-secure-store"; const client = new Ovok({ baseUrl: "https://api.example.com", tenantCode: "your-tenant", secureStore: SecureStore, secureStoreOptions: { keychainAccessible: SecureStore.AFTER_FIRST_UNLOCK }, }); ~~~ The legacy adapter remains available when an app explicitly needs its indexed storage API: ~~~ts const storage = createBackgroundSafeClientStorage({ secureStore, keychainService: "com.example.app", keychainAccessible: SecureStore.AFTER_FIRST_UNLOCK, }); ~~~ `BackgroundSafeSecureStore` requires `getItemAsync` and `setItemAsync`, with optional `deleteItemAsync`. The returned `BackgroundSafeClientStorage` exposes `getItem`, `setItem`, `removeItem`, `clear`, and `reload`. `reload` re-reads the adapter's key index after the device is unlocked. A protected read failure returns `null` without deleting the stored value; retry after the OS makes the keychain available. The adapter does not choose an app key, own credentials, or restore an authenticated client. The host app remains responsible for that work in the Health Connect headless task. ## Local notifications [#local-notifications] The subpath exports `getPushNotificationPermission`, `requestPushNotificationPermission`, and `showPushNotification`. They load the optional `expo-notifications` peer only when called. Permission status is `"granted"`, `"denied"`, or `"undetermined"`. Request permission in the foreground. `showPushNotification` schedules an immediate local notification. It does not create remote push tokens or schedule background execution. BLE queue notifications can instead be configured through `BTProvider.backgroundSync.notifications`; see the [background sync guide](/native-sdk/guide/modules/background-sync). ## Related component references [#related-component-references] - [`BTProvider.backgroundSync`](/native-sdk/guide/components/bt-management/bt-provider/) — durable BLE result queue and scan integration. - [`BackgroundSyncSetting`](/native-sdk/guide/components/ui/background-sync-setting) — UI toggle for background scan state. - [`AndroidHealthSync`](/native-sdk/guide/components/data-sync/android/health-sync/) — foreground Health Connect import. - [`AppleHealthSync`](/native-sdk/guide/components/data-sync/apple/health-sync/) — HealthKit observer delivery. # BreathingExerciseProvider Canonical page: https://docs.ovok.com/native-sdk/guide/components/breathing-exercise/breathing-exercise-provider `BreathingExerciseProvider` owns the Reanimated timeline and exposes it through `useBreathingExercise`. It accepts the same `methods`, `repeat`, and `onFinish` configuration as `BreathingExercise`, plus optional children. ```tsx import { BreathingExerciseProvider, useBreathingExercise } from "@ovok/native/breathing-exercise"; function CustomControls() { const { methodType, remainingTime } = useBreathingExercise(); return {methodType}: {Math.ceil(remainingTime)}; } ; ``` The provider calculates the round duration, animates overall progress from `0` to `1` with linear timing, derives the current phase and remaining time, and calls `onFinish` when complete. It does not pause, seek, restart, persist, or expose a ref-based control API. Mounting a new provider starts a new timeline. `methods` must be the fixed inhale/hold/exhale tuple. `onFinish` is invoked from a Reanimated worklet when progress reaches `1`; it is not automatically marshalled to the JavaScript thread. Wrap JavaScript-only work such as navigation in `runOnJS`, and make the callback safe to invoke once per completed mount. # BreathingExercise Component Canonical page: https://docs.ovok.com/native-sdk/guide/components/breathing-exercise/breathing-exercise The `BreathingExercise` component is the main compound component that provides a complete guided breathing exercise experience. It serves as both a container and a context provider, offering flexible composition through its sub-components. ## Overview [#overview] `BreathingExercise` is designed as a compound component that wraps its children with `BreathingExerciseProvider` to provide breathing exercise state and functionality. It exposes various sub-components as static properties, allowing for flexible UI composition while maintaining a cohesive breathing exercise experience. ## Features [#features] - **🧩 Compound Component Architecture**: Flexible composition with sub-components - **🎯 Context Provider Integration**: Automatic state management setup - **📊 Real-time Progress Tracking**: Live progress and timing updates - **🎨 Synchronized Animation**: Lottie animation tied to breathing phases - **🔄 Configurable Patterns**: Custom inhale-hold-exhale sequences - **Accessibility boundary**: The component accepts host-provided accessibility props; add labels, live-region announcements, and any keyboard behavior in the app - **🎭 Theming Integration**: React Native Paper theme support - **⚡ Performance Optimized**: React Native Reanimated integration ## API Reference [#api-reference] ### Props [#props] ```tsx interface BreathingExerciseProps extends ViewProps { methods: BreathingPattern; repeat: number; onFinish?: () => void; } type BreathingPattern = [ { type: "inhale"; duration: number }, { type: "hold"; duration: number }, { type: "exhale"; duration: number }, ]; ``` | Prop | Type | Required | Description | | -------------- | ------------------ | -------- | ----------------------------------------------- | | `methods` | `BreathingPattern` | ✅ | Array defining the breathing sequence | | `repeat` | `number` | ✅ | Number of times to repeat the breathing pattern | | `onFinish` | `() => void` | ❌ | Callback when exercise completes | | `style` | `ViewStyle` | ❌ | Custom styling for the container | | `...viewProps` | `ViewProps` | ❌ | Standard React Native View props | ## Sub-Components [#sub-components] The `BreathingExercise` component provides the following sub-components as static properties: ### Display Components [#display-components] - **`ProgressBar`**: Visual progress indicator for the entire exercise - **`MethodName`**: Text display for the current breathing phase name - **`RemainingTime`**: Countdown timer for the current phase - **`MethodTypeIcon`**: Icon representing the current breathing phase ### Layout Components [#layout-components] - **`AnimationWrapper`**: Container for the breathing animation - **`Animation`**: Lottie animation synchronized with breathing phases - **`Info`**: Container for information display elements ## Basic Usage [#basic-usage] ### Simple Breathing Exercise [#simple-breathing-exercise] ```tsx import { BreathingExercise } from "@ovok/native/breathing-exercise"; export const SimpleBreathingSession = () => { return ( console.log("Exercise completed!")} > ); }; ``` ### Minimal Setup [#minimal-setup] ```tsx export const MinimalBreathingExercise = () => ( ); ``` ## Advanced Usage [#advanced-usage] ### Custom Layout with Styling [#custom-layout-with-styling] ```tsx import { StyleSheet, View } from "react-native"; import { BreathingExercise } from "@ovok/native/breathing-exercise"; export const CustomBreathingLayout = () => { const handleCompletion = () => { // Navigate to success screen // Log analytics // Show completion message }; return ( {/* Header with progress */} {/* Main animation area */} {/* Bottom info panel */} ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#f5f5f5", }, header: { paddingHorizontal: 24, paddingVertical: 16, }, progressBar: { height: 8, borderRadius: 4, }, animationContainer: { flex: 1, justifyContent: "center", alignItems: "center", paddingHorizontal: 32, }, animation: { width: 300, height: 300, }, infoPanel: { alignItems: "center", paddingHorizontal: 24, paddingVertical: 32, backgroundColor: "white", borderTopLeftRadius: 24, borderTopRightRadius: 24, gap: 20, }, iconRow: { marginBottom: 8, }, textContainer: { alignItems: "center", gap: 8, }, methodText: { fontWeight: "600", textAlign: "center", }, timeText: { opacity: 0.7, textAlign: "center", }, }); ``` ### Responsive Design [#responsive-design] ```tsx import { useWindowDimensions } from "react-native"; export const ResponsiveBreathingExercise = () => { const { width, height } = useWindowDimensions(); const isLandscape = width > height; const isTablet = width > 768; return ( ); }; ``` ### Integration with State Management [#integration-with-state-management] ```tsx import { useAppContext } from "../context/app-context"; export const ConnectedBreathingExercise = () => { const { breathingSettings, updateUserStats, saveExerciseSession } = useAppContext(); const handleFinish = React.useCallback(async () => { const session = { pattern: breathingSettings.preferredPattern, duration: breathingSettings.sessionDuration, completedAt: new Date(), }; await saveExerciseSession(session); updateUserStats({ sessionsCompleted: (prev) => prev + 1, }); }, [breathingSettings, updateUserStats, saveExerciseSession]); return ( {/* Components */} ); }; ``` ## Sub-Component Details [#sub-component-details] ### ProgressBar [#progressbar] Visual progress indicator showing exercise completion. ```tsx ``` ### Animation & AnimationWrapper [#animation--animationwrapper] Lottie animation synchronized with breathing phases. ```tsx ``` ### MethodTypeIcon [#methodtypeicon] Icon representing the current breathing phase. ```tsx ``` ### MethodName [#methodname] Displays the translated name of the current breathing phase. ```tsx ``` ### RemainingTime [#remainingtime] Shows countdown for the current breathing phase. ```tsx ``` ### Info [#info] Container component for grouping information elements. ```tsx {/* Information components */} ``` ## Styling [#styling] ### Theme Integration [#theme-integration] ```tsx import { useAppTheme } from "@ovok/native"; const ThemedBreathingExercise = () => { const theme = useAppTheme(); return ( ); }; ``` ### Custom Styling [#custom-styling] ```tsx const customStyles = StyleSheet.create({ container: { flex: 1, padding: 20, backgroundColor: "#f8f9fa", }, progressBar: { height: 6, backgroundColor: "#e9ecef", borderRadius: 3, }, animation: { width: 280, height: 280, }, info: { alignItems: "center", gap: 16, padding: 24, backgroundColor: "white", borderRadius: 16, shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 8, elevation: 4, }, }); ``` ## Accessibility [#accessibility] The component does not add the semantics below automatically. Apply the props to the root and child components in the integrating app, and verify announcements with the screen readers and input methods your app supports. ### Screen Reader Support [#screen-reader-support] ```tsx ``` ### Keyboard Navigation [#keyboard-navigation] React Native `View` does not provide keyboard navigation by itself. The example below shows host-side focus callbacks only; implement focus order and actions in the app if a keyboard or switch-access experience is required. ```tsx console.log("Exercise focused")} onBlur={() => console.log("Exercise unfocused")} > {/* Components */} ``` ## Performance [#performance] ### Optimization Tips [#optimization-tips] ```tsx // ✅ Good: Memoize breathing patterns const breathingPattern = React.useMemo( () => [ { type: "inhale", duration: 4 }, { type: "hold", duration: 4 }, { type: "exhale", duration: 4 }, ], [], ); // ✅ Good: Memoize completion callback const handleFinish = React.useCallback(() => { // Handle completion }, []); // ✅ Good: Use stable style objects const containerStyle = React.useMemo( () => ({ flex: 1, backgroundColor: "#f5f5f5", }), [], ); ``` ### Performance Monitoring [#performance-monitoring] ```tsx import { startTransition } from "react"; const PerformantBreathingExercise = () => { const [stats, setStats] = React.useState(null); const handleFinish = React.useCallback(() => { startTransition(() => { setStats({ completedAt: Date.now() }); }); }, []); return ; }; ``` ## Testing [#testing] ### Component Testing [#component-testing] ```tsx import { render, screen } from "@testing-library/react-native"; import { BreathingExercise } from "@ovok/native/breathing-exercise"; describe("BreathingExercise", () => { const defaultProps = { methods: [ { type: "inhale", duration: 4 }, { type: "hold", duration: 4 }, { type: "exhale", duration: 4 }, ], repeat: 1, }; it("renders correctly", () => { render( , ); expect(screen.getByRole("timer")).toBeOnTheScreen(); }); it("displays initial method", () => { render( , ); expect(screen.getByText(/inhale/i)).toBeOnTheScreen(); }); it("calls onFinish when complete", () => { const onFinish = jest.fn(); render( , ); // Test completion logic }); }); ``` ### Integration Testing [#integration-testing] ```tsx describe("BreathingExercise Integration", () => { it("integrates with provider correctly", () => { const TestComponent = () => { const { progress, methodType } = useBreathingExercise(); return ( {progress.value} {methodType} ); }; render( , ); expect(screen.getByTestId("progress")).toBeOnTheScreen(); expect(screen.getByTestId("method")).toBeOnTheScreen(); }); }); ``` ## Common Patterns [#common-patterns] ### Session Management [#session-management] ```tsx const useBreathingSession = (pattern, cycles) => { const [isActive, setIsActive] = React.useState(false); const [currentSession, setCurrentSession] = React.useState(null); const startSession = React.useCallback(() => { setCurrentSession({ startTime: Date.now(), pattern, cycles, }); setIsActive(true); }, [pattern, cycles]); const endSession = React.useCallback(() => { setIsActive(false); if (currentSession) { const duration = Date.now() - currentSession.startTime; // Save session data } setCurrentSession(null); }, [currentSession]); return { isActive, startSession, endSession }; }; ``` ### Error Boundaries [#error-boundaries] ```tsx class BreathingExerciseErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, errorInfo) { console.error("BreathingExercise error:", error, errorInfo); } render() { if (this.state.hasError) { return ; } return this.props.children; } } ``` ## Best Practices [#best-practices] ### 1. Configuration Management [#1-configuration-management] ```tsx // ✅ Good: Define patterns as constants const BREATHING_PATTERNS = { BEGINNER: [ { type: "inhale", duration: 3 }, { type: "hold", duration: 2 }, { type: "exhale", duration: 4 }, ], INTERMEDIATE: [ { type: "inhale", duration: 4 }, { type: "hold", duration: 4 }, { type: "exhale", duration: 6 }, ], ADVANCED: [ { type: "inhale", duration: 4 }, { type: "hold", duration: 7 }, { type: "exhale", duration: 8 }, ], } as const; ``` ### 2. Error Handling [#2-error-handling] ```tsx const SafeBreathingExercise = (props) => { const [error, setError] = React.useState(null); const handleError = React.useCallback((error) => { setError(error); console.error("Breathing exercise error:", error); }, []); if (error) { return setError(null)} />; } return ( ); }; ``` ### 3. Lifecycle Management [#3-lifecycle-management] ```tsx const ManagedBreathingExercise = (props) => { const [isActive, setIsActive] = React.useState(false); React.useEffect(() => { // Cleanup on unmount return () => { setIsActive(false); }; }, []); const handleFinish = React.useCallback(() => { setIsActive(false); props.onFinish?.(); }, [props.onFinish]); return ; }; ``` --- The `BreathingExercise` component provides a comprehensive foundation for building guided breathing experiences with maximum flexibility and minimal complexity. Its compound component architecture ensures both ease of use and extensive customization capabilities. # Breathing Exercise Canonical page: https://docs.ovok.com/native-sdk/guide/components/breathing-exercise The breathing module provides a fixed three-phase timeline driven by React Native Reanimated. The UI is composable, but the SDK owns the timer and the bundled Lottie animation. ```tsx import { BreathingExercise } from "@ovok/native/breathing-exercise"; onFinished()} > ; ``` ## Configuration [#configuration] `methods` is a three-item tuple in the order `inhale`, `hold`, `exhale`. Each duration is in seconds. `repeat` is the number of complete rounds. `onFinish` is called when the Reanimated progress reaches `1` from the animation worklet; it is not wrapped in `runOnJS`. Use `runOnJS` inside the worklet-facing callback for JavaScript-only effects such as navigation. The root also accepts React Native `ViewProps`. Children are optional in the type, so the component can be used as a provider/container for a custom consumer tree. ## Compound components [#compound-components] - `ProgressBar`: consumes the exercise progress and forwards the remaining progress-bar props except `progress`. - `AnimationWrapper`: a `View` container. `MethodTypeIcon` is positioned over this wrapper, so render it there when using the bundled layout. - `Animation`: an animated `lottie-react-native` view using the SDK's bundled breathing animation. `source`, `animatedProps`, and `autoPlay` are controlled by the SDK; the public type omits `source`. - `Info`: a `View` with a maximum height of 30% of the current window height. - `MethodTypeIcon`: renders the inhale, hold, or exhale icon for the current phase. Its icon color is currently fixed to black; it has no color prop. - `MethodName`: localized with `breathing-exercise.method.` and styled as a bold 20px label. - `RemainingTime`: displays the current phase's remaining time and is styled as a bold 20px label. All phase text and accessibility labels are caller-owned except for the `MethodName` translation lookup. Add your own translations for the supported languages. ## Direct provider usage [#direct-provider-usage] Use `BreathingExerciseProvider` when you need the timing context without the compound root's `View`. Use `useBreathingExercise` only below that provider. # Breathing Exercise Types Canonical page: https://docs.ovok.com/native-sdk/guide/components/breathing-exercise/types The public barrel explicitly exports `BreathingExerciseContextType`. The component props and animation prop shapes are used to type the exported components but are not separate named exports from the module. The configuration type is also internal. ## Configuration shape [#configuration-shape] ```ts type BreathingPattern = [ { type: "inhale"; duration: number }, { type: "hold"; duration: number }, { type: "exhale"; duration: number }, ]; type BreathingExercise = { methods: BreathingPattern; repeat: number; onFinish?: () => void; }; ``` The tuple is exactly three phases. Durations and repeat counts are numbers; the implementation does not document additional runtime validation, so validate user-provided values in the integrating app. ## Component props [#component-props] `BreathingExerciseProps` is `ViewProps & BreathingExercise`. `BreathingExerciseAnimationProps` is `Omit`; the component always supplies its bundled source and animated progress. ## Context value [#context-value] `BreathingExerciseContextType` contains the configuration and live state: ```ts type BreathingExerciseContextType = BreathingExercise & { progress: SharedValue; roundData: SharedValue<{ method: BreathingExercise["methods"][number]; animationProgress: number; remainingTime: number; }>; remainingTime: number; methodType: BreathingExercise["methods"][number]["type"]; }; ``` `progress` and `roundData` are Reanimated shared values. Read them inside worklets for animated styles; use the React `remainingTime` and `methodType` values for ordinary text rendering. # useBreathingExercise Canonical page: https://docs.ovok.com/native-sdk/guide/components/breathing-exercise/use-breathing-exercise `useBreathingExercise()` reads the nearest `BreathingExerciseProvider` context. ```tsx const { methodType, remainingTime, progress, roundData } = useBreathingExercise(); ``` It returns `BreathingExerciseContextType`: - `methods`, `repeat`, and `onFinish`: the active configuration. - `progress`: a Reanimated `SharedValue` from `0` to `1`. - `roundData`: a Reanimated shared value containing `method`, `animationProgress`, and phase `remainingTime`. - `remainingTime`: the current phase's time remaining as React state, rounded up by the provider's reaction. - `methodType`: `"inhale"`, `"hold"`, or `"exhale"` for the current phase. Use shared values inside Reanimated worklets. For normal React rendering, use `methodType` and `remainingTime` rather than reading `.value` during render. The hook throws `useBreathingExercise must be used within a BreathingExercise component` when called outside the provider. The `BreathingExercise` compound component mounts the provider automatically; `BreathingExerciseProvider` is available for a custom consumer tree. # Bluetooth device instructions Canonical page: https://docs.ovok.com/native-sdk/guide/components/bt-device-instructions `@ovok/native/bt-device-instructions` exports `BTDeviceInstruction`, its prop type, and the `DEVICE_INSTRUCTION_PDFS` mapping. The component chooses a manual from the integrated device enum and delegates rendering to `PDFViewer`. ~~~tsx import { BTDeviceInstruction } from "@ovok/native/bt-device-instructions"; import { IntegratedDevices } from "@ovok/native/bt-management"; ; ~~~ The mapping is maintained by the SDK and is not an app-configurable URL base. Some devices currently have no manual URL; handle `onError` and provide a fallback in the app. See [BTDeviceInstruction](/native-sdk/guide/components/bt-device/bt-device-instruction/) for props and [PDFViewer](/native-sdk/guide/components/pdf/) for displaying arbitrary documents. # BTDeviceInstruction Canonical page: https://docs.ovok.com/native-sdk/guide/components/bt-device/bt-device-instruction `BTDeviceInstruction` resolves an integrated device's manual from `DEVICE_INSTRUCTION_PDFS` and renders it through `PDFViewer`. Import it from `@ovok/native/bt-device-instructions`. ~~~tsx import { BTDeviceInstruction } from "@ovok/native/bt-device-instructions"; import { IntegratedDevices } from "@ovok/native/bt-management"; reportManualError(error)} />; ~~~ ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/bt-device` API reference](/native-sdk/reference/bt-device). # BTDeviceItem Canonical page: https://docs.ovok.com/native-sdk/guide/components/bt-device/bt-device-item `BTDeviceItem` is a themed, pressable container with compound layout parts. `BTDeviceList` uses these parts for its default row; apps can compose them in custom lists. Import it from `@ovok/native/bt-device`. ~~~tsx import { BTDeviceItem } from "@ovok/native/bt-device"; import { DeviceStatus } from "@ovok/native/bt-management"; Blood pressure monitor Manufacturer Instructions ; ~~~ The compound parts are `TopContainer`, `Content`, `Title`, `SubTitle`, `Status`, `Image`, `Divider`, and `BottomContainer`. Their names are properties on `BTDeviceItem`; import the parent component rather than importing those implementation files directly. The root accepts React Native `TouchableOpacityProps` and children. It uses the active SDK app theme for surface, border, radius, shadow, and elevation. The parts provide the row structure; use normal React Native styles and accessibility props for product-specific behavior. See [BTDeviceList](/native-sdk/guide/components/bt-device/bt-device-list/) for the prebuilt list. # BTDeviceList Canonical page: https://docs.ovok.com/native-sdk/guide/components/bt-device/bt-device-list `BTDeviceList` renders the current list from `DeviceListProvider` as a FlashList. Each default row shows the translated title and subtitle, a status label, an image, and an Instructions label. Provide `itemProps.onPress` to wire row taps to your instructions screen; the component does not navigate by itself. Import it from `@ovok/native/bt-device`. ## Basic usage [#basic-usage] ~~~tsx import { BTDeviceList, DeviceListProvider, } from "@ovok/native/bt-device"; openInstructions(item.deviceType), }} /> ; ~~~ The component owns its data source from the device-list context; you do not pass a `data` prop. It forwards the other FlashList props and accepts an optional custom `renderItem`. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/bt-device` API reference](/native-sdk/reference/bt-device). # DeviceListProvider Canonical page: https://docs.ovok.com/native-sdk/guide/components/bt-device/device-list-provider `DeviceListProvider` provides the list state consumed by `BTDeviceList` and `useDeviceList`. It initializes the SDK's built-in device rows, including their display keys, image URIs, integrated device IDs, and disconnected statuses. Import it from `@ovok/native/bt-device`. ~~~tsx import { BTDeviceList, DeviceListProvider, } from "@ovok/native/bt-device"; ; ~~~ It accepts `children` and no other props. Wrap the list once in the part of the tree where its status state should live. Mounting `BTProvider` in the same context lets the SDK update matching row statuses when `onDeviceStatusChanged` fires. Use `useDeviceList` to read or update the list context in app components. Without this provider, the context defaults to an empty list and its setter is a no-op. See [BTDeviceList](/native-sdk/guide/components/bt-device/bt-device-list/) and [Bluetooth status callbacks](/native-sdk/guide/components/bt-management/bt-provider/on-device-status-changed). # Bluetooth device UI Canonical page: https://docs.ovok.com/native-sdk/guide/components/bt-device The `@ovok/native/bt-device` entry point exports a device-status list, its compound row component, a static supported-device list, and the context provider for list data. ## Choose a component [#choose-a-component] | Component | Use it when | | --- | --- | | [BTDeviceList](/native-sdk/guide/components/bt-device/bt-device-list/) | You want a ready-made list of device rows with status and an instructions affordance. | | [BTDeviceItem](/native-sdk/guide/components/bt-device/bt-device-item/) | You are building a row layout that follows the SDK's themed device card. | | [DeviceListProvider](/native-sdk/guide/components/bt-device/device-list-provider/) | You want to supply the list context and let Bluetooth status callbacks update matching rows. | | [SupportedDeviceList](/native-sdk/guide/components/bt-device/supported-device-list/) | You want the older static catalog list with artwork and image credits. | | [BTDeviceInstruction](/native-sdk/guide/components/bt-device/bt-device-instruction/) | You want to show an SDK-hosted manual for an integrated device. | For a richer, selectable catalog with measurement types, optional manual links, and ready-to-use accepted-device declarations, use [SupportedDevicesCatalogList](/native-sdk/guide/components/ui/supported-devices-catalog-list) from `@ovok/native/ui`. ## Data ownership [#data-ownership] `DeviceListProvider` seeds a list of SDK device rows. The list and provider are independent of BLE discovery: place `BTProvider` around the session as well when the app needs live device updates. Status changes are applied by matching a row's `deviceType` to the discovered device name. See the [Bluetooth guide](/native-sdk/guide/modules/bt-management) for a complete flow. # SupportedDeviceList Canonical page: https://docs.ovok.com/native-sdk/guide/components/bt-device/supported-device-list `SupportedDeviceList` renders the static `Devices` catalog as a React Native FlatList. Its default row uses `BTDeviceItem` to show a device name, manufacturer, image, and image credit. Import it from `@ovok/native/bt-device`. ~~~tsx import { SupportedDeviceList } from "@ovok/native/bt-device"; ; ~~~ It accepts FlatList props except `data` and `renderItem`; you may supply a custom `renderItem`. The component supplies the catalog data itself and applies spacing based on the SDK theme. This is a display catalog, not a pairing controller. For each device's ready-to-use declaration and measurement types, use `SUPPORTED_DEVICES` or the richer [SupportedDevicesCatalogList](/native-sdk/guide/components/ui/supported-devices-catalog-list). Check `acceptedDevices.length` before presenting a catalog row as connectable. # Advanced Bluetooth usage Canonical page: https://docs.ovok.com/native-sdk/guide/components/bt-management/advanced-usage Most apps should use `BTProvider`. Use `BTManager` directly only when the app needs to own permission handling, runtime context, scanning, and cleanup itself. ## Manage a session directly [#manage-a-session-directly] `BTManager` takes the app-owned `BleManager`, a stable accepted-device tuple, and optional manager options. The direct manager API does not request platform permissions or provide the React runtime hooks. ~~~tsx import { BleManager } from "react-native-ble-plx"; import { BTManager, IntegratedDevices, } from "@ovok/native/bt-management"; const bleManager = new BleManager(); const acceptedDevices = [IntegratedDevices.BP2] as const; const manager = new BTManager(bleManager, acceptedDevices, { autoConnect: true, autoConnectDelayMs: 700, oneReadingPerConnection: true, }); manager.onDeviceFound(async (device) => { await device.connect(); }); manager.onResult((result) => { saveMeasurement(result.id, result.data); }); manager.onError((failure) => reportBleError(failure)); manager.startScan(); // In the owning effect or service teardown: manager.destroy(); ~~~ Register handlers before starting discovery. The manager exposes callbacks for discovery, status, connection events, results, and errors. Its lifecycle controls include `startScan`, `pauseScan`, `resumeScan`, `setBackgroundScanEnabled`, `restoreDevices`, `keepConnecting`, `forget`, `stopScan`, and `destroy`. Use `pauseScan` and `resumeScan` for a temporary discovery pause; they preserve managed devices and callback registrations. `stopScan` removes callbacks, disconnects managed devices, and clears the device set. `destroy` additionally marks the manager unusable. Do not start or stop discovery directly through `BleManager` while the SDK manager owns the scan. ## What a connection does before the first command [#what-a-connection-does-before-the-first-command] Once a device is connected and its services are discovered, the SDK reads Device Information and the battery level, then subscribes to every declared characteristic. The first command is written only after the device reports notifications or indications as enabled on each of them, so a device that answers a control-point write with nothing until indications are on receives its command in the right order. Where the platform cannot read that setting, the SDK waits a short fixed time instead. When a read, a subscription or the first command fails because the device needs pairing, the SDK keeps the link, emits a `pairing` connection event with `pairingCodeRequired` set, and tries the step again while the user finishes the system pairing dialog, for up to 30 seconds. If the link drops or the time runs out, the step is abandoned and the connection carries on without it. A declared device that has no clock protocol of its own (`clockSync` is `unknown`, as for the Bluetooth SIG profiles) and exposes a writable Current Time characteristic (service `0x1805`, characteristic `0x2A2B`) gets the phone's time written on connect, with a `clock-synchronized` connection event. This follows `BTProvider`'s `clockSync` option: `enabled: false` leaves the device clock alone, `timezone` picks the local or UTC time, and `now` supplies the time. A device whose clock cannot be written keeps its own time. ## React runtime hooks [#react-runtime-hooks] The runtime hooks below require `BTProvider`, except for the two state and permission hooks. | Hook | Behavior | | --- | --- | | `useNearbyDevices()` | Returns discovered runtime devices and `pair(id)`, which connects the matching device. | | `usePairedDevices({ storage, storageKey?, autoPair? })` | Stores remembered peripheral IDs with app-provided async storage. With `autoPair`, connects a remembered device when it is discovered. | | `useDeviceConnection(id)` | Returns the current status and the most recent connection events for that device. | | `useMeasurements(onResult?, options?)` | Collects a bounded in-memory list of results, deduplicated by stable result ID. | | `useScanControl()` | Exposes pause and resume controls for the provider's manager. | | `useRuntimeEvent(event, callback)` | Subscribes to a runtime event; earlier events are not replayed. | | `useBluetoothState({ bleManager?, requestPermission? })` | Observes radio state and exposes a permission request function. | | `useRequestPermissions({ onAccessPermissionChanged? })` | Requests platform Bluetooth permission and returns the current access result. | `useMeasurements` supports `all`, `first-reading-per-kind-per-connection`, and `daily-totals-only`. The first-reading policy resets when the runtime receives a bond event. Daily totals are deduplicated by measurement type and UTC calendar day using the measurement's end, start, or recorded-at time. The list defaults to the latest 100 accepted results; call `clear()` to reset its local state. `useBackgroundSync` exposes a UI setting with `on`, `off`, `restricted`, and `blocked` states. It toggles the manager's background-scan flag and calls the optional app callback. It does not persist the preference or replace the durable queue configured through `BTProvider.backgroundSync`. Keep the provider prop and the UI setting connected to the same app state. `useHealthImport` is an adapter-driven health-store hook, not a BLE permission helper. Its adapter reports authorization per type and requests the selected set. Keep its `types` array and adapter identity stable so configuration changes do not trigger repeated refreshes. ## Compose the runtime manually [#compose-the-runtime-manually] `createBluetoothRuntime` and `BluetoothRuntimeProvider` are exported for advanced composition. The runtime provider supplies context only; it does not create a manager, request permissions, scan, forward events, or clean up devices. See [BluetoothRuntimeProvider](/native-sdk/guide/components/bt-management/runtime-provider/) and prefer the provider's callbacks for ordinary app integration. Runtime events are `deviceFound`, `pairedDevices`, `error`, `status`, `result`, and `connection`. Hooks subscribe from the time they mount and do not replay earlier events. ## Deterministic BLE fixtures [#deterministic-ble-fixtures] The `@ovok/native/bt-management` testing exports include `createFakeBleManager` and `createFakeBleDevice`. The fake manager can emit discovery and radio-state changes. A fake device supports connection, characteristic reads and notifications, notification-state (Client Characteristic Configuration) reads, MTU requests, and disconnects. These helpers do not simulate operating-system permissions or real platform background execution. `defineRecordedDeviceFrames` groups app-owned recorded frames by device key. `replayRecordedFrames` sends each frame to an app-provided sink in order and can apply a delay per frame. Use these helpers to exercise parsing and result-handling code without live hardware. See the [Bluetooth guide](/native-sdk/guide/modules/bt-management), [BTProvider reference](/native-sdk/guide/components/bt-management/bt-provider/), and [runtime hooks](/native-sdk/guide/components/bt-management/hooks/). # BluetoothDevicePicker Canonical page: https://docs.ovok.com/native-sdk/guide/components/bt-management/bluetooth-device-picker `BluetoothDevicePicker` is a theme-aware modal for presenting multiple `BTDeviceSelection` candidates. It is a view only: your callback decides how a choice affects the Bluetooth session. Import it from `@ovok/native/bt-management`. ## Connect it to auto-connect [#connect-it-to-auto-connect] When `BTProvider` has `autoConnect` enabled and more than one candidate is found during the settle window, it calls `onDeviceSelectionRequired`. Keep the supplied candidates and `select` callback in screen state, then pass them to the picker. ~~~tsx { void selection.select(device); setSelection(undefined); }} onDismiss={() => setSelection(undefined)} /> ~~~ Call the selection object's `select(device)` function. The picker calls your `onSelect`; it does not connect by itself. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/bt-management` API reference](/native-sdk/reference/bt-management). # BTProvider Canonical page: https://docs.ovok.com/native-sdk/guide/components/bt-management/bt-provider `BTProvider` is the React boundary for an SDK-managed Bluetooth session. It requests runtime permissions, starts discovery for the device declarations you accept, exposes the runtime to Bluetooth hooks and UI, and releases managed devices when the provider unmounts. Import it from `@ovok/native/bt-management`. ## Minimal setup [#minimal-setup] ```tsx import { BleManager } from "react-native-ble-plx"; import { BTProvider, IntegratedDevices } from "@ovok/native/bt-management"; const bleManager = new BleManager(); const acceptedDevices = [IntegratedDevices.BP2] as const; device.connect()} onResult={(result) => saveMeasurement(result)} > ; ``` Keep `bleManager` and `acceptedDevices` stable. A new array on each render changes the provider's manager configuration and restarts the session. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/bt-management` API reference](/native-sdk/reference/bt-management). ## Background result delivery [#background-result-delivery] `backgroundSync` is opt-in. It enables background scan behavior, creates a durable result queue, and starts the provider-managed Android connected-device foreground service. The queue configuration requires persistent storage and an asynchronous delivery callback: ```tsx measurementStore.getItem(key), setItem: (key, value) => measurementStore.setItem(key, value), }, getOwnerKey: () => authStore.currentAccountKey, onResult: async (result) => { await uploadMeasurement(result, { accountKey: result.ownerKey, idempotencyKey: result.id, }); }, android: { foregroundService: { notificationTitle: "Bluetooth monitoring", notificationBody: "Listening for health measurements", }, }, }} > ``` `storage` must survive process restarts. The queue writes the result before invoking `onResult` and removes it after that promise resolves. Delivery is at least once, so deduplicate server writes by `result.id`. The result also includes `queueId`, `queuedAt`, and `attempt`. Failed items remain queued for automatic retry; default retry settings are three attempts with a 30-second exponential backoff base. The coordinator checks the active `getOwnerKey()` before each delivery and each result includes the `ownerKey` captured when it was queued. Use that value to select the account for persistence. A callback already running cannot be canceled by an account switch; its remaining queued results wait until their owner is active again. The provider's separate `onResult` prop remains an immediate measurement callback. It is not the queue acknowledgement and its return value is not awaited. Use `backgroundSync.onResult` for app-owned delivery that must complete before an item is removed from the queue. `backgroundSync.android.foregroundService` controls the provider-managed Android service notification and optional battery-optimization request. If the app owns the BLE scan outside this provider, use the standalone [`AndroidBluetoothForegroundService`](/native-sdk/guide/components/background-sync/) instead. Do not start both service owners for the same scan. For the iOS restoration identifier, service UUID filters, Android native setup, and HealthKit or Health Connect background paths, see the [background sync guide](/native-sdk/guide/modules/background-sync). ## Permission behavior [#permission-behavior] By default, the provider requests Bluetooth permissions on mount. Android 12 and later requests `BLUETOOTH_CONNECT` and `BLUETOOTH_SCAN`; earlier Android versions request fine location. iOS requests Bluetooth access. It checks again when the app returns from Settings after the app opens Settings through the permission flow. Configure the corresponding native declarations in the [installation guide](/native-sdk/guide/how-to/installation). When `gateOnPermission` is `true`, the provider renders a loading indicator while the automatic request is unresolved. If access is denied, it calls `permissionFallback` when supplied; otherwise it renders `DefaultPermissionFallback`, which opens the app settings. To ask only after the patient chooses to pair, set `requestPermissionOnMount={false}`. `BTProvider` and its runtime stay mounted, but discovery waits until a child calls `useBluetoothState().requestPermission()` and the request succeeds. The hook must render beneath `BTProvider`; its returned promise resolves to whether access was granted. Handle a rejected promise in the app. In this mode, `gateOnPermission` does not gate children, so keep the pairing action available and use the hook's `permissionStatus` to gate other UI if needed. ```tsx import { Button } from "react-native"; import { useBluetoothState } from "@ovok/native/bt-management"; function PairButton() { const { requestPermission } = useBluetoothState(); return ( ); export default BasicAnswerActions; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Styling [#styling] ### Default Styles [#default-styles] Applies horizontal padding using the theme system: ```tsx style={[{ paddingHorizontal: theme.spacing(2) }, style]} ``` ## Related Components [#related-components] - [Answer](/native-sdk/guide/components/journal/answer/) - Parent container component - [Answer.Header](/native-sdk/guide/components/journal/answer-header/) - Header navigation component - [Answer.Question](/native-sdk/guide/components/journal/answer-question/) - Question display component - [Answer.Input](/native-sdk/guide/components/journal/answer-input/) - Text input component # Answer.Header Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/answer-header The `Answer.Header` component provides a horizontal layout container for form navigation and action elements. It's designed to house back buttons, progress indicators, save actions, and other form-related controls at the top of journal entry screens. ## Basic Example [#basic-example] ```typescript import { Answer } from "@ovok/native"; import * as React from "react"; import { Text } from "react-native-paper"; const BasicAnswerHeader = () => ( Header ); export default BasicAnswerHeader; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Styling [#styling] ### Default Styles [#default-styles] ```tsx const styles = StyleSheet.create({ header: { flexDirection: "row", justifyContent: "space-between", }, }); ``` ## Related Components [#related-components] - [Answer](/native-sdk/guide/components/journal/answer/) - Parent container component - [Answer.Question](/native-sdk/guide/components/journal/answer-question/) - Question display component - [Answer.Input](/native-sdk/guide/components/journal/answer-input/) - Text input component - [Answer.Actions](/native-sdk/guide/components/journal/answer-actions/) - Bottom action container # Answer.Input Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/answer-input The `Answer.Input` component renders React Native's `TextInput` with the `react-native-paper` `TextInputProps` type and SDK placeholder styling. ## Basic Example [#basic-example] ```typescript import { Answer } from "@ovok/native"; import * as React from "react"; const BasicAnswerInput = () => ( ); export default BasicAnswerInput; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Component Behavior [#component-behavior] ### Theme Integration [#theme-integration] - **Placeholder Color**: Automatically uses `theme.colors.onSurfaceDisabled` for consistent muted text - **Text Color**: Uses the platform input's inherited text color unless the app supplies one - **Background**: Uses the platform input's default background unless styled by the app ## Styling [#styling] ### Default Styles [#default-styles] ```tsx const styles = StyleSheet.create({ input: { flex: 1, }, }); ``` ### Theme Colors Used [#theme-colors-used] - `theme.colors.onSurfaceDisabled` - Placeholder text color ## Related Components [#related-components] - [Answer](/native-sdk/guide/components/journal/answer/) - Parent container component - [Answer.Header](/native-sdk/guide/components/journal/answer-header/) - Header navigation component - [Answer.Question](/native-sdk/guide/components/journal/answer-question/) - Question display component - [Answer.Actions](/native-sdk/guide/components/journal/answer-actions/) - Bottom action container # Answer.Question Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/answer-question The `Answer.Question` component displays question text in journal and questionnaire forms. It provides consistent typography and styling for question prompts with emphasis on readability and accessibility. ## Basic Example [#basic-example] ```typescript import { Answer } from "@ovok/native"; import * as React from "react"; import { Text } from "react-native-paper"; const BasicAnswerQuestion = () => ( How are you feeling today? ); export default BasicAnswerQuestion; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Styling [#styling] ### Default Styles [#default-styles] ```tsx const styles = StyleSheet.create({ question: { fontSize: 18, fontWeight: "600", }, }); ``` ### Theme Integration [#theme-integration] Uses `react-native-paper` default text colors from the theme system. ## Related Components [#related-components] - [Answer](/native-sdk/guide/components/journal/answer/) - Parent container component - [Answer.Header](/native-sdk/guide/components/journal/answer-header/) - Header navigation component - [Answer.Input](/native-sdk/guide/components/journal/answer-input/) - Text input component - [Answer.Actions](/native-sdk/guide/components/journal/answer-actions/) - Bottom action container # Answer Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/answer The `Answer` component provides a keyboard-aware scrollable container for journal entry forms. It combines `KeyboardAwareScrollView` with `KeyboardToolbar` to create an optimal mobile input experience for healthcare questionnaires and journal entries. ## Basic Example [#basic-example] ```typescript import { Answer } from "@ovok/native"; import * as React from "react"; import { Button } from "react-native-paper"; const BasicAnswer = () => { const [answerText, setAnswerText] = React.useState(""); return ( What is your name? ); }; export default BasicAnswer; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Compound Components [#compound-components] - [**`Answer.Header`**](/native-sdk/guide/components/journal/answer-header/) - Top section for navigation and form actions - [**`Answer.Question`**](/native-sdk/guide/components/journal/answer-question/) - Styled text component for question display - [**`Answer.Input`**](/native-sdk/guide/components/journal/answer-input/) - Theme-aware text input for user responses - [**`Answer.Actions`**](/native-sdk/guide/components/journal/answer-actions/) - Bottom container for submission buttons ## Component Behavior [#component-behavior] ### Keyboard Management [#keyboard-management] - **Automatic Scrolling**: Ensures input fields remain visible when keyboard appears - **Keyboard Toolbar**: Provides native iOS-style toolbar above keyboard - **Scroll Performance**: Optimized for smooth scrolling during text input ### Layout System [#layout-system] - **Flexible Height**: Expands to fill available screen space - **Content Padding**: Default padding of `theme.spacing(6)` with customizable override - **Component Spacing**: Consistent `theme.spacing(5)` gap between child elements ### Theme Integration [#theme-integration] - **Spacing Values**: Uses theme multipliers for consistent layout - **Color Inheritance**: Child components inherit theme colors automatically - **Responsive Design**: Adapts to different screen sizes and orientations ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - Inherits from child components (no direct color usage) # Journal Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal A comprehensive set of React Native components for building journal and questionnaire interfaces in healthcare applications. The Journal module provides keyboard-aware forms, question-answer flows, and display components for past entries. ## Key Features [#key-features] - **Keyboard-Aware Interface**: Built with `react-native-keyboard-controller` for optimal mobile input experience - **Compound Components**: Flexible architecture using compound component patterns for customization - **Healthcare-Focused**: Designed for medical questionnaires, patient journaling, and health tracking - **Material Design 3**: Seamless integration with theming system for consistent visual design - **Form Management**: Input components optimized for text-based responses and multiline content ## Components [#components] - [**`Answer`**](/native-sdk/guide/components/journal/answer/) - Interactive form container for journal entry creation - [**`PastJournalCard`**](/native-sdk/guide/components/journal/past-journal-card/) - Display component for showing completed journal entries - [**`TodayQuestionCard`**](/native-sdk/guide/components/journal/today-question-card/) - Interactive card for displaying daily questions ## Architecture [#architecture] The Journal module follows the compound component pattern, where each main component (`Answer`, `PastJournalCard`, `TodayQuestionCard`) serves as a container with specialized sub-components. This architecture provides: - **Flexibility**: Mix and match sub-components as needed - **Consistency**: Shared theming and styling across all components - **Customization**: Override styles while maintaining design system compliance - **Type Safety**: Full TypeScript support with proper prop definitions ## Dependencies [#dependencies] - `react-native-keyboard-controller` - Keyboard-aware scrolling and toolbar - `react-native-paper` - Material Design components and theming - `expo-linear-gradient` - Gradient backgrounds for visual appeal ## Performance Considerations [#performance-considerations] - **Keyboard Management**: Automatic keyboard handling prevents input field obstruction - **Scroll Optimization**: `KeyboardAwareScrollView` provides smooth scrolling behavior - **Memory Efficiency**: Lightweight components with minimal overhead - **Theme Integration**: Efficient theme consumption without unnecessary re-renders # PastJournalCard.Answer Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/past-journal-card-answer The `PastJournalCard.Answer` component renders the answer text of a past journal entry with a subtle color. ## Basic Example [#basic-example] ```tsx import { PastJournalCard } from "@ovok/native"; import * as React from "react"; const Example = () => { return ( I felt energetic and went for a walk. ); }; export default Example; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.onSurfaceDisabled`: Text color ### Default Styles [#default-styles] ```tsx fontSize: 14; fontWeight: "400"; ``` ## Related Components [#related-components] - [PastJournalCard](/native-sdk/guide/components/journal/past-journal-card/) - [PastJournalCard.Title](/native-sdk/guide/components/journal/past-journal-card-title/) - [PastJournalCard.Date](/native-sdk/guide/components/journal/past-journal-card-date/) # PastJournalCard.Date Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/past-journal-card-date The `PastJournalCard.Date` component displays the date of a past journal entry with subdued emphasis. ## Basic Example [#basic-example] ```tsx import { PastJournalCard } from "@ovok/native"; import * as React from "react"; const Example = () => { return Aug 21, 2025; }; export default Example; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.onSurfaceDisabled`: Text color ### Default Styles [#default-styles] ```tsx fontSize: 16; fontWeight: "400"; ``` ## Related Components [#related-components] - [PastJournalCard](/native-sdk/guide/components/journal/past-journal-card/) - [PastJournalCard.Title](/native-sdk/guide/components/journal/past-journal-card-title/) - [PastJournalCard.Answer](/native-sdk/guide/components/journal/past-journal-card-answer/) # PastJournalCard.Title Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/past-journal-card-title The `PastJournalCard.Title` component renders the title text for a past journal entry with appropriate typography and weight. ## Basic Example [#basic-example] ```tsx import { PastJournalCard } from "@ovok/native"; import * as React from "react"; const Example = () => ( Past Journal ); export default Example; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Styling [#styling] ### Default Styles [#default-styles] ```tsx fontFamily: "DMSans_700Bold"; fontSize: 18; fontWeight: "600"; ``` ## Related Components [#related-components] - [PastJournalCard](/native-sdk/guide/components/journal/past-journal-card/) - [PastJournalCard.Date](/native-sdk/guide/components/journal/past-journal-card-date/) - [PastJournalCard.Answer](/native-sdk/guide/components/journal/past-journal-card-answer/) # PastJournalCard Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/past-journal-card The `PastJournalCard` component displays completed journal entries and questionnaire responses in a Material Design card format. It provides a structured layout for showing historical health data, patient responses, and journal content. `PastJournalCard.Content` is the raw `react-native-paper` `Card.Content` export; it is not an SDK wrapper with a separate prop contract. ## Basic Example [#basic-example] ```typescript import { PastJournalCard } from "@ovok/native"; import * as React from "react"; const BasicPastJournalCard = () => ( Date Title Answer ); export default BasicPastJournalCard; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Component Behavior [#component-behavior] ### Card Design [#card-design] - **Mode**: Uses `"contained"` mode for Material Design 3 elevation - **Background**: Automatically applies `theme.colors.surface` background - **Elevation**: Fixed card elevation for consistent appearance ### Theme Integration [#theme-integration] - **Surface Color**: Uses theme surface color for proper contrast - **Content Styling**: Child components inherit theme colors - **Dark Mode**: Automatically adapts to dark/light theme changes ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.surface` - Card background color ## Related Components [#related-components] - [**`PastJournalCard.Title`**](/native-sdk/guide/components/journal/past-journal-card-title/) - Title text component - [**`PastJournalCard.Date`**](/native-sdk/guide/components/journal/past-journal-card-date/) - Date display component - [**`PastJournalCard.Answer`**](/native-sdk/guide/components/journal/past-journal-card-answer/) - Answer text component - [**`TodayQuestionCard`**](/native-sdk/guide/components/journal/today-question-card/) - Today's question display # TodayQuestionCard.Actions Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/today-question-card-actions The `TodayQuestionCard.Actions` component aligns action items to the right with consistent spacing. ## Basic Example [#basic-example] ```tsx import { TodayQuestionCard } from "@ovok/native"; import * as React from "react"; import { IconButton } from "react-native-paper"; const Example = () => ( ); export default Example; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Styling [#styling] ### Theme Values Used [#theme-values-used] - `theme.spacing(2.5)`: Gap between action items ### Default Styles [#default-styles] ```tsx alignSelf: "flex-end"; flexDirection: "row"; alignItems: "center"; ``` ## Related Components [#related-components] - [TodayQuestionCard](/native-sdk/guide/components/journal/today-question-card/) # TodayQuestionCard.Content Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/today-question-card-content The `TodayQuestionCard.Content` component is a padded container that spaces inner elements consistently. ## Basic Example [#basic-example] ```tsx import { TodayQuestionCard } from "@ovok/native"; import * as React from "react"; const Example = () => ( Title How are you? ); export default Example; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Styling [#styling] ### Theme Values Used [#theme-values-used] - `theme.spacing(5)`: Gap between items - `theme.spacing(2)`: Horizontal padding ## Related Components [#related-components] - [TodayQuestionCard](/native-sdk/guide/components/journal/today-question-card/) # TodayQuestionCard.Gradient Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/today-question-card-gradient The `TodayQuestionCard.Gradient` component provides a gradient background using `expo-linear-gradient` for visually appealing daily prompts. ## Basic Example [#basic-example] ```tsx import { TodayQuestionCard } from "@ovok/native"; import * as React from "react"; const Example = () => ( ); export default Example; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Related Components [#related-components] - [TodayQuestionCard](/native-sdk/guide/components/journal/today-question-card/) - [TodayQuestionCard.Content](/native-sdk/guide/components/journal/today-question-card-content/) - [TodayQuestionCard.Title](/native-sdk/guide/components/journal/today-question-card-title/) - [TodayQuestionCard.Question](/native-sdk/guide/components/journal/today-question-card-question/) - [TodayQuestionCard.Actions](/native-sdk/guide/components/journal/today-question-card-actions/) # TodayQuestionCard.Question Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/today-question-card-question The `TodayQuestionCard.Question` component renders the question text prominently. ## Basic Example [#basic-example] ```tsx import { TodayQuestionCard } from "@ovok/native"; import * as React from "react"; const Example = () => ( How are you feeling? ); export default Example; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Styling [#styling] ### Default Styles [#default-styles] ```tsx fontSize: 19; fontWeight: "600"; ``` ## Related Components [#related-components] - [TodayQuestionCard](/native-sdk/guide/components/journal/today-question-card/) # TodayQuestionCard.Title Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/today-question-card-title The `TodayQuestionCard.Title` component renders the card title with the theme primary color. ## Basic Example [#basic-example] ```tsx import { TodayQuestionCard } from "@ovok/native"; import * as React from "react"; const Example = () => ( Daily Check-in ); export default Example; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.primary`: Text color ### Default Styles [#default-styles] ```tsx fontSize: 16; fontWeight: "600"; ``` ## Related Components [#related-components] - [TodayQuestionCard](/native-sdk/guide/components/journal/today-question-card/) # TodayQuestionCard Canonical page: https://docs.ovok.com/native-sdk/guide/components/journal/today-question-card The `TodayQuestionCard` component displays daily questions and prompts in an interactive card format with gradient background support. It's designed for engaging daily health check-ins, questionnaires, and journal prompts with visual appeal and clear call-to-action elements. ## Basic Example [#basic-example] ```tsx import { TodayQuestionCard } from "@ovok/native"; import * as React from "react"; import { IconButton } from "react-native-paper"; const BasicTodayQuestionCard = () => ( Daily Check-in How are you feeling? ); export default BasicTodayQuestionCard; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/journal` API reference](/native-sdk/reference/journal). ## Compound Components [#compound-components] - [**`TodayQuestionCard.Gradient`**](/native-sdk/guide/components/journal/today-question-card-gradient/) - Linear gradient container using `expo-linear-gradient` - [**`TodayQuestionCard.Content`**](/native-sdk/guide/components/journal/today-question-card-content/) - Padded content container with theme spacing - [**`TodayQuestionCard.Title`**](/native-sdk/guide/components/journal/today-question-card-title/) - Primary-colored title text - [**`TodayQuestionCard.Question`**](/native-sdk/guide/components/journal/today-question-card-question/) - Question text with emphasis styling - [**`TodayQuestionCard.Actions`**](/native-sdk/guide/components/journal/today-question-card-actions/) - Right-aligned action buttons container ## Component Behavior [#component-behavior] ### Card Design [#card-design] - **Mode**: Uses `"contained"` mode for Material Design 3 elevation - **Background**: Automatically applies `theme.colors.surface` background - **Gradient Support**: Designed to work with gradient backgrounds for visual appeal ### Theme Integration [#theme-integration] - **Surface Color**: Uses theme surface color as base - **Component Colors**: Child components use appropriate theme colors - **Responsive Design**: Adapts to different screen sizes and orientations ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.surface` - Card background color ## Related Components [#related-components] - [**`TodayQuestionCard.Gradient`**](/native-sdk/guide/components/journal/today-question-card-gradient/) - Gradient background component - [**`TodayQuestionCard.Content`**](/native-sdk/guide/components/journal/today-question-card-content/) - Content container component - [**`TodayQuestionCard.Title`**](/native-sdk/guide/components/journal/today-question-card-title/) - Title text component - [**`TodayQuestionCard.Question`**](/native-sdk/guide/components/journal/today-question-card-question/) - Question text component - [**`TodayQuestionCard.Actions`**](/native-sdk/guide/components/journal/today-question-card-actions/) - Actions container component - [**`PastJournalCard`**](/native-sdk/guide/components/journal/past-journal-card/) - Historical entries display # Language switcher hook and context Canonical page: https://docs.ovok.com/native-sdk/guide/components/language-switcher/advanced-api `useLanguageSwitcher` reads the current selection and change callback from the nearest `LanguageSwitcher`. The built-in option children already use this context; use the hook when an app-owned child needs to render its own selected state. ```tsx import { LanguageSwitcher, useLanguageSwitcher } from "@ovok/native/language-switcher"; function CurrentLanguage() { const { selectedLanguage } = useLanguageSwitcher(); return {selectedLanguage}; } English ``` The hook throws outside a `LanguageSwitcher`. The context contains only the selected language and setter; it does not load translations or persist the selection. ## Public exports [#public-exports] - `useLanguageSwitcher` - `LanguageSwitcherContext` - `LanguageSwitcherContextType` # LanguageSwitcher.Option.Flag Canonical page: https://docs.ovok.com/native-sdk/guide/components/language-switcher/flag A flexible container component for displaying language flags or flag-related imagery. Provides consistent styling and layout for visual language identification elements. ## Basic Example [#basic-example] ```typescript import { LanguageSwitcher } from "@ovok/native"; import * as React from "react"; import { Text } from "react-native-paper"; const BasicFlag = () => ( 🇺🇸 ); export default BasicFlag; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/language-switcher` API reference](/native-sdk/reference/language-switcher). ## Styling Considerations [#styling-considerations] ### Size Guidelines [#size-guidelines] - Standard emoji flags: 20-28px font size - Image flags: 24-32px width, 16-24px height (3:2 or 4:3 ratio) - Icon flags: 20-24px size for clarity - Responsive sizing for different screen sizes ### Performance [#performance] - Optimize flag images for mobile devices - Use SVG for scalable flag graphics - Consider lazy loading for large flag collections - Cache flag assets for improved performance ### Cultural Sensitivity [#cultural-sensitivity] - Use officially recognized flag representations - Consider regional flag variations when appropriate - Respect flag display protocols and guidelines - Provide fallbacks for unrecognized regions # LanguageSwitcher Canonical page: https://docs.ovok.com/native-sdk/guide/components/language-switcher `LanguageSwitcher` is a controlled `View` that provides the selected language and change callback to its option children. It does not own an i18n instance, a language catalog, persistence, or translation loading. ```tsx const [language, setLanguage] = React.useState("en_US"); English Deutsch ; ``` ## Props and behavior [#props-and-behavior] Required props are `selectedLanguage: string` and `onLanguageChange(language: string)`. The component also accepts React Native `ViewProps`. There is no `languages` prop; render the option children your app supports. `LanguageSwitcher.Option` accepts `value`, `TouchableOpacityProps`, and children. Pressing an option calls `onLanguageChange(value)` and then its optional caller `onPress`. It also provides option state to `RadioButton`, `Label`, and `Flag`. - `Option.RadioButton` wraps Paper's Android radio button and controls `status` and `value` from context; those two props cannot be overridden. - `Option.Label` wraps Paper `Text`, applies the SDK bold label style, and accepts Paper text props. - `Option.Flag` is a plain `View` wrapper; the app supplies the flag content. ## Hook and context [#hook-and-context] `useLanguageSwitcher` reads the provider and throws when used outside `LanguageSwitcher`. `LanguageSwitcherContext` and `LanguageSwitcherContextType` are public escape hatches. The SDK only communicates the selected string; the integrating app decides how that string changes the active locale and whether it is persisted. See [Language switcher hook and context](/native-sdk/guide/components/language-switcher/advanced-api/) for a custom child example. # LanguageSwitcher.Option.Label Canonical page: https://docs.ovok.com/native-sdk/guide/components/language-switcher/label A text component for displaying language names with consistent typography and styling. Built on react-native-paper Text component with custom font styling and theme integration. ## Basic Example [#basic-example] ```typescript import { LanguageSwitcher } from "@ovok/native"; import * as React from "react"; const BasicLabel = () => ( English ); export default BasicLabel; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/language-switcher` API reference](/native-sdk/reference/language-switcher). ## Component Behavior [#component-behavior] ### Typography System [#typography-system] - Uses DMSans_700Bold font family for clear language identification - Applies 16px font size for optimal readability - Includes flex: 1 for proper layout within option containers - Maintains consistent line height and spacing ### Text Rendering [#text-rendering] - Supports multilingual text rendering - Handles right-to-left (RTL) languages properly - Provides accessible text contrast - Integrates with react-native-paper theming ### Layout Integration [#layout-integration] - Automatically adjusts to available space within options - Maintains proper alignment with flags and radio buttons - Supports text wrapping for longer language names - Optimizes layout for different screen sizes ## Styling [#styling] ### Default Typography [#default-typography] - **Font Family**: DMSans_700Bold - **Font Size**: 16px - **Layout**: flex: 1 for space distribution - **Theme Integration**: Inherits theme colors automatically # LanguageSwitcher.Option Canonical page: https://docs.ovok.com/native-sdk/guide/components/language-switcher/language-switcher-option A touchable option component for individual language selection. Provides context for its child components and handles selection state, styling, and interaction feedback with Material Design 3 theming. ## Basic Example [#basic-example] ```typescript import { LanguageSwitcher } from "@ovok/native"; import * as React from "react"; const BasicLanguageSwitcherOption = () => ( // This component needs to be wrapped in a LanguageSwitcher component to work {}}> English ); export default BasicLanguageSwitcherOption; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/language-switcher` API reference](/native-sdk/reference/language-switcher). ## Compound Components [#compound-components] - [**`LanguageSwitcher.Option.RadioButton`**](/native-sdk/guide/components/language-switcher/radio-button/) - Radio button selection control - [**`LanguageSwitcher.Option.Label`**](/native-sdk/guide/components/language-switcher/label/) - Language name display component - [**`LanguageSwitcher.Option.Flag`**](/native-sdk/guide/components/language-switcher/flag/) - Flag display component ## Component Behavior [#component-behavior] ### Selection Logic [#selection-logic] - Compares own `value` prop with parent's `selectedLanguage` - Automatically manages visual selection state - Triggers parent `onLanguageChange` when pressed - Provides selection context to child components ### Visual States [#visual-states] - **Selected**: Primary border color and background emphasis - **Unselected**: Disabled border color and transparent background - **Pressed**: Touch opacity feedback for interaction - **Disabled**: Reduced opacity and disabled interactions ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.primary` - Selected border color - `theme.colors.onSurfaceDisabled` - Unselected border color - `theme.colors.surface` - Background color - `theme.spacing(2)` - Internal gap and padding (8px default) - `theme.borderRadius(2)` - Corner radius (8px default) # LanguageSwitcher Canonical page: https://docs.ovok.com/native-sdk/guide/components/language-switcher/language-switcher A provider component that manages language selection state through React Context API. Serves as the main container for language option components with automatic state management and theme integration. ## Basic Example [#basic-example] ```typescript import { LanguageSwitcher } from "@ovok/native"; import * as React from "react"; import { Text } from "react-native-paper"; const BasicLanguageSwitcher = () => { const [selectedLanguage, setSelectedLanguage] = React.useState("en_US"); return ( English 🇺🇸 German 🇩🇪 ); }; export default BasicLanguageSwitcher; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/language-switcher` API reference](/native-sdk/reference/language-switcher). ## Compound Components [#compound-components] - [**`LanguageSwitcher.Option`**](/native-sdk/guide/components/language-switcher/language-switcher-option/) - Individual language selection option - [**`LanguageSwitcher.Option.Flag`**](/native-sdk/guide/components/language-switcher/flag/) - Flag display component - [**`LanguageSwitcher.Option.Label`**](/native-sdk/guide/components/language-switcher/label/) - Language name display - [**`LanguageSwitcher.Option.RadioButton`**](/native-sdk/guide/components/language-switcher/radio-button/) - Radio button control # LanguageSwitcher.Option.RadioButton Canonical page: https://docs.ovok.com/native-sdk/guide/components/language-switcher/radio-button A radio button control component that automatically manages selection state based on the parent language option context. Built on react-native-paper RadioButton.Android with disabled pointer events for seamless parent option interaction. ## Basic Example [#basic-example] ```typescript import { LanguageSwitcher } from "@ovok/native"; import * as React from "react"; import { Text } from "react-native-paper"; const BasicRadioButton = () => ( ); export default BasicRadioButton; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/language-switcher` API reference](/native-sdk/reference/language-switcher). # MeasurementList.DateRange Canonical page: https://docs.ovok.com/native-sdk/guide/components/measurement/date-range `DateRange` displays the range beginning at `startDate` and provides previous/next controls. It does not filter a list itself; use `onDateChange` to query or filter the app's data. ```tsx setRange({ startDate, endDate })} /> ``` Props: - `startDate`: required date string. - `variant`: required `"week" | "month" | "year"`. - `disabledPrevious` and `disabledNext`: disable the matching control. - `onDateChange`: receives ISO `startDate` and `endDate` values. - `style` and `testID`: container props. The end is calculated by adding one unit and subtracting one day, then moving to the end of that day. A week is therefore a seven-day range from the supplied start; a month or year is a duration from that start, not necessarily a calendar-month/year boundary. Changing the variant triggers `onDateChange` for the current start date. # Measurement Canonical page: https://docs.ovok.com/native-sdk/guide/components/measurement The measurement module provides a `FlashList` wrapper, a default measurement row, and a date-range control. The SDK does not fetch, filter, or paginate measurements; the app supplies data and decides how to query it. Exports are `MeasurementList`, `MeasurementList.Item`, and `MeasurementList.DateRange`. The module is available from `@ovok/native` and `@ovok/native/measurement`. ## Compose a measurement screen [#compose-a-measurement-screen] ```tsx import { useAppTheme } from "@ovok/native"; import { MeasurementList } from "@ovok/native/measurement"; export function MeasurementsScreen({ measurements, setRange }) { const theme = useAppTheme(); return ( <> item.id} contentContainerStyle={{ padding: theme.spacing(4) }} onItemPress={(item) => openMeasurement(item)} /> ); } ``` `MeasurementList` accepts `FlashListProps` except `renderItem`, plus `onItemPress(item, index)`. The default row expects `data` with `{ value: string; unit: string; date: string }`; additional fields can be carried by the generic item type. The list forwards item props to `MeasurementList.Item`, so `badge`, touchable props, and `testID` can be supplied on each item. When a different row is needed, render `MeasurementList.Item` yourself or use a separate `FlashList`; `MeasurementList` intentionally owns its default row renderer. The forwarded ref is a `FlashListRef` and can be used by the host for scrolling. ## Date ranges [#date-ranges] `MeasurementList.DateRange` accepts a required ISO-compatible `startDate` and one of `week`, `month`, or `year`. It renders previous/next controls and calls `onDateChange({ startDate, endDate })` with ISO strings when a control is pressed. `disabledPrevious` and `disabledNext` prevent the corresponding action. The range is calculated relative to the supplied start date; `month` and `year` do not normalize to the first day of a calendar month or year. Changing `variant` also emits the current start date with the new range. # MeasurementList.Item Canonical page: https://docs.ovok.com/native-sdk/guide/components/measurement/measurement-list-item `MeasurementList.Item` is a themed `TouchableOpacity` row. It displays `data.value`, `data.unit`, and `data.date`, and calls `onPress` when tapped. ```tsx ``` `data` is required and has the shape `{ value: string; unit: string; date: string }` plus optional caller fields. The date is formatted with `date-fns` as `HH:mm, dd.MM.yy` using the runtime's date interpretation. Although the public type extends `TouchableOpacityProps`, the implementation consumes only `style`, `testID`, and `onPress`; other touch/accessibility props and arbitrary children are not forwarded. # MeasurementList Canonical page: https://docs.ovok.com/native-sdk/guide/components/measurement/measurement-list `MeasurementList` renders a `FlashList` and supplies a default row renderer. It accepts `FlashListProps` except `renderItem`, plus `onItemPress(item, index)`. Each item must contain `value`, `unit`, and `date` for the default row. ```tsx item.id} onItemPress={(item) => openMeasurement(item)} /> ``` `renderItem` is owned by the component and is not a public override. Use `MeasurementList.Item` directly when a different list renderer is needed. The list prepares FlashList for layout animation when its data changes and forwards the remaining FlashList props. There is no SDK-specific `estimatedItemSize` prop. The component forwards a `ref` to the underlying `FlashList` as a `FlashListRef`, so callers can use FlashList methods and layout-animation preparation through that ref. # ObservationDetail.DataContainer Canonical page: https://docs.ovok.com/native-sdk/guide/components/observation-detail/data-container A themed card container component for grouping related observation data with consistent styling, shadows, and Material Design 3 theming. Provides structured presentation for healthcare information. ## Basic Example [#basic-example] ```typescript import { ObservationDetail } from "@ovok/native"; import * as React from "react"; const vitals = { systolic: 120, diastolic: 80, heartRate: 70, temperature: 37.5, }; const VitalSignsContainer = () => ( ); export default VitalSignsContainer; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/observation-detail` API reference](/native-sdk/reference/observation-detail). ## Component Behavior [#component-behavior] ### Visual Design [#visual-design] - Material Design 3 card appearance with elevation - Themed border and shadow colors - Rounded corners with theme-based radius - Consistent padding and spacing ### Theme Integration [#theme-integration] - Automatically applies surface colors - Respects theme border and shadow colors - Uses theme-based border radius and spacing - Supports light and dark mode variations ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.surface` - Card background color - `theme.colors.outlineVariant` - Card border color - `theme.colors.shadow` - Card shadow color - `theme.borderRadius(2)` - Card corner radius (8px default) # ObservationDetail.DateTime Canonical page: https://docs.ovok.com/native-sdk/guide/components/observation-detail/date-time A date and time display component with flexible formatting options and fallback content support. Designed for healthcare observation timestamps with localization and conditional rendering capabilities. ## Basic Example [#basic-example] ```typescript import { ObservationDetail } from "@ovok/native"; import * as React from "react"; const BasicTimestamp = () => ( ); export default BasicTimestamp; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/observation-detail` API reference](/native-sdk/reference/observation-detail). ## Component Behavior [#component-behavior] ### Date Formatting [#date-formatting] - Uses `date-fns` for reliable date formatting - Supports all date-fns format patterns - `date-fns/format` throws for an invalid date string; validate input before rendering - Provides localized date display ### Conditional Rendering [#conditional-rendering] - Shows formatted date when `dateTime` is provided - Renders `children` content when `dateTime` is omitted. The fallback is returned as a bare fragment, so a plain string must be wrapped in a text component by the host; otherwise React Native can reject the raw string outside ``. # ObservationDetail Canonical page: https://docs.ovok.com/native-sdk/guide/components/observation-detail The ObservationDetail module provides a comprehensive solution for displaying detailed healthcare observation data in a structured, scrollable layout. Built as a compound component system optimized for medical data presentation with support for various data types, photos, and resource information. ## Overview [#overview] The ObservationDetail module offers specialized components for presenting healthcare observations including vital signs, measurements, questionnaire responses, and medical images. All components follow healthcare data display standards with automatic spacing, theming, and safe area handling. ### Key Features [#key-features] - **Compound Architecture**: Flexible structure with composable sub-components for different data types - **Healthcare Data Types**: Support for measurements, questionnaires, photos, and resource information - **Scrollable Layout**: Safe area-aware scrolling with automatic spacing and padding - **Photo Management**: Advanced photo preview with FlashList performance and modal viewing - **Data Presentation**: Structured display of label-value pairs and text content - **Resource Integration**: Display of data sources with optional imagery - **Theme Integration**: Consistent styling with Material Design 3 theming - **Responsive Design**: Automatic layout adaptation for different screen sizes ### Core Components [#core-components] - **[ObservationDetail](/native-sdk/guide/components/observation-detail/observation-detail/)** - Main scrollable container component - **[ObservationDetail.DateTime](/native-sdk/guide/components/observation-detail/date-time/)** - Date and time display component - **[ObservationDetail.DataContainer](/native-sdk/guide/components/observation-detail/data-container/)** - Card container for structured data - **[ObservationDetail.SingleCardDataRow](/native-sdk/guide/components/observation-detail/single-card-data-row/)** - Label-value data row - **[ObservationDetail.TextData](/native-sdk/guide/components/observation-detail/text-data/)** - Text content display - **[ObservationDetail.Resource](/native-sdk/guide/components/observation-detail/resource/)** - Data source information display - **[ObservationDetail.PhotoPreview](/native-sdk/guide/components/observation-detail/photo-preview/)** - Photo gallery with modal preview ### Architecture [#architecture] The ObservationDetail module follows the SDK's compound component pattern: - **Scrollable Container**: `ObservationDetail` serves as the main scrollable layout - **Data Sections**: Components group related information in themed containers - **Flexible Composition**: Mix and match components based on observation type - **Performance Optimized**: Efficient rendering for complex medical data # ObservationDetail Canonical page: https://docs.ovok.com/native-sdk/guide/components/observation-detail/observation-detail A scrollable container component designed for displaying healthcare observation data with automatic safe area handling and theme-based spacing. Serves as the main container for compound observation detail components. ## Basic Example [#basic-example] ```typescript import { ObservationDetail } from "@ovok/native"; import * as React from "react"; const mappedData = { effectiveDateTime: "2021-01-01", systolic: 120, diastolic: 80, heartRate: 70, deviceName: "Blood Pressure Monitor", }; const MedicalObservation = () => { return ( ); }; export default MedicalObservation; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/observation-detail` API reference](/native-sdk/reference/observation-detail). ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.spacing(4)` - Container padding (16px default) - `theme.spacing(3)` - Gap between child elements (12px default) - Safe area bottom inset - Additional bottom padding # ObservationDetail.PhotoPreview Canonical page: https://docs.ovok.com/native-sdk/guide/components/observation-detail/photo-preview An advanced photo gallery component with thumbnail navigation and full-screen modal preview. Built on FlashList for high performance with large photo sets and includes rotation, navigation, and zoom capabilities. ## Basic Example [#basic-example] ```typescript import { ObservationDetail } from "@ovok/native"; import * as React from "react"; const photos = Array.from( { length: 10 }, (_, index) => `https://placehold.co/600x400/FFFFFF/000000/png?text=${index}` ); const BasicPhotoPreview = () => ( ); export default BasicPhotoPreview; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/observation-detail` API reference](/native-sdk/reference/observation-detail). ## Component Behavior [#component-behavior] ### Thumbnail Gallery [#thumbnail-gallery] - Horizontal scrolling FlashList for performance - Active photo highlighting with theme colors - Touch selection for photo navigation - Configurable thumbnail sizes and spacing ### Modal Preview [#modal-preview] - Full-screen photo viewing with animated transitions - Left/right navigation between photos - Rotation controls (90° increments) - Safe area handling for modern devices ### Performance Features [#performance-features] - FlashList optimization for large photo sets - Efficient image loading and caching - Smooth 60fps scrolling and transitions - Memory-conscious image handling ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.primary` - Active thumbnail border - `theme.colors.surface` - Modal button backgrounds - `theme.colors.onSurface` - Modal button icons - `theme.colors.outline` - Modal button borders - `theme.spacing(3)` - Default gap between thumbnails - `theme.borderRadius(2)` - Thumbnail corner radius - `theme.borderRadius(99)` - Modal button corner radius ## Modal Features [#modal-features] ### Navigation Controls [#navigation-controls] - Left/right arrow buttons for photo navigation - Automatic disable on first/last photos - Smooth transitions between images ### Rotation Controls [#rotation-controls] - 90° rotation increments (left/right) - Smooth animated rotations using react-native-reanimated - Rotation state maintained per photo session ## Performance Considerations [#performance-considerations] ### Large Image Sets [#large-image-sets] - FlashList optimization for 100+ photos - Efficient viewport management and recycling - Lazy loading of non-visible thumbnails - Memory-conscious image caching ### Image Loading [#image-loading] - OptimizedImage integration for efficient loading - Placeholder and image-wrapper loading behavior; progressive rendering is not guaranteed by this component - Placeholder handling during load states - Error state management for failed loads # ObservationDetail.Resource Canonical page: https://docs.ovok.com/native-sdk/guide/components/observation-detail/resource A resource information component for displaying data source details with optional imagery. Used to indicate the origin or method of data collection in healthcare observations. ## Basic Example [#basic-example] ```typescript import { ObservationDetail } from "@ovok/native"; import * as React from "react"; const BasicResource = () => ( ); export default BasicResource; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/observation-detail` API reference](/native-sdk/reference/observation-detail). ## Component Behavior [#component-behavior] ### Layout System [#layout-system] - Horizontal row layout with image and text - Optional image display with fallback to text-only - Consistent padding and spacing - Theme-based border and styling ### Image Integration [#image-integration] - Uses OptimizedImage for efficient loading - Automatically sizes and styles image container - Graceful handling when no image provided ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.outlineVariant` - Top border color - `theme.spacing(4)` - Vertical padding (16px default) - `theme.spacing(6)` - Horizontal padding (24px default) - `theme.spacing(2)` - Gap between image and text (8px default) - `theme.spacing(6)` - Image dimensions (24x24px default) - `theme.borderRadius(1)` - Image border radius (4px default) # ObservationDetail.SingleCardDataRow Canonical page: https://docs.ovok.com/native-sdk/guide/components/observation-detail/single-card-data-row A label-value data row component designed for structured display of healthcare information. Provides consistent spacing, typography, and layout for observation data presentation. ## Basic Example [#basic-example] ```typescript import { ObservationDetail } from "@ovok/native"; import * as React from "react"; const BasicMedicalData = () => ( <> ); export default BasicMedicalData; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/observation-detail` API reference](/native-sdk/reference/observation-detail). ## Component Behavior [#component-behavior] ### Layout System [#layout-system] - Uses flexbox row layout with space-between alignment - Label text is flexible and can wrap - Value text is right-aligned and fixed-width - Consistent vertical padding and alignment ### Typography [#typography] - Standard 16px font size for both label and value - Normal font weight (400) for medical data readability - Inherits theme typography when available ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.spacing(4)` - Vertical padding (16px default) - `theme.spacing(6)` - Horizontal padding (24px default) # ObservationDetail.TextData Canonical page: https://docs.ovok.com/native-sdk/guide/components/observation-detail/text-data A text content component with consistent padding and typography for displaying narrative healthcare information. Designed for clinical notes, descriptions, and unstructured observation data. ## Basic Example [#basic-example] ```typescript import { ObservationDetail } from "@ovok/native"; import * as React from "react"; const note = { content: "Patient reports mild discomfort in left shoulder. Range of motion appears normal. No visible swelling or inflammation.", }; const ClinicalNote = () => ( {note.content} ); export default ClinicalNote; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/observation-detail` API reference](/native-sdk/reference/observation-detail). ## Component Behavior [#component-behavior] ### Text Formatting [#text-formatting] - Applies consistent padding for readability - Uses standard 16px font size for medical content - Maintains proper line height for healthcare text - Supports theme-based typography ### Content Support [#content-support] - Handles long-form text content - Supports rich text through children - Maintains consistent spacing with other components ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.spacing(4)` - Text padding (16px default) # OptimizedImage Canonical page: https://docs.ovok.com/native-sdk/guide/components/optimized-image `OptimizedImage` is a layout and retry wrapper around `expo-image`. It reads the native client base URL from `OvokProvider`, so render it below that provider. A layout and retry wrapper for React Native applications. It calculates dimensions, adds sizing parameters to matching client URLs, and delegates loading and caching to `expo-image`. ## Basic Example [#basic-example] ```tsx import { OvokProvider } from "@ovok/core/next/react"; import { Ovok } from "@ovok/native/next"; import { OptimizedImage } from "@ovok/native/image"; import * as SecureStore from "expo-secure-store"; import * as React from "react"; const client = new Ovok({ baseUrl: "https://api.example.com", tenantCode: "example", secureStore: SecureStore, }); const BasicImage = () => ( ); export default BasicImage; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/image` API reference](/native-sdk/reference/image). ## Key Features [#key-features] - **Client URL parameters**: Adds calculated `width`, `height`, and `fit` parameters only to matching client URLs - **Flexible Dimensions**: Support for fixed, percentage, and auto-calculated dimensions - **Aspect Ratio Management**: Automatic aspect ratio calculation and preservation - **Native image loading**: Delegates loading and cache behavior to `expo-image` - **Responsive sizing**: Container-aware sizing with layout-based calculations - **Host-controlled content**: The wrapper does not assume a medical image source or upload workflow ### Responsive Design System [#responsive-design-system] - **Container Awareness**: Images can use parent container dimensions when width or height is calculated - **Percentage Support**: Flexible sizing with percentage-based dimensions - **Auto Calculation**: Intelligent fallback to calculated dimensions - **Aspect Ratio Preservation**: Maintains image proportions across different sizes ## Performance Benefits [#performance-benefits] ### Memory Management [#memory-management] - **expo-image Integration**: Native-level memory management - **Placeholder support**: Passes placeholders through to `expo-image` - **Retry fallback**: Replaces the rendered source after the bounded retry policy is exhausted ### Network Efficiency [#network-efficiency] - **Client URL optimization**: Width, height, and fit query parameters are added only when the URI matches the native client base URL. External URLs are returned unchanged. - **No network guarantee**: `expo-image` owns the actual request and cache behavior; this wrapper does not promise request deduplication, progressive loading, or CDN use. ## Dependencies [#dependencies] - `expo-image` - High-performance image component with native optimization ## Performance Considerations [#performance-considerations] ### Optimization Strategy [#optimization-strategy] - **Placeholder Support**: The placeholder is passed to `expo-image`. - **Bounded Retry**: `useImage` retries up to `maxRetries` before the rendered source is changed to `fallback`, or to `placeholder` when no fallback is supplied. - **Error Handling**: `onError` is forwarded to the rendered `expo-image` instance. It is not a callback for the retry hook's final outcome. ## Failure handling [#failure-handling] `OptimizedImage` retries failed preloads three times by default through `expo-image`. Set `maxRetries` to change the limit and pass `fallback` to render a local or remote image after the retries are exhausted. The visible `expo-image` still owns its own load lifecycle, so `onLoad`/`onError` describe that rendered instance rather than the internal preload. When the fallback uses different intrinsic dimensions, the wrapper keeps the calculated container dimensions and can stretch or distort the fallback; provide matching aspect ratio/size assets or an explicit layout when preserving its shape matters. Because the wrapper preloads through `useImage` and then renders an `expo-image`, request deduplication depends on `expo-image`'s native cache; do not build billing, retry, or analytics logic on an assumption that exactly one network request occurs. ```tsx ``` ### Memory Usage [#memory-usage] - **Efficient Scaling**: Optimal memory usage for different image sizes - **Cache Management**: Intelligent cache eviction policies - **Resource ownership**: Native loading, caching, and cleanup remain owned by `expo-image` # Patient Canonical page: https://docs.ovok.com/native-sdk/guide/components/patient The Patient module provides a comprehensive solution for displaying and managing patient information in healthcare applications. Built on top of [FHIR Patient resources](https://www.hl7.org/fhir/patient.html) with compound components, localization support, and performance optimizations using [FlashList](https://shopify.github.io/flash-list/docs/usage). ## Overview [#overview] The Patient module offers healthcare-specific components for displaying patient demographics, personal information, and patient lists with consistent styling. All components follow FHIR standards and expose host-configurable React Native semantics; accessibility labels, roles, and focus behavior remain application-owned. ### Key Features [#key-features] - **FHIR Compliance**: Built on [FHIR Patient resources](https://www.hl7.org/fhir/patient.html) for healthcare interoperability - **Compound Components**: Flexible card-based architecture with composable sub-components - **High Performance**: List components using [FlashList](https://shopify.github.io/flash-list/docs/usage) for large patient datasets - **Localization Ready**: Full i18n support with date formatting and gender translations - **Accessibility Ready**: Components expose the relevant React Native props; add labels, roles, and focus behavior in the host application - **Theme Integration**: Consistent styling with Material Design 3 theming - **Healthcare Icons**: Medical-appropriate icons and visual indicators ### Core Components [#core-components] - **[PatientCard](/native-sdk/guide/components/patient/patient-card/)** - Main card container with compound architecture - **[PatientCard.Name](/native-sdk/guide/components/patient/patient-name/)** - Patient name display with formatting options - **[PatientCard.Gender](/native-sdk/guide/components/patient/patient-gender/)** - Gender display with visual indicators - **[PatientCard.BirthDate](/native-sdk/guide/components/patient/patient-birth-date/)** - Birth date and age display - **[PatientCard.Meta](/native-sdk/guide/components/patient/patient-meta/)** - Metadata container for additional info - **[PatientList](/native-sdk/guide/components/patient/patient-list/)** - High-performance patient list component ### Architecture [#architecture] The Patient module follows the SDK's compound component pattern: - **Compound Structure**: `PatientCard` serves as the main container with composable sub-components - **FHIR Integration**: Direct compatibility with `@medplum/fhirtypes` Patient resources - **Flexible Composition**: Mix and match components based on specific healthcare workflows - **Performance Optimized**: Efficient rendering for large patient directories # PatientCard.BirthDate.Icon Canonical page: https://docs.ovok.com/native-sdk/guide/components/patient/patient-birth-date/icon Calendar icon component using `Calendar2` from `iconsax-react-nativejs`. ## Basic Example [#basic-example] ```typescript import { PatientCard } from "@ovok/native"; import * as React from "react"; const BirthDateIcon = () => { return ; }; export default BirthDateIcon; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/patient` API reference](/native-sdk/reference/patient). ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.onSurfaceVariant` - Default icon color # PatientCard.BirthDate Canonical page: https://docs.ovok.com/native-sdk/guide/components/patient/patient-birth-date A compound component for displaying patient birth date and age information with calendar icon support. Provides flexible date formatting and age calculation for healthcare applications. ## Basic Example [#basic-example] ```typescript import { PatientCard } from "@ovok/native"; import * as React from "react"; const birthDate = "1990-01-01"; const BasicAgeDisplay = () => ( ); export default BasicAgeDisplay; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/patient` API reference](/native-sdk/reference/patient). ## Compound Components [#compound-components] - [**`PatientCard.BirthDate.Icon`**](/native-sdk/guide/components/patient/patient-birth-date/icon/) - Calendar icon component - [**`PatientCard.BirthDate.Text`**](/native-sdk/guide/components/patient/patient-birth-date/text/) - Date and age text display component ## Localization [#localization] The component uses these translation keys: ```typescript { "patient-card": { "age-years": "{{age}} years old", "birth-date-with-age": "{{date}} ({{age}} years old)" } } ``` ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.onSurfaceVariant` - Icon and text color - `theme.spacing(1)` - Gap between icon and text - `theme.fonts.bodyMedium` - Text typography ### Date Calculation [#date-calculation] - Uses `date-fns` for reliable age calculation - Handles timezone differences appropriately - Supports various date format patterns - Provides localized age display with translations # PatientCard.BirthDate.Text Canonical page: https://docs.ovok.com/native-sdk/guide/components/patient/patient-birth-date/text Date and age text display component with flexible formatting. ## Basic Example [#basic-example] ```typescript import { PatientCard } from "@ovok/native"; import * as React from "react"; const birthDate = "1990-01-01"; const ShowAgeOnly = () => ( ); export default ShowAgeOnly; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/patient` API reference](/native-sdk/reference/patient). ## Localization [#localization] The component uses these translation keys: ```typescript { "patient-card": { "age-years": "{{age}} years old", "birth-date-with-age": "{{date}} ({{age}} years old)" } } ``` ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.onSurfaceVariant` - Text color - `theme.fonts.bodyMedium` - Text typography ### Date Calculation [#date-calculation] - Uses `date-fns` for reliable age calculation - Handles timezone differences appropriately - Supports various date format patterns - Provides localized age display with translations # PatientCard Canonical page: https://docs.ovok.com/native-sdk/guide/components/patient/patient-card A touchable card container component designed for displaying patient information in healthcare applications. Built with compound architecture to provide flexible composition of patient data elements with consistent Material Design 3 styling; add accessibility semantics through the touchable props in the host app. ## Basic Example [#basic-example] ```tsx import { PatientCard } from "@ovok/native"; import * as React from "react"; import { Text } from "react-native-paper"; const patient = { resourceType: "Patient", name: [{ given: ["John"], family: "Doe" }], gender: "male" as const, birthDate: "1990-01-01", address: [ { line: ["123 Main St"], city: "Anytown", state: "CA", postalCode: "12345", }, ], telecom: [{ system: "email", value: "john.doe@example.com" }], photo: [{ url: "https://example.com/photo.jpg" }], identifier: [ { system: "https://example.com/identifier", value: "1234567890" }, ], active: true, }; const TermsScreen = () => { const handlePress = () => { console.log("Patient card pressed"); }; return ( Any kind of data 1 Any kind of data 2 Any kind of data 3 ); }; export default TermsScreen; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/patient` API reference](/native-sdk/reference/patient). ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.surface` - Card background color - `theme.colors.outlineVariant` - Card border color - `theme.colors.shadow` - Card shadow color - `theme.spacing(5)` - Card padding (20px default) - `theme.spacing(3)` - Internal gap between elements (12px default) - `theme.spacing(20)` - Minimum card height (80px default) - `theme.borderRadius(4)` - Card corner radius (16px default) # PatientCard.Gender Canonical page: https://docs.ovok.com/native-sdk/guide/components/patient/patient-gender A visual gender indicator component with icon support and themed styling. Provides accessible gender display for healthcare applications with localization support and multiple visual variants. ## Basic Example [#basic-example] ```typescript import { PatientCard } from "@ovok/native"; import * as React from "react"; const gender = "male" as const; const ProviderGenderDisplay = () => ; export default ProviderGenderDisplay; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/patient` API reference](/native-sdk/reference/patient). ## Component Behavior [#component-behavior] ### Gender Icons [#gender-icons] - **Male**: ♂ symbol with blue color theme (#2196F3) - **Female**: ♀ symbol with pink color theme (#E91E63) - **Other**: ⚲ symbol with purple color theme (#9C27B0) - **Missing**: Returns null when `gender` is absent; the public type does not include an `unknown` value ### Visual Variants [#visual-variants] - **Chip**: Bordered container with background color and rounded corners - **Default**: Simple inline display with icon and text ## Localization [#localization] The component uses these translation keys: ```json { "gender": { "male": "Male", "female": "Female", "other": "Other" } } ``` ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - Gender-specific colors for icons and backgrounds - `theme.spacing(1)` - Gap between icon and text (4px default) - `theme.spacing(3)` - Chip horizontal padding (12px default) - `theme.borderRadius(3)` - Chip corner radius (12px default) - `theme.fonts.labelMedium` - Chip text typography - `theme.fonts.bodyMedium` - Default variant typography # PatientList Canonical page: https://docs.ovok.com/native-sdk/guide/components/patient/patient-list High-performance patient directory component built on [FlashList](https://shopify.github.io/flash-list/docs/usage) for efficient rendering of large patient datasets. Provides default patient card rendering with customizable item rendering and automatic spacing. ## Basic Example [#basic-example] ```typescript import { PatientList } from "@ovok/native"; import { Patient } from "@medplum/fhirtypes"; import * as React from "react"; import { Alert } from "react-native"; const patients: Patient[] = [ { id: "1", name: [{ given: ["John"], family: "Doe" }], gender: "male", birthDate: "1990-01-01", resourceType: "Patient", }, { id: "2", name: [{ given: ["Jane"], family: "Smith" }], gender: "female", birthDate: "1985-05-15", resourceType: "Patient", }, { id: "3", name: [{ given: ["Jim"], family: "Beam" }], gender: "male", birthDate: "1978-09-22", resourceType: "Patient", }, ]; const PatientDirectory = () => { const handlePatientPress = React.useCallback( (patient: Patient, index: number) => { Alert.alert( "Patient Selected", `Selected: ${patient.name?.[0]?.given?.join(" ")} ${ patient.name?.[0]?.family }` ); }, [] ); return ( ); }; export default PatientDirectory; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/patient` API reference](/native-sdk/reference/patient). ## Component Behavior [#component-behavior] ### Default Rendering [#default-rendering] - Automatically renders `PatientCard` with name, gender, and birth date - Uses conditional rendering for optional patient data - Applies consistent spacing and styling - Provides item separators with theme-based spacing ### Performance Optimization [#performance-optimization] - Built on [FlashList](https://shopify.github.io/flash-list/docs/usage) for 60fps scrolling - Efficient memory usage for large patient datasets - Optimized for healthcare directories with hundreds of patients - Automatic viewport management and recycling ### FHIR Integration [#fhir-integration] - Direct compatibility with `@medplum/fhirtypes` Patient resources - Handles optional FHIR fields gracefully - Supports various patient data completeness levels ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.spacing(4)` - Content container padding (16px default) - `theme.spacing(3)` - Item separator height (12px default) # PatientCard.Meta Canonical page: https://docs.ovok.com/native-sdk/guide/components/patient/patient-meta A flexible container component for organizing patient metadata and secondary information. Provides consistent spacing and responsive layout for patient demographics and additional details. ## Basic Example [#basic-example] ```typescript import { PatientCard } from "@ovok/native"; import * as React from "react"; import { Text } from "react-native"; const appointment = { time: "10:00 AM", type: "Checkup", }; const AppointmentMeta = () => ( {appointment.time} {appointment.type} ); export default AppointmentMeta; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/patient` API reference](/native-sdk/reference/patient). ## Component Behavior [#component-behavior] ### Layout System [#layout-system] - **Flexbox Container**: Uses row direction with space-between alignment - **Responsive Wrapping**: Automatically wraps content to new lines when needed - **Consistent Spacing**: Applies theme-based gaps between child elements - **Center Alignment**: Vertically centers all child components ### Content Organization [#content-organization] - Groups related patient information logically - Maintains visual hierarchy with consistent spacing - Supports mixed content types (text, chips, buttons) - Provides flexible layout for various screen sizes ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.spacing(3)` - Gap between child elements (12px default) ## Layout Responsiveness [#layout-responsiveness] - Automatically adjusts for different screen widths - Wraps content intelligently when space is constrained - Maintains readable spacing on all device sizes - Supports both portrait and landscape orientations # PatientCard.Name Canonical page: https://docs.ovok.com/native-sdk/guide/components/patient/patient-name A text component for displaying patient names with configurable formatting options. Built to work with FHIR `HumanName` resources and provides intelligent fallbacks for missing or incomplete name data in healthcare applications. ### Basic Example [#basic-example] ```typescript import { PatientCard } from "@ovok/native"; import * as React from "react"; const BasicPatientName: React.FC = () => { return ; }; export default BasicPatientName; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/patient` API reference](/native-sdk/reference/patient). ## Component Behavior [#component-behavior] ### Name Formatting [#name-formatting] - **firstLast**: "John Michael Doe" format (given names followed by family name) - **lastFirst**: "Doe, John Michael" format (family name followed by given names) - **Multiple Given Names**: Automatically joins multiple given names with spaces - **Missing Data Handling**: Gracefully handles missing given or family names ### Fallback Logic [#fallback-logic] 1. Uses the first `HumanName` object from the array 2. Falls back to "Unknown Patient" for completely missing names 3. Shows only available name parts when some fields are missing 4. Returns empty display for invalid or empty name objects ### FHIR Compliance [#fhir-compliance] - Fully compatible with FHIR R4 `HumanName` structure - Supports `given` and `family` name components - Handles arrays of given names appropriately - Ignores FHIR `use`, `text`, and other metadata fields ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.onSurface` - Primary text color for patient names - `theme.fonts.headlineSmall` - Typography scale for prominent name display # PDF Canonical page: https://docs.ovok.com/native-sdk/guide/components/pdf The PDF module provides a comprehensive solution for displaying PDF documents within React Native applications. Built on top of [react-native-pdf](https://github.com/wonday/react-native-pdf) with enhanced loading states, theme integration, and automatic error handling for seamless document viewing experiences. ## Overview [#overview] The PDF module offers a streamlined approach to PDF document rendering with built-in loading animations, consistent theming, and robust error handling. It supports both local and remote PDF files with smooth transitions and user-friendly loading states. ### Key Features [#key-features] - **Seamless PDF Rendering**: Built on [react-native-pdf](https://github.com/wonday/react-native-pdf) for reliable cross-platform document display - **Enhanced Loading States**: Animated loading indicators with fade in/out transitions using react-native-reanimated - **Theme Integration**: Automatic theme-aware styling with backdrop colors and consistent design - **Error Handling**: Built-in error management for network failures and invalid documents - **Flexible Styling**: Customizable container and PDF styles for various layout requirements - **Test Coverage**: Comprehensive unit tests for reliable component behavior ### Architecture [#architecture] The PDF module follows the SDK's architectural principles: - **Single Component**: Focused PDFViewer component for all PDF viewing needs - **Props-based Customization**: Style, behavior, and content customization through props - **Theme Integration**: Automatic integration with the app's theme system - **Performance Optimized**: Efficient rendering with conditional loading states ### Basic Example [#basic-example] ```typescript import { PDFViewer } from "@ovok/native/pdf"; import * as React from "react"; const TermsScreen = () => { const handleLoadComplete = (pages: number) => { console.log(`Terms document has ${pages} pages`); }; return ( ); }; export default TermsScreen; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/pdf` API reference](/native-sdk/reference/pdf). ## Component Behavior [#component-behavior] ### Loading states [#loading-states] 1. **Initial Loading**: Shows animated loading indicator with theme-aware backdrop 2. **Document Ready**: Displays PDF content with fade-in animation 3. **Error callback**: Forwards loading failures through the inherited `onError` callback; the SDK does not render a separate error screen. ### Animation System [#animation-system] - Uses `react-native-reanimated` for smooth fade in/out transitions - Loading indicator appears immediately when `sourceURI` is provided - Content fades in seamlessly when document is ready ### Theme Integration [#theme-integration] - Automatically applies theme colors for loading backdrop - Respects app theme for consistent visual experience - Uses `useAppTheme` hook for dynamic theming The viewer shows its loading overlay until `onLoadComplete` fires. A missing or failing source is reported through the inherited PDF callback, but the component does not replace that callback with an SDK-owned error UI. Render your own error state around the viewer when the app needs a retry or empty state. # PDFViewer Canonical page: https://docs.ovok.com/native-sdk/guide/components/pdf/pdf-viewer PDF document viewer component built on [react-native-pdf](https://github.com/wonday/react-native-pdf) with enhanced loading states, theme integration, and automatic error handling. Provides a seamless document viewing experience with smooth loading animations and consistent styling. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/pdf` API reference](/native-sdk/reference/pdf). ## Component Behavior [#component-behavior] ### Loading States [#loading-states] 1. **Initial Loading**: Shows animated loading indicator with theme-aware backdrop 2. **Document Ready**: Displays PDF content with fade-in animation 3. **Error State**: Handles loading failures through error callbacks ### Animation System [#animation-system] - Uses `react-native-reanimated` for smooth fade in/out transitions - Loading indicator appears immediately when `sourceURI` is provided - Content fades in seamlessly when document is ready ### Theme Integration [#theme-integration] - Automatically applies theme colors for loading backdrop - Respects app theme for consistent visual experience - Uses `useAppTheme` hook for dynamic theming ## Styling [#styling] ### Container Customization [#container-customization] ```typescript const containerStyle = { backgroundColor: '#f5f5f5', borderRadius: 8, margin: 16, }; ``` ### PDF Content Styling [#pdf-content-styling] ```typescript const pdfStyle = { flex: 1, backgroundColor: 'white', }; ``` ### Full Screen PDF [#full-screen-pdf] ```typescript ``` ## Usage Patterns [#usage-patterns] ### Privacy Policy Display [#privacy-policy-display] ```typescript import * as React from "react"; import { PDFViewer } from "@ovok/native/pdf"; export const PrivacyPolicyScreen = () => { return ( ); }; ``` ### Terms and Conditions [#terms-and-conditions] ```typescript import * as React from "react"; import { PDFViewer } from "@ovok/native/pdf"; export const TermsScreen = () => { const handleLoadComplete = (pages: number) => { console.log(`Terms document has ${pages} pages`); }; return ( ); }; ``` ### Device Instruction Manual [#device-instruction-manual] ```typescript import * as React from "react"; import { Alert } from "react-native"; import { PDFViewer } from "@ovok/native/pdf"; interface DeviceManualProps { deviceType: string; manualUrl: string; } export const DeviceManual = ({ deviceType, manualUrl }: DeviceManualProps) => { const handleError = (error: Error) => { Alert.alert( "Manual Not Available", `Unable to load ${deviceType} instruction manual. Please try again later.` ); }; return ( ); }; ``` ### Healthcare Document Viewer [#healthcare-document-viewer] ```typescript import * as React from "react"; import { View, StyleSheet } from "react-native"; import { ActivityIndicator, Text } from "react-native-paper"; import { PDFViewer } from "@ovok/native/pdf"; interface HealthcareDocProps { documentId: string; documentUrl: string; title: string; } export const HealthcareDocumentViewer = ({ documentId, documentUrl, title }: HealthcareDocProps) => { const [isLoading, setLoading] = React.useState(true); const [error, setError] = React.useState(null); const handleLoadComplete = () => { setLoading(false); setError(null); }; const handleError = (err: Error) => { setLoading(false); setError(err.message); }; if (error) { return ( Unable to load document {error} ); } return ( ); }; const styles = StyleSheet.create({ container: { flex: 1, margin: 16, }, errorContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 24, }, }); ``` ### Password Protected PDF [#password-protected-pdf] ```typescript import * as React from "react"; import { PDFViewer } from "@ovok/native/pdf"; interface SecureDocumentProps { documentUrl: string; password: string; } export const SecureDocument = ({ documentUrl, password }: SecureDocumentProps) => { return ( { console.error('PDF Error:', error); }} testID="secure-document" /> ); }; ``` ## Error Handling [#error-handling] ### Network Errors [#network-errors] ```typescript const handleNetworkError = (error: Error) => { if (error.message.includes('network')) { // Handle network connectivity issues showNetworkErrorDialog(); } else { // Handle other PDF errors showGenericErrorDialog(); } }; ``` ### Validation and Fallbacks [#validation-and-fallbacks] ```typescript const ValidatedPDFViewer = ({ url }: { url: string }) => { if (!url) { return ; } return ( showDocumentErrorAlert()} /> ); }; ``` ## Performance Considerations [#performance-considerations] ### Large Documents [#large-documents] - Use appropriate `fitPolicy` settings for optimal rendering - Consider implementing pagination for very large documents - Monitor memory usage with large PDF files ### Network Optimization [#network-optimization] - Implement proper loading states for slow connections - Consider caching strategies for frequently accessed documents - Handle offline scenarios gracefully ### Animation Performance [#animation-performance] - Loading animations are optimized with `react-native-reanimated` - Smooth 60fps transitions without JavaScript bridge overhead - Minimal performance impact on document rendering # PickerSheet Canonical page: https://docs.ovok.com/native-sdk/guide/components/picker-sheet The PickerSheet module provides a comprehensive solution for creating bottom sheet-based picker interfaces with smooth wheel picker components. Built on top of [@gorhom/bottom-sheet](https://gorhom.github.io/react-native-bottom-sheet/) and [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/) for optimal performance and fluid animations. ## Overview [#overview] The PickerSheet system combines the convenience of bottom sheet modals with the smooth, iOS-style wheel picker interactions. Perfect for date selection, option picking, and any scenario requiring user selection from a list of items. ### Key Features [#key-features] - **Bottom Sheet Integration**: Built on [@gorhom/bottom-sheet](https://gorhom.github.io/react-native-bottom-sheet/) for native-like modal experiences - **Smooth Wheel Picker**: iOS-style wheel picker with smooth scrolling and visual feedback - **Animated Interactions**: Uses [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/) for 60fps animations - **Safe Area Support**: Automatic safe area handling with react-native-safe-area-context - **Theme Integration**: Built-in support for theme colors and spacing - **Accessibility**: The primitives forward the props they expose, but do not add a complete accessibility model. Add labels, roles, and announcements in the host app. - **TypeScript Support**: Complete type safety with comprehensive type definitions - **Performance Optimized**: Efficient rendering with FlatList and optimized animations `PickerSheet` accepts its content through `children`; it does not expose a general accessibility or container-props bag. `WheelPicker` exposes `containerProps` for its outer `View`, while labels, roles, and announcements for the sheet remain host-owned. ## Architecture [#architecture] The PickerSheet system consists of: ### Core Components [#core-components] - **[PickerSheet](/native-sdk/guide/components/picker-sheet/picker-sheet/)** - Main bottom sheet container with backdrop and safe area handling - **[WheelPicker](/native-sdk/guide/components/picker-sheet/wheel-picker/)** - Animated wheel picker with smooth scrolling and visual feedback ## External Dependencies [#external-dependencies] - [@gorhom/bottom-sheet](https://gorhom.github.io/react-native-bottom-sheet/) - For bottom sheet modal functionality - [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/) - For smooth animations and scroll handling - [react-native-safe-area-context](https://github.com/th3rdwave/react-native-safe-area-context) - For safe area handling ## Provider requirement [#provider-requirement] Mount `BottomSheetModalProvider` directly from `@gorhom/bottom-sheet` inside `GestureHandlerRootView` before rendering `PickerSheet`. Without that provider, the modal cannot present correctly. - [react-native-gesture-handler](https://docs.swmansion.com/react-native-gesture-handler/) - For scroll gestures in WheelPicker # PickerSheet Canonical page: https://docs.ovok.com/native-sdk/guide/components/picker-sheet/picker-sheet Bottom sheet modal container component built on [@gorhom/bottom-sheet](https://gorhom.github.io/react-native-bottom-sheet/) with automatic backdrop, safe area handling, and theme integration. Provides a native-like modal experience for picker interfaces. ## Quick Example [#quick-example] ```tsx import { PickerSheet, WheelPicker } from "@ovok/native/picker-sheet"; import { BottomSheetModal } from "@gorhom/bottom-sheet"; import React from "react"; import { StyleSheet, View } from "react-native"; import { Button, Text } from "react-native-paper"; const PickerSheetExample = () => { const bottomSheetRef = React.useRef(null); const [selectedIndex, setSelectedIndex] = React.useState(0); const options = ["Option 1", "Option 2", "Option 3", "Option 4", "Option 5"]; const handleOpenPress = () => { bottomSheetRef.current?.present(); }; return ( Select an Option ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", alignItems: "center", }, title: { textAlign: "center", marginBottom: 20, }, }); export default PickerSheetExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/picker-sheet` API reference](/native-sdk/reference/picker-sheet). ## Component Behavior [#component-behavior] The PickerSheet component: 1. **Bottom Sheet Integration**: Uses BottomSheetModal from @gorhom/bottom-sheet for native-like modal behavior 2. **Dynamic Sizing**: Automatically adjusts height based on content with `enableDynamicSizing` 3. **Backdrop Handling**: Includes automatic backdrop with appear/disappear animations 4. **Safe Area Support**: Automatically handles safe area insets for proper bottom spacing 5. **Theme Integration**: Uses theme colors for background and spacing ### Bottom Sheet Configuration [#bottom-sheet-configuration] ```tsx // Internal configuration {children} ``` ### Backdrop Configuration [#backdrop-configuration] ```tsx // Automatic backdrop with smooth transitions const renderBackdrop = (backdropProps: BottomSheetBackdropProps) => ( ); ``` ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.surface` - Background color for the bottom sheet - `theme.spacing(3)` - Content padding (12px by default) - `theme.spacing(4)` - Additional bottom padding (16px by default) ## Related Components [#related-components] - [WheelPicker](/native-sdk/guide/components/picker-sheet/wheel-picker/) - Main wheel picker component for use inside PickerSheet ## External Dependencies [#external-dependencies] - [@gorhom/bottom-sheet](https://gorhom.github.io/react-native-bottom-sheet/) - For bottom sheet modal functionality - [react-native-safe-area-context](https://github.com/th3rdwave/react-native-safe-area-context) - For safe area inset handling # WheelPicker Canonical page: https://docs.ovok.com/native-sdk/guide/components/picker-sheet/wheel-picker iOS-style wheel picker component with smooth scrolling, visual feedback animations, and performance optimizations. Built with [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/) and optimized FlatList for 60fps performance. ## Quick Example [#quick-example] ```tsx import { WheelPicker } from "@ovok/native/picker-sheet"; import { useAppTheme } from "@ovok/native"; import React from "react"; const options = ["Small", "Medium", "Large", "Extra Large"]; const WheelPickerExample = () => { const theme = useAppTheme(); const [selectedIndex, setSelectedIndex] = React.useState(0); return ( ); }; export default WheelPickerExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/picker-sheet` API reference](/native-sdk/reference/picker-sheet). ## Component Behavior [#component-behavior] The WheelPicker component: 1. **Smooth Scrolling**: Uses animated FlatList with optimized scroll handling 2. **Visual Feedback**: Items scale and fade based on distance from center 3. **Snap to Position**: Automatically snaps to the nearest item on scroll end 4. **Performance Optimized**: Efficient rendering with proper item layout calculations 5. **Gesture Handling**: Supports both scrolling and momentum-based selection3 The option shown in the center selection indicator is the option identified by `selectedIndex`. Scrolling calls `onChange` with that same option's zero-based index, including when `options` contains fewer values than `visibleItems`. ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.surfaceVariant` - Default selection indicator background - `theme.borderRadius(2)` - Default border radius for selection indicator ## Related Components [#related-components] - [PickerSheet](/native-sdk/guide/components/picker-sheet/picker-sheet/) - Bottom sheet container for WheelPicker ## External Dependencies [#external-dependencies] - [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/) - For smooth animations and scroll handling - [react-native-gesture-handler](https://docs.swmansion.com/react-native-gesture-handler/) - For scroll gestures # Polyfills and runtime setup Canonical page: https://docs.ovok.com/native-sdk/guide/components/polyfills Runtime setup has a dedicated `@ovok/native/polyfills` subpath so it can run before the app imports the rest of the SDK. `polyfillOvokWebAPIs` is the preferred initializer for new code. ```js // index.js: initialize before Expo Router loads the app bundle. const { polyfillOvokWebAPIs } = require("@ovok/native/polyfills"); polyfillOvokWebAPIs(); require("expo-router/entry"); ``` Set the app's `package.json` `main` field to `index.js` so this file runs before Expo Router imports the app. Keep this entry file in CommonJS form; a static import of the app or `expo-router/entry` can evaluate SDK modules before the initializer. ## Public exports [#public-exports] | Export | Purpose | | --- | --- | | `polyfillOvokWebAPIs` | Installs the web APIs required by the OVOK native runtime | | `cleanupOvokNativeRuntime` | Removes the installed polyfills for tests or controlled teardown | | `ExpoClientStorage` | Client storage implementation backed by Expo storage primitives | | `ExtendedExpoCrypto` | Expo-compatible crypto implementation | | `IExpoClientStorage` | Storage adapter type | | `PolyfillEnabledConfig` | Optional polyfill configuration type | | `initWebSocketManager` | Initializes the WebSocket manager used by the client runtime | Call `polyfillOvokWebAPIs` once from the application entry point, before importing the app module, creating, or using the `Ovok` client. Do not call it during render or once per screen. Use `cleanupOvokNativeRuntime` only when a test or controlled runtime teardown needs to remove the globals. ## Storage and credentials [#storage-and-credentials] The `Ovok` client from `@ovok/native/next` keeps its session in the `secureStore` you pass it, such as `expo-secure-store`; `ExpoClientStorage` is not needed for it. For credentials needed after an Android background relaunch, use the dedicated adapter from [`@ovok/native/background-sync`](/native-sdk/guide/components/background-sync/). ## Public import boundary [#public-import-boundary] Import runtime setup from `@ovok/native/polyfills`; this subpath loads the polyfill module without evaluating the package root and its other SDK modules. Import the app and other native features only after the setup call. # ProgressBar Canonical page: https://docs.ovok.com/native-sdk/guide/components/progress-bar The ProgressBar module provides a smooth, animated progress indicator component built with [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/) for optimal performance. Perfect for displaying task completion, loading states, or any percentage-based progress visualization. ## Overview [#overview] The ProgressBar component is designed to provide fluid animations and precise progress tracking with minimal performance overhead. ### Key Features [#key-features] - **Smooth Animations**: Built with [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/) for 60fps animations - **Flexible Progress Input**: Supports both static numbers and animated SharedValues - **Customizable Styling**: Full control over colors, dimensions, and styling - **Theme Integration**: Built-in support for theme colors and spacing - **Spring Animations**: Natural spring-based animation transitions - **TypeScript Support**: Full type safety with comprehensive type definitions - **Accessibility boundary**: Add the progress role, value, and announcements in the app; this primitive does not add accessibility semantics automatically - **Performance Optimized**: Efficient rendering with minimal re-renders ## Quick Example [#quick-example] ```tsx import { ProgressBar, useAppTheme } from "@ovok/native"; import React from "react"; const ProgressBarExample = () => { const theme = useAppTheme(); const [progress, setProgress] = React.useState(0.7); return ( ); }; export default ProgressBarExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/progress-bar` API reference](/native-sdk/reference/progress-bar). ## Component Behavior [#component-behavior] The ProgressBar component: 1. **Animated Progress**: Uses react-native-reanimated for smooth spring animations 2. **Flexible Input**: Accepts both static numbers and SharedValues for progress 3. **Automatic Scaling**: Converts progress (0-1) to percentage width (0-100%) 4. **Theme Integration**: Uses theme colors and can be customized with theme values 5. **Overflow Handling**: Properly clips progress fill within container bounds ### Progress Value Handling [#progress-value-handling] The component automatically detects and handles different progress input types: ```tsx // Static number (0 to 1) ; // SharedValue for animations const animatedProgress = useSharedValue(0.5); ; ``` ### Animation Configuration [#animation-configuration] Built-in spring animation with optimized parameters: ```tsx // Internal animation settings { damping: 15, // Controls bounce - higher = less bounce stiffness: 100, // Controls speed - higher = faster } ``` ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.primary` - Default progress fill color - `theme.colors.gray[300]` - Default container background color ## External Dependencies [#external-dependencies] - [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/) - For smooth animations and SharedValue support # ProgressRing Canonical page: https://docs.ovok.com/native-sdk/guide/components/progress-ring `ProgressRing` displays a fraction from 0 to 1, or a dashed ring when the target is unknown. It can contain any React content and can optionally respond to presses. ```tsx import { ProgressRing } from "@ovok/native/progress-ring"; import { Text } from "react-native"; 65% ``` When `progress` is omitted or `null`, the ring uses a dashed indicator and does not announce an empty value. Finite values are clamped to 0–1. Set `onPress` to make the ring a button; otherwise it exposes progress-bar accessibility semantics. Provide an `accessibilityLabel` appropriate to the host app's language and context. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `progress` | `number \| null` | unknown | Fraction from 0 to 1; omitted or `null` means unknown. | | `children` | `ReactNode` | - | Optional content centered inside the ring. | | `size` | `number` | `48` | Width and height in points. | | `strokeWidth` | `number` | `4` | Ring thickness in points. | | `color` | `string` | theme primary | Progress indicator color. | | `trackColor` | `string` | theme gray 300 | Background ring color. | | `onPress` | `PressableProps['onPress']` | - | Makes the ring tappable. | Other supported accessibility and pressable props are forwarded to the root component. Render it below the SDK `ThemeProvider` so default colors come from the active theme. # Providers, hooks, and submit utilities Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/advanced-api Use the compound [`QuestionnaireForm`](/native-sdk/guide/components/questionnaire-response-form/) for the standard form. The exports on this page are lower-level building blocks for an app that needs a custom renderer or navigation UI. They expose implementation state and should be used together with the documented questionnaire types. ## Providers and hooks [#providers-and-hooks] | Export | Purpose | | --- | --- | | `QuestionnaireFormProvider` | Owns Formik values, validation, and submit behavior for a questionnaire. | | `QuestionnaireNavigationProvider` | Shares current page/item and navigation actions with navigation children. | | `useQuestionnaireForm` | Reads form values, errors, submission state, and questionnaire navigation state. | | `useQuestionnaireNavigation` | Reads the current navigation context. | | `useQuestionnaireNavigationState` | Derives required, answered, final-item, and progress state from form and navigation inputs. | | `useNavigationHandlers` | Builds the next/previous handlers used by the standard navigation UI. | | `useInitialSelectedValues` | Derives initial form values from questionnaire items. | `useQuestionnaireForm` and `useQuestionnaireNavigation` throw when used outside the matching provider. `QuestionnaireForm` mounts the form provider for you; the standard navigation component manages the navigation provider. Prefer those higher-level components unless you are replacing their rendering behavior. ## Submit utility [#submit-utility] `QuestionnaireSubmitUtils.createQuestionnaireResponse(responses, pages, questionnaire)` builds a FHIR `QuestionnaireResponse` with `status: "completed"`, a reference to the questionnaire, response items, and an authored timestamp. It does not add subject, encounter, author, or provenance details. Add the context required by your workflow before persisting the resource. The standard form can either call your `onSubmit(values)` handler or, when that handler is omitted, produce the FHIR response and report it through `onSuccess`. Choose one path deliberately and handle failures at the screen boundary. ## Contexts and types [#contexts-and-types] The subpath also exports `QuestionnaireFormContext`, `QuestionnaireNavigationContext`, their context/provider types, `QuestionnaireFormProps`, `QuestionnaireFormValues`, `ResponseValues`, `ExtendedQuestionnaireItem`, and the FHIR `QuestionnaireResponse` type. Use the hooks in component code instead of reading contexts directly. # QuestionnaireForm.Content.AllItems Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/content/all-items `Content.AllItems` reads the form's `allItems` state and renders each enabled item in a flat `View`. It is useful with `QuestionnaireForm paged={false}`. ```tsx ; ``` It accepts `ViewProps` and adds a themed gap. Each item receives a generated test ID of `all-items-` and updates the form through the normal questionnaire field renderer. The list is flat; nested FHIR item hierarchy is not recreated by this component. It returns `null` when no enabled items exist. # QuestionnaireForm.Content.Error Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/content/error `Content.Error` reads the form's validation and submission state and returns `null` when there is no message and no custom children. ```tsx ``` It renders a Paper `Text` with the error color. A custom `children` value replaces the translation lookup. Otherwise the component passes `submissionError` first, then `errorMessage`, to `i18next`; values that are not keys may be rendered unchanged by the active i18next configuration. When a submission error exists, it also renders a compact `Try again` button that calls the form's `retrySubmit` function. The component does not provide a dismiss action or an accessibility announcement by itself; add that behavior around it when your app requires it. Validation messages are translation keys such as `questionnaire-form.error.required-fields` and, from the paged required-item guard, `questionnaire-form.error.required` (English default: `This question is required`). Submission errors may be backend/error strings. Supply matching i18n resources or pass custom children. # QuestionnaireForm.Content Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/content `QuestionnaireForm.Content` is a themed `View` that renders its children only when the current form state has content to show. It accepts `ViewProps` and adds a themed vertical gap. ## Children [#children] - `QuestionnaireForm.Content.Item` renders the current enabled item in paged mode. - `QuestionnaireForm.Content.AllItems` renders all enabled items as a flat list and is intended for `paged={false}` layouts. - `QuestionnaireForm.Content.Error` renders the current validation or submission message. The content components must be descendants of `QuestionnaireForm`; otherwise their hooks throw because the form context is missing. The SDK owns the item renderer and field value updates, while the app owns surrounding layout and submission policy. # QuestionnaireContent.Item Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/content/item Renders the current questionnaire item for paged mode, automatically handling field type selection and conditional logic. ## Overview [#overview] The `QuestionnaireContent.Item` component automatically renders the current questionnaire item based on its FHIR type, handles conditional logic evaluation, and provides real-time validation feedback. It serves as the main content renderer for paged questionnaire navigation. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/questionnaire-response-form` API reference](/native-sdk/reference/questionnaire-response-form). ## Features [#features] - **Automatic Field Rendering**: Selects appropriate field component based on FHIR item type - **Conditional Logic**: Evaluates `enableWhen` rules in real-time - **Validation Integration**: Shows required-field indicators. Inline validation text is rendered by `Content.Error`, not by `Content.Item` itself. - **Accessibility boundary**: The item forwards host view props; add labels, roles, and announcements around the rendered field where the app requires them - **Custom Styling**: Full control over item container appearance # QuestionnaireHeader Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/header The header components provide title display and progress tracking for questionnaire forms. These components work together to create informative headers that guide users through multi-page questionnaires with clear navigation context. ## Overview [#overview] The header component system consists of a main container and specialized sub-components for displaying questionnaire titles and progress information. Components accept host styling and view/text props; the integrating app supplies the accessibility semantics required by its experience. ## Components [#components] - **[QuestionnaireHeader.Title](/native-sdk/guide/components/questionnaire-response-form/header/title/)** - Displays questionnaire title with customizable styling - **[QuestionnaireHeader.Subtitle](/native-sdk/guide/components/questionnaire-response-form/header/subtitle/)** - Shows progress information and custom subtitle text ## Features [#features] - **📋 Title Display**: Automatic questionnaire title rendering with fallback support - **📊 Progress Tracking**: Real-time progress information for multi-page questionnaires - **🎨 Customizable**: Full styling control with theme integration - **Accessibility boundary**: Forward supported props and add heading semantics in the host app when the header is used as a navigational landmark - **📱 Responsive**: Adapts to different screen sizes and orientations ## Quick Start [#quick-start] ```tsx import { QuestionnaireForm } from "@ovok/native"; import { Questionnaire } from "@medplum/fhirtypes"; const questionnaire: Questionnaire = { resourceType: "Questionnaire", status: "draft", title: "Basic Header", item: [], }; const BasicHeader = () => { return ( ); }; export default BasicHeader; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/questionnaire-response-form` API reference](/native-sdk/reference/questionnaire-response-form). ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] The header components use the following theme values by default: - `theme.colors.surface` - Header background color - `theme.spacing()` - Consistent spacing throughout header components # QuestionnaireHeader.Subtitle Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/header/subtitle Displays progress information using an app-owned i18next translation key and formatting. ## Overview [#overview] The `QuestionnaireHeader.Subtitle` component automatically displays progress information for questionnaires, showing current page/step information with customizable prefix text. It provides real-time updates as users navigate through the form. ## Basic Example [#basic-example] ```tsx import { QuestionnaireForm } from "@ovok/native"; import { Questionnaire } from "@medplum/fhirtypes"; const questionnaire: Questionnaire = { resourceType: "Questionnaire", status: "draft", title: "Basic Header", item: [ { linkId: "1", text: "What is your name?", type: "string", }, ], }; const BasicHeader = () => { return ( ); }; export default BasicHeader; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/questionnaire-response-form` API reference](/native-sdk/reference/questionnaire-response-form). ## Features [#features] - **Automatic Progress Display**: Shows current page/step information automatically - **Customizable Prefix**: Add custom text before progress information - **Real-time Updates**: Updates automatically as user navigates - **Custom Content Override**: Replace automatic content with custom text - **Theme Integration**: Uses theme colors and typography ## Styling [#styling] ### Theme Colors [#theme-colors] - `theme.colors.onSurfaceVariant` - Default text color - `theme.fonts.bodyMedium` - Default typography style ## Localization [#localization] The component uses these translation keys: ```json { "questionnaire-form": { "header": { "subtitle": "{currentItemNumber} of {totalItems}" } } } ``` # QuestionnaireHeader.Title Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/header/title Displays the questionnaire title with automatic fallback and customizable styling. ## Overview [#overview] The `QuestionnaireHeader.Title` component automatically displays the questionnaire title from the form context or allows for custom title override. It integrates with the theme system and forwards supported text props so the host app can provide its required accessibility semantics. ## Basic Example [#basic-example] ```tsx import { QuestionnaireForm } from "@ovok/native"; import { Questionnaire } from "@medplum/fhirtypes"; const questionnaire: Questionnaire = { resourceType: "Questionnaire", status: "draft", title: "Basic Header", // it will be displayed in the header item: [], }; const BasicHeader = () => { return ( ); }; export default BasicHeader; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/questionnaire-response-form` API reference](/native-sdk/reference/questionnaire-response-form). ## Features [#features] - **Automatic Title Display**: Automatically retrieves and displays the questionnaire title from context - **Custom Override**: Supports custom title content through children prop - **Theme Integration**: Uses theme typography and colors automatically - **Accessibility**: Forward supported text accessibility props from the host app - **Responsive**: Typography scales appropriately across devices ## Styling [#styling] ### Theme Variables Used [#theme-variables-used] - `theme.colors.onSurface` - Default text color - `theme.fonts.headlineSmall` - Default typography style # QuestionnaireResponseForm Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form `QuestionnaireForm` renders a FHIR `Questionnaire` as a compound component. It supports paged or all-items layouts, enabled-when conditions, default answers, required-field validation, and either caller-owned submission or the SDK's FHIR `QuestionnaireResponse` creation. ```tsx saveValues(values)} > ``` ## Props and submission modes [#props-and-submission-modes] `questionnaire` is required. `paged` defaults to `true`; when false, the root is a `ScrollView` and `Content.AllItems` is the matching content primitive. The root also accepts the relevant React Native `ViewProps`/`ScrollViewProps`, `style`, and `testID`. The module also exposes providers, hooks, contexts, and a response builder for custom renderers. See [advanced API](/native-sdk/guide/components/questionnaire-response-form/advanced-api/). Choose exactly one submission mode: - `onSubmit(values, formikHelpers?)`: the app owns persistence. The callback is async and receives `QuestionnaireFormValues`; the SDK does not create a FHIR response in this mode. - `onSuccess(response)` and optional `onError(error)`: the SDK gets the active profile from `@ovok/core`, builds a completed `QuestionnaireResponse`, adds `subject` and a stable identifier, and calls `createResourceIfNoneExist`. This mode requires a configured core client/profile. The SDK-managed mode assigns a stable identifier and uses `createResourceIfNoneExist`. The identifier is retained for the form instance, so a second legitimate submission of the same questionnaire can be treated as an existing response. Remount the form or use the app-owned `onSubmit` mode when repeated submissions are separate records. When observation extraction is enabled, the SDK saves extracted resources and the completed `QuestionnaireResponse` in one FHIR transaction. After the transaction succeeds, it invalidates cached searches for the response and each extracted resource type before returning the reloaded response. A rejected transaction does not invalidate caches or report submission success. `initialValues` can seed answers. Values are strings, booleans, `null`, or `undefined`; the SDK removes disabled conditional answers during validation. Importing `@ovok/native/questionnaire-response-form` registers English defaults for the form's buttons, yes/no choices, progress subtitle, validation and submission errors, and accessibility hints. Existing English resources are not overwritten, so an app can provide its own copy. Decimal text questions accept either `.` or `,` as the decimal separator; the form normalizes the value before creating the FHIR `valueDecimal`. ## FHIR and UI behavior [#fhir-and-ui-behavior] Top-level groups become pages. If the questionnaire has no group items, the SDK creates one synthetic page. In paged mode, one enabled item is shown at a time. In all-items mode, `Content.AllItems` renders the enabled items in a flat list. Supported item renderers and response mapping are defined by the current source; common types include `boolean`, `choice`, `date`, `dateTime`, `decimal`, `integer`, `string`, and `text`. Conditional items use `enableWhen` with `all` or `any` behavior. `answerOption.initialSelected` seeds choices when an item becomes active. Required validation runs before submission and considers only enabled items. Paged navigation also prevents advancing from an unanswered required item. ## Compound exports [#compound-exports] `Header`, `Header.Title`, `Header.Subtitle`, `Content`, `Content.Item`, `Content.AllItems`, `Content.Error`, `Navigation`, `Navigation.PreviousButton`, `Navigation.NextButton`, and `Navigation.SubmitButton` are exported from the compound root. The form provider and hooks are public for custom layouts; use them only inside the corresponding form context. `useQuestionnaireForm()` returns the Formik state plus questionnaire navigation data, `errorMessage`, `submissionError`, and `retrySubmit()`. Validation errors clear once the enabled items are valid. `submissionError` takes precedence in the default error component and is the error message from the latest failed async submission; it may already be a translation key, but arbitrary backend text is not translated automatically. The default `Content.Error` renders that value through `i18next` and offers a `Try again` button when `submissionError` is present. The `onError` callback fires for failures from both the SDK-managed FHIR submission path and a custom `onSubmit` callback. `useQuestionnaireNavigation()` returns `isCurrentItemRequired`, `isCurrentItemAnswered`, `isLastItem`, `currentItemNumber`, `totalItems`, `showPrevious`, `isSubmitting`, `handleNext`, and `handlePrevious`. It must be used inside `QuestionnaireNavigationProvider`, which is normally mounted by `QuestionnaireFormProvider`. The remaining public hooks support custom renderers: - `useQuestionnaireNavigationState(...)` calculates the current-item flags and counters when the app owns the navigation provider. - `useNavigationHandlers(...)` returns `handleNext` and `handlePrevious` for the current page/item state. Required answers are checked before advancing. - `useInitialSelectedValues(...)` applies FHIR `answerOption.initialSelected` values and initializes enabled boolean items to `null` without triggering validation. `QuestionnaireSubmitUtils.createQuestionnaireResponse(responses, pages, questionnaire)` creates a completed FHIR `QuestionnaireResponse` with the questionnaire reference, authored timestamp, and response items. It does not persist the response or add the active patient subject; the SDK-managed submission path adds those app/client-owned fields before saving. `QuestionnaireFormValues`, `ResponseValues`, `ExtendedQuestionnaireItem`, and the provider/context prop types are public TypeScript exports. The SDK extends FHIR questionnaire items with optional `placeholder`, `helperText`, and `answerOption.initialSelected` fields for rendering. The SDK supplies layout primitives and FHIR mapping, not a router, persistence policy, analytics policy, or app-specific questionnaire schema. # QuestionnaireForm.Navigation Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/navigation `QuestionnaireForm.Navigation` is a `react-native-keyboard-controller` `KeyboardAvoidingView` with a row layout, `padding` behavior, and a keyboard offset of `100`. It accepts `KeyboardAvoidingViewProps` except `contentContainerStyle`. `QuestionnaireNavigationProvider` is also exported for custom navigation layouts, but its props are an internal implementation boundary: it requires the current page/item, enabled-item arrays, page arrays, Formik state, and several state setters. It is not a small standalone provider to configure from app data. It must be rendered inside `QuestionnaireForm`; its public context exposes `isCurrentItemRequired`, `isCurrentItemAnswered`, `isLastItem`, `currentItemNumber`, `totalItems`, `showPrevious`, `isSubmitting`, `handleNext`, and `handlePrevious`. The compound buttons read state from the form and navigation contexts. Render the buttons that match your layout; buttons do not navigate through a router. - `PreviousButton`: outlined, hidden on the first item, calls the previous handler; its disabled state uses only the caller's `disabled` prop. - `NextButton`: contained, hidden on the last item, disabled for unanswered required items and while submitting. - `SubmitButton`: contained, shown on the last item (or in non-paged mode), submits the form, disables while submitting, and shows loading while submitting. The buttons override caller `onPress` with the form action. `NextButton` and `SubmitButton` combine caller `disabled` with their own state; `PreviousButton` does not add a submitting/validation disabled state. Use `children` to replace translated button labels. # QuestionnaireForm.Navigation.NextButton Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/navigation/next-button The next button is a React Native Paper `Button` with `mode="contained"`. It is hidden on the final enabled item, disabled when the current item is required but unanswered, and disabled while submission is in flight. It accepts the shared navigation button props. The component owns `onPress`; caller `onPress` is not invoked. Pass children to replace the localized `common.next` label. # QuestionnaireForm.Navigation.PreviousButton Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/navigation/previous-button The previous button is a React Native Paper `Button` with `mode="outlined"`. It is hidden on the first item and returns to the previous enabled item/page when pressed. It accepts the shared navigation button props. The component owns `onPress`; caller `onPress` is not invoked. Pass children to replace the localized `common.previous` label. # QuestionnaireForm.Navigation.SubmitButton Canonical page: https://docs.ovok.com/native-sdk/guide/components/questionnaire-response-form/navigation/submit-button The submit button is a React Native Paper `Button` with `mode="contained"`. In paged mode it is hidden until the final enabled item. In all-items mode it is available without paging. It owns `onPress`, disables during submission, and displays Paper's loading state while the submission is in flight. Pass children to replace the localized `common.submit` label. The form performs required-field validation before invoking the chosen submission mode. # Setting Canonical page: https://docs.ovok.com/native-sdk/guide/components/setting The Setting module provides a comprehensive solution for building performant setting lists with section headers, custom components, and automatic border radius management. Built on top of [FlashList](https://shopify.github.io/flash-list/docs/usage) for optimal performance with large datasets. ## Overview [#overview] The Setting module is designed for creating settings screens and configuration lists with proper visual hierarchy, section grouping, and custom component integration. ### Key Features [#key-features] - **High Performance**: Built on [FlashList](https://shopify.github.io/flash-list/docs/usage) for efficient rendering of large lists - **Section Headers**: Automatic section header rendering with string items - **Custom Components**: Support for custom components with border radius integration - **Automatic Styling**: Dynamic border radius management for grouped items - **Theme Integration**: Built-in theming support with spacing and colors - **Flexible Icons**: Support for both icon functions and React Native Paper List.Icon - **TypeScript Support**: Full type safety with comprehensive type definitions - **Accessibility**: Forwards the underlying list/item semantics; add labels, roles, and actions in the host app where the screen needs them ## Architecture [#architecture] The Setting system consists of several key components: ### Core Components [#core-components] - **[SettingList](/native-sdk/guide/components/setting/setting-list/)** - Main list component with [FlashList](https://shopify.github.io/flash-list/docs/usage) integration - **[SettingListItem](/native-sdk/guide/components/setting/setting-list-item/)** - Individual setting item with icon and navigation support - **[ListHeader](/native-sdk/guide/components/setting/list-header/)** - Section header component for grouping settings ## Component Hierarchy [#component-hierarchy] The Setting list follows a clear component structure: ``` SettingList (FlashList Container) ├── ListHeader (Section Header) ├── SettingListItem (Standard Item) ├── SettingListItem (Standard Item) ├── ListHeader (Section Header) ├── CustomComponent (Custom Item) └── SettingListItem (Standard Item) ``` ## Related Components [#related-components] This Setting module integrates seamlessly with other SDK components to provide comprehensive settings and configuration solutions for healthcare applications. # ListHeader Canonical page: https://docs.ovok.com/native-sdk/guide/components/setting/list-header Section header component that provides visual separation and labeling for grouped settings. Features dynamic spacing based on position in the list and theme integration for consistent typography. ## Quick Example [#quick-example] ```tsx import { ListHeader } from "@ovok/native"; import React from "react"; const ListHeaderExample = () => { return ( ); }; export default ListHeaderExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/setting` API reference](/native-sdk/reference/setting). ## Component Behavior [#component-behavior] The ListHeader component: 1. **Dynamic Spacing**: Adjusts padding based on position in the list 2. **Typography**: Uses DMSans_700Bold font family for clear hierarchy 3. **Theme Integration**: Respects theme spacing values for consistency 4. **Accessibility boundary**: Provides visual grouping only; add a heading role or announcement in the host app if the section needs one ### Spacing Logic [#spacing-logic] The component applies different spacing based on position: ```tsx // Top padding: none for first item, theme.spacing(6) for others paddingTop: !isFirst ? theme.spacing(6) : 0; // Bottom padding: none for last item, theme.spacing(4) for others paddingBottom: !isLast ? theme.spacing(4) : 0; ``` This creates proper visual separation between sections while avoiding unnecessary spacing at list boundaries. ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.spacing(6)` - Top spacing between sections (24px by default) - `theme.spacing(4)` - Bottom spacing after headers (16px by default) ## Related Components [#related-components] - [SettingList](/native-sdk/guide/components/setting/setting-list/) - Container component that automatically renders ListHeaders - [SettingListItem](/native-sdk/guide/components/setting/setting-list-item/) - Setting items that appear under headers # SettingListItem Canonical page: https://docs.ovok.com/native-sdk/guide/components/setting/setting-list-item Individual setting item component built on React Native Paper's List.Item. Provides consistent styling, icon support, navigation arrows, and automatic border radius management for grouped settings. ## Quick Example [#quick-example] ```tsx import { SettingListItem, useAppTheme } from "@ovok/native"; import { User } from "iconsax-react-nativejs"; import React from "react"; const SettingListItemExample = () => { const theme = useAppTheme(); return ( } onPress={() => console.log("Profile pressed")} borderTopRadius={true} borderBottomRadius={true} /> ); }; export default SettingListItemExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/setting` API reference](/native-sdk/reference/setting). ## Component Behavior [#component-behavior] The SettingListItem component: 1. **Icon Management**: Supports both custom left icons and automatic right navigation arrow 2. **Border Radius**: Conditionally applies border radius for grouped appearance 3. **Theme Integration**: Uses theme colors and spacing for consistent styling 4. **Touch Feedback**: Provides appropriate touch feedback via React Native Paper 5. **Accessibility boundary**: Forwards the underlying Paper list-item semantics; configure labels, roles, and actions in the host app ### Icon System [#icon-system] - **Left Icon**: Custom icon function or React Native Paper List.Icon component - **Right Icon**: Automatic ArrowRight2 icon unless custom `right` prop is provided - **Icon Colors**: Left icons use `theme.colors.primary`, right icons use `theme.colors.onSurfaceDisabled` ### Border Radius Logic [#border-radius-logic] Border radius is applied based on item position in grouped lists: ```tsx // Top radius for first item in group borderTopRadius={true} // Bottom radius for last item in group borderBottomRadius={true} // Both for single items borderTopRadius={true} borderBottomRadius={true} ``` ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.primary` - Left icon color - `theme.colors.onSurfaceDisabled` - Right arrow color and inactive text - `theme.colors.surface` - Background color - `theme.spacing(3)` - Horizontal padding - `theme.spacing(2)` - Vertical padding - `theme.borderRadius(2)` - Border radius value ## Related Components [#related-components] - [SettingList](/native-sdk/guide/components/setting/setting-list/) - Container component that renders SettingListItem - [ListHeader](/native-sdk/guide/components/setting/list-header/) - Section header component for grouping # SettingList Canonical page: https://docs.ovok.com/native-sdk/guide/components/setting/setting-list High-performance list component built on [FlashList](https://shopify.github.io/flash-list/docs/usage) that provides optimized rendering for settings screens. Supports section headers, custom components, and automatic border radius management for grouped items. ## Quick Example [#quick-example] ```tsx import { SettingList, useAppTheme } from "@ovok/native"; import { Information, Settings, User } from "iconsax-react-nativejs"; import React from "react"; export const SettingListExample = () => { const theme = useAppTheme(); const settingsData = [ "Account", { title: "Profile", leftIcon: () => , onPress: () => console.log("Profile pressed"), }, { title: "Preferences", leftIcon: () => , onPress: () => console.log("Preferences pressed"), }, "Information", { title: "About", leftIcon: () => , onPress: () => console.log("About pressed"), }, ]; return ( ); }; export default SettingListExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/setting` API reference](/native-sdk/reference/setting). ## Component Behavior [#component-behavior] The SettingList component: 1. **Item Type Detection**: Automatically detects whether items are headers (strings), standard items, or custom components 2. **Border Radius Management**: Automatically applies appropriate border radius to grouped items 3. **Section Header Rendering**: Renders string items as section headers using ListHeader component 4. **Custom Component Integration**: Supports custom components with border radius props 5. **Performance Optimization**: Uses [FlashList](https://shopify.github.io/flash-list/docs/usage) for efficient rendering of large lists ### Data Structure [#data-structure] The `data` prop accepts three types of items: ```tsx // Section header (string) "Settings" // Standard setting item { title: "Account", leftIcon: () => , onPress: () => navigation.navigate("Account"), } // Custom component { custom: true, component: MyCustomComponent, // Additional props passed to component someCustomProp: "value", } ``` ### Border Radius Logic [#border-radius-logic] The component automatically manages border radius for visual grouping: - **Top radius**: Applied to first item or item following a section header - **Bottom radius**: Applied to last item or item before a section header - **Custom components**: Receive `borderTopRadius` and `borderBottomRadius` props ## Data Types [#data-types] ### SettingListItemProps [#settinglistitemprops] Standard setting list item: ```tsx type SettingListItemProps = ListItemProps & { title: string; onPress?: () => void; leftIcon?: React.ComponentProps["icon"]; borderTopRadius?: boolean; borderBottomRadius?: boolean; }; ``` ### CustomSettingListItem [#customsettinglistitem] Custom component integration: ```tsx type CustomSettingListItem = { custom: true; borderTopRadius?: boolean; borderBottomRadius?: boolean; component: React.ComponentType<{ borderTopRadius?: boolean; borderBottomRadius?: boolean; }>; [key: string]: unknown; }; ``` ## Related Components [#related-components] - [SettingListItem](/native-sdk/guide/components/setting/setting-list-item/) - Individual setting item component - [ListHeader](/native-sdk/guide/components/setting/list-header/) - Section header component # Socket hooks Canonical page: https://docs.ovok.com/native-sdk/guide/components/socket/hooks Both hooks require a `SocketProvider` ancestor. They are intended for real-time features; use the SDK client for request and response API calls. ## `useSocket` [#usesocket] Returns `{ socket, isConnected }`. `socket` is `null` until the first connection is established. Check `isConnected` before emitting or attaching a listener. Calling the hook outside `SocketProvider` throws. ```tsx const { socket, isConnected } = useSocket(); ``` ## `useAiEventListener` [#useaieventlistener] Returns `subscribe(type, callback)` for the `message` event on `/ai/session/message`. The callback receives the event's content, mode, reference, sender, sent time, and session. `subscribe` returns an unsubscribe function; call it when an app-owned subscription ends. ```tsx import * as React from "react"; import { useAiEventListener } from "@ovok/native/socket"; const { subscribe } = useAiEventListener(); React.useEffect(() => { return subscribe("message", handleMessage); }, [subscribe, handleMessage]); ``` Event consumers should tolerate reconnects and repeated messages. The provider's current network recovery behavior can leave a replacement socket without the original listener set. # Socket Canonical page: https://docs.ovok.com/native-sdk/guide/components/socket The Socket module wraps a `socket.io-client` connection to the Ovok backend and exposes the live `Socket` instance through React context. It connects when the native next client has a session, disconnects on sign-out, and reconnects the same socket when network access returns. This is the channel real-time SDK features (AI streaming, server-pushed logs, presence) ride on. Most apps only need it if they consume one of those features; REST traffic uses the native `Ovok` client. ## Exports [#exports] ```ts // from @ovok/native/socket export { SocketProvider } from "./components/socket-provider"; export { SocketContext } from "./contexts/socket-context"; export type { SocketContextType } from "./types/socket-context-type"; export type { SocketLogPayload } from "./types/socket-log-payload"; export { useAiEventListener } from "./hooks/use-ai-event-listener"; export { useSocket } from "./hooks/use-socket"; ``` Source: `src/modules/socket/index.ts`. ## `` [#socketprovider] Wrap your app (inside `OvokProvider` so the client + access token are available) to open the socket connection. ### Props [#props] ```ts import type { SocketLogPayload } from "@ovok/native/socket"; type SocketProviderProps = React.PropsWithChildren<{ onError?: (error: Error) => void; onConnectionError?: (error: Error) => void; onPing?: (latency: number) => void; onConnect?: () => void; onDisconnect?: () => void; onLogs?: (message: SocketLogPayload) => void; }>; ``` | Prop | When it fires | |---|---| | `onConnect` | Socket transport opened and authenticated with the bearer token. | | `onDisconnect` | Socket transport closed (network change, manual disconnect, idle timeout). | | `onError` | `error` event from the socket — typically protocol-level failures. | | `onConnectionError` | `connect_error` event — the handshake or authentication failed. Both `onError` and `onConnectionError` flip internal state back to `disconnected`. | | `onPing` | Socket.IO `ping` event latency/value supplied by the client transport. | | `onLogs` | Server-pushed log line. `SocketLogPayload = { message: string; level: 'info' \| 'warn' \| 'error' }`. | `SocketProvider` reads the native client's `baseUrl` and active session access token from `OvokProvider`, so it must be a descendant of that provider. The connection URL is `${baseUrl}events`. ### Reconnection [#reconnection] `SocketProvider` registers a `NetInfo` listener. When the network goes offline it calls `socket.disconnect()`. When the network returns it reconnects that socket with its listeners intact. An account switch closes the previous socket before connecting with the new token. Default `socket.io-client` options are 5 reconnection attempts with 1s → 5s delay. ## `useSocket()` [#usesocket] Read the live socket + connection state from context. ```ts type SocketContextType = { socket: ReturnType | null; isConnected: boolean; }; const { socket, isConnected } = useSocket(); ``` Throws if called outside ``. Returned `socket` is `null` without a session; gate connected operations on `isConnected`. ## `useAiEventListener()` [#useaieventlistener] Subscribe to AI events streamed over the socket (currently the `/ai/session/message` channel). ```ts type MessageEvent = { content: string; mode: "user" | "assistant"; reference: string; sender: string; sentAt: string; session: string; }; const { subscribe } = useAiEventListener(); ``` Use: ```tsx import { useAiEventListener } from "@ovok/native/socket"; function ChatView() { const { subscribe } = useAiEventListener(); const [messages, setMessages] = React.useState([]); React.useEffect(() => { const unsubscribe = subscribe("message", (event) => { setMessages((prev) => [...prev, event as MessageEvent]); }); return () => unsubscribe?.(); }, [subscribe]); return ; } ``` `subscribe(type, callback)` returns an unsubscribe function. Multiple subscribers per event type are supported; each receives every event independently. ## Full integration example [#full-integration-example] ```tsx import { OvokProvider } from "@ovok/core/next/react"; import { ThemeProvider as OvokThemeProvider, DEFAULT_COLORS, } from "@ovok/native"; import { Ovok } from "@ovok/native/next"; import { SocketProvider } from "@ovok/native/socket"; import * as SecureStore from "expo-secure-store"; const client = new Ovok({ baseUrl: "https://api.ovok.com/", tenantCode: "your-tenant", secureStore: SecureStore, }); function App() { return ( console.log("socket up")} onDisconnect={() => console.log("socket down")} onConnectionError={(e) => console.error("handshake failed", e)} onLogs={(payload) => console.log(`[${payload.level}]`, payload.message)} > ); } ``` ## When to mount it [#when-to-mount-it] - Mount **once at the root**, inside `OvokProvider`. Multiple `SocketProvider` instances create multiple sockets, which counts against the backend's per-user connection limit. - Mount **only if** you consume AI events, server-pushed logs, or another socket-only feature. REST traffic via `useFhirSearch` / `client.create` does not need a socket. - Mount **before** any consumer of `useSocket` or `useAiEventListener` in the tree — these throw if called outside. ## Related [#related] - [OvokProvider documentation](https://docs.ovok.com/) — the FHIR client + auth wrapper this depends on # SocketProvider Canonical page: https://docs.ovok.com/native-sdk/guide/components/socket/socket-provider Mount one `SocketProvider` below `OvokProvider`. It reads the current client's base URL and access token, connects to the Ovok `events` endpoint, and provides the socket and connection state to descendants. ```tsx import { OvokProvider } from "@ovok/core/next/react"; import { SocketProvider } from "@ovok/native/socket"; ``` The provider exposes callbacks for connection errors, transport errors, ping, and server-pushed log payloads. Keep `onLogs` free of identifiers and tokens. Mounting multiple providers opens multiple server connections. The current network reconnection path can replace the socket without restoring its listener set. Treat reconnect as best effort and keep a retry or refresh path for features that require live events. See [Socket hooks](/native-sdk/guide/components/socket/hooks/) for reading the connection and subscribing to AI session messages. # Socket types and context Canonical page: https://docs.ovok.com/native-sdk/guide/components/socket/types The socket subpath exports `SocketContext`, `SocketContextType`, and `SocketLogPayload`. | Type | Purpose | | --- | --- | | `SocketContextType` | The current Socket.IO instance, when connected, and `isConnected`. | | `SocketLogPayload` | Server log event with `message` and `level` (`info`, `warn`, or `error`). | `SocketProvider` accepts optional connect, disconnect, error, ping, and log callbacks. Its internal props type is not separately exported from the package. Use `useSocket` for normal consumption. `SocketContext` is exported for advanced integrations, but direct context access couples a component to the provider shape. # TabProvider and useTab Canonical page: https://docs.ovok.com/native-sdk/guide/components/tab/advanced-api `TabProvider` exposes a controlled `value` and `onChange` pair through `TabContext`. `useTab` reads that pair from a descendant. Use this API when you need to build a custom tab bar; the standard `Tab` already composes the provider and `Tab.Item`. ```tsx import { TabProvider, useTab } from "@ovok/native/tab"; function CustomTabButton({ value, children }) { const tabs = useTab(); return ( ); } Overview ``` `useTab` throws outside `TabProvider`. `TabContext` and `TabContextType` are exported for advanced integrations; prefer the hook for component code. # Tab Canonical page: https://docs.ovok.com/native-sdk/guide/components/tab Every symbol below is re-exported from the package barrel — you can `import { X } from '@ovok/native'` for any of them. Earlier guidance treated some of these as "internal-only"; that's no longer accurate, the barrel was expanded in #139 so the docs and the public surface match. - `Tab`, `Tab.Item` — controlled compound — pass `value: string`, `onChange: (v: string) => void`. `Tab.Item` accepts `value`, `icon`, active/inactive style slots. - `TabProvider` — standalone provider for custom tab UIs that don't want `Tab`'s default rendering. - `useTab` — hook returning `{ value, onChange }`; use it below `` or ``. - `TabContext` — underlying React context — escape hatch. - `TabProps`, `TabContextType` — TypeScript types. `TabItemProps` is used internally and is not a named package export; use the `Tab.Item` props inferred from the component. `useTab()` outside a `Tab` or `TabProvider` returns the context's empty default object; calling its `onChange` then fails with a generic type error. Keep consumers below one of those providers. The Tab module provides a flexible tab navigation component system built using the compound component pattern. It offers controlled state management, customizable styling, and seamless integration with the theme system for creating consistent navigation experiences in healthcare applications. See [TabProvider and useTab](/native-sdk/guide/components/tab/advanced-api/) when you need a custom tab bar. ## Overview [#overview] The Tab module is designed around a compound component architecture, providing maximum flexibility while maintaining a clean and intuitive API for building tab-based navigation interfaces. ### Key Features [#key-features] - **Compound Component Pattern**: `Tab` container with `Tab.Item` children for flexible composition - **Controlled State**: Fully controlled component with value and onChange props - **Theme Integration**: Built-in theming support with spacing, colors, and typography - **Icon Support**: Optional icon rendering for tab items with dynamic color support - **Customizable Styling**: Individual styling for active/inactive states and overall appearance - **Accessibility**: Test IDs are supported, but the components do not add semantic tab roles or states automatically; supply those semantics in the host navigation. - **TypeScript Support**: Full type safety with comprehensive type definitions ## Architecture [#architecture] The Tab system consists of several interconnected components: ### Core Components [#core-components] - **[Tab](/native-sdk/guide/components/tab/tab/)** - Main container component that manages state and provides context - **[Tab.Item](/native-sdk/guide/components/tab/tab-item/)** - Individual tab item component with icon and text support ## Related Components [#related-components] This Tab module integrates seamlessly with other SDK components to provide comprehensive navigation solutions for healthcare applications. # Tab.Item Canonical page: https://docs.ovok.com/native-sdk/guide/components/tab/tab-item Individual tab item component that represents a single tab within a Tab container. Supports icons, custom styling for active/inactive states, and theme integration with automatic color management. ## Quick Example [#quick-example] ```tsx import { Tab } from "@ovok/native"; import { Home, Settings, User } from "iconsax-react-nativejs"; import React from "react"; export const TabItemExample = () => { const [activeTab, setActiveTab] = React.useState("home"); return ( }> Home } > Profile } > Settings ); }; export default TabItemExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/tab` API reference](/native-sdk/reference/tab). ## Component Behavior [#component-behavior] The Tab.Item component: 1. **State Awareness**: Automatically detects if it's the active tab using context 2. **Dynamic Styling**: Applies different styles based on active/inactive state 3. **Color Management**: Provides appropriate colors to icon functions 4. **Event Handling**: Handles press events to update tab selection 5. **Theme Integration**: Uses theme colors for consistent appearance ### Color System [#color-system] Tab.Item automatically provides colors to icons and text based on state: - **Active**: `theme.colors.primary` - **Inactive**: `theme.colors.onSurfaceDisabled` ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.primary` - Active tab color (text and icon) - `theme.colors.onSurfaceDisabled` - Inactive tab color (text and icon) - `theme.spacing(1)` - Gap between icon and text - `theme.spacing(2)` - Vertical padding The component does not add an accessibility role, state, or label automatically. ## Related Components [#related-components] - [Tab](/native-sdk/guide/components/tab/tab/) - Parent container component # Tab Container Canonical page: https://docs.ovok.com/native-sdk/guide/components/tab/tab The main Tab container component that manages the selected state and provides context to child `Tab.Item` components through the compound component pattern. ## Quick Example [#quick-example] ```tsx import { Tab } from "@ovok/native"; import React from "react"; import { StyleSheet, View } from "react-native"; const styles = StyleSheet.create({ container: { padding: 16, }, }); const TabContainerExample = () => { const [activeTab, setActiveTab] = React.useState("first"); return ( First Tab Second Tab Third Tab ); }; export default TabContainerExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/tab` API reference](/native-sdk/reference/tab). ## Component Behavior [#component-behavior] The Tab container component: 1. **State Management**: Manages the currently selected tab through controlled props 2. **Context Provision**: Provides tab state to all child components via React Context 3. **Layout Container**: Renders a horizontal flexbox container for tab items 4. **Event Handling**: Handles tab selection changes and notifies parent components The container adds no accessibility role or label. Add accessibility semantics to the tab items or surrounding navigation according to the host app. ## Related Components [#related-components] - [Tab.Item](/native-sdk/guide/components/tab/tab-item/) - Individual tab item components # Colors Canonical page: https://docs.ovok.com/native-sdk/guide/components/theme/colors `DEFAULT_COLORS` is a typed starting palette for `ThemeProvider`. It contains Paper-compatible MD3 color tokens plus `success`, `error`, `warning`, and the extended `gray`, `blue`, `purple`, `pink`, `cyan`, `green`, `red`, `orange`, and `yellow` palettes. ```tsx import { DEFAULT_COLORS, ThemeProvider } from "@ovok/native"; ; ``` ## Palette shape [#palette-shape] The normal palette keys are `25`, `50`, and `100` through `1000`. `gray` also contains the optional `1100` shade. Do not document a `1100` shade for the other families unless the type and runtime palette gain it. Semantic colors are plain strings. The SDK does not compute accessible foreground colors when a semantic or brand color is overridden. Pair custom backgrounds with an explicitly tested `on*` color and verify light and dark themes. ## Extending the palette [#extending-the-palette] Use object spread so unrelated MD3 tokens and shades remain available: ```tsx const colors = { ...DEFAULT_COLORS, primary: "#0f766e", blue: { ...DEFAULT_COLORS.blue, 700: "#0f766e" }, }; ``` `DEFAULT_COLORS` is not a runtime contrast engine or a clinical interpretation layer. Status meaning and thresholds remain application-owned. # Theme Canonical page: https://docs.ovok.com/native-sdk/guide/components/theme The Theme module provides a comprehensive theming system built on Material Design 3 with custom color palettes, responsive spacing, and typography. It enables consistent design across your healthcare application with support for both light and dark modes. ## Overview [#overview] The Theme module integrates with React Native Paper to provide a powerful, flexible theming system that supports: ### Key Features [#key-features] - **Material Design 3**: Built on React Native Paper's MD3 implementation - **Custom Color System**: Extended color palettes with semantic healthcare colors - **Responsive Spacing**: Multiplier-based spacing system for consistent layouts - **Font loading**: Loads DM Sans variants before rendering children; Paper typography is not automatically rewired - **Dark Mode Support**: Uses the `dark` value supplied by the app; custom colors are used as supplied and are not contrast-adjusted automatically - **Healthcare Colors**: Semantic colors for success, error, and warning states - **TypeScript Support**: Full type safety throughout the theming system - **Performance Optimized**: Memoized theme generation ## Architecture [#architecture] The theming system consists of several key components: ### Core Components [#core-components] - **[ThemeProvider](/native-sdk/guide/components/theme/theme-provider/)** - Root provider component for theming context - **[useAppTheme](/native-sdk/guide/components/theme/use-app-theme/)** - Hook for accessing theme values in components ### Utilities & Configuration [#utilities--configuration] - **[Colors](/native-sdk/guide/components/theme/colors/)** - Comprehensive color system and palettes - **[Multipliers](/native-sdk/guide/components/theme/multipliers/)** - Spacing and border radius configuration ## Theme Configuration [#theme-configuration] ### Basic Theme Setup [#basic-theme-setup] ```tsx import { DEFAULT_COLORS, DEFAULT_MULTIPLIERS, ThemeProvider, } from "@ovok/native"; import { Text } from "react-native-paper"; const themeConfig = { colors: { ...DEFAULT_COLORS, // Override specific colors primary: "#2563EB", secondary: "#7C3AED", }, dark: false, spacingMultiplier: DEFAULT_MULTIPLIERS.spacing, borderRadiusMultiplier: DEFAULT_MULTIPLIERS.borderRadius, }; const App = () => ( Themed Text ); export default App; ``` ## Color System [#color-system] The theme provides an extensive color system with semantic meaning: ### Primary Colors [#primary-colors] - **Primary**: Main brand color for actions and highlights - **Secondary**: Supporting brand color for accents - **Tertiary**: Additional brand color for variety ### Semantic Colors [#semantic-colors] - **Success**: `#15B05D` - Positive health indicators, completed actions - **Error**: `#ED3D31` - Critical alerts, dangerous values, errors - **Warning**: `#FBEE37` - Attention needed, caution states ### Extended Palettes [#extended-palettes] Blue, purple, pink, cyan, green, red, orange, and yellow each include 12 shades (25, 50, and 100-1000). Gray includes those 12 plus the optional 1100 shade: - **Gray**: Neutral colors for text and backgrounds - **Blue**: Primary brand variations - **Green**: Success and health indicators - **Red**: Error and danger states - **Orange**: Warning and attention colors - **Purple, Pink, Cyan, Yellow**: Additional accent colors ## Spacing System [#spacing-system] The theme uses a multiplier-based spacing system for consistency: ```tsx const theme = useAppTheme(); // Usage patterns ``` ### Common Spacing Values [#common-spacing-values] - `theme.spacing(1)` - 4px - Tight spacing - `theme.spacing(2)` - 8px - Small gaps - `theme.spacing(3)` - 12px - Medium spacing - `theme.spacing(4)` - 16px - Standard padding - `theme.spacing(6)` - 24px - Large spacing - `theme.spacing(8)` - 32px - Section spacing ## Border Radius System [#border-radius-system] Consistent border radius for visual hierarchy: ```tsx ``` ## Typography Integration [#typography-integration] `ThemeProvider` requires the `@expo-google-fonts/dm-sans` peer dependency and loads the DM Sans font assets before rendering children. Install it with `npx expo install @expo-google-fonts/dm-sans`. Loading the assets does not replace React Native Paper's typography configuration; set a `fontFamily` yourself when a Paper text variant should use one of these faces. ### Available Font Weights [#available-font-weights] - **DMSans_400Regular** - Body text, descriptions - **DMSans_400Regular_Italic** - Emphasized body text - **DMSans_500Medium** - Subheadings, labels - **DMSans_500Medium_Italic** - Emphasized labels - **DMSans_700Bold** - Headings, titles - **DMSans_700Bold_Italic** - Emphasized headings ### Usage with React Native Paper [#usage-with-react-native-paper] ```tsx import { Text } from "react-native-paper"; Heading Text Body content Small labels ``` ## Dark Mode Support [#dark-mode-support] The app selects light or dark mode by passing `dark`: ```tsx const themeConfig = { colors: DEFAULT_COLORS, dark: true, // Enable dark mode spacingMultiplier: 4, borderRadiusMultiplier: 4, }; ``` Dark mode automatically: - Switches base MD3 theme to dark variant - Uses dark MD3 base tokens for values the app does not override; test custom colors for contrast in both light and dark mode - Preserves semantic color meanings - Keeps custom color overrides # Multipliers Canonical page: https://docs.ovok.com/native-sdk/guide/components/theme/multipliers `DEFAULT_MULTIPLIERS` is the exported convenience value: ```ts const DEFAULT_MULTIPLIERS = { spacing: 4, borderRadius: 4, } as const; ``` Pass the values explicitly to `ThemeProvider`: ```tsx theme={{ colors: DEFAULT_COLORS, dark: false, spacingMultiplier: DEFAULT_MULTIPLIERS.spacing, borderRadiusMultiplier: DEFAULT_MULTIPLIERS.borderRadius, }} ``` The generated helpers are direct multiplication: ```ts theme.spacing(4); // 16 with spacingMultiplier: 4 theme.borderRadius(2); // 8 with borderRadiusMultiplier: 4 ``` The SDK does not choose responsive multipliers based on screen width. If an app wants tablet or compact values, it owns that configuration and supplies a new theme to the provider. # ThemeProvider Canonical page: https://docs.ovok.com/native-sdk/guide/components/theme/theme-provider `ThemeProvider` generates an MD3 theme, loads the SDK's DM Sans font files, wraps children in `react-native-paper`'s `PaperProvider`, and includes the SDK's `DeviceListProvider`. ```tsx import { DEFAULT_COLORS, ThemeProvider as OvokThemeProvider } from "@ovok/native"; const theme = { colors: { ...DEFAULT_COLORS, primary: "#2563eb" }, dark: false, spacingMultiplier: 4, borderRadiusMultiplier: 4, }; ; ``` `@ovok/native` exports a `ThemeProvider` name. Alias it when the app also imports a `ThemeProvider` from `expo-router` or another navigation/theming package: ```tsx import { ThemeProvider as OvokThemeProvider } from "@ovok/native"; ``` `ThemeProvider` requires the `@expo-google-fonts/dm-sans` peer dependency. Install it with `npx expo install @expo-google-fonts/dm-sans` before bundling this provider. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/theme` API reference](/native-sdk/reference/theme). ## Rendering behavior [#rendering-behavior] The provider returns `null` until all six DM Sans variants have loaded. The fonts are loaded to make them available to the app, but the generated Paper theme does not wire a custom `fontFamily` into Paper's typography. Configure typography in your app if you need Paper text variants to use DM Sans. `useAppTheme()` outside an SDK `ThemeProvider` resolves the default Paper theme; the SDK spacing and border-radius helpers are available only after the generated theme is installed. Mount one provider around the components that consume it. # useAppTheme Canonical page: https://docs.ovok.com/native-sdk/guide/components/theme/use-app-theme `useAppTheme` is a typed wrapper around React Native Paper's `useTheme`: ```tsx const theme = useAppTheme(); return ( ); ``` ## Returned values [#returned-values] The returned `AppTheme` includes the Paper MD3 theme, extended colors, `spacing(value)`, `borderRadius(value)`, `roundness`, and `dark`. Both helper functions multiply the supplied number by the corresponding value passed to `ThemeProvider`; they do not round or clamp the argument. Call the hook below `ThemeProvider` to receive the SDK-generated helpers. Outside that provider, React Native Paper returns its default theme, which does not provide the SDK's `spacing`, `borderRadius`, or extended custom colors; calling those missing helpers can crash. Mount the SDK theme provider or use `useOvokUi`, which supplies fallback helper functions. ## Color contrast [#color-contrast] The SDK exposes semantic colors such as `success`, `error`, and `warning`, but it does not calculate contrast or automatically choose an `on*` color for custom overrides. Test text and control contrast in both light and dark configurations, especially if replacing `primary`, `error`, or palette shades. # Tile.CompleteAnimation Canonical page: https://docs.ovok.com/native-sdk/guide/components/tile/complete-animation Success animation overlay component that displays a celebratory animation when measurements are completed, providing positive user feedback and visual confirmation. ## Quick Example [#quick-example] ```tsx import { Tile } from "@ovok/native"; import React from "react"; const CompleteAnimationExample = () => { const [showAnimation, setShowAnimation] = React.useState(true); const handleAnimationEnd = () => { console.log("Animation completed"); setShowAnimation(false); }; return ( Blood Pressure Measurement {showAnimation && ( )} ); }; export default CompleteAnimationExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/tile` API reference](/native-sdk/reference/tile). ## Component Behavior [#component-behavior] The CompleteAnimation component: 1. **Overlay**: Positions absolutely over the entire tile content 2. **Entry Animation**: Fades in smoothly when displayed 3. **Success Icon**: Shows large green checkmark (TickCircle, 50px, Bold variant) 4. **Completion Text**: Displays "Completed" message below the icon 5. **Duration**: Runs for 3 seconds before triggering callback 6. **Exit Animation**: Fades out smoothly when removed 7. **Callback**: Executes `onAnimationEnd` when animation finishes ## Animation Timeline [#animation-timeline] ``` 0ms - Component mounts 0-300ms - FadeIn entrance animation 3000ms - Animation duration completes - onAnimationEnd callback fired (if provided) 3000ms+ - FadeOut exit animation (when component unmounts) ``` ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.surface` - Background overlay color - `theme.colors.success` - Checkmark icon color - `theme.spacing(2)` - Gap between icon and text ## Related Components [#related-components] - [Tile.MeasuringSpinner](/native-sdk/guide/components/tile/measuring-spinner/) - Loading state before completion - [Tile.MeasuredValue](/native-sdk/guide/components/tile/measured-value/) - Result display after animation - [Tile.Status](/native-sdk/guide/components/tile/status/) - Status updates throughout measurement process # Tile Canonical page: https://docs.ovok.com/native-sdk/guide/components/tile The Tile module provides interactive measurement display components designed for healthcare applications. It offers a complete solution for displaying measurement data, device status, and task progress with visual feedback and animations. ## Overview [#overview] The Tile module is built using a compound component pattern, providing maximum flexibility for different measurement types and device states while maintaining visual consistency across your healthcare application. ### Key Features [#key-features] - **Measurement Display**: Show measurement values, units, and timestamps - **Device Status**: Visual indicators for device connectivity and measurement progress - **Task Management**: Progress tracking with completion states and animations - **Interactive States**: Visual feedback for measuring, connected, and completed states - **Icon Support**: Pre-built measurement type icons for various healthcare devices - **Animation Support**: Smooth completion animations and loading spinners - **Theme Integration**: Consistent styling with Material Design 3 theming - **Accessibility boundary**: Add screen-reader labels, roles, and touch-target behavior in the app; the module does not add complete semantics automatically - **TypeScript**: Full type safety throughout all components ## Components [#components] ### Main Container [#main-container] - **[Tile](/native-sdk/guide/components/tile/tile/)** - Main container component with state management ### Content Components [#content-components] - **[Tile.StartSection](/native-sdk/guide/components/tile/start-section/)** - Header section with task icon and completion state - **[Tile.Title](/native-sdk/guide/components/tile/title/)** - Task title display component - **[Tile.TaskIcon](/native-sdk/guide/components/tile/task-icon/)** - Measurement type icons for various healthcare devices - **[Tile.MeasuredValue](/native-sdk/guide/components/tile/measured-value/)** - Display measurement values with units and time - **[Tile.MeasuringSpinner](/native-sdk/guide/components/tile/measuring-spinner/)** - Loading indicator during measurements - **[Tile.NoMeasuredValue](/native-sdk/guide/components/tile/no-measured-value/)** - Placeholder for missing measurements - **[Tile.Status](/native-sdk/guide/components/tile/status/)** - Device connection status indicator - **[Tile.CompleteAnimation](/native-sdk/guide/components/tile/complete-animation/)** - Success animation for completed measurements ## Common Patterns [#common-patterns] ### Measurement Flow States [#measurement-flow-states] The Tile component supports several common measurement flow states: 1. **Not Started**: Shows task icon, title, and "No data" placeholder 2. **Device Connected**: Shows connection status when device is ready 3. **Measuring**: Shows spinner animation during active measurement 4. **Completed**: Shows measured value with timestamp 5. **Success Animation**: Optional celebration animation on completion ### Measurement Types Support [#measurement-types-support] The component supports various healthcare measurement types: - Blood Pressure (`MeasurementTypeKey.bloodPressure`) - Blood Glucose (`MeasurementTypeKey.bloodGlucose`) - Body Weight (`MeasurementTypeKey.bodyWeight`) - Temperature (`MeasurementTypeKey.temperature`) - Heart Rate (`MeasurementTypeKey.heartRate`) - ECG (`MeasurementTypeKey.ecg`) - Blood Oxygen (`MeasurementTypeKey.bloodOxygenPulseRate`) - Step Count (`MeasurementTypeKey.stepCount`) - And many more... # Tile.MeasuredValue Canonical page: https://docs.ovok.com/native-sdk/guide/components/tile/measured-value Displays measurement results with a prominent value, unit label, and timestamp in a consistent format for healthcare data. ## Quick Example [#quick-example] ```tsx import { Tile } from "@ovok/native"; import React from "react"; const MeasuredValueExample = () => { return ( ); }; export default MeasuredValueExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/tile` API reference](/native-sdk/reference/tile). ## Component Behavior [#component-behavior] The MeasuredValue component displays data in a structured layout: 1. **Value and Unit Row**: Value and unit are displayed side-by-side with baseline alignment 2. **Value Prominence**: Large, bold text for the measurement value (24px, primary color) 3. **Unit Styling**: Smaller, muted text for the unit (14px, disabled color) 4. **Timestamp**: Displayed below the value in smaller, muted text (12px, disabled color) 5. **Typography**: Uses custom DMSans font family for enhanced readability ## Layout Structure [#layout-structure] ``` ┌─────────────────────────┐ │ [VALUE] [UNIT] │ ← Baseline aligned │ [TIMESTAMP] │ ← Below value/unit └─────────────────────────┘ ``` ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.primary` - Value text color for prominence - `theme.colors.onSurfaceDisabled` - Unit and timestamp text color for subtle appearance - `theme.spacing(1)` - Gap between value and unit ## Typography Specifications [#typography-specifications] ### Value Text [#value-text] - **Font Family**: DMSans_700Bold - **Font Size**: 24px - **Color**: theme.colors.primary - **Weight**: Bold (700) ### Unit Text [#unit-text] - **Font Family**: DMSans_400Regular - **Font Size**: 14px - **Color**: theme.colors.onSurfaceDisabled - **Weight**: Regular (400) ### Time Text [#time-text] - **Font Family**: DMSans_400Regular - **Font Size**: 12px - **Color**: theme.colors.onSurfaceDisabled - **Weight**: Regular (400) ## Related Components [#related-components] - [Tile.NoMeasuredValue](/native-sdk/guide/components/tile/no-measured-value/) - Placeholder when no data is available - [Tile.MeasuringSpinner](/native-sdk/guide/components/tile/measuring-spinner/) - Loading state during measurements - [Tile.Status](/native-sdk/guide/components/tile/status/) - Device status when not measuring # Tile.MeasuringSpinner Canonical page: https://docs.ovok.com/native-sdk/guide/components/tile/measuring-spinner Simple loading indicator component that displays during active measurements, providing visual feedback that the device is currently taking a measurement. ## Quick Example [#quick-example] ```tsx import { Tile } from "@ovok/native"; import React from "react"; const MeasuringSpinnerExample = () => { return ( ); }; export default MeasuringSpinnerExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/tile` API reference](/native-sdk/reference/tile). ## Component Behavior [#component-behavior] The MeasuringSpinner component: 1. **Size**: Defaults to the small size; `ActivityIndicatorProps` can override it 2. **Color**: Defaults to the theme primary color; `ActivityIndicatorProps` can override it 3. **Animation**: Continuous rotation animation indicating active measurement 4. **Integration**: Designed to replace other content during measurement state ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.primary` - Spinner color for brand consistency ## Related Components [#related-components] - [Tile.MeasuredValue](/native-sdk/guide/components/tile/measured-value/) - Result display after measurement - [Tile.Status](/native-sdk/guide/components/tile/status/) - Device status when not measuring - [Tile.CompleteAnimation](/native-sdk/guide/components/tile/complete-animation/) - Success animation after measurement # Tile.NoMeasuredValue Canonical page: https://docs.ovok.com/native-sdk/guide/components/tile/no-measured-value Placeholder component that displays helpful text when no measurement data is available, with support for custom content and localization. ## Quick Example [#quick-example] ```tsx import React from "react"; import { Tile } from "@ovok/native"; export const NoMeasuredValueExample = () => { return ( ); }; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/tile` API reference](/native-sdk/reference/tile). ## Component Behavior [#component-behavior] The NoMeasuredValue component: 1. **Default Text**: Shows localized "No measured value" message when no children provided 2. **Custom Content**: Supports custom text or components via children prop 3. **Typography**: Uses consistent small text styling (13px, regular weight) 4. **Placeholder Role**: Indicates missing data state to users ## Localization [#localization] ### Translation key [#translation-key] The component requests this translation key when no children are supplied: ```json { "tile": { "no-measured-value": "No data available" } } ``` - `tile.no-measured-value` - Placeholder key for missing measurements. Define it in the app's i18next resources; the SDK does not ship a default locale, so an absent resource can render the raw key. ## Related Components [#related-components] - [Tile.MeasuredValue](/native-sdk/guide/components/tile/measured-value/) - Displays actual measurement data - [Tile.MeasuringSpinner](/native-sdk/guide/components/tile/measuring-spinner/) - Loading state during measurement - [Tile.Status](/native-sdk/guide/components/tile/status/) - Device connection status information # Tile.StartSection Canonical page: https://docs.ovok.com/native-sdk/guide/components/tile/start-section Header section component that displays the task icon on the left, shows completion state with a checkmark, and supports optional right-side content for additional controls or information. ## Quick Example [#quick-example] ```tsx import { MeasurementTypeKey } from "@ovok/core/next"; import { Tile } from "@ovok/native"; import React from "react"; import { IconButton } from "react-native-paper"; const StartSectionExample = () => { return ( ( )} right={() => } testID="measurement-start-section" /> ); }; export default StartSectionExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/tile` API reference](/native-sdk/reference/tile). ## Component Behavior [#component-behavior] The StartSection component provides a flexible header layout with conditional rendering: 1. **Not Completed State**: Shows the `left` function content (typically a task icon) 2. **Completed State**: Replaces left content with a green checkmark (TickCircle icon) 3. **Right Content**: Always renders the `right` function content if provided 4. **Layout**: Uses space-between justification to separate left and right content ## Localization [#localization] This component does not use any localization keys directly. Localization is handled by the content rendered through the `left` and `right` functions. ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.success` - Default color for the completion checkmark icon ## Related Components [#related-components] - [Tile.TaskIcon](/native-sdk/guide/components/tile/task-icon/) - Measurement type icons for left side - [Tile.Title](/native-sdk/guide/components/tile/title/) - Title component that typically follows StartSection - [Tile](/native-sdk/guide/components/tile/tile/) - Parent container component # Tile.Status Canonical page: https://docs.ovok.com/native-sdk/guide/components/tile/status Device connection status indicator that displays the current state of a Bluetooth measurement device with color-coded text and localized status messages. ## Quick Example [#quick-example] ```tsx import { DeviceStatus, Tile } from "@ovok/native"; import React from "react"; const StatusExample = () => { return ( ); }; export default StatusExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/tile` API reference](/native-sdk/reference/tile). ## Device Status Types [#device-status-types] The component supports these device status values: ### DeviceStatus.CONNECTED [#devicestatusconnected] - **Color**: Green (700 shade) - **Meaning**: Device is connected and ready for measurement - **Translation Key**: `tile.status.connected` ### DeviceStatus.DISCONNECTED [#devicestatusdisconnected] - **Color**: Red (700 shade) - **Meaning**: Device is not connected or out of range - **Translation Key**: `tile.status.disconnected` ### DeviceStatus.MEASURING [#devicestatusmeasuring] - **Color**: Blue (700 shade) - **Meaning**: Device is actively taking a measurement - **Translation Key**: `tile.status.measuring` ### DeviceStatus.LOW_BATTERY [#devicestatuslow_battery] - **Color**: Orange (700 shade) - **Meaning**: Device battery is low and needs charging - **Translation Key**: `tile.status.low_battery` ## Component Behavior [#component-behavior] The Status component: 1. **Color Mapping**: Automatically maps device status to appropriate theme colors 2. **Text Display**: Shows localized status text based on the status value 3. **Typography**: Uses small, consistent text styling (12px, regular weight) 4. **Color Memoization**: Optimizes color calculations for performance ## Localization [#localization] ### Translation keys supplied by the app [#translation-keys-supplied-by-the-app] The component uses these translation keys: ```json { "tile": { "status": { "connected": "Connected", "disconnected": "Disconnected", "measuring": "Measuring...", "low_battery": "Low Battery" } } } ``` - `tile.status.connected` - Device is connected and ready - `tile.status.disconnected` - Device is not connected - `tile.status.measuring` - Device is actively measuring - `tile.status.low_battery` - Device battery is low The SDK requests these keys through the app's `react-i18next` resources; it does not ship the English strings shown above. If a key is missing, the raw key may be rendered. ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.green[700]` - Connected status - `theme.colors.red[700]` - Disconnected status - `theme.colors.blue[700]` - Measuring status - `theme.colors.orange[700]` - Low battery status ## Color Accessibility [#color-accessibility] The component uses semantic colors that provide clear meaning: - **Green**: Positive state (connected/ready) - **Red**: Error state (disconnected/unavailable) - **Blue**: Active state (measuring/in progress) - **Orange**: Warning state (low battery/attention needed) The 700 shades are defaults, not a contrast guarantee. Check the actual palette against the app's background in every supported theme. ## Related Components [#related-components] - [Tile.MeasuringSpinner](/native-sdk/guide/components/tile/measuring-spinner/) - Visual indicator for measuring state - [Tile.NoMeasuredValue](/native-sdk/guide/components/tile/no-measured-value/) - Placeholder when device is disconnected - [Tile.MeasuredValue](/native-sdk/guide/components/tile/measured-value/) - Result display when measurement completes # Tile.TaskIcon Canonical page: https://docs.ovok.com/native-sdk/guide/components/tile/task-icon Displays healthcare measurement type icons using SVG graphics with theme integration and support for various medical device types. ## Quick Example [#quick-example] ```tsx import React from "react"; import { Tile, useAppTheme } from "@ovok/native"; import { MeasurementTypeKey } from "@ovok/core/next"; export const TaskIconExample = () => { const theme = useAppTheme(); return ( ( )} /> ); }; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/tile` API reference](/native-sdk/reference/tile). ## Component Behavior [#component-behavior] The TaskIcon component: 1. **Icon Selection**: Uses `measurementTypeKey` to select the appropriate SVG icon 2. **Color Application**: Applies the specified color (or theme primary) to the SVG fill 3. **Size Control**: Sets both width and height to the same value for square icons 4. **Fallback**: Returns null if no icon is found for the measurement type 5. **Memoization**: Uses React.useMemo to optimize SVG generation ## Localization [#localization] This component does not use localization directly as it displays visual icons. However, it's often used alongside localized text: ```tsx import { useTranslation } from "react-i18next"; export const LocalizedIconExample = () => { const { t } = useTranslation(); return ( ( )} /> {t("tile.bloodPressure.label")} ); }; ``` ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.primary` - Default icon fill color when no custom color is provided ## Technical Implementation [#technical-implementation] The component uses: - **react-native-svg**: For SVG rendering - **Memoization**: Performance optimization for icon generation - **Dynamic SVG**: Icons are generated as SVG strings with dynamic color injection ## Related Components [#related-components] - [Tile.StartSection](/native-sdk/guide/components/tile/start-section/) - Common container for TaskIcon - [Tile.Title](/native-sdk/guide/components/tile/title/) - Often used together to identify measurement type - [Tile.Status](/native-sdk/guide/components/tile/status/) - Alternative status display for device states # Tile Component Canonical page: https://docs.ovok.com/native-sdk/guide/components/tile/tile The main container component that provides the foundation for displaying measurement data with interactive states, visual feedback, and consistent styling. ## Quick Example [#quick-example] ```tsx import { MeasurementTypeKey } from "@ovok/core/next"; import { Tile, useAppTheme } from "@ovok/native"; import React from "react"; import { StyleSheet, View } from "react-native"; const styles = StyleSheet.create({ container: { flex: 1, }, }); const BasicTileExample = () => { const theme = useAppTheme(); return ( ( )} /> Blood Pressure Measurement ); }; export default BasicTileExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/tile` API reference](/native-sdk/reference/tile). ## Component Behavior [#component-behavior] The Tile component automatically adjusts its visual appearance based on the measurement state: 1. **Normal State**: Standard appearance with surface background and subtle shadow 2. **Measuring State** (`isMeasuring={true}`): Enhanced elevation and z-index for prominence 3. **Other Device Measuring** (`isOtherDeviceMeasuring={true}`): Reduced opacity (50%) to indicate inactive state 4. **Content Layout**: Uses flex gap spacing between child components for consistent alignment The component serves as a container that manages visual states while delegating specific functionality to its child components. It does not add an accessibility role or label; provide those on interactive children. ## Localization [#localization] This component does not use any localization keys directly. Localization is handled by child components like `Tile.Title`, `Tile.NoMeasuredValue`, and `Tile.Status`. ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] - `theme.colors.surface` - Main background color of the tile - `theme.colors.outlineVariant` - Border color for subtle outline - `theme.colors.shadow` - Shadow color for depth effect - `theme.spacing(4)` - Internal padding around content - `theme.spacing(2)` - Gap between child components - `theme.borderRadius(4)` - Rounded corner radius ## Visual States [#visual-states] ### Normal State [#normal-state] - Standard surface background - Subtle border and shadow - All child components fully visible ### Measuring State [#measuring-state] - Enhanced elevation (zIndex: 10, elevation: 10) - Draws attention to active measurement - Usually combined with `Tile.MeasuringSpinner` ### Inactive State (Other Device Measuring) [#inactive-state-other-device-measuring] - Reduced opacity (50%) - Indicates this tile is not currently active - Prevents user interaction confusion ## Child Components [#child-components] The Tile component is designed to work with these specific child components: - `Tile.StartSection` - Header with task icon and completion state - `Tile.Title` - Measurement task title - `Tile.MeasuredValue` - Displayed measurement results - `Tile.MeasuringSpinner` - Loading indicator during measurement - `Tile.NoMeasuredValue` - Placeholder for missing data - `Tile.Status` - Device connection status - `Tile.CompleteAnimation` - Success animation overlay - `Tile.TaskIcon` - Measurement type icons ## Related Components [#related-components] - [Tile.StartSection](/native-sdk/guide/components/tile/start-section/) - Header section component - [Tile.Title](/native-sdk/guide/components/tile/title/) - Title display component - [Tile.MeasuredValue](/native-sdk/guide/components/tile/measured-value/) - Value display component # Tile.Title Canonical page: https://docs.ovok.com/native-sdk/guide/components/tile/title Simple title text component that displays measurement task names with consistent typography and theme integration. ## Quick Example [#quick-example] ```tsx import { Tile } from "@ovok/native"; import React from "react"; const TitleExample = () => { return ( Blood Pressure Measurement ); }; export default TitleExample; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/tile` API reference](/native-sdk/reference/tile). ## Component Behavior [#component-behavior] The Title component renders text using React Native Paper's Text component with: 1. **Typography**: Uses `titleLarge` variant from Material Design 3 2. **Font Family**: Custom font "DMSans_700Bold" for enhanced readability 3. **Font Size**: Fixed at 16px for consistent hierarchy 4. **Style Merging**: Combines default styles with custom styles passed via props ## Localization [#localization] This component does not handle localization directly. Translation should be handled by the parent component: ```tsx import { useTranslation } from "react-i18next"; export const LocalizedTitleExample = () => { const { t } = useTranslation(); return ( {t("measurements.bloodPressure.title")} ); }; ``` Common translation keys used with Tile.Title: ```json { "tile": { "bloodPressure": { "label": "Blood Pressure" }, "bloodGlucose": { "label": "Blood Glucose" }, "bodyWeight": { "label": "Body Weight" }, "temperature": { "label": "Temperature" } } } ``` ## Styling [#styling] ### Theme Colors Used [#theme-colors-used] This component uses the default text color from the theme through React Native Paper's Text component. ## Accessibility Features [#accessibility-features] - **Semantic Role**: Inherits proper text semantics from React Native Paper - **Screen Reader**: Text content is automatically read by screen readers - **Font Scaling**: Respects user's system font size preferences - **High Contrast**: Works with system accessibility settings ## Related Components [#related-components] - [Tile.StartSection](/native-sdk/guide/components/tile/start-section/) - Header section that typically precedes the title - [Tile.MeasuredValue](/native-sdk/guide/components/tile/measured-value/) - Value display that typically follows the title - [Tile.Status](/native-sdk/guide/components/tile/status/) - Status text component with similar styling # BackgroundSyncSetting Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/background-sync-setting `BackgroundSyncSetting` is a themed switch for Bluetooth background scanning. Render it beneath `BTProvider`, where `useBackgroundSync` can reach the active Bluetooth runtime: ~~~tsx import { useState } from "react"; import { BackgroundSyncSetting } from "@ovok/native/ui"; import { BTProvider } from "@ovok/native/bt-management"; function MonitoringSettings() { const [backgroundEnabled, setBackgroundEnabled] = useState(false); return ( { setBackgroundEnabled(enabled); await saveBackgroundPreference(enabled); }} /> ); } ~~~ The app owns the preference. Pass its current value to both the setting and `BTProvider.backgroundSync.enabled`, and persist changes in `onEnabledChange`. The setting's `enabled` prop initializes its local switch state; it does not subscribe to later prop changes. Keep the two values in sync from app-owned state. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/ui` API reference](/native-sdk/reference/ui). ## Related [#related] - [`BTProvider`](/native-sdk/guide/components/bt-management/bt-provider/) — Bluetooth session and queue configuration. - [Background sync APIs](/native-sdk/guide/components/background-sync/) — Android services, headless work, and helpers. # BluetoothStateNotice Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/bluetooth-state-notice `BluetoothStateNotice` observes Bluetooth radio and permission state. It renders a themed card when Bluetooth is unavailable and returns no UI while the radio is on. It does not scan or establish a Bluetooth session. ~~~tsx import { BluetoothStateNotice } from "@ovok/native/ui"; navigation.navigate("BluetoothSettings")} /> ~~~ Pass the app's long-lived `BleManager` so the notice observes the same radio state as the Bluetooth feature. Without a manager, the state is `unsupported`. ## States and actions [#states-and-actions] | State | Default behavior | | --- | --- | | `on` | Render nothing. | | `unauthorized` | Show an access button; the default action requests Bluetooth permission. | | `off` | Show an action that opens Bluetooth settings. | | `unsupported` | Explain that Bluetooth LE is unavailable; no action button. | The default permission request uses `react-native-permissions`. Provide `requestPermission` to use app-specific permission logic. Provide `onOpenSettings` to own the settings action; otherwise, the component opens Bluetooth settings through the platform link. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/ui` API reference](/native-sdk/reference/ui). # Calendar Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/calendar `Calendar` is a presentational month picker exported from `@ovok/native/ui`. It supports controlled or internal selection, month navigation, localized labels, week-start configuration, disabled dates, and optional day markers. It does not persist values or perform platform or network work. ```tsx import { Calendar } from "@ovok/native/ui"; ``` Pass `selectedDate` to control selection; update it in `onDateSelect`. Without `selectedDate`, the component keeps its own selection, initialized by `defaultSelectedDate`. Month navigation is controlled by `visibleMonth` and `onVisibleMonthChange`, or internally initialized by `defaultVisibleMonth`. Selection callbacks return local calendar `Date` values. Date-only strings in `YYYY-MM-DD` form are parsed as local calendar dates to avoid UTC day shifts. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `selectedDate` | `Date \| string \| null` | internal | Controlled selected day; `null` clears it | | `defaultSelectedDate` | `Date \| string` | — | Initial selection for uncontrolled mode | | `onDateSelect` | `(date: Date) => void` | — | Called when an enabled day is selected | | `visibleMonth` | `Date \| string` | internal | Controlled month to display | | `defaultVisibleMonth` | `Date \| string` | selected day or today | Initial month for uncontrolled mode | | `onVisibleMonthChange` | `(month: Date) => void` | — | Called with the first day of the displayed month | | `locale` | `string` | device locale | Locale for month, weekday, and accessible date labels | | `weekStartsOn` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6` | `1` | First weekday, where 0 is Sunday | | `minDate`, `maxDate` | `Date \| string` | — | Inclusive selectable date bounds | | `isDateDisabled` | `(date: Date) => boolean` | — | Additional caller-defined disabled dates | | `markers` | `readonly CalendarDayMarker[]` | `[]` | Static marked days | | `getMarkerForDate` | `(date: Date) => CalendarDayMarker \| undefined` | — | Dynamic day marker, useful for composed calendars | | `labelForDate` | `(date: Date) => string` | localized date | Override the accessible date label | | `previousMonthLabel`, `nextMonthLabel` | `string` | “Previous month”, “Next month” | Accessible navigation button labels | | `theme`, `slots` | `OvokThemeOverride`, `Partial` | Paper theme/default slot | Optional UI theme and primitive overrides | | `testID` | `string` | `calendar` | Prefix for calendar and day test IDs | `CalendarDayMarker` accepts `date`, optional `label`, `backgroundColor`, `color`, and optional `rangePosition` (`single`, `start`, `middle`, or `end`) to draw a continuous marked band. Every date and navigation control exposes an accessible label; selected and disabled states are also exposed to assistive technology. # EcgStripViewer Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/ecg-strip-viewer `EcgStripViewer` renders chronological ECG samples in a scrollable strip with page controls. Pass the samples in millivolts and the sampling rate in samples per second. It is a presentation component; your app extracts and validates the ECG data before rendering. Import it from `@ovok/native/ui`. ~~~tsx import { EcgStripViewer } from "@ovok/native/ui"; { setVisiblePage({ page, pageCount }); }} />; ~~~ ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/ui` API reference](/native-sdk/reference/ui). # FlowFrame Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/flow-frame `FlowFrame` gives onboarding, pairing, setup, and guided tasks a shared layout for safe areas, keyboard avoidance, optional step progress, and back navigation. It does not own routes, step state, persistence, or form controls. ```tsx navigation.goBack()} footer={} > ``` The content region is not wrapped in a `ScrollView`, so it can contain a `ScrollView`, `FlatList`, or another screen-owned scrolling view without nested scroll containers. Give a scrollable child `style={{ flex: 1 }}` when it should fill the available space. Safe-area edges default to all four sides and can be overridden when the host shell already handles some edges. The frame uses React Native's `KeyboardAvoidingView`; choose `keyboardBehavior` and `keyboardVerticalOffset` to match the host navigation header. On Android, the hardware back button calls `onBack` when it is supplied. Return `false` from the callback to let the host navigation handler continue; omit `onBack` or set `handleAndroidBack={false}` to leave the hardware action to the host. The visible back button calls the same callback. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/ui` API reference](/native-sdk/reference/ui). # HealthImportCard Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/health-import-card `HealthImportCard` renders health-access state and per-type status for an app-provided `HealthImportAdapter`. It can also display optional `SyncProgress` values. Import the component from `@ovok/native/ui` and the adapter type from `@ovok/native/bt-management`. ~~~tsx import { HealthImportCard } from "@ovok/native/ui"; import type { HealthImportAdapter } from "@ovok/native/bt-management"; type HealthType = "steps" | "weight"; const adapter: HealthImportAdapter = { getStatus: async (type) => readPermissionStatus(type), request: async (types, background) => { await requestAppHealthAccess(types, { background }); }, }; healthTypeLabels[type]} /> ~~~ This is an adapter-driven UI component. It does not configure HealthKit or Health Connect, and it does not start the SDK's `DataSync` import pipeline. For those integrations, see [`DataSync`](/native-sdk/guide/components/data-sync/) and the [HealthKit and Health Connect guide](/native-sdk/guide/modules/data-sync). ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/ui` API reference](/native-sdk/reference/ui). ## Status and request behavior [#status-and-request-behavior] The component calls `getStatus` for each listed type on mount and after a successful request. It shows these built-in labels: | Adapter status | Displayed state | | --- | --- | | `authorized` | Up to date | | `shouldRequest` | Waiting for permission | | `refused` | Not shared | | `unsupported` | Unavailable on this device | | No status yet | Checking access | The card is enabled only when every listed type is `authorized`. It marks refused types with an additional notice. If `getStatus` fails, the card displays the error and keeps that type's previous status, if one was already available. Turning the card on calls `adapter.request(types, background)` and refreshes the statuses when the promise resolves. Turning it off only changes local UI state. The adapter contract has no revoke, stop, or cancel method, so switching off does not revoke OS permission or stop an app-owned import service. The card does not subscribe to permission changes made elsewhere; refresh or remount it from app-owned state when access may have changed in system settings. The built-in copy goes through `react-i18next` with the English text above as the default, so it renders unchanged until your app adds these keys to its locale resources: | Key | Default | | --- | --- | | `health-import-card.title` | Health data import | | `health-import-card.status.authorized` | Up to date | | `health-import-card.status.shouldRequest` | Waiting for permission | | `health-import-card.status.refused` | Not shared | | `health-import-card.status.unsupported` | Unavailable on this device | | `health-import-card.status.checking` | Checking access | | `health-import-card.not-shared` | Some data types are not shared. You can enable them in your health app. | | `health-import-card.connect` | Connect health data | | `health-import-card.stop` | Stop import | An explicit `title` prop still wins over the translated title. `statusLabels` and `reasonLabels` customize only the nested sync-progress list; type names come from `labelForType`. See [Reusable flows](/native-sdk/guide/how-to/reusable-flows) for the app integration boundary. # App UI components Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui Import the SDK's reusable UI components and shared theming helpers from `@ovok/native/ui`: ~~~tsx import { BluetoothStateNotice, MeasurementTrendChart, useOvokUi, } from "@ovok/native/ui"; ~~~ These components render presentation and local interaction state. The app owns navigation, active user and patient context, persistence, authorization policy, and product-specific language. Use the separate [Reusable flows](/native-sdk/guide/components/ui/reusable-flows/) section for pairing, manual entry, and adapter-driven health access. ## Components [#components] | Component | What it renders | Reference | | --- | --- | --- | | `BluetoothStateNotice` | Bluetooth radio/permission status and a recovery action | [BluetoothStateNotice](/native-sdk/guide/components/ui/bluetooth-state-notice) | | `BackgroundSyncSetting` | A switch for Bluetooth background-scan state | [BackgroundSyncSetting](/native-sdk/guide/components/ui/background-sync-setting) | | `SupportedDevicesCatalogList` | Device catalog cards with metadata, credits, and optional manuals | [SupportedDevicesCatalogList](/native-sdk/guide/components/ui/supported-devices-catalog-list) | | `EcgStripViewer` | A paged SVG ECG waveform from app-provided samples | [EcgStripViewer](/native-sdk/guide/components/ui/ecg-strip-viewer) | | `MeasurementTrendChart` | One or more numeric series with optional normal range and thresholds | [MeasurementTrendChart and Sparkline](/native-sdk/guide/components/ui/measurement-trend-chart) | | `UrineTestResult` | A urine-analysis measurement with analyte labels and usual-range state | [UrineTestResult](/native-sdk/guide/components/ui/urine-test-result) | The focused flows are: - [`PairingFlow`](/native-sdk/guide/components/ui/pairing-flow) - [`ManualEntryForm`](/native-sdk/guide/components/ui/manual-entry-form) - [`HealthImportCard`](/native-sdk/guide/components/ui/health-import-card) ## Theme and slots [#theme-and-slots] `useOvokUi({ theme?, slots? })` returns a merged `OvokTheme` and resolved Paper primitive slots (`ResolvedOvokUiSlots`: every slot except `UrineAnalyteRow` is always set; a slot you omit or pass as `undefined` falls back to the Paper primitive). It reads the active React Native Paper theme when available and supplies default theme and spacing helpers when no app theme is installed. There is no separate UI provider. The exports include `OvokTheme`, `OvokThemeOverride`, `OvokUiProps`, `OvokUiSlots`, `UrineAnalyteRowProps`, and `mergeOvokTheme`. UI slots can replace `Button`, `Card`, `Text`, `Switch`, `TextInput`, and `ActivityIndicator`; `UrineTestResult` also accepts an `UrineAnalyteRow` renderer. Replacement components should accept the props of the corresponding React Native Paper component. The merge is shallow for top-level properties and one level deep for `colors` and `fonts`. Components use `spacing` and `borderRadius` as functions, so overrides for those entries must also be functions. For the app-level provider and typography setup, see [Theme](/native-sdk/guide/components/theme/) and [App shell and providers](/native-sdk/guide/how-to/app-shell). ## Related guides [#related-guides] - [App UI](/native-sdk/guide/modules/ui) — choose components and integrate them with the app shell. - [Reusable flows](/native-sdk/guide/how-to/reusable-flows) — compose pairing, measurement entry, and health access. - [Bluetooth](/native-sdk/guide/modules/bt-management) and [Health data](/native-sdk/guide/modules/data-sync) — configure the feature APIs behind UI. # ManualEntryForm Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/manual-entry-form `ManualEntryForm` builds numeric inputs from the SDK's `measurementFieldCatalog` for one `MeasurementTypeKey`. It validates required fields and catalog ranges, then passes a typed value to the app's async save callback. ~~~tsx import { MeasurementTypeKey } from "@ovok/core/next"; import { ManualEntryForm, type ManualEntrySaveInput } from "@ovok/native/ui"; const saveMeasurement = async (input: ManualEntrySaveInput) => { await measurementRepository.save({ patientId: activePatient.id, ...input }); }; fieldLabels[field] ?? field} onSaved={() => navigation.goBack()} /> ~~~ The form does not select a patient, construct a FHIR resource, choose offline behavior, or navigate. Those decisions stay in the app's callback and screen. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/ui` API reference](/native-sdk/reference/ui). # MeasurementTrendChart Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/measurement-trend-chart `MeasurementTrendChart` renders one or more numeric series as SVG polylines. It can also show a normal-value band and dashed threshold lines. The component is a presentation primitive: it does not label axes, format units, infer dates, or make clinical decisions. ```tsx import { MeasurementTrendChart, type MeasurementReading, } from "@ovok/native/ui"; const readings: MeasurementReading[] = [ { at: Date.parse("2026-01-01"), values: [120, 80] }, { at: Date.parse("2026-01-02"), values: [118, 78] }, ]; ; ``` ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/ui` API reference](/native-sdk/reference/ui). ## `Sparkline` [#sparkline] `Sparkline` is the same chart with compact defaults: `width` defaults to `160` and `height` defaults to `48`. Passing either prop overrides its compact default. ```tsx import { Sparkline } from "@ovok/native/ui"; ; ``` If `readings` and all optional domain values are empty, the component renders an empty view with the requested dimensions. Values are scaled to the supplied chart box; the chart does not clamp outliers or validate measurement units. # NearbyDevicePrompt Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/nearby-device-prompt Mount `NearbyDevicePrompt` inside `BTProvider` to offer one accepted nearby device at a time. The prompt never connects until the person taps “Yes, pair it”. Without mounting it, the SDK behaves as before. ```tsx import { NearbyDevicePrompt } from "@ovok/native/ui"; analytics.track("device_paired", { id: device.id })} /> ``` `Not mine` persists the device ID under `${storageKey}.declined-nearby-devices` (or `declinedStorageKey` when supplied). `Later` skips it for the current Bluetooth provider session without writing storage. Devices already remembered by `usePairedDevices` and declined IDs are not offered. If a connection fails, the dialog shows the same device-neutral, Bluetooth-error-code keyed copy as `PairingFlow`, with a retry button. The component is foreground UI and does not change background synchronization. The headless `useNearbyDeviceOffer` hook provides the same offer, actions, status, and typed `BluetoothError` without rendering UI. | Prop | Type | Description | | --- | --- | --- | | `storage` | `PairedDeviceStorage` | Required persistence adapter used for remembered and declined device IDs. | | `storageKey` | `string` | Pairing key used by `usePairedDevices`; defaults to `@ovok/native/paired-devices`. | | `declinedStorageKey` | `string` | Optional key for persisted “Not mine” device IDs. | | `enabled` | `boolean` | Suppress the prompt while the app is showing its own pairing UI. Defaults to `true`. | | `hint` | `string` | Optional app-owned device-specific pairing instruction. | | `labels` | `Record` | Override `title`, `pair`, `notMine`, `later`, `retry`, `pairing`, `hint`, and Bluetooth error-code copy. | | `onPaired` | `(device: RuntimeDevice) => void` | Called after connection and pairing storage succeed. | | `onError` | `(error: Error, device?: RuntimeDevice) => void` | Called after a connection or persistence error. | | `theme`, `slots`, `testID` | shared UI props | Optional theme, primitive overrides, and test ID. | The hook is exported from `@ovok/native/bt-management`; the prompt is exported from `@ovok/native/ui`. # PairingFlow Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/pairing-flow `PairingFlow` renders devices discovered by the active Bluetooth runtime, starts pairing, presents a pairing-code field when the runtime requests one, and remembers the ID of a device after it becomes bonded. Import it from `@ovok/native/ui` and render it beneath `BTProvider`. ~~~tsx import { BTProvider } from "@ovok/native/bt-management"; import { PairingFlow } from "@ovok/native/ui"; confirmPairingCode(device, code)} onPaired={(device) => navigation.navigate("DeviceDetails", { id: device.id })} onError={(error, device) => reportPairingError(error, device?.id)} /> ~~~ `BTProvider` owns discovery and the BLE runtime. This component does not create a manager or start a scan. Supply a `PairedDeviceStorage` implementation; the flow stores a JSON array of IDs, not device objects or credentials. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/ui` API reference](/native-sdk/reference/ui). ## Pairing lifecycle [#pairing-lifecycle] The flow exposes these statuses through render state and custom device actions: | Status | Meaning | | --- | --- | | `idle` | No pairing attempt is active. | | `pairing` | `useNearbyDevices().pair` is in progress or awaiting the bond event. | | `code-required` | A runtime pairing event requested a code; the flow shows its input. | | `paired` | The selected device emitted a bonded event. | | `error` | Pairing or code handling failed. | `onPairingCode` receives the trimmed value and selected runtime device. The flow does not confirm the code itself; provide a handler for the device's pairing procedure. A resolved handler returns the status to `pairing`. The matching bonded event updates the visible status to `paired`; after the underlying pair operation resolves, the flow stores the ID and calls `onPaired` only if it observed that event. If the pair operation rejects, the flow reports an error and does not store the ID. The default row starts pairing and shows optional device image, name, manufacturer, and pair action. It does not render a forget control. To offer forgetting, supply `renderDevice` and call `actions.forget()` from your row. That method asks the active Bluetooth manager to forget the device, then removes its ID from storage; it rejects if the manager is not ready. `PairingFlowRenderState` contains `devices`, `paired` IDs, optional `selected` device, `status`, and optional `error`. `renderHeader` and `renderEmpty` receive this state. `renderDevice` receives one device and an actions object: ~~~ts { pair: () => Promise; forget: () => Promise; status: PairingFlowStatus; } ~~~ The status is shared by the flow's current selection. If rows need independent per-device state or richer accessibility behavior, own that presentation in the custom row. The `labels` keys and default copy are: | Key | Default | | --- | --- | | `header` | Add a device | | `description` | Wake your monitor and choose it when it appears nearby. | | `empty` | No supported devices found yet. | | `device` | Bluetooth device (used when the manufacturer name is empty) | | `pair` | Pair | | `pairingCodePrompt` | Type the code your monitor shows | | `pairingCode` | Pairing code | | `continue` | Continue | | `pairing` | Pairing the selected device… | | `paired` | The selected device is ready. | | `retry` | Try again | | `remembered` | A count-specific remembered-device message | The default pairing, paired, and remembered messages include the selected device name or count. A value supplied in `labels` replaces the message verbatim; the flow does not interpolate placeholders in custom strings. See [Reusable flows](/native-sdk/guide/how-to/reusable-flows) for integration guidance and [Bluetooth](/native-sdk/guide/modules/bt-management) for provider and device discovery setup. # PeriodCalendar Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/period-calendar `PeriodCalendar` composes the shared `Calendar` component and marks inclusive date ranges supplied by the host application. The app remains responsible for collecting and storing the data. ```tsx import { PeriodCalendar, type PeriodDateRange } from "@ovok/native/ui"; const periods: PeriodDateRange[] = [ { startDate: "2026-05-03", endDate: "2026-05-07" }, ]; ``` The start and end dates are inclusive. Overlapping and adjacent intervals are merged for display. The shared calendar provides navigation, selection, localization, accessibility, and theme/slot handling. This component does not infer cycle length, predict future periods or fertility windows, persist health data, request platform permissions, or provide medical advice. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `periods` | `readonly PeriodDateRange[]` | required | Host-supplied `{ startDate, endDate }` intervals | | `periodLabel` | `string` | `Period` | Complete accessible marker and legend label; supply translated text when needed | | `labelForPeriodDate` | `(date: Date) => string` | `periodLabel` | Optional date-specific accessible marker label | | `showLegend` | `boolean` | `true` | Show the marker legend | | Calendar props | `CalendarProps` except `markers` and `getMarkerForDate` | — | Selection, month, locale, bounds, theme, and slots | # PrerequisiteGate Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/prerequisite-gate `PrerequisiteGate` prevents app content from flashing before an asynchronous, host-owned prerequisite check finishes. The host's `check` callback reads the current account/project state; the SDK does not assume a backend endpoint or store prerequisite state on the device. ```tsx loadRequiredTaskForCurrentAccount()} pending={} renderRequired={(task, refresh) => ( )} onError={logPrerequisiteCheckFailure} > ``` - `scopeKey` must change when the signed-in account or project changes. A result from the previous scope is hidden immediately while the new check runs. - Return `null` when nothing is required, or return the host's requirement value for `renderRequired`. After saving the required task, call `refresh`; the gate checks the server again before revealing its children. - While loading, `pending` is shown. It defaults to `null`, so the children do not render early. Keep the loading view non-blocking and app-localized. - If `check` rejects (for example, because the device is offline or access is unavailable), `onError` is called and the gate renders its children. This is deliberately fail-open: it must not lock a person out because a check failed. This is a presentation gate, not an authorization boundary. The server must still enforce access rules on protected data and operations. The host must use an account-scoped, authorized source if the requirement needs to follow the person across devices. Keep the `check` callback stable where practical; it is re-read when the `scopeKey` changes or `refresh` is called. # Reusable flows Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/reusable-flows These higher-level components from `@ovok/native/ui` package common interaction patterns while leaving product policy and persistence to the host app. | Component | SDK handles | App provides | | --- | --- | --- | | [`PairingFlow`](/native-sdk/guide/components/ui/pairing-flow) | Discovered-device list, pairing state, pairing-code input, and persistence of bonded device IDs | `BTProvider`, async paired-device storage, code confirmation when required; custom rows to expose `forget` | | [`ManualEntryForm`](/native-sdk/guide/components/ui/manual-entry-form) | Measurement-catalog fields, numeric validation, and save-pending UI | Async persistence callback, patient mapping, and product labels | | [`HealthImportCard`](/native-sdk/guide/components/ui/health-import-card) | Adapter status display, access-request action, and optional sync progress | `HealthImportAdapter`, health permission policy, and the import service | The components can be adopted independently. For setup and end-to-end examples, see [Reusable flows](/native-sdk/guide/how-to/reusable-flows). For every `@ovok/native/ui` export, theme behavior, and slots, see [App UI components](/native-sdk/guide/components/ui/). # SupportedDevicesCatalogList Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/supported-devices-catalog-list `SupportedDevicesCatalogList` renders the richer SDK device catalog as cards with artwork, manufacturer, measurement types, image credits, and an optional manual link. Import it from `@ovok/native/ui`. ~~~tsx import { SupportedDevicesCatalogList } from "@ovok/native/ui"; { if (device.acceptedDevices.length > 0) { chooseAcceptedDevices(device.acceptedDevices); } }} />; ~~~ By default the component reads `SUPPORTED_DEVICES`. Each `SupportedDeviceDefinition` includes an ID, display metadata, declared measurement types, optional manual URL, and an `acceptedDevices` array. Some catalog entries have no SDK device declaration. Treat an empty array as display-only and do not pass it as a supported Bluetooth connection. ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/ui` API reference](/native-sdk/reference/ui). # UrineTestResult Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/urine-test-result `UrineTestResult` renders a `UrineAnalyzeMeasurement` using the SDK's analyte definitions and measurement field catalog. It formats values and displays a usual range label when the catalog provides both bounds. It is a presentation component, not a clinical interpretation. ~~~tsx import { UrineTestResult } from "@ovok/native/ui"; labels[key] ?? fallback} accessibilityLabelForAnalyte={(key, fallback) => `${labels[key] ?? fallback}`} /> ~~~ ## Props [#props] Every prop, with its type and description, is listed in the [`@ovok/native/ui` API reference](/native-sdk/reference/ui). # WearableProviderIcon Canonical page: https://docs.ovok.com/native-sdk/guide/components/wearables `WearableProviderIcon` draws a provider's monogram on its brand colour, for each wearable in `@ovok/core`'s wearables namespace and for Apple Health and Health Connect. `WEARABLE_PROVIDERS` holds each provider's display name, colour and monogram. ```tsx import { WEARABLE_PROVIDERS, WearableProviderIcon } from "@ovok/native/wearables"; {WEARABLE_PROVIDERS.polar.name} ``` The icons are original monograms, not the providers' logos. The icon is labelled with the provider's name for screen readers. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `provider` | `WearableSource` | - | A `WearableProvider` from `@ovok/core`, `"apple-health"` or `"health-connect"`. | | `size` | `number` | `40` | Width and height in points. | # Getting started Canonical page: https://docs.ovok.com/native-sdk/guide/getting-started This guide connects an Expo Router app to an OVOK environment and renders a working email sign-in screen. It assumes you have an OVOK API URL and a patient tenant code. If you are choosing native dependencies or configuring platform permissions, start with [Installation and native setup](/native-sdk/guide/how-to/installation). The repository example currently uses Expo SDK 57 and React Native 0.86.3. Match the versions and peer dependencies to your app; the [installation guide](/native-sdk/guide/how-to/installation#compatibility-baseline) is the source for this repository's compatibility baseline. The complete SDK needs a native build. Expo Go does not include all of its native modules. ## 1. Install the SDK [#1-install-the-sdk] ~~~bash npm install @ovok/native @ovok/core ~~~ Install the peer dependencies required by the APIs you will import. Use the peer-dependency matrix in [Installation and native setup](/native-sdk/guide/how-to/installation#install-the-package), and use `npx expo install` for Expo packages so Expo can select compatible versions. The code below uses the SDK root entry, theme, authentication UI, and native next client. For a smaller import surface, use the documented subpaths in the [Public API map](/native-sdk/guide/public-api). ## 2. Add your OVOK environment values [#2-add-your-ovok-environment-values] Create `.env.local` in the Expo app root and replace the sample values with the ones for your OVOK environment: ~~~dotenv EXPO_PUBLIC_OVOK_BASE_URL=https://api.example.com EXPO_PUBLIC_TENANT_CODE=your-patient-tenant-code ~~~ Expo embeds `EXPO_PUBLIC_` values in the app bundle. Use them for public configuration only; never put private credentials or secrets in them. Restart Expo after changing the file. ## 3. Initialize the app shell [#3-initialize-the-app-shell] First initialize the runtime from the entry module as shown in [Polyfills and runtime setup](/native-sdk/guide/components/polyfills/). The client example below assumes that bootstrap completed before this app module was loaded. In an Expo Router app, put the following in `app/_layout.tsx`; if your project uses Expo's `src` directory, use `src/app/_layout.tsx` instead. ~~~tsx import { OvokProvider } from "@ovok/core/next/react"; import { DEFAULT_COLORS, DEFAULT_MULTIPLIERS, ThemeProvider as OvokThemeProvider, } from "@ovok/native"; import { Ovok } from "@ovok/native/next"; import * as SecureStore from "expo-secure-store"; import { Stack } from "expo-router"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { KeyboardProvider } from "react-native-keyboard-controller"; const baseUrl = process.env.EXPO_PUBLIC_OVOK_BASE_URL; const tenantCode = process.env.EXPO_PUBLIC_TENANT_CODE; if (!baseUrl || !tenantCode) { throw new Error("Set EXPO_PUBLIC_OVOK_BASE_URL and EXPO_PUBLIC_TENANT_CODE in .env.local"); } // Keep the client outside the component so it is not recreated on each render. const client = new Ovok({ baseUrl, tenantCode, secureStore: SecureStore, }); export default function RootLayout() { return ( ); } ~~~ `KeyboardProvider` supports the keyboard-aware sign-in form. Add `BottomSheetModalProvider` and a navigation theme when the screens you use need them; see [App shell and providers](/native-sdk/guide/how-to/app-shell) for the full provider setup. ## 4. Add the sign-in route [#4-add-the-sign-in-route] Create `app/index.tsx` (or `src/app/index.tsx`) and add the email sign-in screen. Patient sign-in requires a tenant code; `SignIn.EmailForm` reports success and errors so your app can own navigation and messaging. ~~~tsx import { SignIn } from "@ovok/native"; import { useRouter } from "expo-router"; import { Alert } from "react-native"; const tenantCode = process.env.EXPO_PUBLIC_TENANT_CODE; if (!tenantCode) { throw new Error("Set EXPO_PUBLIC_TENANT_CODE in .env.local"); } export default function SignInScreen() { const router = useRouter(); return ( router.replace("/home")} onError={(error) => Alert.alert("Sign-in failed", error.message)} > ); } ~~~ ## 5. Add a destination after sign-in [#5-add-a-destination-after-sign-in] Create `app/home.tsx` (or `src/app/home.tsx`) so the success route exists: ~~~tsx import { Text, View } from "react-native"; export default function HomeScreen() { return ( You are signed in. ); } ~~~ Replace this screen and the `/home` route with your app's authenticated navigation when you integrate the flow. For MFA and social sign-in setup, continue to [Authentication](/native-sdk/guide/modules/auth). ## 6. Build and run on a native target [#6-build-and-run-on-a-native-target] Build and launch on an iOS simulator/device: ~~~bash npx expo prebuild npx expo run:ios ~~~ Or build and launch on Android: ~~~bash npx expo prebuild npx expo run:android ~~~ `prebuild` applies your Expo config and native plugins. Rebuild the native app after adding a native dependency or changing a config plugin. JavaScript-only changes do not require another prebuild. See [Troubleshooting](/native-sdk/guide/how-to/troubleshooting) if the native build or sign-in flow fails. ## Where to go next [#where-to-go-next] - Add a BLE measurement flow with [Bluetooth](/native-sdk/guide/modules/bt-management) and the [device catalog](/native-sdk/guide/modules/bt-device). - Import Apple Health or Health Connect records with [Health data](/native-sdk/guide/modules/data-sync). - Set up durable background delivery with [Background sync](/native-sdk/guide/modules/background-sync). - Find package entry points and import paths in the [Public API map](/native-sdk/guide/public-api). # Build an app with the SDK Canonical page: https://docs.ovok.com/native-sdk/guide/how-to/app-building This guide shows how to grow a working `@ovok/native` setup into a mobile app. It uses a practical order: initialize the SDK once, add an authenticated route, connect one health workflow, and then expand the app around the data it receives. Start with the [quick start](/native-sdk/guide/getting-started) to install the SDK and render sign-in. This page assumes that the app has an OVOK environment URL, a patient tenant code, and a native development build. See [installation and native setup](/native-sdk/guide/how-to/installation) for package peers, Expo configuration, and platform permissions. ## Decide what the SDK owns [#decide-what-the-sdk-owns] The SDK provides native integrations, health-specific UI, and typed state. The host app still decides how users move through the app and what happens to the data. | Area | SDK provides | Your app provides | | --- | --- | --- | | Runtime | OVOK client integration, native polyfills, theme context | Environment values, one client instance, application startup | | Authentication | Sign-in, registration, recovery, profile and session components | Routes, tenant policy, error messaging, account rules | | Bluetooth | Device protocols, scan lifecycle, decoded measurements | Device choice, patient association, persistence and upload policy | | Health import | HealthKit and Health Connect authorization and sync components | Requested data types, code mapping, permission education and retry UX | | Forms and records | Questionnaire and observation presentation components | Resource selection, app navigation and workflow decisions | | Background work | Queues and platform scheduling helpers | Durable credentials, consent, idempotent upload and user-visible status | The SDK components do not replace your app's navigation, patient selection, data retention, or support policy. Make those decisions at the point where data enters your application. ## 1. Set up the app shell once [#1-set-up-the-app-shell-once] Keep the client and native managers outside React renders. Mount the providers once above the routes that use the SDK. The full provider order and theme contract are in [App shell and providers](/native-sdk/guide/how-to/app-shell). Initialize the native runtime from the app entry module before importing this app shell, as shown in [Polyfills and runtime setup](/native-sdk/guide/components/polyfills/). ```tsx import { OvokProvider } from "@ovok/core/next/react"; import { DEFAULT_COLORS, DEFAULT_MULTIPLIERS, ThemeProvider as OvokThemeProvider, } from "@ovok/native"; import { Ovok } from "@ovok/native/next"; import * as SecureStore from "expo-secure-store"; import { BottomSheetModalProvider } from "@gorhom/bottom-sheet"; import { KeyboardProvider } from "react-native-keyboard-controller"; import type { PropsWithChildren } from "react"; const baseUrl = process.env.EXPO_PUBLIC_OVOK_BASE_URL; const tenantCode = process.env.EXPO_PUBLIC_TENANT_CODE; if (!baseUrl || !tenantCode) { throw new Error("Set EXPO_PUBLIC_OVOK_BASE_URL and EXPO_PUBLIC_TENANT_CODE"); } const client = new Ovok({ baseUrl, tenantCode, secureStore: SecureStore }); export function AppProviders({ children }: PropsWithChildren) { return ( {children} ); } ``` `OvokProvider` comes from `@ovok/core/next/react`; the UI `ThemeProvider` comes from `@ovok/native`. Add your navigation theme and safe-area setup to this shell as your app needs them. `BottomSheetModalProvider` is a peer provider used by SDK sheets and must be imported from `@gorhom/bottom-sheet`. Keep public environment configuration in your app's environment system. Values embedded in the client bundle are visible to users; never put private credentials in `EXPO_PUBLIC_` variables. ## 2. Add sign-in and choose the authenticated destination [#2-add-sign-in-and-choose-the-authenticated-destination] Use the compound sign-in component to keep the SDK's validation and authentication behavior while your app owns navigation and error presentation. ```tsx import { SignIn } from "@ovok/native"; import { useRouter } from "expo-router"; import { Alert } from "react-native"; const tenantCode = process.env.EXPO_PUBLIC_TENANT_CODE; export function SignInScreen() { const router = useRouter(); if (!tenantCode) throw new Error("Set EXPO_PUBLIC_TENANT_CODE"); return ( router.replace("/home")} onError={(error) => Alert.alert("Sign-in failed", error.message)} > router.push("/register")} /> ); } ``` The destination route and tenant value are app-specific. For registration, MFA, social login, session guards, and account controls, continue to [Authentication](/native-sdk/guide/modules/auth). ## 3. Add one Bluetooth measurement flow [#3-add-one-bluetooth-measurement-flow] Start with a device the app intends to support. Select it by the catalog's stable ID and pass its `acceptedDevices` declarations to `BTProvider`: ```tsx import { BleManager } from "react-native-ble-plx"; import { BTProvider } from "@ovok/native/bt-management"; import { SUPPORTED_DEVICES } from "@ovok/native/bt-device"; const bleManager = new BleManager(); const bp2 = SUPPORTED_DEVICES.find( (device) => device.id === "catalog-viatom-bp2", ); export function BloodPressureRoute() { if (!bp2) throw new Error("The selected device is missing from the SDK catalog"); return ( device.connect()} onResult={(result) => { const idempotencyKey = result.id; // Associate with the active patient and persist or upload in app code. void saveMeasurement({ idempotencyKey, deviceData: result.deviceData, measurement: result.data, }); }} onError={({ error, deviceData }) => { reportBluetoothError(error, deviceData); }} > ); } ``` `BloodPressureScreen`, `saveMeasurement`, and `reportBluetoothError` represent the app's screen, persistence, and error policy. The result includes a stable `id`, `deviceData`, and decoded `data`; use the ID as the backend idempotency key if a result can be retried. Keep the `BleManager` at module scope or in another long-lived owner so route renders do not create competing scans. For an app that discovers several compatible devices, enable `autoConnect`, store the `onDeviceSelectionRequired` callback, and render the SDK's [BluetoothDevicePicker](/native-sdk/guide/components/bt-management/bluetooth-device-picker/) or an app-owned chooser before calling its supplied `select` function. Use [SupportedDevicesCatalogList](/native-sdk/guide/components/ui/supported-devices-catalog-list) to let people browse catalog metadata, and [BTDeviceList](/native-sdk/guide/components/bt-device/bt-device-list/) for the SDK's connection-status rows. See [Bluetooth](/native-sdk/guide/modules/bt-management), [Supported devices and catalog](/native-sdk/guide/modules/bt-device), and [BTDeviceInstruction](/native-sdk/guide/components/bt-device/bt-device-instruction/) for native setup, accepted device declarations, and available manuals. ## 4. Decide how measurements become app data [#4-decide-how-measurements-become-app-data] Bluetooth decoding is only one part of a measurement workflow. Before persisting a result, decide which patient it belongs to, whether it needs local retention, and how it is uploaded. Handle duplicate delivery with the stable result ID. If the user can enter a value manually, validate it against the same app-level rules as a device measurement. For display, `MeasurementList` accepts data from the host app, and `ObservationDetail` provides composable detail sections. These components help render records; your app remains responsible for selecting the resources and wiring screen navigation. See [Health data and measurements](/native-sdk/guide/modules/data-sync) for observation code mapping and data-sync behavior. ## 5. Add Apple Health or Health Connect import [#5-add-apple-health-or-health-connect-import] Add platform authorization on the route that explains why the app needs the data. Keep each platform's identifiers and mapping in app configuration. For example, an Apple Health screen can use the SDK's automatic authorization prompt: ```tsx import { DataSync } from "@ovok/native/data-sync"; import { appleDataToSync } from "./health-sync-config"; export function AppleHealthRoute() { return ( ); } ``` `health-sync-config` contains the app's platform-to-observation mapping. Map each platform data type to the appropriate OVOK observation code; request only the types the feature uses. Use `AndroidHealthConnectAuthorizationProvider` with `AndroidHealthSync` on Android. Both providers expose authorization states that your UI should represent, including refusal and partial access where applicable. If the app needs its own explanation or consent screen before the OS prompt, set `skipRequest` and `renderManualRequestUI` together. The render callback receives the request function. Follow the [health data guide](/native-sdk/guide/modules/data-sync) for mappings, manual authorization UI, progress, partial access, and platform setup. ## 6. Build forms and content screens around real app data [#6-build-forms-and-content-screens-around-real-app-data] Questionnaire forms accept a FHIR `Questionnaire`; their success callback returns the submitted `QuestionnaireResponse` for the app to persist or route onward. The example below assumes `saveQuestionnaireResponse` and `reportQuestionnaireError` are app handlers. ```tsx import { QuestionnaireForm } from "@ovok/native"; import type { Questionnaire } from "@medplum/fhirtypes"; export function IntakeRoute({ questionnaire }: { questionnaire: Questionnaire }) { return ( saveQuestionnaireResponse(response)} onError={reportQuestionnaireError} > ); } ``` The SDK provides other focused presentation components for content, observations, settings, pickers, and guided flows. Compose them where they fit your screen, and keep data fetching, empty states, route transitions, and app-specific completion policy in the host app. Browse the [component reference](/native-sdk/guide/components/ui/) and [SDK feature map](/native-sdk/guide/sdk-features) for the available surfaces. ## 7. Add background work after foreground flows [#7-add-background-work-after-foreground-flows] First make the foreground flow understandable and recoverable. Then enable only the background path the feature needs: - BLE result delivery uses `BTProvider.backgroundSync` and a durable storage adapter. - Android Health Connect scheduled import uses WorkManager and a registered headless task. - Apple HealthKit observer delivery uses `AppleHealthSync.backgroundDelivery` and native HealthKit configuration. Background callbacks may run without the React tree or in-memory session. The app must restore the minimum client and patient context needed to process work, persist queued results, and make uploads idempotent. Keep a foreground status and retry path for work that cannot complete. Read the [background sync guide](/native-sdk/guide/modules/background-sync) before adding native background services. ## Before shipping [#before-shipping] Exercise the complete workflow on every native platform you support: - fresh install, sign-in, sign-out, and expired-session recovery; - permission allowed, denied, and partially granted; - one live device measurement and, where supported, one history measurement; - duplicate delivery and app restart during queued work; - offline pause, recovery, and retry; - small screens, keyboard behavior, safe areas, dark theme, and accessibility; - translated labels and useful empty, loading, and error states. For implementation details, continue to the [public API map](/native-sdk/guide/public-api), [Bluetooth guide](/native-sdk/guide/modules/bt-management), [health data guide](/native-sdk/guide/modules/data-sync), and [component reference](/native-sdk/guide/components/ui/). # App shell and providers Canonical page: https://docs.ovok.com/native-sdk/guide/how-to/app-shell The app shell creates one native `Ovok` client and makes it available to routes that use the SDK. Provider ownership is explicit: `@ovok/core/next/react` supplies the client context, `@ovok/native` supplies the mobile UI theme and feature components, and your app supplies navigation and any app-wide services. Use this page after [installation and native setup](/native-sdk/guide/how-to/installation). For a minimal working sign-in app, follow the [quick start](/native-sdk/guide/getting-started); this guide explains where each provider belongs as the app grows. ## Provider tree [#provider-tree] For an Expo Router app, a typical root looks like this: ```text KeyboardProvider └── GestureHandlerRootView └── OvokProvider @ovok/core/next/react └── ThemeProvider @ovok/native └── BottomSheetModalProvider optional peer provider └── Navigation ThemeProvider └── App routes ``` Add optional app providers, such as query-cache persistence or localization, where their context is needed. Keep feature providers close to the routes that use them; Bluetooth scans and health authorization should not start just because the app shell mounted. ## Initialize the client outside React renders [#initialize-the-client-outside-react-renders] Initialize the runtime from the entry module before importing this layout, as shown in [Polyfills and runtime setup](/native-sdk/guide/components/polyfills/). This example assumes that bootstrap has already run. Keep the client at module scope so a route render does not recreate its identity or secure session storage. Put the initializer in a module such as `ovok-client.ts`; have the root layout and other app services import that same client instance. ```tsx import { Ovok } from "@ovok/native/next"; import * as SecureStore from "expo-secure-store"; const baseUrl = process.env.EXPO_PUBLIC_OVOK_BASE_URL; const tenantCode = process.env.EXPO_PUBLIC_TENANT_CODE; if (!baseUrl || !tenantCode) { throw new Error("Set EXPO_PUBLIC_OVOK_BASE_URL and EXPO_PUBLIC_TENANT_CODE"); } export const ovokClient = new Ovok({ baseUrl, tenantCode, secureStore: SecureStore, }); ``` Use your app's environment setup for `baseUrl` and optional client configuration. Expo embeds `EXPO_PUBLIC_` values in the app bundle, so they are suitable for public configuration only. See [Installation](/native-sdk/guide/how-to/installation) for native dependencies and [Authentication](/native-sdk/guide/modules/auth) for session behavior. ## Compose the Expo Router root [#compose-the-expo-router-root] This example follows the provider boundaries used by the reference app. The SDK theme is separate from the navigation theme, even when both use the same brand palette. ```tsx import { BottomSheetModalProvider } from "@gorhom/bottom-sheet"; import { OvokProvider } from "@ovok/core/next/react"; import { DEFAULT_COLORS, DEFAULT_MULTIPLIERS, ThemeProvider as OvokThemeProvider, } from "@ovok/native"; import { DefaultTheme, Stack, ThemeProvider as NavigationThemeProvider, } from "expo-router"; import type { PropsWithChildren } from "react"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { KeyboardProvider } from "react-native-keyboard-controller"; import { ovokClient } from "./ovok-client"; function SdkProviders({ children }: PropsWithChildren) { return ( {children} ); } export default function RootLayout() { return ( ); } ``` `OvokProvider` is exported by `@ovok/core/next/react`; the SDK `ThemeProvider` is exported by `@ovok/native`. Rename the latter on import when using another provider with the same name. `BottomSheetModalProvider` is imported directly from `@gorhom/bottom-sheet`; mount it once when a screen uses SDK bottom sheets such as `PickerSheet` or `DataSync.ManuallyRequestSheet`. If you use `SafeAreaProvider`, a persisted query client, localization, error reporting, or app configuration context, add those providers where their hooks and components need them. The reference app places `GestureHandlerRootView` around navigation and uses the keyboard provider above it. ## Configure the SDK theme [#configure-the-sdk-theme] `ThemeProvider` applies the React Native Paper theme, loads the bundled DM Sans fonts, and provides device-list context used by the supported-device UI. Its `theme` prop contains: | Property | Purpose | | --- | --- | | `colors` | Paper colors plus the SDK's semantic and indexed color palette; start with `DEFAULT_COLORS` and override values your app uses. | | `dark` | Whether the SDK theme is in dark mode. | | `spacingMultiplier` | Spacing scale; `DEFAULT_MULTIPLIERS.spacing` is the baseline. | | `borderRadiusMultiplier` | Corner-radius scale; `DEFAULT_MULTIPLIERS.borderRadius` is the baseline. | Read the active theme with `useAppTheme`. Navigation has its own color shape and must receive a navigation theme separately; map the brand colors to navigation's `primary`, `background`, `card`, `text`, `border`, and `notification` values rather than passing the SDK color object directly. The SDK theme provider returns `null` while its fonts load. Account for that initial render in the app's launch experience; the provider does not accept a loading fallback prop. ## Place feature providers near their screens [#place-feature-providers-near-their-screens] Mount these providers only for flows that use them: | Provider | Place it | What to keep in mind | | --- | --- | --- | | `BTProvider` | Around the Bluetooth screen or flow | Pass a long-lived `BleManager` and the accepted device declarations. Unmounting stops the provider-owned scan and tears down its managed devices. | | `DataSync.AppleHealthAuthorizationProvider` | Around the iOS Health import screen | Request only the HealthKit identifiers the feature reads or writes. | | `DataSync.AndroidHealthConnectAuthorizationProvider` | Around the Android Health Connect screen | Declare platform record permissions in native app configuration as well as in the authorization flow. | | `SocketProvider` | Around screens that use socket context | Keep the URL, authentication policy, subscriptions, and reconnect UX app-owned. | Do not mount Bluetooth or health import providers globally unless the product intentionally keeps that workflow active across every route. See the [Bluetooth guide](/native-sdk/guide/modules/bt-management), [Health data guide](/native-sdk/guide/modules/data-sync), and [Background sync](/native-sdk/guide/modules/background-sync) for lifecycle and platform details. ## Context requirements [#context-requirements] Render SDK features below the providers they use: - `OvokProvider`: authentication forms and account controls, patient and observation features that use the active client or patient, data-sync components, socket context, questionnaire submission helpers, and result handlers that use the client. - `ThemeProvider`: components that call `useAppTheme`, the device catalog list, and themed SDK UI. - `BottomSheetModalProvider`: SDK components that open a Gorhom bottom-sheet modal. - `KeyboardProvider`: keyboard-aware forms that use `react-native-keyboard-controller`. When a component renders without expected data, check its provider ancestry and the current authentication or patient state before changing its props. See [Architecture and lifecycle](/native-sdk/guide/architecture) for the responsibilities of each boundary. # Installation and native setup Canonical page: https://docs.ovok.com/native-sdk/guide/how-to/installation This guide covers the package, its peer dependencies, and the native configuration needed by each feature. It targets Expo projects using Prebuild or EAS Build, as in the repository example. A full `@ovok/native` app needs a native development build; Expo Go does not contain all of the SDK's native modules. ## Compatibility baseline [#compatibility-baseline] The repository example currently uses: | Platform | Example baseline | | --- | --- | | Expo | SDK 57 | | React Native | 0.86.3 | | React | 19.2.3 | | Android | Minimum SDK 26 | | iOS | Deployment target 16.4 in the example app | These are the example app's settings, not a promise that every combination of Expo and React Native works. Match the native peer packages to your app's Expo SDK. Use [`npx expo install`](https://docs.expo.dev/more/expo-cli/) for Expo and React Native packages so Expo can select compatible versions. The package's exact peer ranges are declared in the root `package.json`. ## Install the package [#install-the-package] Install the SDK and its OVOK client: ~~~bash npm install @ovok/native @ovok/core ~~~ With Yarn, use `yarn add @ovok/native @ovok/core` instead. That installs the stable releases. Install release candidates with `@ovok/native@next @ovok/core@next` or the newest development builds with `@ovok/native@dev @ovok/core@dev`. The badges under each page title show the release on each channel that first shipped the page. The required peer dependencies in `@ovok/native` are `@ovok/core` (version `0.4.49-dev.503` or newer, for its `next` client), `react`, `react-native`, `react-native-ble-plx`, and `react-native-permissions`. An Expo project already has React and React Native; install the native peers using Expo's installer: ~~~bash npx expo install react-native-ble-plx react-native-permissions ~~~ Install optional peer packages only for the features your app imports. For example, add Expo crypto and secure storage when a feature uses them: ~~~bash npx expo install expo-crypto expo-secure-store ~~~ The feature matrix below groups the optional peers declared by the package. Treat it as a selection guide; `package.json` is the version-range source of truth. | Feature | Optional peer packages | | --- | --- | | Core UI | @expo-google-fonts/dm-sans, @gorhom/bottom-sheet, react-native-gesture-handler, react-native-reanimated, react-native-safe-area-context, react-native-keyboard-controller, react-native-paper, react-native-svg | | Authentication | @react-native-google-signin/google-signin, expo-apple-authentication, expo-web-browser, formik, yup, i18next, react-i18next, iconsax-react-nativejs | | HealthKit | @kingstinct/react-native-healthkit (16.2.0 or newer), react-native-nitro-modules (0.35 or newer) | | Health Connect | expo-health-connect, react-native-health-connect | | Network-aware import | @react-native-community/netinfo | | Media and forms | expo-image, expo-linear-gradient, lottie-react-native, @react-native-community/datetimepicker, react-native-modal-datetime-picker, react-native-element-dropdown, @shopify/flash-list, date-fns, react-native-render-html | | PDFs and files | react-native-pdf, react-native-blob-util | | Crypto and storage | expo-crypto, expo-secure-store, expo-standard-web-crypto | | Sockets and telemetry | socket.io-client, @opentelemetry/api, @opentelemetry/api-logs | | Expo config plugin | @expo/config-plugins (provided by Expo in an Expo app) | | Background notifications | expo-notifications | | Background persistence | An app-owned durable store implementing `getItem` and `setItem` | HealthKit import needs both HealthKit packages: `@kingstinct/react-native-healthkit` 16 is built on Nitro Modules, which `react-native-nitro-modules` provides. They are native modules, so adding or upgrading them needs a new native build, not only a JavaScript update. The package root exports shared UI, authentication, and Bluetooth-management APIs. Optional integrations such as Health Connect, PDF, sockets, and background sync are available through public subpaths. Import them from the path listed in the [Public API map](/native-sdk/guide/public-api) and install peers for the APIs you use; this keeps unrelated native modules out of the import graph. ## Configure Expo native capabilities [#configure-expo-native-capabilities] Installing `@ovok/native` does not add permissions or enable background services. The SDK provides an opt-in Expo config plugin for Bluetooth, HealthKit, Health Connect, background services, and notifications. Add it to the `plugins` array in `app.config.ts` or `app.json` only for capabilities your app uses. Expo applies config plugins during Prebuild or EAS Build; changing app config requires a new native build. See [Expo config plugins](https://docs.expo.dev/config-plugins/introduction/). For example, this enables Bluetooth background support: ~~~ts plugins: [ [ "@ovok/native", { bluetooth: { background: true, bluetoothAlwaysPermission: "Allow $(PRODUCT_NAME) to connect to health devices", }, }, ], ] ~~~ The snippet is a `plugins` array entry, not a complete app config. Add other options only when the app needs them: | Option | Native setup it enables | | --- | --- | | `bluetooth` | Composes the `react-native-ble-plx` plugin, sets the iOS Bluetooth usage description, and adds Android scan/connect permissions. Set `background: true` for iOS background-central mode and the Android connected-device service path. | | `healthKit` | Composes the HealthKit plugin and adds the HealthKit entitlement. Set `{ background: true }` when using HealthKit background delivery. Add the app-specific iOS usage descriptions yourself. | | `healthConnect` | Composes the `expo-health-connect` plugin. Declare Android read/write permissions for the record types your app requests. | | `backgroundSync` | Enables Android background service configuration. For BLE, set `backgroundSync.android.foregroundService` when using the provider-managed service. For Health Connect scheduling, set `healthConnect` and a truthy `backgroundSync`. See [Background sync](/native-sdk/guide/modules/background-sync). | | `notifications` | Composes the `expo-notifications` plugin. Enable it only when the app uses notifications. | `backgroundSync.android.foregroundService.requestBatteryOptimizationExemption` adds the Android permission that allows the SDK to ask for battery-optimization consent. It does not grant the exemption. The user still makes that choice in Android settings. The repository example configures some third-party plugins directly in `example/app.config.ts`. The SDK plugin is a convenience for the capabilities above; for each native feature, keep its plugin configuration in one place and add any options that the wrapper does not manage directly. ## iOS setup [#ios-setup] Add only the capabilities the app uses: - **Bluetooth:** include a clear `NSBluetoothAlwaysUsageDescription`. The SDK plugin's `bluetoothAlwaysPermission` option sets it. Set `bluetooth.background: true` only when using background central restoration. - **HealthKit:** enable the HealthKit capability and set `NSHealthShareUsageDescription` and `NSHealthUpdateUsageDescription` in the app config. Set `healthKit: { background: true }` when using `AppleHealthSync` with `backgroundDelivery`. - **Apple Sign-In:** add `expo-apple-authentication` to the plugin list and set `ios.usesAppleSignIn: true`. - **Google Sign-In:** add the Google Sign-In config plugin and provide its iOS URL scheme. Use explanations that match your app's actual data use. Do not copy the example app's bundle identifiers, OAuth client IDs, or usage text. Test Bluetooth, HealthKit, and social sign-in on physical iOS hardware. For HealthKit, add app-specific usage text in `app.config.ts`: ~~~ts ios: { infoPlist: { NSHealthShareUsageDescription: "Explain why this app reads the selected health data.", NSHealthUpdateUsageDescription: "Explain why this app writes the selected health data.", }, }, ~~~ ## Android setup [#android-setup] - **Bluetooth:** request only the Bluetooth permissions required for the app's scan and connection flow. The SDK plugin adds scan/connect permissions when `bluetooth` is enabled. Background BLE also needs the Android foreground service path. - **Health Connect:** declare the `android.permission.health.READ_*` and `WRITE_*` permissions that match the record types in your `dataToSync` configuration. Do not copy the full example list if your app imports fewer types. For background reads, request Health Connect background access and enable the matching background service configuration. - **Notifications:** Android may require notification permission at runtime for background notifications. Add the notification plugin and request permission through your app's notification flow. For example, if the app reads and writes weight, add only those record permissions to `android.permissions` in `app.config.ts`: ~~~ts android: { permissions: [ "android.permission.health.READ_WEIGHT", "android.permission.health.WRITE_WEIGHT", ], }, ~~~ Add the matching permissions for every record type in `dataToSync`. When using the SDK plugin for Health Connect background work, it adds `READ_HEALTH_DATA_IN_BACKGROUND` and the required service declarations; when configuring native projects directly, add the equivalent permission and service setup yourself. The SDK/plugin adds foreground-service declarations for the background features it configures. If you manage native configuration yourself, preserve the corresponding service types and permissions. See [Android's Health Connect setup](https://developer.android.com/health-and-fitness/health-connect/get-started) for the current platform requirements. Health Connect requires Android 9 (API 28) or newer with Google Play services; on Android 13 and earlier, users install the Health Connect app from Google Play. ## Build a development app [#build-a-development-app] Install Expo's development client, apply the native configuration, and build for the platform you use: ~~~bash npx expo install expo-dev-client npx expo prebuild npx expo run:ios ~~~ For Android, use: ~~~bash npx expo run:android ~~~ The first native build includes the installed native modules and config plugins. Start Metro against that build with `npx expo start --dev-client`. For local builds, run Prebuild and rebuild after adding a native dependency or changing a config plugin; EAS Build applies the app config as part of its native build. JavaScript-only changes can be loaded from Metro without rebuilding. See [Expo's development build guide](https://docs.expo.dev/develop/development-builds/introduction/) for the dev-client workflow. Avoid `npx expo prebuild --clean` unless you intentionally want Expo to regenerate the native projects. Review native project changes before committing them. ## Initialize the OVOK client [#initialize-the-ovok-client] Initialize the native runtime once from the app entry module before importing the app or other SDK modules. See [Polyfills and runtime setup](/native-sdk/guide/components/polyfills/) for the bootstrap example. The client module can then create the native `Ovok` client: ~~~tsx import { OvokProvider } from "@ovok/core/next/react"; import { Ovok } from "@ovok/native/next"; import * as SecureStore from "expo-secure-store"; const client = new Ovok({ baseUrl: process.env.EXPO_PUBLIC_OVOK_BASE_URL, tenantCode: process.env.EXPO_PUBLIC_TENANT_CODE, secureStore: SecureStore, }); ~~~ Mount `OvokProvider` near the app root. The [Quick start](/native-sdk/guide/getting-started) shows a complete app shell and sign-in route. The package also exports `cleanupOvokNativeRuntime`, `ExtendedExpoCrypto`, and `initWebSocketManager` for explicit cleanup, crypto, and WebSocket setup. ## Check the native configuration [#check-the-native-configuration] Before testing a feature, inspect the resolved Expo config and check Expo package compatibility: ~~~bash npx expo config --type public npx expo install --check ~~~ Then build the platform you ship and verify that the generated iOS `Info.plist`/entitlements or Android manifest contain only the permissions and services required by the enabled features. Test Bluetooth and health integrations on physical hardware. # Invites and carers Canonical page: https://docs.ovok.com/native-sdk/guide/how-to/invites-and-carers A patient can share their record with a practitioner or with a carer (a FHIR `RelatedPerson`), and a practitioner can invite a patient into their care. Both send an email whose link opens the patient app at `/accept-invite?invite=&code=`. The client methods and mutation hooks come from `@ovok/core`; `@ovok/native` adds carer sign-in and a hook that accepts the invite from the deep link. ## Share a record [#share-a-record] Use `useShareRecord` from `@ovok/core` while a patient is signed in. A carer gets only the Observation `codes` you name; a practitioner gets the whole record. ```tsx import { useShareRecord } from "@ovok/core"; const { mutate: shareRecord } = useShareRecord(); await shareRecord({ recipient: "related-person", email: "carer@example.com", firstName: "Alex", lastName: "Doe", codes: ["8480-6", "8462-4"], }); ``` Use `recipient: "practitioner"` without `codes` to share with a practitioner. The answer is always `{ status: "sent" }`, so it does not reveal whether the address has an account. ## Accept an invite from its link [#accept-an-invite-from-its-link] `useAcceptInviteLink` from `@ovok/native` reads `invite` and `code` from the link and picks the right route: - `accept.run(link)`: a signed-in patient accepts a practitioner's care invite; a signed-in carer accepts a record share. - `createCarerAccount.run(link, { email, password })`: a new carer, signed out, sets a password. This creates their account, starts the share, and signs them in. ```tsx import { useAcceptInviteLink } from "@ovok/native"; const { accept, createCarerAccount } = useAcceptInviteLink({ tenantCode }); // `link` is the accept-invite URL your app's deep-link routing received. // Signed in: await accept.run(link); // New carer, from a set-password form: await createCarerAccount.run(link, { email, password }); ``` The invite email does not tell the app whether the carer already has an account. Ask the carer to sign in or create a password, and use `accept` or `createCarerAccount` accordingly. A 409 with `address_has_account` from `createCarerAccount` means the address already has an account: sign in and call `accept` instead. `parseInviteLink(link)` is exported for apps that route the link themselves. It throws when the link has no `invite` or `code`. ## Sign in carers [#sign-in-carers] Set `loginType="RelatedPerson"` on `SignIn.EmailForm` (or `type: "RelatedPerson"` on `useSignIn`) with the tenant code. The project setting `RELATED_PERSON_LOGIN_ENABLED` must not be `false`. Carers reset a forgotten password with `ResetPassword.Form` and `type="RelatedPerson"`. ## Show and leave a carer's shares [#show-and-leave-a-carers-shares] A signed-in carer sees the shares patients gave them in `received` from `usePatientSharing` (`@ovok/core` 0.4.48 or later); it is empty for patients. Each entry has `consentId`, `sharer`, `codes`, `startedAt` and `endsAt`. ```tsx import { usePatientSharing, useRevokePatientSharing } from "@ovok/core"; const { data } = usePatientSharing(); const { mutate: leaveShare } = useRevokePatientSharing(); const received = data?.received ?? []; await leaveShare(received[0].consentId); ``` Leaving a share ends it for both sides. A 404 means the share is not the carer's; a 409 means it already ended or changed meanwhile, so reload the list. ## Deprecated invite methods [#deprecated-invite-methods] The `@ovok/core` methods `invitePractitioner`, `invitePatient`, `acceptPractitionerInvite` and `acceptPatientInvite` (and the hooks `useInvitePractitioner` and `useInvitePatient`) call routes that stop working on 1 December 2026. Use `shareRecord`, `acceptRecordShare`, `inviteToCare` and `acceptCareInvite` instead. # Logs and telemetry Canonical page: https://docs.ovok.com/native-sdk/guide/how-to/observability Connect SDK diagnostics to the systems your team already uses. Ovok provides a logger plus OpenTelemetry helpers for traces, metrics, and log records. Your app owns provider registration, exporters, destinations, retention, access controls, and alerting. The OpenTelemetry API peers are optional. Without providers, telemetry calls are no-ops and SDK features continue to run; the default SDK logger still writes to the console. For the complete API surface, see [Logging](/native-sdk/guide/components/helpers/logging) and [Telemetry](/native-sdk/guide/components/helpers/telemetry). ## Configure telemetry during startup [#configure-telemetry-during-startup] If your app registers OpenTelemetry providers globally, the SDK uses those providers. Otherwise, pass the providers you want the SDK to use: ~~~ts import { configureOvokTelemetry } from "@ovok/native/helpers"; configureOvokTelemetry({ tracerProvider: appTracerProvider, meterProvider: appMeterProvider, loggerProvider: appLoggerProvider, }); ~~~ Each provider is optional. `tracerProvider` supplies spans, `meterProvider` supplies counters and histograms, and `loggerProvider` supplies OpenTelemetry log records. Call this before mounting feature providers or starting work that should be observed. The SDK does not register or shut down your providers. Install `@opentelemetry/api` for traces and metrics and `@opentelemetry/api-logs` for OTel log records. Both are optional peer dependencies. You do not need to install them when you only want the default console logger or a custom `configureOvokLogger` callback. ## Route logs to the app logger [#route-logs-to-the-app-logger] Use `configureOvokLogger` to replace the SDK's default console destination: ~~~ts import { configureOvokLogger, sanitizeOvokTelemetryAttributes, } from "@ovok/native/helpers"; configureOvokLogger((level, message, extra = {}) => { appLogger.write({ level, message, attributes: sanitizeOvokTelemetryAttributes(extra), }); }); ~~~ The callback receives the message and `extra` values as supplied. The SDK also emits an OpenTelemetry log when a logger provider is available, even when you have configured this callback. Keep the callback fast and non-throwing: the SDK calls it synchronously and does not catch exceptions from app logger code. Use `ovokLogger(level, message, extra?)` for app-owned diagnostics through the same path. `slog(error, scope, additionalData?, level?)` is the established compatibility helper used by SDK features. Calling `configureOvokLogger()` without an argument restores the default console logger. ## Add spans around app-owned work [#add-spans-around-app-owned-work] `withOvokSpan` runs an operation in a span when a tracer is available and returns the operation's result: ~~~ts import { withOvokSpan } from "@ovok/native/helpers"; const result = await withOvokSpan( "app.measurement.persist", { provider: "bluetooth", measurementTypeKey: "body-weight" }, () => measurementRepository.save(measurement), ); ~~~ It records success or failure on an available span, ends the span, and rethrows the original operation error. If telemetry is unavailable, the operation still runs normally. Use `recordOvokMetric` for counters and `recordOvokDuration` for durations in milliseconds; their attributes use the SDK's operational allowlist. ## Know what the SDK already records [#know-what-the-sdk-already-records] The SDK currently emits Bluetooth connection and discovery signals, device reading and status events, background queue delivery metrics, and health-import spans and batch metrics. The exact span names, event names, metric names, and meanings are in the [built-in signal catalog](/native-sdk/guide/components/helpers/telemetry#built-in-sdk-signals). These signals appear only when the relevant feature runs and an OpenTelemetry provider is available. The `ovok.queue.depth` instrument is a counter: the SDK adds the current queue length when it writes the queue. It is not a gauge. Use the reference catalog to interpret it correctly in dashboards. ## Keep diagnostic data safe [#keep-diagnostic-data-safe] The SDK filters attributes passed to its span, metric, duration, and span-event helpers through an allowlist of operational keys. The filter does not apply to `emitOvokLog`, `slog`, `ovokLogger`, or a custom logger callback. Log messages and `extra` values are forwarded as supplied. Keep credentials, patient and account identifiers, clinical values, and raw device payloads out of log messages and extras. The allowlist is not a guarantee that every allowed identifier is non-sensitive; review those values under your app's data policy. Redact app-owned log fields before forwarding them to a vendor. ## Verify the integration [#verify-the-integration] 1. Register or pass the providers before starting the feature you want to observe. 2. Trigger a representative Bluetooth, background-delivery, or health-import flow. 3. Confirm the expected records reach the app's exporter and inspect their attributes for data your policy excludes. 4. Confirm the feature still works with OpenTelemetry peers omitted if your app treats telemetry as optional. For SDK logger behavior, see [Logging](/native-sdk/guide/components/helpers/logging). For every telemetry helper, type, attribute rule, and built-in signal, see [Telemetry](/native-sdk/guide/components/helpers/telemetry). Related feature guides cover [Bluetooth](/native-sdk/guide/modules/bt-management), [Background sync](/native-sdk/guide/modules/background-sync), and [HealthKit and Health Connect](/native-sdk/guide/modules/data-sync). # Reusable flows Canonical page: https://docs.ovok.com/native-sdk/guide/how-to/reusable-flows The `@ovok/native/ui` module includes three higher-level components for common app tasks: pairing a nearby device, collecting a manual measurement, and presenting health-data access through an app-provided adapter. Each component handles its own local UI state. Your app supplies the provider, storage, persistence, permissions, patient context, and navigation that give the flow meaning in your product. Use the [App UI guide](/native-sdk/guide/modules/ui) for the complete UI catalog, shared theme, and slot customization. | Flow | Use it when | Your app supplies | | --- | --- | --- | | [`PairingFlow`](/native-sdk/guide/components/ui/pairing-flow) | Users need to choose and pair a discovered Bluetooth device | An active `BTProvider`, `PairedDeviceStorage`, and a code handler when the device requests one | | [`ManualEntryForm`](/native-sdk/guide/components/ui/manual-entry-form) | Users need to enter a measurement defined by the SDK catalog | An async save callback, patient mapping, and product-specific labels | | [`HealthImportCard`](/native-sdk/guide/components/ui/health-import-card) | You need an access-status and request UI around an existing health adapter | A `HealthImportAdapter`, permission policy, and any separate import service | Adopt these independently. Pairing and health access do not depend on each other, and manual entry can be used without either provider. ## Pair and remember a Bluetooth device [#pair-and-remember-a-bluetooth-device] Render `PairingFlow` inside the Bluetooth provider that owns the current device session. The flow presents devices already discovered by that provider; it does not create a BLE manager or start a scan. ~~~tsx import { BTProvider, IntegratedDevices } from "@ovok/native/bt-management"; import { PairingFlow } from "@ovok/native/ui"; const acceptedDevices = [IntegratedDevices.BP2] as const; analytics.track("device_paired", { id: device.id })} onError={(error, device) => reportPairingError(error, device?.id)} /> ~~~ `storage` implements async `getItem(key)` and `setItem(key, value)` methods. The flow stores a JSON array of device IDs under `@ovok/native/paired-devices` by default; set `storageKey` to keep a separate collection. It does not store credentials or device records. When the runtime reports that pairing needs a code, the flow displays an input and passes its value and selected device to `onPairingCode`. Provide this callback to run the device- or platform-specific confirmation. A successful callback returns the UI to the pairing state; the device still needs to report that it is bonded before the flow remembers it and calls `onPaired`. The default device row starts pairing. If users also need to forget remembered devices, render a custom row with `renderDevice`; its `actions` argument includes a `forget()` function. The flow exposes devices, remembered IDs, the selected device, status, and error to custom render callbacks. ## Collect and save a manual measurement [#collect-and-save-a-manual-measurement] `ManualEntryForm` uses the SDK's `measurementFieldCatalog` for the selected `MeasurementTypeKey`. Required fields, numeric bounds, and units come from that catalog. The form validates values and calls the app's async save function with a plain typed payload: ~~~tsx import { MeasurementTypeKey } from "@ovok/core/next"; import { ManualEntryForm, type ManualEntrySaveInput } from "@ovok/native/ui"; const saveMeasurement = async (input: ManualEntrySaveInput) => { await measurementRepository.save({ patientId: activePatient.id, ...input, }); }; measurementLabels[field] ?? field} onSaved={() => navigation.goBack()} /> ~~~ The app decides which patient owns the entry, how it is persisted or queued, and whether it should be converted into a FHIR resource. The callback must resolve only after the app considers the save complete; `onSaved` runs after it resolves. While the callback is pending, the form blocks another save and shows a loading state. Validation and rejected-save errors appear inline. `initialValues` and `recordedAt` seed state when the form mounts. If the active measurement changes after that, remount with a new React `key` or manage editing state in the app. The built-in copy is English; provide `title`, `labelForField`, and `labelForUnit` for your product language and units. ## Request health-data access through an adapter [#request-health-data-access-through-an-adapter] `HealthImportCard` is a status and request surface for an app-owned `HealthImportAdapter`. Use it when the app already owns the platform authorization implementation: ~~~tsx import { HealthImportCard } from "@ovok/native/ui"; import type { HealthImportAdapter } from "@ovok/native/bt-management"; type HealthType = "steps" | "weight"; const adapter: HealthImportAdapter = { getStatus: (type) => readAccessStatus(type), request: async (types, background) => { await requestHealthAccess(types, { background }); }, }; healthTypeLabels[type]} progress={progressByType} /> ~~~ `getStatus` returns `authorized`, `shouldRequest`, `refused`, or `unsupported` for each app-defined type. `request(types, background)` receives the whole type list and the `background` option. On mount and after a successful request, the card reads statuses again; it considers the card enabled only when every listed type is authorized. Switching the card off only changes its enabled state. The adapter has no revoke, stop, or cancel method, so the control does not disable OS permissions or stop an import service. The component also does not configure HealthKit or Health Connect or start the SDK's `DataSync` pipeline. Use the native permission providers and import components documented in [HealthKit and Health Connect](/native-sdk/guide/modules/data-sync) when you need those integrations. ## Keep app decisions at the app boundary [#keep-app-decisions-at-the-app-boundary] These flows are building blocks rather than end-to-end product screens. Keep these decisions in app-owned code: - which devices and measurement types the user can select; - where device IDs and measurements are stored; - which patient or account owns each measurement; - how health access is explained and requested; - when to navigate after an operation succeeds; - how errors, analytics, and translations fit the product. Use the [flow references](/native-sdk/guide/components/ui/reusable-flows/) for each component's props, callbacks, and lifecycle details. # Troubleshooting Canonical page: https://docs.ovok.com/native-sdk/guide/how-to/troubleshooting ## The export is undefined [#the-export-is-undefined] Check the package and export names: - ThemeProvider as OvokThemeProvider comes from @ovok/native. - Ovok comes from @ovok/native/next, and OvokProvider from @ovok/core/next/react. SDK components throw if the provider holds a client that is not the native Ovok. - There is no @ovok/mobile package alias and no bare native Provider. - Use the root package or documented subpath, not a source path. ## A native module cannot be found [#a-native-module-cannot-be-found] The JavaScript dependency exists but the installed binary predates the dependency or config plugin. Rebuild a development client after native changes. Expo Go does not contain the SDK's complete native module set. ## BLE permission or scan failures [#ble-permission-or-scan-failures] Check, in order: 1. The app is a development/production native build. 2. react-native-ble-plx and its config plugin are installed. 3. iOS Bluetooth usage descriptions or Android Bluetooth permissions are present. 4. Bluetooth is powered on. 5. The device advertisement's name or localName matches the accepted declaration. 6. The required service UUID is advertised. 7. A second screen or manager is not scanning at the same time. 8. Background mode has service UUID filters. onError contains the BLE/protocol error and may include deviceData. ## A device is found but no reading arrives [#a-device-is-found-but-no-reading-arrives] Confirm the exact declaration and measurement protocol: - the model is the correct entry in SUPPORTED_DEVICES; - the device is ready to measure or has stored history available; - oneReadingPerConnection is not suppressing the expected stream; - the result callback is mounted before connecting; - for ECG file devices, persist and pass delivered file names; - for a custom device, verify frame selector, byte order, units, and service UUIDs. Do not widen a name matcher until the advertisement has been captured and the device protocol is understood. ## Health authorization never completes [#health-authorization-never-completes] For HealthKit, check the requested identifiers, capability, usage descriptions, and the provider's notRequested identifiers. For Health Connect, check initialization, the exact record types, and whether the status is refused rather than error. The sync component intentionally does not import a type whose authorization is still pending. Handle partial authorization instead of treating it as a global failure. ## Health import pauses [#health-import-pauses] wifiOnly pauses on cellular data with reason wifi-only. No network pauses with reason offline. Keep the sync component mounted; it resumes when NetInfo reports an acceptable network. ## Health import fails with 429 or 503 [#health-import-fails-with-429-or-503] Health saves retry rate-limit, server and upstream errors (429, 500, 502, 503, 504) up to three times, waiting at least the server's `Retry-After` value. A 501 means the environment does not have the feature; it is not retried. If the import still fails, `onError` receives the final error. Check whether the app is importing too many records at once or the service is still unavailable. ## Background work does not run [#background-work-does-not-run] Background work requires all of the following: - a native build with the correct plugin and permissions; - durable queue storage; - a stable iOS restoration identifier; - service UUIDs for an iOS background scan; - an Android foreground service for long-lived BLE monitoring; - a registered Android Health Connect headless task for process-death import; - restored auth and patient state in headless work; - acceptance that the OS can defer background execution. A background task is not a substitute for foreground UI and cannot render a React component after process death. ## Results are duplicated [#results-are-duplicated] BLE queue delivery is at least once. Deduplicate on the backend using the queued result's stable `id`. Do not remove the queue item before the server confirms acceptance. # Measurement field catalog Canonical page: https://docs.ovok.com/native-sdk/guide/measurement-field-catalog `measurementFieldCatalog` is exported from `@ovok/native/bt-management`. It is the canonical field vocabulary used by custom Bluetooth declarations and the optional UI components. Each field records its unit and decode bounds; some fields also include adult, resting reference ranges for non-diagnostic UI feedback: | Field | Unit | Normal range | | --- | --- | --- | | Blood pressure systolic | mmHg | 90–120 | | Blood pressure diastolic | mmHg | 60–80 | | Heart rate / pulse rate | bpm | 60–100 | | Body temperature | °C | 36.5–37.3 | | Blood oxygen | % | 95–100 | | Respiratory rate | /min | 12–20 | These are display hints, not diagnostic thresholds. Body weight, blood glucose, perfusion index, and RR interval remain unset because their expected values depend on context such as height, fasting state, device, activity, altitude, or clinical history. ## Field shape [#field-shape] ```ts interface CatalogField { unit: string; min: number; max: number; required?: boolean; display?: string; normalMin?: number; normalMax?: number; } ``` `min` and `max` are protocol/decode bounds. A decoded value outside those bounds is treated as a malformed reading by declaration validation. `required` identifies fields needed for a complete result case. `normalMin` and `normalMax` are optional presentation hints and must not be used as diagnosis or alarm thresholds. ```ts import { MeasurementTypeKey } from "@ovok/core/next"; import { measurementFieldCatalog, } from "@ovok/native/bt-management"; const fields = measurementFieldCatalog[MeasurementTypeKey.bloodPressure]; const systolicUnit = fields?.systolic.unit; // "mmHg" ``` The catalog includes blood pressure, body weight, temperature, blood glucose, blood oxygen/pulse rate, heart rate, respiratory rate, urine analysis, and uric acid fields. ECG and other multi-notification streams are handled by their protocol implementations rather than a simple declarative field map. Sources: [MedlinePlus vital signs](https://medlineplus.gov/ency/article/002341.htm), [American Heart Association blood pressure](https://www.heart.org/en/health-topics/high-blood-pressure/blood-pressure-explained), and [FDA pulse oximeter basics](https://www.fda.gov/consumers/consumer-updates/pulse-oximeter-basics). # Authentication Canonical page: https://docs.ovok.com/native-sdk/guide/modules/auth Use this guide to add authentication screens to a React Native app. The SDK provides composable forms and calls the active native `Ovok` client; your app owns routes, session UX, error messages, and account-specific policy. Before you start, install the native dependencies for the auth features you use and mount the [app shell and providers](/native-sdk/guide/how-to/app-shell). The forms need `OvokProvider` from `@ovok/core/next/react` and the SDK `ThemeProvider` from `@ovok/native`. ## 1. Add patient email sign-in [#1-add-patient-email-sign-in] Create a sign-in route and compose the screen from its exported children. Patient sign-in requires the tenant code configured on your native client. Pass the same code to the form's existing `tenantCode` prop. ```tsx import { SignIn } from "@ovok/native"; import { useRouter } from "expo-router"; import { Alert } from "react-native"; const tenantCode = process.env.EXPO_PUBLIC_TENANT_CODE; if (!tenantCode) { throw new Error("Set EXPO_PUBLIC_TENANT_CODE in your app environment"); } export default function SignInScreen() { const router = useRouter(); return ( router.replace("/home")} onError={(error) => Alert.alert("Sign-in failed", error.message)} > ); } ``` Replace `/home` with an authenticated route in your app. The callback runs after the client accepts the login; use it to update app navigation or refresh patient-specific state. Keep `EXPO_PUBLIC_` values limited to public configuration, not credentials. For practitioner sign-in, set `loginType="Practitioner"`; `tenantCode` is optional for that variant. See [Sign-in components](/native-sdk/guide/components/auth/sign-in/) for form children, validation, and callback types. The built-in auth fields show validation errors after the person changes a field or submits the form. Focusing and leaving an untouched required field does not show an error; see the [sign-in input reference](/native-sdk/guide/components/auth/sign-in/form/inputs). Network error keys are used for recognized transport failures and timeouts only when no HTTP response is present. Other `TypeError`s remain generic errors, so a programming bug is not presented as a connectivity problem. ## 2. Add registration and password recovery [#2-add-registration-and-password-recovery] Give registration and password recovery their own routes so users can reach them from sign-in and return to the correct point in your app. Compose the exported `Register` and `ResetPassword` children for the fields and actions you want to show. The app decides where successful registration or a reset request leads next. Use the detailed [registration reference](/native-sdk/guide/components/auth/register/) and [password-reset reference](/native-sdk/guide/components/auth/reset-password/) for their compound components and required props. Add [profile editing](/native-sdk/guide/components/auth/profile/), [logout](/native-sdk/guide/components/auth/logout-button/), or [account deletion](/native-sdk/guide/components/auth/delete-account-button/) only where those actions belong in your account UX. ## 3. Add social sign-in when your app needs it [#3-add-social-sign-in-when-your-app-needs-it] Social buttons require their native packages and platform configuration before the screen can render them. Follow the [installation guide](/native-sdk/guide/how-to/installation) to configure Google Sign-In and Apple Sign-In in the native build. Apple Sign-In is available on iOS. On the web the same buttons work without those packages; follow [Sign in on the web](/native-sdk/guide/components/auth/sign-in/social-logins/#sign-in-on-the-web). Compose the buttons inside `SignIn.SocialLogins` and provide the OVOK integration ID and provider client IDs: ```tsx ``` Treat user cancellation as a normal outcome. Keep provider errors visible during development and show app-owned recovery messaging when a login fails. ## 4. Handle MFA and rate limits [#4-handle-mfa-and-rate-limits] When the backend requires MFA, the email form switches to its verification step and renders the code field. The SDK manages the field and submit state; your app still handles success and error callbacks. The keyboard flow moves from email to password to submit, then focuses the MFA field when verification is needed. The sign-in, registration, and reset-password forms use the server's `Retry-After` wait for rate-limit cooldowns, falling back to 60 seconds when there is no hint. For a custom form, use `getRateLimitDetails`, `setRateLimitFormError`, and `useRateLimitCooldown` from the public auth exports. A backend response outside the supported shape still needs your app's normal error handling. See [Authentication API details](/native-sdk/guide/components/auth/). ## 5. Add session and account controls [#5-add-session-and-account-controls] Use `SessionList` when users need to inspect or revoke sessions on other devices. `useSession` exposes session operations for a custom account screen. Logout and account-deletion controls call the active client; provide their success and error callbacks to keep navigation and messaging in the app's control. See the [session reference](/native-sdk/guide/components/auth/session/) and the [public API map](/native-sdk/guide/public-api) for supported imports. ## 6. Sign in carers [#6-sign-in-carers] A carer (FHIR `RelatedPerson`) signs in to the patient app with `loginType="RelatedPerson"` and the tenant code, and resets a password with the reset form's `RelatedPerson` type. Carer accounts come from accepting a patient's record-share invite; see [Invites and carers](/native-sdk/guide/how-to/invites-and-carers). ## Integration checklist [#integration-checklist] - The auth routes render below `OvokProvider` and the SDK theme provider. - Patient sign-in receives a tenant code from public app configuration. - Native social sign-in packages and config plugins are included only when used. - The app handles success, failure, cancellation, and post-login navigation. - The native app is rebuilt after adding or changing a native auth dependency. ## API reference [#api-reference] Every export of `@ovok/native/auth`, with signatures, props and types, is in the [`auth` API reference](/native-sdk/reference/auth). # Background sync Canonical page: https://docs.ovok.com/native-sdk/guide/modules/background-sync Background work is a set of platform-specific delivery paths, not a single SDK scheduler. Pick the path that matches the data source, configure its native capabilities, and restore the application state it needs when the operating system starts work outside the foreground app. | Your app needs to… | Use | Reference | | --- | --- | --- | | Deliver Bluetooth readings through a durable queue | `BTProvider.backgroundSync` | [Queue Bluetooth readings](#queue-bluetooth-readings) | | Keep a Bluetooth scan active on Android | `BTProvider`'s foreground service, or `AndroidBluetoothForegroundService` when you own the scan | [Run an Android BLE foreground service](#run-an-android-ble-foreground-service) | | Import Health Connect data after Android stops the process | WorkManager plus a registered headless task | [Schedule Health Connect imports](#schedule-health-connect-imports) | | Import HealthKit updates while the app is backgrounded | `AppleHealthSync.backgroundDelivery` | [Receive HealthKit updates](#receive-healthkit-updates) | The operating system controls when background work runs. These APIs do not promise continuous execution or an exact schedule. See [installation and native setup](/native-sdk/guide/how-to/installation) for the config plugin options and rebuild requirements. ## Queue Bluetooth readings [#queue-bluetooth-readings] `BTProvider.backgroundSync` persists each result before calling its asynchronous `onResult` handler. Supply durable storage so the queue survives process death: ~~~tsx import { BTProvider, IntegratedDevices } from "@ovok/native/bt-management"; const acceptedDevices = [IntegratedDevices.BP2] as const; measurementStore.getItem(key), setItem: (key, value) => measurementStore.setItem(key, value), }, getOwnerKey: () => authStore.currentAccountKey, onResult: async (result) => { await uploadMeasurement(result, { accountKey: result.ownerKey, idempotencyKey: result.id, }); }, maxRetries: 3, retryBackoffMs: 30_000, }} onError={({ error }) => reportBluetoothError(error)} > ; ~~~ The store must implement asynchronous `getItem` and `setItem` and persist data across app restarts. Choose storage and retention rules that fit the sensitivity of your measurement data. The `onResult` promise is the queue's acknowledgement: resolve it only when your server has accepted the result. Reject it to leave the item queued for retry. Delivery is **at least once**. The queue removes an item after `onResult` resolves, so a process exit between server acceptance and local removal can deliver it again. Use `result.id` as a server-side idempotency key. `queueId` identifies one enqueue operation; `attempt` is the current delivery attempt; `queuedAt` is the enqueue time. The default is three attempts with a 30-second exponential backoff base. Exhausted items remain persisted and are retried when the provider flushes the queue, such as when it mounts, the app returns to the foreground, or network connectivity returns. If the signed-in account changes while the app remains online, call `useBackgroundSync().flush()` from a component inside `BTProvider` to retry entries owned by that account. It retries pending and exhausted entries immediately, resetting their retry delay, and resolves when its current delivery pass finishes. The SDK also starts a flush when network connectivity returns. The coordinator checks `getOwnerKey()` before every queued delivery, so a mid-flush account switch stops later readings from being handed to the new account. Each `backgroundSync.onResult` value also includes the original `ownerKey`; route or save the reading with that key rather than looking up whichever account is active when your callback runs. A callback already in progress cannot be canceled by an account switch, so it must use the supplied owner key for the entire request. Mismatched readings remain queued until their owner is active again. A coordinator also tells what it still holds: `getQueued()` lists the current account's results that are waiting to be accepted, and `subscribe(listener)` reports each change (the first subscriber reads the stored queue in). `useQueuedResults(coordinator)` wraps both for a screen that shows readings not saved yet. `getOwnerKey` is required: a `BackgroundSyncCoordinator` created without it throws, rather than refusing every result as it arrives. The account it names has to outlast the moments background work runs in. The native next client retains its saved session during a temporary refresh outage; use its tenant, project, and profile references when deriving a stable owner key for your queue. New results capture `getOwnerKey()` when they enter the queue, before waiting for storage or another delivery. Results left by older SDK versions without an owner cannot be safely assigned to an account. On the first flush while an account is available, the SDK drops those legacy results and reports their count through `backgroundSync.onError` with code `BluetoothErrorCode.BACKGROUND_SYNC`; it never guesses which account owns them. Delivery errors also report that stable code and are retried according to the configured limit. Retry metrics include the error code, whether another attempt will run, and whether the item is exhausted. `backgroundSync.onError` receives a `BluetoothErrorCode.BACKGROUND_SYNC` error for each delivery failure; inspect its `originalError` for the underlying transport or native details. `BTProvider.onResult` is a separate immediate measurement callback. With background sync enabled it still fires when a measurement arrives, while `backgroundSync.onResult` handles acknowledged queue delivery. Keep these roles separate if you need server delivery to be durable. ## Restore iOS Bluetooth state [#restore-ios-bluetooth-state] Create the BLE manager once, outside React renders, with a stable restoration identifier: ~~~ts import { createBackgroundBleManager } from "@ovok/native/bt-management"; export const bleManager = createBackgroundBleManager({ restoreStateIdentifier: "com.example.app.bluetooth", }); ~~~ Use the same identifier in `backgroundSync.restoreStateIdentifier`. Enable `bluetooth.background` in the Expo config plugin and rebuild the native app. The SDK restores known peripherals and flushes queued results when iOS restores the BLE manager. Keep `BTProvider` mounted for the monitoring session and make its callback and storage dependencies stable. iOS background scanning needs service UUID filters, and Android needs them while the screen is off. In the background the SDK scans for the services of every accepted device it knows them for: built-in devices from its own table, custom device definitions from `mainServices` (`getBackgroundServiceUUIDs` returns the list). A device whose services aren't known is found by the foreground scan only; add the service it advertises to `backgroundSync.serviceUUIDs` to find it in the background too. The foreground scan is never filtered. For devices that do not advertise a service UUID, or advertise it only briefly after a measurement, keep a connection request pending instead of relying on the filtered scan. On iOS, `keepConnecting` asks CoreBluetooth to connect to each device without a timeout, so the system reconnects it whenever it is in range. A device that connects is handled like one the scan found, and the request is made again if it drops the link. It does nothing on Android. ~~~ts import { useBluetoothRuntime } from "@ovok/native/bt-management"; const runtime = useBluetoothRuntime(); runtime.manager?.keepConnecting(pairedDeviceIds); ~~~ Disconnecting a device with `disconnectDevice`, `forget`, or `stopScan` ends its request; call `keepConnecting` again to resume it. CoreBluetooth decides when it restores the app and delivers events. A restoration identifier and background mode do not guarantee continuous scanning. ## Run an Android BLE foreground service [#run-an-android-ble-foreground-service] When `backgroundSync.enabled` is true, `BTProvider` manages the Android connected-device foreground service with the scan. Configure its notification and optional battery optimization request in the provider options: ~~~tsx ~~~ The `requestBatteryOptimizationExemption` option asks Android to show its system consent UI while the app is active; it does not grant an exemption. Explain the request in your product UI and check the current state with `isAndroidBatteryOptimizationIgnored` after the app resumes. The foreground service can run without the exemption, subject to Android's power policies. If your app owns the BLE manager and scan lifecycle outside `BTProvider`, use the standalone [`AndroidBluetoothForegroundService`](/native-sdk/guide/components/background-sync/) or the start/stop functions from `@ovok/native/background-sync`. Use one service owner per scan; `BTProvider` already starts its own service. Android service permissions must be present in the native build. See [installation and native setup](/native-sdk/guide/how-to/installation). Changing an inline `onError` callback does not restart the service. If the component unmounts while the battery-exemption prompt is pending, the service is not started. ## Schedule Health Connect imports [#schedule-health-connect-imports] Android Health Connect background work is separate from Bluetooth. WorkManager wakes a headless JavaScript task; that task must restore the authenticated client and patient identity because there is no React tree and the SDK cannot serialize a client or credentials. Register the task once from the application entry point, before Android needs to start the headless runtime: ~~~ts import { registerAndroidHealthConnectBackgroundTask, runAndroidHealthConnectSync, } from "@ovok/native/background-sync"; registerAndroidHealthConnectBackgroundTask(async ({ reason }) => { const { client, patientId } = await restoreHealthSyncSession(); reportBackgroundRun(reason); await runAndroidHealthConnectSync({ client, patientId, dataToSync: androidDataToSync, onError: reportHealthSyncError, }); }); ~~~ Schedule periodic work from a foreground flow after the user enables it: ~~~ts import { cancelAndroidHealthConnectSync, scheduleAndroidHealthConnectSync, } from "@ovok/native/background-sync"; await scheduleAndroidHealthConnectSync({ intervalMinutes: 15, notificationTitle: "Health data sync", notificationBody: "Syncing recent Health Connect records", }); // When the user turns scheduled import off: await cancelAndroidHealthConnectSync(); ~~~ WorkManager's minimum interval is 15 minutes; it may run later because Android applies its own scheduling and power policies. The worker also requires network connectivity. If you pass a custom `taskName` to `scheduleAndroidHealthConnectSync`, register the headless task with that same name. The default is `OvokHealthConnectBackgroundSync`. Android runs the headless task through a foreground service and shows a notification while the work runs. Set `notificationTitle` and `notificationBody` when scheduling to provide app-appropriate copy. Request Health Connect's separate background-read permission with `backgroundAccess` on `AndroidHealthConnectAuthorizationProvider`, in addition to the foreground record permissions. Configure the Health Connect background service in the Expo plugin and rebuild. See the [authorization provider](/native-sdk/guide/components/data-sync/android/health-connect-authorization-provider/) and [Health Connect guide](/native-sdk/guide/modules/data-sync). `runAndroidHealthConnectSync` performs one import without rendering [`AndroidHealthSync`](/native-sdk/guide/components/data-sync/android/health-sync/). Restore the native `Ovok` session and pass its matching Patient ID; the import rejects a different patient. Pass the same `dataToSync` mapping used by the foreground component. `onProgress` and `onError` can report headless work to app-owned logging or persistence; do not depend on screen state to observe the result. ## Receive HealthKit updates [#receive-healthkit-updates] `AppleHealthSync` can enable HealthKit observer delivery for each mapped sample type: ~~~tsx import { UpdateFrequency } from "@kingstinct/react-native-healthkit"; import { DataSync } from "@ovok/native/data-sync"; ; ~~~ Enable `healthKit: { background: true }` in the Expo config plugin, provide the HealthKit usage descriptions, and rebuild. Keep `AppleHealthSync` mounted for as long as the app should receive observer updates: unmounting it removes its subscriptions and disables background delivery for the mapped identifiers. HealthKit and iOS choose when to deliver an observer update; the frequency is a request, not a timer. See the [`AppleHealthSync` reference](/native-sdk/guide/components/data-sync/apple/health-sync/). ## Optional: notify after BLE delivery [#optional-notify-after-ble-delivery] The BLE queue can schedule a local notification after `backgroundSync.onResult` accepts a measurement: ~~~ts backgroundSync: { enabled: true, storage: measurementStorage, onResult: uploadMeasurement, notifications: { enabled: true, title: "New measurement", body: (result) => `${deviceTitle(result.deviceData)} reported a result`, data: (result) => ({ resultId: result.id }), }, } ~~~ Without a `body`, the SDK uses the same wording with `deviceTitle`, so the notification names the product (for example "American Health Gate AHG-427B reported a measurement") rather than the decoder key. Install and configure `expo-notifications`, request notification permission from a foreground screen, and enable the `notifications` config plugin option. These are local notifications; they do not start background work or provide remote push tokens. The standalone permission and notification functions are listed in the [`background-sync` API reference](/native-sdk/guide/components/background-sync/). ## Before shipping [#before-shipping] - Use durable storage for queued BLE results and deduplicate uploads by `result.id`. - Resolve the queue callback only after the server accepts the result. - Build the native app with only the Bluetooth, HealthKit, Health Connect, service, and notification capabilities the app uses. - Register the Health Connect headless task from the application entry point and restore its client, patient identity, and data mapping there. - Keep HealthKit observer components mounted while observer delivery is needed. - Explain foreground service notifications and any battery optimization request to users. ## API reference [#api-reference] Every export of `@ovok/native/background-sync`, with signatures, props and types, is in the [`background-sync` API reference](/native-sdk/reference/background-sync). # Breathing exercises Canonical page: https://docs.ovok.com/native-sdk/guide/modules/breathing-exercise Use the breathing exercise module when a screen needs a timed inhale, hold, and exhale sequence. The SDK provides the animation and timer; your app decides when to start the exercise, what completion means, and whether to save the result. ## Render an exercise [#render-an-exercise] ```tsx import { BreathingExercise } from "@ovok/native/breathing-exercise"; ``` Durations are expressed in seconds. Keep the sequence and repeat count in the screen's configuration so they can reflect the care plan or product experience. Use `onFinish` to advance the screen or record completion; it does not persist a clinical observation for you. ## Add controls around the animation [#add-controls-around-the-animation] Use `BreathingExerciseProvider` and `useBreathingExercise` when the screen needs custom start, pause, or reset controls around the SDK animation. Keep those controls in the same provider subtree. If the built-in controls meet the need, use `BreathingExercise` directly. ## References [#references] - [BreathingExercise and its props](/native-sdk/guide/components/breathing-exercise/breathing-exercise/) - [BreathingExerciseProvider](/native-sdk/guide/components/breathing-exercise/breathing-exercise-provider/) - [useBreathingExercise](/native-sdk/guide/components/breathing-exercise/use-breathing-exercise/) - [Types](/native-sdk/guide/components/breathing-exercise/types/) ## API reference [#api-reference] Every export of `@ovok/native/breathing-exercise`, with signatures, props and types, is in the [`breathing-exercise` API reference](/native-sdk/reference/breathing-exercise). # Device instructions Canonical page: https://docs.ovok.com/native-sdk/guide/modules/bt-device-instructions `@ovok/native/bt-device-instructions` shows the instruction PDF the SDK hosts for an integrated Bluetooth device. `BTDeviceInstruction` picks the manual from `DEVICE_INSTRUCTION_PDFS` by device type and renders it with the PDF viewer, so it needs the `react-native-pdf` and `react-native-blob-util` peers. ```tsx import { BTDeviceInstruction } from "@ovok/native/bt-device-instructions"; import { IntegratedDevices } from "@ovok/native/bt-management"; ; ``` Not every device has a manual. Handle `onError` and show your own help content when the PDF is missing or fails to load. ## Components [#components] - [BTDeviceInstruction](/native-sdk/guide/components/bt-device-instructions/) - [PDF viewer](/native-sdk/guide/modules/pdf) for any other document. - [Supported devices and catalog](/native-sdk/guide/modules/bt-device) for device metadata. ## API reference [#api-reference] Every export of `@ovok/native/bt-device-instructions`, with signatures, props and types, is in the [`bt-device-instructions` API reference](/native-sdk/reference/bt-device-instructions). # Supported devices and catalog Canonical page: https://docs.ovok.com/native-sdk/guide/modules/bt-device The device catalog joins display metadata with the Bluetooth declarations the SDK can use. Import it from `@ovok/native/bt-device`: For the complete current model list, see [all supported Bluetooth devices](/native-sdk/guide/supported-devices). ~~~tsx import { SUPPORTED_DEVICES, SUPPORTED_ACCEPTED_DEVICES, Devices, } from "@ovok/native/bt-device"; ~~~ ## Pick a connectable entry [#pick-a-connectable-entry] `SUPPORTED_DEVICES` is the app-facing catalog. Each row contains `id`, `name`, `manufacturer`, image and attribution data, measurement types, an optional manual URL, and an `acceptedDevices` array for `BTProvider`. ~~~tsx const selected = SUPPORTED_DEVICES.find( (device) => device.id === selectedId, ); const acceptedDevices = selected?.acceptedDevices ?? []; if (acceptedDevices.length > 0) { // Use this declaration list as BTProvider.acceptedDevices. } ~~~ Some rows are useful for display but have no accepted declaration. An empty array means the current SDK catalog does not provide a decoder for that row. Do not offer a connect action for it. `SUPPORTED_ACCEPTED_DEVICES` is a de-duplicated union of the declaration arrays in the catalog. Use it only when the feature intentionally accepts every catalog declaration; most apps should provide the narrower set that matches their product. Catalog IDs are generated from each entry's name. Use the exported `id` as the selection key rather than constructing it from a display name. ## What each device is [#what-each-device-is] Every row also says what the product is, so an app needs no table of its own: | Field | Meaning | | --- | --- | | `kind` | What it is for: `blood-pressure-monitor`, `weight-scale`, `pulse-oximeter`, `thermometer`, `glucose-meter`, `ecg-recorder`, `heart-rate-monitor`, `activity-tracker`, `urine-analyzer`, `lipid-analyzer`, `respiratory-therapy`, `sleep-monitor`, or `multi-parameter-monitor` (three or more kinds of reading, such as the Checkme or the Lepod). | | `primaryMeasurement` | The reading it is for. Heart rate comes along with most readings, so it is the main one only on a device that measures nothing else. | | `delivery` | `spot`: one reading per measurement. `live`: values every second or so while connected (live oximeters, heart-rate straps, the Lepod). | | `keys` | The keys BTManager reports its devices under (`deviceData.name`). | | `shared` | Its parser also serves other products (rebadged models, a Bluetooth SIG profile), so a connected device may be any of them; `deviceData.variant` names the one it is when its advertised name says. | | `imageCredit` | `creditsForImage` as `{ label, url? }`. | ## Find and filter devices [#find-and-filter-devices] ~~~tsx import { MeasurementTypeKey } from "@ovok/core/next"; import { filterSupportedDevices, findSupportedDevice, useSupportedDevices, } from "@ovok/native/bt-device"; const scales = useSupportedDevices({ kind: "weight-scale" }); const hartmann = filterSupportedDevices({ manufacturer: "HARTMANN", kind: "blood-pressure-monitor" }); const recorders = filterSupportedDevices({ measures: MeasurementTypeKey.ecg, delivery: "spot" }); const product = findSupportedDevice(device.deviceData); // a connected device's catalog product ~~~ Every field of a filter has to match, and a list matches any one of its values. Text matches in any case, or pass a `RegExp` (`{ manufacturer: /yonker/i }`). `where` covers anything else. A string passed to `findSupportedDevice` is a catalog id, else a product name, else a reported key; pass a connected device's `deviceData` to get the product it is. Live devices send a reading every second or so. To keep the whole stream, pass `resultPoliciesFor(devices)` as `resultPolicies`: it gives live devices `LIVE_RESULT_POLICY`, which records their values as [series](/native-sdk/guide/modules/bt-management#streams-as-series) and still reports each blood pressure, glucose reading and ECG recording they take. ## Follow connected devices by what they are [#follow-connected-devices-by-what-they-are] `useBTDevice` and `useBTDevices` from `@ovok/native/bt-management` take the same filter, plus the connection `status` and a `where(device, product)`: ~~~tsx import { DeviceStatus, useBTDevice, useBTDevices } from "@ovok/native/bt-management"; const { device, connect } = useBTDevice({ kind: "blood-pressure-monitor", manufacturer: "HARTMANN" }); const connectedScales = useBTDevices({ kind: "weight-scale", status: DeviceStatus.CONNECTED }); ~~~ A model key works as before: `useBTDevice(IntegratedDevices.BP2)`. A failed measurement's `BluetoothError.translationKey` is one of `MeasurementFeedbackKey` (`STUCK`, `CORRUPT_FRAME`, `LOOSE_SLEEVE`, …); compare against those rather than the strings. ## Choose the right catalog UI [#choose-the-right-catalog-ui] | Component | Data and behavior | | --- | --- | | [SupportedDevicesCatalogList](/native-sdk/guide/components/ui/supported-devices-catalog-list) | Uses `SUPPORTED_DEVICES` by default. Shows artwork, name, manufacturer, measurement types, image credit, and an optional manual. `onSelect` returns metadata; it does not connect. | | [SupportedDeviceList](/native-sdk/guide/components/bt-device/supported-device-list/) | Uses the simpler `Devices` array and renders the static name, manufacturer, image, and image credit. | | [BTDeviceList](/native-sdk/guide/components/bt-device/bt-device-list/) | Shows the separate status-list context; it is not the supported catalog. | | [BTDeviceInstruction](/native-sdk/guide/components/bt-device/bt-device-instruction/) | Resolves an integrated device's manual from the SDK instruction mapping. | The richer catalog list displays the raw `name` and `manufacturer` strings. The simpler `SupportedDeviceList` uses `nameKey` and `manufacturerKey` with the catalog strings as fallback values. Add locale resources when your app wants translated catalog labels; measurement keys should also be mapped to app-facing copy. Image URLs, bundled assets, and their `creditsForImage` values are part of the exported data. The catalog UI displays credit by default. If you replace the photo or credit slot, keep the attribution visible in your app's catalog experience. ## Device match and result identity [#device-match-and-result-identity] A catalog declaration describes the device names or services the SDK can match and the protocol used to decode its frames. A product family can contain several models or firmware versions; verify the exact device variant your app offers. For standard GATT profiles, the service layout alone does not make every device with that service a match. ### Rebadged devices [#rebadged-devices] Some manufacturers sell the same device under several brands. `DEVICE_VARIANTS` lists each brand and model next to the built-in parser it shares: Transtek and Bioland glucose meters sold by American Health Gate, LinkSun and Pursonic; Jamr blood-pressure monitors sold as Jamr, Sinocare, ProMedica, Ease Healthcare, Gamma, GLOWY and Nebucor; AOJ thermometers; TaiDoc and FORA multi-parameter meters (TD-4279, TD-4289, TD-4206, FORA 6 Connect, FORA 6 Duo, Test N'GO Advance) on the GlucoCheck parser, which reports only their glucose records and drops ketone, cholesterol and control-solution results; and the Vive Precision ECG on the PM10 parser. When an advertised name matches a variant, the connected device reports the parser in `deviceData.name` and the product in `deviceData.variant`: ```ts device.deviceData.name; // "Bioland-BGM", the parser device.deviceData.variant; // { manufacturer: "American Health Gate", model: "AHG-427B" } ``` `deviceTitle` shows the variant's model. Accepting the parser in `acceptedDevices` accepts every variant of it. `variant` is unset for a parser that serves a single product. Transtek's own "command" protocol (generations A2 and A3) is built in too, as `Transtek BPM`, `Transtek Scale`, `Transtek Scale 1525` and `Transtek Tracker`: 180 white-label and rebadged products, including Transtek's Smart BP Monitor and Smart Weight Scale lines and products sold by Zewa, Medicare Lifesense, iProven, Kinetik Wellbeing, Welch Allyn and others. These devices pair with a password, so give the SDK somewhere to keep it (see [Keep device pairing secrets](/native-sdk/guide/modules/bt-management#keep-device-pairing-secrets)). Scales report a weight only once they mark it complete, so the values shown while someone steps on are not readings, and a scale set to pounds is converted to kilograms. The tracker reports its live running total for the day; its stored points and end-of-day statistics are earlier totals of the same steps and are not reported again. Records dated more than a day ahead of the phone are dropped as an unset device clock. These vendors have built-in classes too: - **Famidoc** (`Famidoc BPM`, `Famidoc IR Thermometer`, `Famidoc Contact Thermometer`): FDBP blood-pressure monitors, FDIR infrared and FDTH contact thermometers, and rebrands such as Trister and BYDOC. Records are acknowledged one by one and the session ends after a minute without a record. No pairing secret is involved. - **AOJ Medical** (`AOJ BPM`, `AOJ BPM FFF0`, `AOJ-70B`): the AOJ-30/33 blood-pressure monitors and rebrands (CliniCare, Oxiline, Oxmedi, B.Well, Sinocare), the Cazon BSX530B (`AOJ BPM FFF0`, which only pushes readings), and the AOJ-70A/70B pulse oximeter. The SDK sets the monitor's clock, downloads its stored records and leaves them on the device. The oximeter reports one spot reading, the last valid saturation and pulse, once valid values stop for three seconds. - **Jumper Medical** (`Jumper Oximeter`, `Jumper BPM`, `Jumper Thermometer`): the JPD-500D/500G pulse oximeters and rebrands (Zewa, AndesFit, Arystone, Kinetik, Tenovi, Qardio, Medicare Lifesense, LifeSyne), the HA120 blood-pressure monitor and rebrands (Oxiline, Alphamed, Medicare Lifesense), and the FR302/FR409 thermometers and rebrands (Zewa, iProven, Kinetik). All three only push live readings, so the phone's clock times them. The oximeter reports one spot reading once valid values stop for three seconds. A thermometer's repeated transmission of the same temperature within 30 seconds is dropped. - **Joytech (Sejoy)** (`Joytech BPM`, `Joytech Thermometer`): DBP blood-pressure monitors, including the Controly AFIB Connect, and DET thermometers. The SDK sets the clock, asks a monitor for its history and acknowledges every record. Blood-pressure readings carry `irregularHeartbeat` and `atrialFibrillation`. Thermometer readings from the object/surface mode are skipped. - **A&D Medical** (`A&D BPM`, `A&D BPM CTS`, `A&D Scale`): the UA-651BLE, UA-911BT-C and UA-656BLE blood-pressure monitors, the UA-1200BLE and UB-1100BLE (`A&D BPM CTS`, clock on Current Time), and the UC-352BLE scale. The SDK sets the clock on every connection: a monitor gets the SIG Date Time a second after connecting, then sends its readings over the SIG Blood Pressure profile with the device timestamp, `irregularHeartbeat` and the user as `memorySlot`; an exact repeat in one connection is reported once. The scale takes the A&D set-time command and reports kilograms, converting a scale set to pounds. All of them need an OS bond; the SDK has no explicit bonding step, so pairing relies on the platform's prompt when the device asks for encryption. - **Yonker** (`Yonker Oximeter`, `Yonker BPM`, `Yonker Thermometer`, `Yonker Scale`, `Yonker 80B`): the YK-81C pulse oximeter and rebrands (Balans Plus, Incoterm), the YK-BPA/YK-IBPA blood-pressure monitors and rebrands (Metiko, OxiPro), the YK-IRT4 thermometer and the Balans Plus BPTI 24, the AiLink weight scale and the Balans Plus BPBI 24, and the YK-80B oximeter (Orluminis YK-83B). The SDK sets a monitor's clock and keeps the time each record carries; the monitor pushes its records by itself. The oximeters report one spot reading once valid values stop for three seconds. Thermometer readings in Fahrenheit are converted to Celsius, and a repeated transmission of the same temperature within 30 seconds is dropped. The scale is set to kilograms and reports the weight when it signals the measurement complete; body composition is not read. - **Cofoe** (`Cofoe BPM`, `Cofoe BPM History`, `Cofoe Glucometer`, `Cofoe Glucometer CGH25`, `Cofoe Thermometer`): KF-65/KF-66EP blood-pressure monitors (`Cofoe BPM`, a live reading timed by the phone) and the KF-66EP+, KF-65BY/W/BW/G/DPLUS, KF-66DP, KF-67C/BP and Carditek Smart (`Cofoe BPM History`, stored records that keep the monitor's own time); the KF-B06, CGH200 and Novocont Comfort glucometers; the CGH25 and CGH30 glucometers; and the KF-HW-081A thermometer. The SDK sets each device's clock where the protocol has one, acknowledges every record, and never deletes a glucometer's memory. Blood-pressure readings carry `irregularHeartbeat`; glucose arrives in mmol/L and is reported in mg/dL. Every frame's checksum is verified and a frame that fails it is dropped. - **Transtek A6 scales** (`GBS-2012-B`, `RPM_SCALE`): the GBS-2012-B and other A6-generation body-composition scales - GBF-2008-BF/BF1, LS212-B (also sold as Rossmax WF262), SFX61, Kinetik BTS200, Zewa 21300 v2, Pic BodyStation Easy, EZFAST GBF-2108-B, Prosper PW-100, Dovant BIANOVA 300 and the Dynamics SMART/FIT scales. Weight only; body composition isn't decoded. The separate **Transtek A6 blood-pressure** decoder (`A610`, `TRANSTEK_A6_BPM`) supports 94 catalogue models, including TMB-2079/2088 and listed rebrands. It reports systolic, diastolic, mean pressure, pulse, the record's UTC time, memory user and irregular-heartbeat status. The A6 BP layout and workflow follow Transtek Health 2.0.5's APK: authenticate, set the BP time with `0x1102`, then sync records with `0x4901` and decode `0x4902`. The app's A610 path omits the scale-only init exchange, ignores the optional local-time bytes and exposes no AFib flag. The A6_1970 time-base and AFIBWithoutIHB variants remain outside the catalogue because the APK does not establish their timestamp or AFib semantics. The A6 scale stays on `RPM_SCALE`; Mambo 2/6 activity bands remain unsupported while the Mambo class decodes A5 oxygen records. - **TaiDoc (FORA)** (`TaiDoc Multi`, `TaiDoc BPM`, `TaiDoc Thermometer`, `TaiDoc Oximeter`, `TaiDoc Scale`): FORA and TaiDoc 2-in-1 meters, glucose meters and blood-pressure monitors on the 0x51 command protocol (FORA D40, MD, Premium V10, Test N'GO Voice, Diamond MINI, TD-3128, TD-3223, TD-3261, TD-4266, TD-4277, Pic Solution GoGlic/BeGlic, GlucoMaxx Connect), the Diamond Cuff/P20b monitors, TD-12xx and FORA IR42 thermometers, TD-8255/8201, Test N'GO SpO2 and PO200 pulse oximeters, and the TD-2555 and Test N'GO Scale 550. The SDK sets the clock, downloads every device user's stored records with the meter's own timestamps and the user in `memorySlot`, then powers the meter off; it never clears the memory. `TaiDoc Multi` reports blood pressure or glucose by each record's type, and only patient glucose (no control-solution or other-analyte records). Blood-pressure readings carry `irregularHeartbeat`. Thermometer object-mode records are skipped, and the scale reports weight only. The TaiDoc TD1035 is a standard Health Thermometer. `DEVICE_VARIANTS` also lists products that implement a Bluetooth SIG profile (blood pressure, glucose, thermometer, weight scale, heart rate, spot-check pulse oximetry): Omron, Beurer, A&D, Accu-Chek, Contour, Medisana, Polar, Wahoo and many more. These are found by service, so any compliant device works whether or not it is listed; a listed product additionally gets its brand and model in `deviceData.variant` when its advertised name identifies it. A few products share one advertised name with others (for example several Contour meters advertise `Contour…`), so they are listed without a name pattern and connect under the profile's generic name. Each catalog entry's image is the manufacturer's or a retailer's photo, credited with its page, or a generic illustration that names the page the product was identified from. A Bluetooth SIG device is read from its frames as the specification lays them out: - A frame that carries the device's own timestamp dates the reading (`recordedAt`): blood pressure, thermometer, weight scale and spot-check oximeter. Blood pressure in kPa is converted to whole mmHg, and a weight of `0xFFFF`, which a scale sends when the measurement failed, is dropped. - A multi-user monitor or scale reports its user as `memorySlot`: the device's user index plus one, left out when the device does not know the user. A thermometer reports where it measured as `temperatureType` (`armpit`, `body`, `ear`, `finger`, `gastrointestinal-tract`, `mouth`, `rectum`, `toe` or `tympanum`), and a heart-rate strap its RR intervals as `rrIntervals`, in milliseconds. A strap kept as a [series](/native-sdk/guide/modules/bt-management#streams-as-series) records only its heart rate. - To report only the readings of the people a device is paired to, list their slots in `acceptedMemorySlots` of that device's `resultPolicies` entry. The SDK does not register users on a multi-user scale through the User Data Service, so a person's slot is the one the device assigns. Bluetooth result IDs are stable for repeated delivery when the device identity and measurement payload are unchanged. The identity uses the device serial number when available, then manufacturer data, model, device name, and finally the platform peripheral ID. The final fallback is the platform peripheral ID, so a changed peripheral ID produces a different result identity. The result's `id` is enumerable and non-writable at runtime. It is included in object spreads and JSON serialization. Use it as an idempotency key when the app retries persistence or uploads. See [Bluetooth](/native-sdk/guide/modules/bt-management), [supported-device definitions](/native-sdk/guide/components/bt-management/supported-devices/), and [custom devices](/native-sdk/guide/components/bt-management/custom-devices/). ## API reference [#api-reference] Every export of `@ovok/native/bt-device`, with signatures, props and types, is in the [`bt-device` API reference](/native-sdk/reference/bt-device). # Bluetooth Canonical page: https://docs.ovok.com/native-sdk/guide/modules/bt-management Use the Bluetooth module to discover supported BLE devices, connect to them, and receive normalized measurements. Your app owns the Bluetooth manager lifetime, the accepted device list, the user experience around measurement, and what happens to each result. ## Before you start [#before-you-start] - Follow [Installation and native setup](/native-sdk/guide/how-to/installation) to install native peers and configure platform permissions. - Test on a physical iOS or Android device. Simulators do not reproduce the full BLE scan, permission, and pairing path. - Decide which device models the app will support. Review [all supported Bluetooth devices](/native-sdk/guide/supported-devices) and the [supported device catalog](/native-sdk/guide/components/bt-management/supported-devices/); use [custom device declarations](/native-sdk/guide/components/bt-management/custom-devices/) only when the SDK does not already implement the protocol. ## 1. Create a long-lived BLE manager [#1-create-a-long-lived-ble-manager] Create one `BleManager` for the app or Bluetooth feature. Keep it outside a component render, or in a stable app-level ref, so a render does not replace the native manager. ~~~tsx import { BleManager } from "react-native-ble-plx"; import { BTProvider, IntegratedDevices, } from "@ovok/native/bt-management"; const bleManager = new BleManager(); const acceptedDevices = [ IntegratedDevices.BP2, IntegratedDevices.F4, ] as const; ~~~ `acceptedDevices` is a typed allowlist. The SDK only creates handlers for entries in that list. Keep the array identity stable for the lifetime of the provider. ## 2. Mount `BTProvider` around the measurement flow [#2-mount-btprovider-around-the-measurement-flow] `BTProvider` requests Bluetooth access, creates the managed device runtime, starts discovery, and tears it down when it unmounts. Keep it mounted for as long as the flow should own the scan and connections. ~~~tsx export function MeasurementFlow() { return ( device.connect()} onDeviceStatusChanged={({ deviceData, status }) => { console.log(deviceData.name, status); }} onResult={(result) => { const idempotencyKey = result.id; const measurement = result.data; void saveMeasurement({ idempotencyKey, measurement }); }} onError={({ deviceData, error, code }) => { reportBluetoothError(deviceData?.name, error, code); }} > ); } ~~~ By default, the permission request runs when the provider mounts. If access is denied, the provider renders its default settings prompt; supply `permissionFallback` to render your own. To wait until a patient chooses to pair, set `requestPermissionOnMount={false}` and call `useBluetoothState().requestPermission()` from a child action. The provider stays mounted, but discovery starts only after that request succeeds. See [BTProvider permission behavior](/native-sdk/guide/components/bt-management/bt-provider/) for an example. ## 3. Handle readings and connection state [#3-handle-readings-and-connection-state] A result contains `deviceData` and normalized measurement `data`. It also has a stable `id` for deduplication. The SDK defines `id` as an enumerable property that is non-writable at runtime, so object spreads and JSON serialization include it. Pass it as an idempotency key when the app may retry uploads. A stored record keeps its `id` whenever the device sends it again, in any time zone. A reading without a time of its own is a new measurement each time, so its `id` includes when it arrived. `legacyId` is the id SDKs before 1.16.1 gave the same reading: look it up to recognise readings an earlier version already saved. Use `onDeviceStatusChanged` for the compact status values: `Connected`, `Disconnected`, `Measuring`, and `LowBattery`. Use `onConnectionEvent` for pairing prompts, bonding, battery values, and history transfer progress. A transfer's `progress.total` can be missing; show a count rather than a percentage unless a total is present. The provider callbacks are app-owned boundaries. Persist, associate with a patient, validate, and upload measurements in your app. The SDK does not choose a patient or submit results to your backend. ## 4. Add a device selection and pairing experience [#4-add-a-device-selection-and-pairing-experience] For apps that connect to whichever accepted device is nearby, enable `autoConnect`. One discovered device connects automatically after the settle delay; when multiple devices are found, handle `onDeviceSelectionRequired` and present a chooser such as [BluetoothDevicePicker](/native-sdk/guide/components/bt-management/bluetooth-device-picker/). For a discover-and-pair screen, use [PairingFlow](/native-sdk/guide/components/ui/pairing-flow). It reads nearby devices from the provider runtime and stores remembered device IDs through the storage adapter you supply. See [Bluetooth state notice](/native-sdk/guide/components/ui/bluetooth-state-notice) to give users a clear route to enable Bluetooth or permissions. ## Keep device pairing secrets [#keep-device-pairing-secrets] Some devices hand the phone a secret once, at pairing, and expect it back on every later connection. Transtek's white-label blood-pressure monitors, scales and activity tracker do: the device sends a 32-bit password while it is in pairing mode, and every later session proves the phone holds it. The SDK keeps these secrets in memory for the app session. Give it durable, private storage so a paired device keeps working after the app restarts: ```ts import * as SecureStore from "expo-secure-store"; import { setDeviceSecretStorage } from "@ovok/native"; setDeviceSecretStorage({ getItem: (key) => SecureStore.getItemAsync(key.replace(/[^A-Za-z0-9._-]/g, "_")), setItem: (key, value) => SecureStore.setItemAsync(key.replace(/[^A-Za-z0-9._-]/g, "_"), value), }); ``` Call it once at startup, before connecting. A device without a stored secret reports a `bluetooth.pairing-required` error: put it in pairing mode (on most Transtek devices, hold the Bluetooth or memory button until the display flashes) and connect again. ## 5. Add device UI where it helps [#5-add-device-ui-where-it-helps] The package has two device catalog approaches: - [SupportedDevicesCatalogList](/native-sdk/guide/components/ui/supported-devices-catalog-list) shows the richer catalog with measurement types, manual links, artwork, and an optional selection callback. - [BTDeviceList](/native-sdk/guide/components/bt-device/bt-device-list/) renders the SDK's device-status list. Pair it with [DeviceListProvider](/native-sdk/guide/components/bt-device/device-list-provider/) and optionally use [BTDeviceInstruction](/native-sdk/guide/components/bt-device/bt-device-instruction/) for an available manual. Catalog entries are metadata. Check each entry's `acceptedDevices` before offering a connect action; entries with no accepted device declaration cannot be passed to `BTProvider`. For ECG readings, prepare the waveform samples and sampling rate from the result data in your app, then render them with [EcgStripViewer](/native-sdk/guide/components/ui/ecg-strip-viewer). The viewer presents a trace; it does not parse a device result or interpret a rhythm. ## Lifecycle and operational choices [#lifecycle-and-operational-choices] - Mount one provider for one active scanning scope. Unmounting it stops scanning, detaches subscriptions, and destroys its managed `BTManager`. - Use `useScanControl` to pause and resume scanning without unmounting the provider. - Configure [background delivery](/native-sdk/guide/modules/background-sync) separately. It requires durable storage and native background configuration; it is opt-in. - Tune result filtering only when the product requires it. `resultPolicies` can select `all`, `daily-totals-only`, `first-reading-per-kind-per-connection`, or `series` at the device or measurement level. A device's entry can also list `acceptedMemorySlots`, so that only the readings of those device users are reported. ## Streams as series [#streams-as-series] A device that streams, such as a heart-rate strap, a live oximeter or the Lepod, sends a value every second or so. With a `series` result policy (`LIVE_RESULT_POLICY` sets it for live devices), the manager keeps every live value in a series of one-second slots, one per device and kind of measurement, with `null` for a second nothing arrived in. A series closes when its device disconnects, after an hour, or after 15 minutes without a value, and is reported as one result: `result.series` holds every value (`{ measurementTypeKey, start, periodMs, values }`), and `result.data` each property's mean. Save it with @ovok/core's `seriesObservations`, which writes the values as `valueSampledData`. - A disconnect ends the device's series, so it's saved straight away; reconnecting starts a new one. - Pass `seriesStorage` (the store your results queue uses; `BTProvider` passes its background-sync storage) so a series survives the app closing. Without it, series live in memory. - A reading dated more than two minutes from now is a stored record, not a live value, and is reported on its own. So are the single measurements `LIVE_RESULT_POLICY` keeps as `all`: blood pressure, glucose and ECG recordings. - To show values before they are stored, read `manager.getOpenSeries()` (each with its `latest` values) and `subscribeOpenSeries`, or `useOpenSeries(manager)`. Readings still waiting in a `BackgroundSyncCoordinator` come from `getQueued()` and `subscribe`, or `useQueuedResults(coordinator)`. - A Viatom O2Ring, Oxyfit, KidsO2 or BabyO2 on the legacy O2 protocol, kept as a series, also streams its pulse wave when the ring serves one: raw 125 Hz samples (unitless, inverted, so systolic peaks are minima), handed over in results of up to five minutes and when the device disconnects. `result.series` is `{ measurementTypeKey: bloodOxygenPulseRate, start, periodMs: 8, values: { pulseWave } }`, with `null` where the sensor lost contact or samples never arrived; the id starts `wave:`, and `result.data` holds only `measurementTypeKey` and `recordedAt`. Its saturation and pulse rate still go into the one-second series. A ring that answers without a wave is polled for saturation and pulse rate as before. The five minutes being recorded are kept in memory only, so closing the app loses them. - Keep native permission and Bluetooth-on state distinct. Permission being granted does not guarantee that the radio is powered on. ## Glucose meters [#glucose-meters] A Bluetooth SIG glucose meter (`standardGlucoseDevice`) keeps its readings until the app asks for them. After connecting, the SDK writes a request to the Record Access Control Point: the records after the newest one it has read, or every record when it has no store or nothing stored yet. - Pass `recordCursorStorage` to `BTManager` (the store your results queue uses; `BTProvider` passes its background-sync storage) so the next connection asks only for newer records. A meter that refuses the sequence-number filter is asked for every record instead. The SDK stores each meter's newest sequence number under `@ovok/native/glucose-sequence/`, counting a record it withholds too. - A meter that was reset starts numbering again, so its new records are skipped until it passes the stored number. Overwrite that entry with an empty string to download every record again. - `result.data.bloodGlucose` is in mg/dL with one decimal, so a 5.5 mmol/L record reads 99.1 and converts back to 5.5. `reportedUnit` says which unit the meter showed. - Each reading also carries `sequenceNumber`, `specimen` and `sampleLocation` (see `GlucoseRecordDetails`). - When the meter flags a result above or below what it can measure, the reading has `outOfRange: "high"` or `"low"`: its `bloodGlucose` is the edge of the meter's range, so do not store it as a measurement. A low battery, a hot or cold sensor or a time fault leaves the value usable and is listed in `sensorStatus`. A record flagged as a failed test (sensor fault, too little blood, strip error, wrong strip, interrupted read, device fault) is withheld. - The Glucose Measurement Context characteristic (meal, tester, health, exercise and medication) is not read yet. ## Viatom ER1 and BP2 history [#viatom-er1-and-bp2-history] An ER1 or BP2 keeps its recordings until the app asks: connecting only lists them, and `device.syncHistory()` (web: `BluetoothRuntime.syncHistory(id)`) reads them over the open connection. - Pass `recordCursorStorage` to `BTManager` (web: `builtInDevices(accepted, { recordCursorStorage })`) and return a promise from `onResult` that resolves once the reading is queued or saved, such as `return coordinator.enqueue(result)`. A later sync then opens only the files whose readings were not taken. The web runtime takes a reading once its sink saved or queued it. - A reading whose promise rejects, or whose callback returns nothing, leaves its file to be read again on the next sync. - The SDK stores each device's file names under `@ovok/native/lepu-delivered-files/`, only those the device still lists. Overwrite that entry with an empty string to read every file again. ## Related references [#related-references] - [BTProvider and its callbacks](/native-sdk/guide/components/bt-management/bt-provider/) - [Supported devices](/native-sdk/guide/components/bt-management/supported-devices/) - [Custom devices](/native-sdk/guide/components/bt-management/custom-devices/) - [Bluetooth components](/native-sdk/guide/components/bt-device/) - [PairingFlow](/native-sdk/guide/components/ui/pairing-flow) - [Background sync](/native-sdk/guide/modules/background-sync) ## API reference [#api-reference] Every export of `@ovok/native/bt-management`, with signatures, props and types, is in the [`bt-management` API reference](/native-sdk/reference/bt-management). # CMS content and translations Canonical page: https://docs.ovok.com/native-sdk/guide/modules/cms Use the CMS hooks when a screen needs content managed in Ovok CMS, such as a legal page, release notes, or localized app copy. The hooks return request state; they do not render a screen or choose navigation, caching UI, or empty and error states for the host app. CMS locale follows the app's `react-i18next` language. The SDK maps that language to a CMS locale (for example, `de-DE` to `de`) and updates requests when the app language changes. Pass `options.locale` when a request needs a different locale. ## Read a CMS document [#read-a-cms-document] Import the hooks from the optional `cms` subpath: ```tsx import { useCmsDocument, useCmsLocale } from "@ovok/native/cms"; type Article = { title: string; body: string; }; function ArticleScreen({ slug }: { slug: string }) { const locale = useCmsLocale(); const request = useCmsDocument
("articles", slug); return ; } ``` Use `useCmsDocument(collection, slug, options)` for one entry and `useCmsDocuments(collection, options)` for a collection page. The generic type describes the content shape your app expects; keep it aligned with the CMS schema. Handle loading, missing content, request errors, and retry behavior in the host screen using the returned `OvokRequestState`. For the built-in legal page and release notes endpoints, use `useLegalPage(slug, options)` and `useReleaseNotes(options)`. Legal pages can be read before sign-in when you provide the tenant code. Release notes require a session. The hooks use the current app locale unless `options.locale` overrides it. ## Load CMS translations [#load-cms-translations] Call `useCmsTranslations` once in a component below the app's i18next provider, usually near the application root: ```tsx import { useCmsTranslations } from "@ovok/native/cms"; function CmsTranslationBootstrap({ tenantCode }: { tenantCode: string }) { useCmsTranslations({ tenantCode }); return null; } ``` The hook loads the CMS `translations` collection for the current CMS locale and merges it into the i18next `translation` namespace. App-owned strings take precedence. CMS strings can replace the SDK's built-in English defaults, while an explicit `options.locale` targets a specific CMS locale. It returns the underlying `OvokRequestState`; surface failures through host-owned logging or UI if the translations are required for the screen. For a signed-out app, pass `tenantCode` so the CMS can resolve the tenant. Place the hook under the i18next provider and call it once; do not add it to every screen. A language change triggers a request for the new CMS locale. ## Choose the right hook [#choose-the-right-hook] | Need | Hook | | --- | --- | | One document from a collection | `useCmsDocument(collection, slug, options)` | | A page of collection documents | `useCmsDocuments(collection, options)` | | A legal page that can be loaded before sign-in with `tenantCode` | `useLegalPage(slug, options)` | | Release notes for a signed-in user | `useReleaseNotes(options)` | | App language as a CMS locale | `useCmsLocale()` | | CMS-backed translations in i18next | `useCmsTranslations(options)` | The `cms` hooks read CMS data. For app-owned content cards and FHIR Composition details, see [Content components](/native-sdk/guide/modules/content). ## References [#references] See the [CMS hook reference](/native-sdk/guide/components/cms/) for imports and the generated signatures for each export. ## API reference [#api-reference] Every export of `@ovok/native/cms`, with signatures, props and types, is in the [`cms` API reference](/native-sdk/reference/cms). # Content components Canonical page: https://docs.ovok.com/native-sdk/guide/modules/content Use the content module to render app-owned content collections or a detail view backed by a FHIR `Composition`. These are presentation components: the app loads the content, applies access rules, and handles navigation. ## Choose the surface [#choose-the-surface] - Use `ContentCard` for one item in a grid or feed. - Use `ContentList` for a titled or horizontally scrolling collection. - Use `ContentDetail` when a `Composition` should provide the content for a detail screen. ```tsx import { ContentCard } from "@ovok/native/content"; openContent(item.id)}> {item.title} {item.summary} ``` The card and list primitives can render your own view model. They do not fetch content or decide which items a user can see. For `ContentDetail`, load and authorize the `Composition` in the app, then pass it through the component's `composition` prop; the component provides it to `useComposition` descendants. ## Keep content behavior in the app [#keep-content-behavior-in-the-app] Own loading, empty, and error states at the screen level. Handle links, downloads, and analytics in the callbacks you pass to the components. Use the composition hook only inside the provider subtree, and do not treat a rendered resource as proof that the user is authorized to access it. ## References [#references] - [ContentCard](/native-sdk/guide/components/content/content-card/) - [ContentList](/native-sdk/guide/components/content/content-list/) - [ContentDetail and composition context](/native-sdk/guide/components/content/content-detail/) - [Content module exports](/native-sdk/guide/components/content/) ## API reference [#api-reference] Every export of `@ovok/native/content`, with signatures, props and types, is in the [`content` API reference](/native-sdk/reference/content). # HealthKit and Health Connect Canonical page: https://docs.ovok.com/native-sdk/guide/modules/data-sync Use the data sync module to import selected records from Apple HealthKit on iOS or Health Connect on Android. The authorization provider handles the platform permission flow; its matching sync component reads records and saves them as OVOK observations for the signed-in patient. Apple Health import needs `@kingstinct/react-native-healthkit` 16.2.0 or newer and `react-native-nitro-modules` 0.35 or newer. Both are native modules: after you add or upgrade them, build the app again, because a JavaScript update cannot load them. HealthKit identifiers are plain strings such as `"HKQuantityTypeIdentifierBodyMass"`; version 16 has no `HKQuantityTypeIdentifier` enum to import. Before adding the integration, complete [installation and native setup](/native-sdk/guide/how-to/installation) and mount the app inside the authenticated [OVOK provider tree](/native-sdk/guide/how-to/app-shell). Health sync needs an initialized client and a patient profile, and it runs in a native development build rather than Expo Go. ## Pick the platform API [#pick-the-platform-api] | Platform | Authorization provider | Import component | Native source | | --- | --- | --- | --- | | iOS | `DataSync.AppleHealthAuthorizationProvider` | `DataSync.AppleHealthSync` | HealthKit | | Android | `DataSync.AndroidHealthConnectAuthorizationProvider` | `DataSync.AndroidHealthSync` | Health Connect | Import the module from `@ovok/native/data-sync`. The optional, adapter-driven [`HealthImportCard`](/native-sdk/guide/components/ui/health-import-card) is a separate UI primitive; it does not replace these providers or run this import pipeline. ## 1. Map records to OVOK observations [#1-map-records-to-ovok-observations] Each `dataToSync` entry connects an OVOK measurement key to one or more platform record identifiers. Leave `code` out: the SDK codes a core measurement key the way core codes that measurement from any source, and any other key by its reviewed LOINC term or the platform's own type. Set `code` and `system` only to store a type under a different code. ~~~ts import { MeasurementTypeKey } from "@ovok/core/next"; import type { AppleHealthSyncProps } from "@ovok/native/data-sync"; export const appleDataToSync: AppleHealthSyncProps["dataToSync"] = { [MeasurementTypeKey.bodyWeight]: { typeIdentifiers: [ { typeIdentifier: "HKQuantityTypeIdentifierBodyMass" }, ], minDate: new Date("2025-01-01T00:00:00.000Z"), }, }; ~~~ Android uses Health Connect record names for the same mapping: ~~~ts import { MeasurementTypeKey } from "@ovok/core/next"; import type { AndroidHealthSyncProps } from "@ovok/native/data-sync"; export const androidDataToSync: AndroidHealthSyncProps["dataToSync"] = { [MeasurementTypeKey.bodyWeight]: { typeIdentifiers: [ { typeIdentifier: "Weight" }, ], minDate: new Date("2025-01-01T00:00:00.000Z"), }, }; ~~~ ### Apple Watch ECG [#apple-watch-ecg] Map `MeasurementTypeKey.ecg` to the `HKElectrocardiogramType` identifier to import the recordings made with the Apple Watch ECG app (iOS 14 or later): ~~~ts [MeasurementTypeKey.ecg]: { typeIdentifiers: [{ typeIdentifier: "HKElectrocardiogramType" }], }, ~~~ Each recording becomes OVOK's ECG observation: the waveform in millivolts as sampled data, its duration in seconds, and the average heart rate as a second observation. The start of the recording is its time. Apple's own classification (such as sinus rhythm or atrial fibrillation) and the symptoms the person noted are not imported: the SDK saves what was measured and gives no reading of it. Add `HKElectrocardiogramType` to `readIdentifiers` of the authorization provider as well. Recordings are read at most ten at a time, whatever `chunkSize` is, because each one holds the whole waveform. The first read defaults to the most recent 30 days on both platforms. Set `minDate` to choose an earlier initial boundary. Later runs use the latest matching observation already stored for the patient and provider as their starting point. Daily totals and summaries re-read the last seven imported days, so a total that a wearable changes after a late sync is updated. The SDK also keeps provider pagination anchors in the native client's secure storage, scoped to the current tenant, project, patient, provider, and data type. When a record is deleted in Apple Health or Health Connect, the observations imported from it are deleted too. They are found by the `observation-sync-record` identifier the import gives them; observations imported before it existed don't have it, so they stay. The SDK has built-in modes for common data shapes: | `mode` | Result | | --- | --- | | `point` | One observation per source sample or record. This is the default for most measurement keys. | | `daily-total` | One total for each completed day. This is the default for step count, distance, active energy, flights climbed, exercise minutes, water, carbohydrates, and calories eaten. | | `daily-summary` | One daily summary. Heart rate defaults to an average with minimum and maximum components. | | `session` | One observation for each session. Sleep and workout default to this mode. | | `series` | One observation per finished hour holding a value a minute as `valueSampledData` (`E` for a minute without one), for frequent quantities such as heart rate, SpO₂ and respiratory rate. Apple Health's statistics and Health Connect's aggregation give the minute averages, following the user's source priority; Health Connect types it doesn't aggregate (SpO₂, respiratory rate) are averaged from their records. Each run reads the last three imported hours again and writes over them. | The exported `HealthDataType` enum includes `height`, `bodyFatPercentage`, `bodyMassIndex`, `leanBodyMass`, `distance`, `activeEnergy`, `flightsClimbed`, `exerciseMinutes`, `heartRateSummary`, `sleep`, `workout`, `water`, `carbohydrates`, `caloriesEaten`, `bloodAlcohol`, and `insulin`. Health Connect has no blood alcohol or insulin record. Use these keys for data that is not represented by a core measurement key. Set `mode` on an entry to override its default. ## 2. Configure native permissions [#2-configure-native-permissions] Add the SDK config plugin for the platform integrations your app uses. For an import-only flow, request only read permissions for the record types in `dataToSync`: ~~~ts plugins: [ [ "@ovok/native", { healthKit: true, healthConnect: true, }, ], ], ios: { infoPlist: { NSHealthShareUsageDescription: "Explain why the app reads the selected health data.", }, }, android: { permissions: ["android.permission.health.READ_WEIGHT"], }, ~~~ For HealthKit background delivery, use `healthKit: { background: true }` and add the background delivery option in step 5. Add `NSHealthUpdateUsageDescription` and HealthKit write permissions only if your app also writes data back to the health store. For Health Connect, declare the matching `android.permission.health.READ_*` permissions for every record type you request. The plugin composes the platform libraries; native config changes take effect after you rebuild the app. See [installation and native setup](/native-sdk/guide/how-to/installation) for plugin details, usage descriptions, and development builds. ## 3. Mount the authorization provider and sync component [#3-mount-the-authorization-provider-and-sync-component] The provider requests access automatically when a request is needed. Pass only the identifiers the feature will read. For import-only flows, omit `writeIdentifiers`. The mapping objects, status setters, progress state, and error handler below are app-owned values; define them in the screen or feature module. ~~~tsx import * as React from "react"; import { ActivityIndicator } from "react-native"; import { DataSync } from "@ovok/native/data-sync"; export function AppleHealthImport() { return ( } onAuthorizationStatusChange={setHealthKitStatus} > ); } ~~~ For Health Connect, use its record identifiers and provider: ~~~tsx import { ActivityIndicator } from "react-native"; import { DataSync } from "@ovok/native/data-sync"; export function HealthConnectImport() { return ( } onAuthorizationStatusChange={setHealthConnectStatus} > ); } ~~~ Both sync components read the active native client and Patient session from `@ovok/core/next/react`. Mount them only after sign-in. The provider controls the permission UI; the sync component starts its import when mounted. ### Own the permission screen [#own-the-permission-screen] Provide both `renderManualRequestUI` and `skipRequest` when your app owns the prompt. Set `skipRequest={false}` to let the provider render the callback UI and avoid automatic permission requests: ~~~tsx import { Button } from "react-native"; import { DataSync } from "@ovok/native/data-sync"; ( ``` Keep draft state, validation rules, retry behavior, and persistence in the screen or your form layer. Show a clear success or failure state after saving; rendering an answer form does not submit it automatically. ## References [#references] - [Answer form](/native-sdk/guide/components/journal/answer/) - [Today's question card](/native-sdk/guide/components/journal/today-question-card/) - [Past journal card](/native-sdk/guide/components/journal/past-journal-card/) - [Journal component index](/native-sdk/guide/components/journal/) ## API reference [#api-reference] Every export of `@ovok/native/journal`, with signatures, props and types, is in the [`journal` API reference](/native-sdk/reference/journal). # Language switcher Canonical page: https://docs.ovok.com/native-sdk/guide/modules/language-switcher `LanguageSwitcher` renders language options and reports the selected value. It is a controlled component: your localization layer remains responsible for loading translations, changing the active locale, and persisting the preference. ```tsx import { LanguageSwitcher } from "@ovok/native/language-switcher"; function LanguageSettings({ language, changeLanguage }) { return ( English Deutsch ); } ``` Use the same locale identifiers your translation system expects. Update the controlled `language` value after the localization change succeeds, and present loading or failure feedback in the surrounding screen. The SDK does not provide a language catalog or translation files. ## References [#references] - [LanguageSwitcher](/native-sdk/guide/components/language-switcher/language-switcher/) - [Option, flag, label, and radio button](/native-sdk/guide/components/language-switcher/) - [Switcher hook and context](/native-sdk/guide/components/language-switcher/advanced-api/) ## API reference [#api-reference] Every export of `@ovok/native/language-switcher`, with signatures, props and types, is in the [`language-switcher` API reference](/native-sdk/reference/language-switcher). # Measurement lists Canonical page: https://docs.ovok.com/native-sdk/guide/modules/measurement Use `MeasurementList` to render a collection of measurements with the SDK's row and date-range primitives. The list is a UI layer, not a query client: your app decides which observations to load, how to sort them, and what a selected range means. ```tsx import { MeasurementList } from "@ovok/native/measurement"; item.id} onItemPress={(item) => openMeasurement(item)} ListHeaderComponent={ setRange({ startDate, endDate })} /> } /> ``` Fetch or derive the displayed observations when the range changes, and provide a screen-level loading, empty, and error state. Keep clinical interpretation and unit conversion in the data layer so the same rules apply to charts, cards, and measurement detail screens. ## References [#references] - [MeasurementList](/native-sdk/guide/components/measurement/measurement-list/) - [MeasurementList.Item](/native-sdk/guide/components/measurement/measurement-list-item/) - [MeasurementList.DateRange](/native-sdk/guide/components/measurement/date-range/) - [Measurement component index](/native-sdk/guide/components/measurement/) ## API reference [#api-reference] Every export of `@ovok/native/measurement`, with signatures, props and types, is in the [`measurement` API reference](/native-sdk/reference/measurement). # Background sync on the next client (preview) Canonical page: https://docs.ovok.com/native-sdk/guide/modules/next-background-sync `@ovok/native/next/background-sync` exposes Android background task helpers and cross-platform offline measurement scheduling for apps using `@ovok/core/next`. It reuses the existing background-sync module and keeps its legacy import path available. Register a headless task with the host application's task manager, restore the authenticated next client and patient, then run the Health Connect import: ```ts import { registerAndroidHealthConnectBackgroundTask, runAndroidHealthConnectSync, } from "@ovok/native/next/background-sync"; registerAndroidHealthConnectBackgroundTask(async () => { const { client, patientId } = await restoreHealthSyncSession(); await runAndroidHealthConnectSync({ client, patientId, dataToSync }); }); ``` Register the handler from the app entry point and restore the client and patient inside it. The SDK checks that the restored session still belongs to `patientId` before importing. See the [full background-sync guide](/native-sdk/guide/modules/background-sync) for platform setup and the [background-sync API reference](/native-sdk/reference/next-background-sync). ## Core offline measurement queue [#core-offline-measurement-queue] Install the Expo task packages in the host app: ```sh npx expo install expo-background-task expo-task-manager ``` Define the task from the app entry point so it is available when the OS starts a fresh JavaScript runtime. Restore the client from the host app's secure session storage inside the callback; the SDK never serializes credentials into task input. ```ts import { registerOfflineMeasurementBackgroundTask, scheduleOfflineMeasurementBackgroundSync, cancelOfflineMeasurementBackgroundSync, } from "@ovok/native/next/background-sync"; registerOfflineMeasurementBackgroundTask(() => restoreOvokClient()); async function onBackgroundSyncEnabled() { await scheduleOfflineMeasurementBackgroundSync({ minimumIntervalMinutes: 15, }); } async function onBackgroundSyncDisabled() { await cancelOfflineMeasurementBackgroundSync(); } ``` The restored client must use the same durable storage, tenant, and API base; Core scopes the queue to that owner and retains conditional creates and retry state, so a restarted task can safely retry a queued measurement. Call `cancelOfflineMeasurementBackgroundSync` to stop future runs. WorkManager will not run more often than the 15-minute minimum. iOS uses BGTaskScheduler and chooses its own execution time, which may be later than the requested interval. Expo shares one background worker across registered tasks, and the last registered task sets the worker's minimum interval. With Expo Continuous Native Generation, prebuild adds iOS background processing configuration; manually managed iOS apps must add Expo BackgroundTask's required `UIBackgroundModes` and permitted task identifier to `Info.plist`. # Bluetooth in browsers (preview) Canonical page: https://docs.ovok.com/native-sdk/guide/modules/next-bluetooth-web `@ovok/native/next/bluetooth/web` runs [Bluetooth on the next client](/native-sdk/guide/modules/next-bluetooth) in a browser. It has the same `BluetoothRuntime`, devices, result policies and hooks, with a Web Bluetooth scanner in place of `react-native-ble-plx`. Every integrated device and every `defineCustomDevice` declaration runs through it, because the scanner hands the device classes a Web Bluetooth device with the `react-native-ble-plx` API they already use. Nothing in it loads `react-native-ble-plx` or `react-native-permissions`, so a web bundle (React Native Web, Expo web) can import it. Import the web entry only in web code, for example from a `.web.ts` file. ## Browsers [#browsers] | Browser | Web Bluetooth | |---|---| | Chrome and Edge on desktop (Windows, macOS, Linux, ChromeOS) and Android | Yes | | Bluefy on iOS and iPadOS | Yes | | Safari, and every other browser on iOS and iPadOS | No: they all use WebKit, which has no Web Bluetooth | | Firefox | No | The page must be served over HTTPS (or from `localhost`). Use `isWebBluetoothAvailable()` to choose between the Bluetooth screen and a message that says which browser or app to use instead. ## Pick, connect, save [#pick-connect-save] A page can only reach the devices the user picks in the browser's chooser, and the chooser only opens from a user gesture: ```tsx import * as React from 'react'; import { Button } from 'react-native'; import { BluetoothProvider, builtInDevices, createWebBluetoothRuntime, IntegratedDevices, useBluetooth, webBluetoothScanner, } from '@ovok/native/next/bluetooth/web'; import { ovok } from './ovok'; // the next Ovok client, signed in const accepted = [IntegratedDevices.BP2, IntegratedDevices.F4]; const scanner = webBluetoothScanner({ acceptedDevices: accepted }); const bluetooth = createWebBluetoothRuntime({ client: ovok, scanner, devices: [builtInDevices(accepted)] }); export const App = () => ; const AddDevice = () => { const runtime = useBluetooth(); const add = async () => { await runtime.startScan(); const device = await scanner.chooseDevice(); // undefined when the user closes the chooser if (device) await runtime.pair(device.id); }; return ; return

{data?.profile.reference ?? 'No active session'}

; } export function AppProviders({ children }: PropsWithChildren) { const [client] = useState(() => new Ovok({ baseUrl: 'https://api.sandbox.ovok.com', tenantCode: 'your-tenant', })); return {children}; } ``` `useSession()` returns `data`, `loading`, `isRefreshing`, `isStale`, `error`, and `refetch`. `useSearch()` and `useResource()` read FHIR resources. `useOvokQuery()` and `useOvokMutation()` provide request and mutation state for other workflows. Keep user-specific server clients request-scoped. Never send a machine `clientSecret` to browser code. The API remains responsible for authentication, project membership, and authorization. See [React integration](/web-sdk/core/react) and the [complete API reference](/web-sdk/core/reference/) for the available React surface. # Sign users in Canonical page: https://docs.ovok.com/web-sdk/core/guides/sign-in This guide uses the `ovok` client from [Get started](/web-sdk/core/getting-started). Pass a persistent `storage` when users should stay signed in across app restarts. ## Sign in and out [#sign-in-and-out] ```ts const result = await ovok.auth.login({ profileType: 'Practitioner', email: 'ada@example.com', password, }); if (result.status === 'mfa-required') { await ovok.auth.verifyMfa(result.challenge, codeFromAuthenticatorApp); } await ovok.auth.logout(); ``` - **Login flow:** `login` runs the tenant login with PKCE and signs in to the configured `tenantCode`. `profileType` is `Patient`, `Practitioner` or `RelatedPerson`. - **Session storage:** the session is saved in `storage` under `ovok::session`. The client never clears other keys. - **Refresh:** access tokens refresh a minute before they expire. - A refused refresh token signs the user out and calls `onUnauthenticated`. - An outage keeps the session, so a later call can retry. - **Logout:** `logout` always clears the local session, even when the server cannot be reached. ## Saved accounts and session changes [#saved-accounts-and-session-changes] The client keeps a private saved session for each signed-in profile in the configured storage. `ovok.session.savedAccounts.list()` returns profile and project metadata without tokens. Switch or remove an account by its profile reference. Removing the active account switches to the next available saved account, when one exists: ```ts const accounts = await ovok.session.savedAccounts.list(); await ovok.session.savedAccounts.switch('Patient/123'); await ovok.session.savedAccounts.remove('Patient/123'); ``` Listen for sign-in, sign-out, account switches and rejected refresh tokens with `ovok.session.onChange(listener)`. The listener receives the active `Session` or `null`; call the returned function to unsubscribe. `ovok.session.current()` reads the restored session snapshot. `ovok.invites.accept(body)` sends a record-share invite to the practitioner route or a care invite to the patient route based on the active profile. ## Sign in a server as a machine client [#sign-in-a-server-as-a-machine-client] On a server, pass `clientId` and `clientSecret` from a client application. The client fetches its own token from `/oauth2/token` and renews it before it expires. A machine client cannot call `ovok.auth.login`. ```ts const ovok = new Ovok({ baseUrl: process.env.OVOK_BASE_URL, tenantCode: process.env.OVOK_TENANT_CODE, clientId: process.env.OVOK_CLIENT_ID, clientSecret: process.env.OVOK_CLIENT_SECRET, }); ``` ## Related [#related] - [ovok.auth](/web-sdk/core/namespaces/auth) and [ovok.session](/web-sdk/core/namespaces/session) guides. - [Errors and retries](/web-sdk/core/errors-and-retries) for refused sign-ins and expired sessions. # useClient Canonical page: https://docs.ovok.com/web-sdk/core/hooks/use-client The legacy `useClient` hook is no longer exported from `@ovok/core`. Use `useOvok` from `@ovok/core/next/react` to read the client below `OvokProvider`. See [React integration](/web-sdk/core/react). # useObservations Canonical page: https://docs.ovok.com/web-sdk/core/hooks/use-observations The legacy `useObservations` hook is no longer exported from `@ovok/core`. Read measurements with `ovok.measurements`, or FHIR Observations with `useSearch` from `@ovok/core/next/react`. See [ovok.measurements](/web-sdk/core/namespaces/measurements). # usePatientQuestionnaireResponses Canonical page: https://docs.ovok.com/web-sdk/core/hooks/use-patient-questionnaire-responses The legacy `usePatientQuestionnaireResponses` hook is no longer exported from `@ovok/core`. Read the signed-in patient's responses through `ovok.patient`. See [ovok.patient](/web-sdk/core/namespaces/patient). # useSaveMeasurement Canonical page: https://docs.ovok.com/web-sdk/core/hooks/use-save-measurement The legacy `useSaveMeasurement` hook is no longer exported from `@ovok/core`. Save readings with `ovok.measurements.save`, or wrap it in `useOvokMutation` from `@ovok/core/next/react`. See [ovok.measurements](/web-sdk/core/namespaces/measurements). # Measurements and health data Canonical page: https://docs.ovok.com/web-sdk/core/measurements-and-health-data Measurements are saved and read through `ovok.measurements`. See [ovok.measurements](/web-sdk/core/namespaces/measurements). # Blood glucose Canonical page: https://docs.ovok.com/web-sdk/core/measurements/blood-glucose Blood glucose readings use the `bloodGlucose` measurement category of `ovok.measurements`. See [ovok.measurements](/web-sdk/core/namespaces/measurements). # Blood pressure Canonical page: https://docs.ovok.com/web-sdk/core/measurements/blood-pressure Blood pressure readings use the `bloodPressure` measurement category of `ovok.measurements`. See [ovok.measurements](/web-sdk/core/namespaces/measurements). # Body weight Canonical page: https://docs.ovok.com/web-sdk/core/measurements/body-weight Body weight readings use the `bodyWeight` measurement category of `ovok.measurements`. See [ovok.measurements](/web-sdk/core/namespaces/measurements). # ECG Canonical page: https://docs.ovok.com/web-sdk/core/measurements/ecg ECG recordings use the `ecg` measurement category of `ovok.measurements`. See [ovok.measurements](/web-sdk/core/namespaces/measurements). # ovok.accounts Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/accounts One read call for an account switcher. It needs a signed-in user. ## List the user's accounts [#list-the-users-accounts] ```ts const accounts = await ovok.accounts.list(); for (const { name, email } of accounts) { console.log(name, email); } ``` - Each entry carries an `email` and a `name`. Nothing more. - Calls `GET accounts` and returns a plain array, not a `PagePromise`. - This lists accounts on the server. Accounts saved on the device for quick sign-in are a different feature; see [ovok.session](/web-sdk/core/namespaces/session). ## Reference [#reference] - [accounts API reference](/web-sdk/core/reference/core/accounts): every method and type. - [ovok.session](/web-sdk/core/namespaces/session): saved accounts and switching. - [ovok.auth](/web-sdk/core/namespaces/auth): sign-in. - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.ai Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/ai AI features of the Ovok API, called by a signed-in app. Routes live under `ai`. ## Translate text [#translate-text] ```ts const result = await ovok.ai.translate({ sourceLanguage: 'en', targetLanguage: 'de', text: ['Take one tablet daily.'], }); ``` - `text` is an array, and the response has the same shape with the translated strings. ## Run a chat session [#run-a-chat-session] Create a session with an assistant prompt, then send messages to it. `send` returns the reply. ```ts await ovok.ai.chat.sessions.create({ assistant: { system: 'You answer questions about sleep.' }, participant: 'Patient/123', messages: [], }); // sessionId identifies a session you created or listed. const reply = await ovok.ai.chat.messages.send(sessionId, { sender: 'Patient/123', content: 'Why do I wake up at night?', }); const history = await ovok.ai.chat.messages.list(sessionId, { _sort: 'sent', _count: 20 }); ``` - `ovok.ai.chat.sessions` has `create`, `list` and `retrieve`. `retrieve` accepts `messageCount` to include the latest messages. - `ovok.ai.chat.messages` has `list` and `send`. - `list` calls return the server's response envelope, not a `PagePromise`. ## Search FHIR data in natural language [#search-fhir-data-in-natural-language] ```ts const answer = await ovok.ai.fhirSearch({ text: 'Latest blood pressure of Jane Doe' }); console.log(answer.markdown); ``` - An LLM plans and runs the FHIR queries, so the answer can be wrong or invented. The response includes the `plan` that was run so you can check it. - `fhirVersion: 'R4' | 'R5'` pins the version; omitted, the server default applies. - For queries you control, use [ovok.fhir](/web-sdk/core/namespaces/fhir). ## Reference [#reference] - [ai API reference](/web-sdk/core/reference/core/ai): every method and type. - [ovok.fhir](/web-sdk/core/namespaces/fhir) - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.auth Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/auth Sign-in, registration, password and server-side session calls for a patient or practitioner app. These need a client created without `clientSecret`; a machine client throws `OvokConfigError`. Sign-in stores the session through the client's `storage`. ## Sign a user in [#sign-a-user-in] ```ts const result = await ovok.auth.login({ profileType: 'Practitioner', email, password }); if (result.status === 'mfa-required') { await ovok.auth.verifyMfa(result.challenge, codeFromAuthenticatorApp); } ``` - `profileType` is `Patient`, `Practitioner` or `RelatedPerson`. - `login` returns `{ status: 'signed-in', session }` or `{ status: 'mfa-required', challenge }`. Pass the challenge back to `verifyMfa`. - Tokens come from a PKCE exchange handled for you. The tenant comes from the client's `tenantCode`. - `ovok.auth.current()` returns the current session, or `null` when signed out. `ovok.auth.me()` fetches the profile. ## Register [#register] ```ts const result = await ovok.auth.register({ email, password, passwordConfirm: password, name: 'Ada', surname: 'Lovelace', }); if (result.status === 'clinician-invite') { // no session was issued; the person must accept a clinician invitation } await ovok.auth.registerPractitioner({ email, password, passwordConfirm: password, name, surname }); ``` - `register` creates a patient. `registerPractitioner` creates a practitioner and returns the `Session`. - A password and confirmation that differ throw `OvokValidationError` before any request. ## Social sign-in [#social-sign-in] ```ts const session = await ovok.auth.socialLogin('google', googleCredential); ``` - Providers are `apple` and `google`. The credential comes from the provider's own SDK. - Needs `clientId` in the client config; without it the call throws `OvokConfigError`. ## Continue a sign-in made elsewhere [#continue-a-sign-in-made-elsewhere] ```ts const session = await ovok.auth.adoptSession({ accessToken: earlier.accessToken, refreshToken: earlier.refreshToken || null, profile: { reference: earlier.profile.reference, display: earlier.profile.display }, }); ``` - Use it to carry a session saved by another client, such as the legacy `OvokClient`, into this one. Do not write the session into storage yourself: the storage key and shape belong to the SDK. - It begins the session as a login does: the session is stored, announced to `ovok.session.onChange` listeners, used on the next request and refreshed with `refreshToken`. - `accessToken` and a `profile.reference` such as `Patient/123` are required. `refreshToken`, `expiresIn` (seconds), `project` and the `display` names are optional. - Omit `expiresIn` when the token's age is unknown: the first request then refreshes the session. Without a `refreshToken` the token is used until the server refuses it. - It replaces any current session. A missing or malformed field throws `OvokValidationError` naming the field, and nothing is stored. ## Passwords and account deletion [#passwords-and-account-deletion] ```ts await ovok.auth.changePassword({ oldPassword, newPassword }); await ovok.auth.resetPassword({ email }); await ovok.auth.completePasswordReset(body); // body from the reset email's link await ovok.auth.deleteAccount(request); ``` - `changePassword` sends only the old and new password. Check any confirmation field in your app. - `resetPassword` and `completePasswordReset` need no signed-in user. - `deleteAccount` schedules the deletion; the user stays signed in until then. ## Sessions and sign-out [#sessions-and-sign-out] ```ts const sessions = await ovok.auth.sessions.list(); await ovok.auth.sessions.revoke('current'); await ovok.auth.logout(); ``` - `logout` always clears the local session, even when the server cannot be reached. - Revoking `'current'` also ends the session on this device. ## Reference [#reference] - [auth API reference](/web-sdk/core/reference/core/auth): every method and type. - [ovok.session](/web-sdk/core/namespaces/session): saved accounts and account switching. - [Sign users in](/web-sdk/core/guides/sign-in) - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.bots Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/bots Runs a bot configured on the project and returns its output. The caller needs permission to run that bot. ## Run a bot [#run-a-bot] ```ts const output = await ovok.bots.execute('https://example.com/bots|daily-summary', { patientId: '123', }); ``` - The first argument is the bot's `system|value` identifier. - The input and output are plain JSON objects (`Record`). Their shape is whatever the bot defines. - Calls `POST bots?identifier=...`. A failing bot surfaces as an `OvokError` subclass; see [errors and retries](/web-sdk/core/errors-and-retries). - Bots can have side effects, so the call is not retried after a network failure. ## Reference [#reference] - [bots API reference](/web-sdk/core/reference/core/bots): every method and type. - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.cms Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/cms Reads published content from the Ovok CMS. Reads are always made as the client's `tenantCode`. Legal pages and translations can be read before sign-in; other collections need a signed-in user. ## Read a legal page [#read-a-legal-page] ```ts const terms = await ovok.cms.legalPage('terms-and-conditions', { locale: 'de-DE' }); ``` - `locale` takes an app language (`de-DE`) or a CMS locale (`de`). Omitted, the CMS answers in its default locale. - The `body` field is rich-text JSON, not HTML; render it with a rich-text renderer. ## List and read documents [#list-and-read-documents] ```ts const page = await ovok.cms.documents.list('faqs', { limit: 20, sort: '-publishedAt' }); for await (const doc of ovok.cms.documents.list('faqs')) { console.log(doc.title); } const doc = await ovok.cms.documents.retrieve('faqs', 'how-to-pair-a-device'); ``` - `list` returns a `PagePromise`: await it for the first page, or `for await` to walk every page. - `limit` is at most 50. `sort` names a top-level field; prefix it with `-` for descending. - `retrieve` takes a slug and throws `OvokValidationError` for an empty one. A draft and a missing document both come back as not found. - Both calls use `v1/public/cms/collections/{collection}/items` and merge in the shared tenant's published documents. ## Release notes [#release-notes] ```ts const notes = await ovok.cms.releaseNotes.list({ limit: 5 }); ``` - Same paging and params as `documents.list`; newest first unless `sort` says otherwise. ## Load translations [#load-translations] ```ts const translations = await ovok.cms.translations('de'); ``` - Returns the `translations` collection as one nested tree: one group per document slug, with keys split at the dots. - Reads every page of the collection, 50 documents at a time. If the CMS still offers a next page after 500 pages, it throws `OvokError` with code `cms_translations_page_limit` instead of returning a partial tree. - Nothing is cached on the device. Cache the result in your app if you need it offline. ## Reference [#reference] - [cms API reference](/web-sdk/core/reference/core/cms): every method and type. - [ovok.content](/web-sdk/core/namespaces/content): the older content routes. - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.consent Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/consent Consent of the signed-in user. Legal consent covers the terms and conditions; medical consent covers medical notifications. ## Read and record legal consent [#read-and-record-legal-consent] ```ts const { legal } = await ovok.consent.legal.retrieve(); const mustAccept = legal === null || (legal.status === 'revoked' && legal.revokedReason === 'tos-updated'); if (mustAccept) { await ovok.consent.legal.set(true); } ``` - `legal` is `null` when the user never answered. A revoked record with reason `tos-updated` means the terms changed and the user must accept again. - `set(false)` withdraws consent. - Calls `GET` and `POST v1/me/consent/legal`. ## Read and record medical consent [#read-and-record-medical-consent] ```ts const { medical } = await ovok.consent.medical.retrieve(); await ovok.consent.medical.set(true); ``` - `medical` is `null` until the user answers; otherwise it carries `acceptedAt`. - Calls `GET` and `POST v1/me/consent/medical`. ## Request a signature [#request-a-signature] ```ts const request = await ovok.consent.requestSignature(consentId); ``` - Asks the server to start a signature for an existing consent. The response describes the document to sign (`documentId`, `title`, `numberOfPages`, `email`). ## Reference [#reference] - [consent API reference](/web-sdk/core/reference/core/consent): every method and type. - [ovok.cms](/web-sdk/core/namespaces/cms): legal pages to show before asking. - [ovok.invites](/web-sdk/core/namespaces/invites) - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.content Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/content The older managed-content routes under `cms`: items grouped by type and language, with a `key` for each item. Use it to read and edit content. For published delivery to apps, prefer [ovok.cms](/web-sdk/core/namespaces/cms). ## Search and read items [#search-and-read-items] ```ts const found = await ovok.content.search('blog', 'en'); const item = await ovok.content.retrieve('blog', 'en', 'welcome'); ``` - `type` is a content type such as `blog`, `video`, `audio`, `template` or `export-template`. - `search` takes an optional query as its third argument. It returns the server's search envelope, not a `PagePromise`. - Calls `GET cms/{type}/{language}` and `GET cms/{type}/{language}/{key}`. ## Create, replace and delete [#create-replace-and-delete] ```ts await ovok.content.create('blog', 'en', body); await ovok.content.update('blog', 'en', 'welcome', body); await ovok.content.delete('blog', 'en', 'welcome'); ``` - `update` is a full replace (`PUT`). `body` has the same shape for create and update. ## Pair translations [#pair-translations] ```ts const pairs = await ovok.content.map('blog', 'de'); ``` - Pairs each default-language item with its translation in the given language. ## Copy from the parent project [#copy-from-the-parent-project] ```ts await ovok.content.copyFromParent('blog', 'en', 'welcome'); await ovok.content.copyAllFromParent('blog', 'en'); ``` - Both resolve to `{ success }`. They only make sense for a child project. ## Reference [#reference] - [content API reference](/web-sdk/core/reference/core/content): every method and type. - [ovok.cms](/web-sdk/core/namespaces/cms) - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.documents Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/documents Uploaded documents. Uploading is two steps: register the document with the API, then send the file to the pre-signed target it returns. ## Upload a file [#upload-a-file] ```ts const doc = await ovok.documents.createUpload({ fileName: 'report.pdf', contentType: 'application/pdf', isPublic: false, }); if (doc.uploadOptions) { const form = new FormData(); for (const [name, value] of Object.entries(doc.uploadOptions.fields)) form.append(name, value); form.append('file', file); await fetch(doc.uploadOptions.url, { method: 'POST', body: form }); } ``` - `createUpload` only registers the document. The file goes straight to the storage URL; the SDK does not send it. - Put the `file` field last in the form, as pre-signed POST targets expect. - `replaceUpload(documentId, body)` registers a new file for an existing document. It takes the same `fileName`, `contentType` and `isPublic`. ## List and change documents [#list-and-change-documents] ```ts const documents = await ovok.documents.list(); await ovok.documents.updateMetadata(documentId, metadata); await ovok.documents.delete(documentId); ``` - `list` takes an optional search query and returns the server's envelope. - Calls routes under `document`. ## Build download URLs [#build-download-urls] ```ts const url = ovok.documents.downloadUrl(documentId, { width: 400 }); const publicUrl = ovok.documents.publicDownloadUrl(publicToken); ``` - Both methods build a URL and make no request. - `downloadUrl` needs the bearer token: fetch it with the session's token, and it redirects to a signed URL. It cannot be used as an ``. - `publicDownloadUrl` needs no bearer, so it fits an image or media element. The token comes from a document registered with `isPublic: true`. - `width`, `height` and `fit` resize image downloads. ## Reference [#reference] - [documents API reference](/web-sdk/core/reference/core/documents): every method and type. - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.email Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/email Email settings of the project. Today it exposes the template list, which shows what each template needs. ## List email templates [#list-email-templates] ```ts const { templates } = await ovok.email.templates.list(); for (const template of templates) { console.log(template.name, template.audience, template.params); } ``` - Each template has a `name`, an `audience` (the kind of recipient), the `params` it accepts, an `example` of parameter values, and the placeholder `syntax` per email provider. - Calls `GET v1/email/templates`. It needs a signed-in user. - It lists templates only. It does not send email or change a template. ## Reference [#reference] - [email API reference](/web-sdk/core/reference/core/email): every method and type. - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.fhir Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/fhir Typed FHIR R4 access for any app. The FHIR base path comes from the client's `fhirPath` option (default `fhir`). What a user can see or change is decided by their access policy on the server. ## Read and search [#read-and-search] ```ts const patient = await ovok.fhir.read('Patient', id); const page = await ovok.fhir.search('Observation', { patient: `Patient/${id}`, _count: 50 }); for await (const observation of ovok.fhir.search('Observation', { patient: `Patient/${id}` })) { // every page, fetched as you go } const first = await ovok.fhir.searchOne('Patient', { identifier: 'urn:mrn|123' }); ``` - `search` returns a `PagePromise`: await it for `{ data, hasMore, total }`, or `for await` for every item. - Included resources are left out of `data`. - A list value repeats its parameter, which FHIR reads as AND: `date: ['ge2026-01-01', 'le2026-02-01']`. For OR, write one comma-separated string. - `searchOne` returns the first match or `null`. ## Create, update, patch, delete [#create-update-patch-delete] ```ts await ovok.fhir.create(observation, { ifNoneExist: 'identifier=urn:device|42' }); await ovok.fhir.update(patient); await ovok.fhir.patch('Patient', id, [{ op: 'replace', path: '/active', value: false }]); await ovok.fhir.delete('Patient', id); ``` - `update` replaces the resource and throws `OvokValidationError` when it has no `id`. - `create` with `ifNoneExist` is a conditional create. A retry cannot duplicate it, so it is retried after a network failure. A plain `create` is not. - `patch` takes JSON Patch operations. ## Batch and transaction bundles [#batch-and-transaction-bundles] ```ts const result = await ovok.fhir.batch(bundle); ``` - Posts the bundle to the FHIR base and returns the response bundle. Set `bundle.type` to `batch` or `transaction`. - Check each entry's `response.status` in the result; a batch can succeed in part. ## React [#react] `useResource`, `useSearch` and `useSubscription` from `@ovok/core/next/react` wrap these calls. See [React](/web-sdk/core/react). ## Reference [#reference] - [fhir API reference](/web-sdk/core/reference/core/fhir): every method and type. - [ovok.realtime](/web-sdk/core/namespaces/realtime): subscribe to FHIR changes. - [ovok.measurements](/web-sdk/core/namespaces/measurements): saving readings safely. - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.health Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/health A health probe. It needs no sign-in and grants no access to project data. ## Check the API [#check-the-api] ```ts const health = await ovok.health.check(); if (!health.ok) { throw new Error('Ovok API is not healthy'); } ``` - The route always answers 200. Read `ok`, not the HTTP status. - `dependencies` holds an `ok` flag per dependency, by name. - `version`, `buildEnv` and `commitHash` are filled when the server reports them, and can be `null`. - Calls `GET healthcheck`. ## Reference [#reference] - [health API reference](/web-sdk/core/reference/core/health): every method and type. - [Get started](/web-sdk/core/getting-started) - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.invites Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/invites Invitations to share a record or to enter a care relationship. Each flow has `create` (send) and `accept` (redeem). Calls routes under `v1/invites`. ## Share a record [#share-a-record] A patient shares their record with a practitioner, or some codes with a carer. ```ts await ovok.invites.recordShares.create({ recipient: 'practitioner', email: 'dr@example.com', firstName: 'Ada', lastName: 'Lovelace', }); await ovok.invites.recordShares.create({ recipient: 'related-person', email: 'carer@example.com', firstName: 'Sam', lastName: 'Lee', codes, }); ``` - A `related-person` invite also takes `codes`, the data the carer may see. - `create` resolves to `{ status: 'sent' }`. ## Invite a patient into care [#invite-a-patient-into-care] ```ts await ovok.invites.care.create({ email, firstName, lastName }); ``` - A practitioner sends this. The patient redeems it with `care.accept`. ## Accept an invite [#accept-an-invite] ```ts const share = await ovok.invites.accept({ inviteId, code }); ``` - `accept` picks the flow from the signed-in profile: a practitioner accepts a record share, a patient accepts a care invite. It throws `OvokConfigError` for any other profile or when signed out. - Call a flow's `accept` directly when you know the kind. `recordShares.accept` also takes an optional `password`. - `ovok.invites.practitioners` and `ovok.invites.patients` are deprecated. Use `recordShares` with `recipient: 'practitioner'`, and `care`. The routes sunset on 2026-12-01. ## Reference [#reference] - [invites API reference](/web-sdk/core/reference/core/invites): every method and type. - [ovok.sharing](/web-sdk/core/namespaces/sharing): the shares an accepted invite creates. - [ovok.auth](/web-sdk/core/namespaces/auth) - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.locales and ovok.localizations Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/localization `ovok.locales` holds the project's list of supported languages and its default language. `ovok.localizations` holds the translation entries for each language. Both are admin tools: call them from a console or a server client with the right project role, not from a patient app. ## Set the supported languages [#set-the-supported-languages] ```ts const locales = await ovok.locales.retrieve(); await ovok.locales.update({ languages: ['en', 'de', 'fr'], defaultLanguage: 'en', }); ``` - `update` sends a `PATCH` and resolves to the saved locales. ## Read and edit translation entries [#read-and-edit-translation-entries] Entries are keyed by language and translation key. ```ts const { total, resources } = await ovok.localizations.list('de', { search: 'welcome', _count: 20 }); const entry = await ovok.localizations.retrieve('de', 'home.welcome'); await ovok.localizations.update('de', 'home.welcome', { value: 'Willkommen' }); await ovok.localizations.delete('de', 'home.welcome'); ``` - `list` resolves to one page, `{ total, resources }`. Page with `_count` and `_offset`. - `update` sets the entry with a `PUT`, so it creates a missing key. ## Work with i18next documents [#work-with-i18next-documents] `ovok.localizations.i18next` reads and writes a whole language as one i18next document, so a client can load all strings in one request. ```ts const document = await ovok.localizations.i18next.retrieve('de'); await ovok.localizations.i18next.update('de', { home: { welcome: 'Willkommen' } }); ``` - `update` patches the document. The server queues the write (202), so a read right after may not show it yet. - Values are text or nested objects. ## Reference [#reference] - [localization API reference](/web-sdk/core/reference/core/localization): every method and type. - [Errors and retries](/web-sdk/core/errors-and-retries) - [ovok.projects](/web-sdk/core/namespaces/projects) for project settings and features. # ovok.measurements Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/measurements `ovok.measurements` turns a typed measurement into FHIR Observations, saves them safely and reads the latest values back. Patient apps call it for the signed-in user; a server machine client can call it with an explicit `patientId`. ## Save a measurement [#save-a-measurement] `save` builds the Observations and sends them as one conditional-create transaction, so a retry cannot duplicate a reading. ```ts import { MeasurementTypeKey } from '@ovok/core'; const result = await ovok.measurements.save({ measurement: { measurementTypeKey: MeasurementTypeKey.heartRate, heartRate: 70 }, }); if (result.status === 'queued') { console.log('Saved for later', result.queueId); } ``` - Without `patientId`, the reading belongs to the signed-in profile. - `result.status` is `'saved'` (with the server `response` bundle) or `'queued'`. - `build` returns the Observations without saving. `saveObservations` saves Observations you built yourself, main observation first. - If the server refuses or leaves out an observation, the save throws an `OvokError` with the refused status; see [errors and retries](/web-sdk/core/errors-and-retries). - Observations are `final`, carry a FHIR category (`vital-signs`, or `laboratory` for glucose and urine), code quantities in UCUM, and are dated by the measurement's `recordedAt` unless you pass `effectiveDateTime`. - A reading of several observations (a blood pressure, a pulse oximeter reading, an ECG, a urine strip) ends with a group observation whose `hasMember` points at the others: a blood pressure's is the FHIR panel 85354-9 with the pressures as components, a urine strip's is 24357-6, and the rest use the code system `https://sdk.ovok.com/fhir/CodeSystem/measurement-type`. The other observations keep their codes and links, and `observationsToMeasurements` reads either shape. Readings saved before groups existed get theirs from `scripts/backfill-reading-groups.mjs` (a dry run unless `--apply`). - A measurement's `memorySlot` (the monitor's user) is kept on its first observation. An ECG needs its `duration`; without it the save throws. ## Retry queued readings [#retry-queued-readings] A connection failure queues the reading in `storage` and returns `{ status: 'queued' }`. Flush the queue when the device is back online. ```ts const outcome = await ovok.measurements.offlineQueue.flush(); console.log(outcome.saved, outcome.queued, outcome.exhausted); ``` - The queue only sends readings for the account that queued them. - The default storage is in memory. Pass persistent `storage` to the client to keep readings across restarts. - `flush({ includeExhausted: true })` also retries readings that ran out of retries; `resetExhausted: true` gives them a fresh set first. ## Save many readings at once [#save-many-readings-at-once] `saveObservationGroups` saves a monitor's stored readings in as few requests as fit. Each group is one reading with its main observation first. ```ts await ovok.measurements.saveObservationGroups(groups, { identifierSystems: [APP_READING_SYSTEM] }); ``` - It is not queued offline. - A request with one reading is a transaction, atomic when the project enables FHIR transactions. A request with several is sent as two batches, every main observation first, so a reading's other observations never point at one that wasn't saved. If it fails, some readings may already be saved; saving them again is safe. - A main observation that matches several saved copies counts as saved. - It stops, without sending the rest, if another account signs in between requests. - `identifierSystems` names the identifiers that make a reading unique; `replace: true` overwrites a reading saved under the same identifiers. ## Read the latest readings [#read-the-latest-readings] ```ts const codes = ovok.measurements.codesFor([MeasurementTypeKey.heartRate]); const newest = await ovok.measurements.latest({ me: true, codes: codes.split(',') }); const bundle = await ovok.measurements.lastn(patientId, { code: codes, max: 50, _elements: 'code,effectiveDateTime' }); ``` - `latest` returns the newest observation per code for yourself (`me: true`) or a patient (`me: false` with `patientId`). - `lastn` returns the newest `max` observations per code in one `$lastn` request and passes other search parameters on. - `lastForPatient` reads `patient/{patientId}/observation`. ## Measurement categories [#measurement-categories] `MeasurementTypeKey` has these keys: `babySleep`, `bloodGlucose`, `bloodOxygenPulseRate`, `bloodPressure`, `bodyWeight`, `cosinussMultiParam`, `ecg`, `heartRate`, `heartRateVariability`, `lipidPanel`, `photoUpload`, `respiratoryRate`, `respiratoryTherapy`, `restingHeartRate`, `spirometryPanel`, `stepCount`, `symptomQuestionnaire`, `temperature`, `urineAnalysis`, `vo2Max`, `walkingHeartRateAverage` and the deprecated `uricAcid`. The [measurement type list](/web-sdk/core/reference/core/measurements#measurementtypekey) gives each key's value, and the pages under measurements describe each type's fields. ## Reference [#reference] - [measurements API reference](/web-sdk/core/reference/core/measurements): every method and type. - [ovok.patient](/web-sdk/core/namespaces/patient) for reading a patient's saved records. # ovok.patient Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/patient `ovok.patient` is the patient app's view of the signed-in patient's FHIR records. It needs a signed-in patient session. ## Read records [#read-records] Each sub-resource wraps one FHIR resource type: `appointments`, `schedules`, `slots`, `measurements` (Observations), `carePlans`, `questionnaires`, `questionnaireResponses`, `devices` and `notifications` (CommunicationRequests). ```ts const carePlans = await ovok.patient.carePlans.list(); const plan = await ovok.patient.carePlans.retrieve(carePlans[0].id!); ``` - `list` takes FHIR search parameters and resolves to the first page's resources, as an array. - `retrieve` reads one resource by id. `schedules` and `slots` can only be listed. ## Manage appointments [#manage-appointments] `appointments` also creates and replaces appointments. ```ts const appointment = await ovok.patient.appointments.create(newAppointment); await ovok.patient.appointments.update(appointment.id!, { ...appointment, comment: 'Moved' }); ``` - `update` replaces the appointment with the given id. ## Load the dashboard [#load-the-dashboard] `dashboard` reads the profile, the latest observations, the measurement history and the care plans in one call. ```ts const { profile, latestObservations, measurementHistory, carePlans } = await ovok.patient.dashboard({ latestObservations: { max: 5 }, }); ``` - Each read is scoped to the signed-in patient unless its query names another. - `latestObservations` alone reads `fhir/Observation/$lastn`. ## Reference [#reference] - [patient API reference](/web-sdk/core/reference/core/patient): every method and type. - [ovok.measurements](/web-sdk/core/namespaces/measurements) to save readings. - [ovok.questionnaires](/web-sdk/core/namespaces/questionnaires) to submit answers. # ovok.projects Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/projects `ovok.projects` is for project admins, from a console or a server client. `members`, `features` and `settings` act on the current project, the one the session belongs to. ## List your projects [#list-your-projects] ```ts for await (const project of ovok.projects.list()) { console.log(project.projectId, project.name); } ``` - `list` returns a `PagePromise`: await it for the first page, or `for await` for every project. - It lists the projects the caller administers, wherever they are signed in. ## Manage members [#manage-members] ```ts const invited = await ovok.projects.members.invite({ email: 'ada@example.com', firstName: 'Ada', lastName: 'Lovelace', admin: false, }); await ovok.projects.members.update(invited.id, { admin: true }); await ovok.projects.members.remove(invited.id); ``` - `list` pages through members and filters by `accessPolicyId`, `profileId` or `userId`. - `update` and `remove` take the membership id. ## Turn features on and off [#turn-features-on-and-off] ```ts const { features } = await ovok.projects.features.retrieve(); await ovok.projects.features.update(['ai', 'bots', 'email']); ``` - `update` sends the full list of features to enable. ## Change settings [#change-settings] Boolean settings and text settings use separate calls. ```ts await ovok.projects.settings.update('PATIENT_REGISTRATION_ENABLED', true); await ovok.projects.settings.updateText('PATIENT_APP_URL', 'https://app.example.com'); await ovok.projects.settings.updateText('PATIENT_APP_URL', null); ``` - Both resolve to all project settings. - Passing `null` clears a text setting. - The server rejects an invalid value or a disallowed app URL; see [errors and retries](/web-sdk/core/errors-and-retries). ## Reference [#reference] - [projects API reference](/web-sdk/core/reference/core/projects): every method, setting key and type. - [ovok.slim](/web-sdk/core/namespaces/slim) for the care-home project tree. # ovok.questionnaires and ovok.questionnaireResponses Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/questionnaires `ovok.questionnaires` runs questionnaire operations on the FHIR server. `ovok.questionnaireResponses` saves and processes the answers. Patient apps call both for the signed-in user. ## Pre-fill a questionnaire [#pre-fill-a-questionnaire] `populate` runs `$populate` on a stored Questionnaire. ```ts const filled = await ovok.questionnaires.populate('questionnaire-id'); ``` - Pass a `Parameters` resource as the second argument to give the server context. Without it, an empty one is sent. - It resolves to the `Parameters` the server returns. ## Submit a response [#submit-a-response] ```ts const bundle = await ovok.questionnaireResponses.submit(response); ``` - `submit` saves one QuestionnaireResponse in a transaction and resolves to the response bundle. - To save derived Observations with it, use `submitWithObservations(response, observations)`. It is one transaction, so the response is never saved without its observations. ## Extract observations [#extract-observations] ```ts const extracted = await ovok.questionnaireResponses.extract(responseId); ``` - It runs `$extract` on a stored response and resolves to `Parameters`. - A response that is not stored yet cannot be extracted: submit it first. ## Reference [#reference] - [questionnaires API reference](/web-sdk/core/reference/core/questionnaires): every method and type. - [ovok.patient](/web-sdk/core/namespaces/patient) to read a patient's questionnaires and responses. # ovok.realtime Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/realtime `ovok.realtime` opens a FHIR R4 websocket subscription through the API host. Signed-in apps call it to react to new or changed resources without polling. ## Subscribe to changes [#subscribe-to-changes] `subscribe` takes a FHIR search string as the criteria and a handler. ```ts import type { RealtimeNotification } from '@ovok/core'; const notifications: RealtimeNotification[] = []; const unsubscribe = await ovok.realtime.subscribe( 'Observation?subject=Patient/123', (notification) => { notifications.push(notification); }, ); ``` - It creates a `Subscription` resource, then connects the socket. - Empty criteria throw `OvokValidationError`. - If the socket cannot start, the new subscription is deleted again and the error is thrown. - The handler receives `SubscriptionStatus` event notifications. `notification.resources` holds the changed resources the server sent with each one. Handshake, heartbeat and ping/pong messages stay internal. ## Stay connected [#stay-connected] The client keeps the connection alive for you. - It refreshes the binding token before it expires and reconnects with a fresh token if the socket drops, waiting longer between failed attempts. - When the user signs out it pauses; when a user signs in again it reconnects. - The socket URL must be on the configured API host, or the subscription fails with `OvokServiceError`. ## Stop listening [#stop-listening] ```ts await unsubscribe(); ``` - It closes the socket and deletes the server subscription. - Call it when the screen unmounts, or the subscription stays open. ## Reference [#reference] - [realtime API reference](/web-sdk/core/reference/core/realtime): every method and type. - [ovok.session](/web-sdk/core/namespaces/session) for session changes. - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.session Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/session `ovok.session` reports who is signed in and keeps the accounts saved on this device. Sign-in itself is in `ovok.auth`. A machine client has no user session: `current` returns `null` and saved accounts throw `OvokConfigError`. ## Read the current session [#read-the-current-session] ```ts const session = await ovok.session.current(); if (session === null) { // signed out } else { console.log(session.profile.reference, session.project.reference); } ``` - It returns the restored session, or `null` when signed out. - The `Session` holds the access token, its expiry, the project and the profile. ## Follow session changes [#follow-session-changes] ```ts const stop = ovok.session.onChange((session) => { console.log(session?.profile.reference ?? 'signed out'); }); stop(); ``` - The listener fires when a session starts, changes or ends, including when a refused refresh token signs the user out. - It receives the active `Session` or `null`. The returned function stops listening. ## Switch between saved accounts [#switch-between-saved-accounts] The client saves a private session for each signed-in profile in the configured storage. ```ts const accounts = await ovok.session.savedAccounts.list(); await ovok.session.savedAccounts.switch('Patient/123'); await ovok.session.savedAccounts.remove('Patient/123'); ``` - `list` returns each account's `id`, `profile`, `project`, `active` and `expired`, without tokens. - Accounts are identified by profile reference. - `switch` and `remove` throw `OvokAccountError` when the account is missing or its session has expired (`switch`) or is not saved (`remove`). - `remove` signs the account out on the server unless it has expired, then forgets it. Removing the active account switches to the next saved one, when there is one. ## Reference [#reference] - [session API reference](/web-sdk/core/reference/core/session): every method and type. - [ovok.realtime](/web-sdk/core/namespaces/realtime), which pauses when the session ends. - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.sharing Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/sharing `ovok.sharing` lets a patient share chosen observation codes with another person, and see or revoke those shares. Patient apps call it for the signed-in patient. A project admin turns sharing on in the sharing settings. ## Invite someone [#invite-someone] The patient creates an invite for a set of observation codes and passes the `inviteId` and `code` to the recipient. ```ts const invite = await ovok.sharing.invites.create({ codes: ['8867-4'], endsAt: null, }); console.log(invite.inviteId, invite.code, invite.expiresAt); ``` - `endsAt` is an ISO 8601 end time, or `null` for no end. - The invite expires at `expiresAt`. ## Redeem an invite [#redeem-an-invite] The recipient redeems it while signed in. ```ts const share = await ovok.sharing.invites.redeem({ inviteId, code }); ``` - It resolves to the created share. - To accept a record-share invite with the active profile, `ovok.invites.accept` picks the right route for you. ## List and revoke shares [#list-and-revoke-shares] ```ts const { outgoing, incoming, practitioners, relatedPersons, received } = await ovok.sharing.shares.list(); await ovok.sharing.shares.revoke(consentId); ``` - Groups the server does not send yet come back as empty arrays. - `revoke` takes the id of the share's consent. ## Change sharing settings [#change-sharing-settings] ```ts const settings = await ovok.sharing.settings.retrieve(); await ovok.sharing.settings.update({ enabled: true, practitionerSharingEnabled: true }); ``` - `update` replaces the settings. `practitionerSharingEnabled: null` leaves that flag unchanged. ## Reference [#reference] - [sharing API reference](/web-sdk/core/reference/core/sharing): every method and type. - [invites guide](/web-sdk/core/namespaces/invites) - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.signals Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/signals `ovok.signals` covers the parts of Signals that go through Ovok: turning it on for a patient, repairing residents whose limits did not reach it, and a gateway for the Signals API. Care-home apps and server clients call it. The old `/v1/signals/{patients,alerts,raw-alerts,notes,settings}` routes are gone; alert notes live under `ovok.slim.notifications.notes`. ## Enable Signals for a patient [#enable-signals-for-a-patient] ```ts const result = await ovok.signals.enable(patientId); ``` - It is idempotent: retry after a 409 or 503. - Readings saved through Ovok reach Signals without a second submit. ## Call the Signals API [#call-the-signals-api] The gateway forwards a request to `v1/signals/api/{path}`. The server checks that the caller's role may use the route. ```ts const patients = await ovok.signals.gateway.request({ method: 'GET', path: ['patient'], query: { limit: 20 }, }); ``` - Pass each path segment separately so the client encodes it. Empty segments, `.`, `..`, slashes and control characters throw `OvokValidationError`. - `body` is sent as JSON. The result type is whatever you pass as the type argument, `unknown` by default. ## Repair undeliverable residents [#repair-undeliverable-residents] Some residents' limits may not reach Signals. List them, then repair. ```ts const { count, residents } = await ovok.signals.undeliverable.list(); const outcome = await ovok.signals.undeliverable.repair({ patientIds: residents.map((r) => r.patientId) }); console.log(outcome.repaired, outcome.stillUndeliverable); ``` - Without `patientIds`, `repair` repairs every resident `list` shows. - The result counts attempted, repaired, still undeliverable, skipped and not reached. ## Reference [#reference] - [signals API reference](/web-sdk/core/reference/core/signals): every method and type. - [ovok.slim](/web-sdk/core/namespaces/slim) for thresholds and notifications. - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.slim Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/slim `ovok.slim` calls the `v1/slim` routes that power a care-home dashboard. Practitioner apps call it with a signed-in user whose project role allows it. It has many sub-resources; this page groups them by task. Lists that the server pages (`patients`, `devices`, `locations`, `zones`, `changeHistory`, medical notifications) return a `PagePromise`: await it for the first page, or `for await` for every item. ## Residents and devices [#residents-and-devices] ```ts for await (const resident of ovok.slim.patients.list({ search: 'smith' })) { console.log(resident); } const resident = await ovok.slim.patients.retrieve(patientId); const vitals = await ovok.slim.patients.currentVitals(patientId); ``` - `patients` has `list`, `retrieve`, `create`, `update`, `delete`, `everything` (the `$everything` bundle) and `currentVitals`. - `update` replaces the editable fields: leaving out `locationId` unassigns the resident's devices. `delete` returns 409 while the resident still has a device. - `devices` has `list`, `retrieve`, `create`, `update`, `delete` and `assignToProject`. `create` returns 409 when another customer holds the serial. ## Live values and telemetry [#live-values-and-telemetry] ```ts const telemetry = await ovok.slim.devices.liveTelemetry({ count: 50 }); for await (const row of ovok.slim.devices.live({ count: 50 })) { console.log(row); } ``` - `live` and `liveTelemetry` take `count` from 1 to 100; anything else throws `OvokValidationError` before any request. - Identical concurrent live reads share one request, and it is aborted only once every caller has aborted. - `telemetry(deviceId)` reads one device. `effectiveObservationIds` and `lastObservationIds` have per-device and all-device variants. ## Notifications and notes [#notifications-and-notes] ```ts const page = await ovok.slim.notifications.outOfBed.list({ patient: patientId }); await ovok.slim.notifications.alarms.acknowledge(notificationId); await ovok.slim.notifications.notes.create({ kind: 'alarm', id: notificationId, text: 'Checked on the resident' }); ``` - `notifications` groups `alarms`, `outOfBed`, `medical` and `notes`. Each of the first three has `list` and `recent`; `alarms` and `medical` also `acknowledge`. - `medical.list` pages with a cursor and `medical.retrieve` reads one episode. `acknowledge` can take about 12 seconds, and the client retries a 503 because the server makes it safe to repeat. - Note `kind` is `'oob'`, `'alarm'`, `'medical'` or `'alert'`. - `notifications.list` is deprecated: use `outOfBed.list`, `alarms.list` or `medical.list`. ## Thresholds, trends and sleep [#thresholds-trends-and-sleep] ```ts const home = await ovok.slim.thresholds.retrieve(); await ovok.slim.patients.thresholds.update(patientId, { settings: { heartRate: { deviationPercent: 20 } }, }); const trends = await ovok.slim.trends.realtime({ patientId, startTime, endTime, graphType: 'heartRate', }); ``` - `thresholds` is the home default; `patients.thresholds` is per resident. A home with no stored limits reads as the default template. - Threshold updates are never retried. A 502 means Signals did not take every resident's limits and nothing was written; a 409 on a resident means another save is running. - `trends.graphs` reads history by day range; `trends.realtime` is limited to 20 calls per minute per caller, so load once per view and wait `retryAfterMs` after a 503. - `sleep.statistics` takes `patientId`, `endDate` and optional `lastDayCount`. ## Places, projects and staff [#places-projects-and-staff] - `locations` and `zones`: `locations` has `list`, `retrieve`, `create`, `update`, `delete`; `zones` has `list`, `retrieve` and `deviceCounts`. - `projects` reads and replaces a project, lists its `users` and counts `deviceCounts` and `patientCounts`. `projects.children` lists, creates and deletes child projects. - `policies` and `organizations` are CRUD resources over access policies and organizations. - `practitioners.invite` invites a practitioner by email, and `users.delete` deletes a user by profile type and id. - `exports.patientPdf` generates a resident PDF, and `changeHistory.list` pages the change history. - `ovok.slim.health()` checks the slim API. ## Reference [#reference] - [slim API reference](/web-sdk/core/reference/core/slim): every method and type. - [ovok.signals](/web-sdk/core/namespaces/signals) for Signals repair and the gateway. - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.videoCalls Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/videocalls `ovok.videoCalls` covers the LiveKit video-call routes under `video-call/livekit`: appointments, access to a call and invitation emails. Practitioner and patient apps call it with a signed-in user; guests get access through an invite. ## Schedule a call [#schedule-a-call] ```ts const appointment = await ovok.videoCalls.appointments.create({ start: '2026-11-02T10:00:00Z', end: '2026-11-02T10:30:00Z', comment: 'Follow-up', videoCallParticipants: [{ email: 'patient@example.com' }], }); const upcoming = await ovok.videoCalls.appointments.list(); ``` - `list` resolves to an array and takes a query. - `update(appointmentId, body)` replaces the appointment, so send the full body. ## Get access to a call [#get-access-to-a-call] ```ts const permission = await ovok.videoCalls.access.permission(appointmentId); const access = await ovok.videoCalls.access.createUser(appointmentId); console.log(access.videoCallUrl, access.livekitJwt, access.passphrase); ``` - `permission` returns how the server says the caller may join. - `createUser` is for the signed-in user. `createGuest(appointmentId, { guestEmail })` creates guest access. ## Email participants [#email-participants] ```ts await ovok.videoCalls.emails.invite({ appointmentId, emailRecipients: [{ email: 'patient@example.com', profileRef: 'Patient/123' }], }); ``` - `invite`, `update` and `cancel` take the same body. - `ovok.videoCalls.notifyActive(appointmentId)` tells the server a call is active. ## Reference [#reference] - [videoCalls API reference](/web-sdk/core/reference/core/videocalls): every method and type. - [Errors and retries](/web-sdk/core/errors-and-retries) # ovok.wearables Canonical page: https://docs.ovok.com/web-sdk/core/namespaces/wearables `ovok.wearables` has two halves. `providers` holds a project's provider settings and is for admins. `connections` is the patient app's side: connect a provider, sync its data and disconnect. Providers are `oura`, `whoop`, `strava`, `withings`, `polar`, `suunto`, `garmin` and `ultrahuman`. ## Connect a provider [#connect-a-provider] ```ts const { authorizationUrl } = await ovok.wearables.connections.authorize('oura'); ``` - `authorize` returns the provider's one-time consent page. Open `authorizationUrl` for the patient, who grants access there. - `list` shows the patient's current connections. ## Sync data [#sync-data] ```ts const result = await ovok.wearables.connections.sync('oura'); console.log(result.created, result.syncedThrough); ``` - It reports how many observations were created and the time the data was synced up to. ## Disconnect [#disconnect] ```ts await ovok.wearables.connections.delete('oura'); ``` ## Configure providers [#configure-providers] ```ts const providers = await ovok.wearables.providers.list(); const oura = await ovok.wearables.providers.retrieve('oura'); ``` - `create`, `patch` and `delete` change a provider's settings for the project. - The calls go to `v1/wearables/providers` and `v1/wearables/connections`. ## Reference [#reference] - [wearables API reference](/web-sdk/core/reference/core/wearables): every method and type. - [ovok.measurements](/web-sdk/core/namespaces/measurements) for how readings are stored. - [Errors and retries](/web-sdk/core/errors-and-retries) # The Ovok client Canonical page: https://docs.ovok.com/web-sdk/core/next-client `@ovok/core` exports the current `Ovok` client. The `@ovok/core/next` entry remains available for existing imports. Both entries use the same client and talk to the Ovok API directly in Node, browsers and React Native. This client is also the contract the Java and Python SDKs follow, so the same API names are available in each language's idiom. ## Create a client [#create-a-client] ```ts import { Ovok } from '@ovok/core'; const ovok = new Ovok({ baseUrl: 'https://api.sandbox.ovok.com', tenantCode: 'your-tenant', }); ``` Options such as `storage`, `timeoutMs` and `onUnauthenticated` are described in [Configure the client](/web-sdk/core/client-configuration). A bad option throws `OvokConfigError` from the constructor, not from the first request. ## Namespaces [#namespaces] Each area of the Ovok API has its own namespace, and each has a guide page: - [ovok.auth](/web-sdk/core/namespaces/auth) and [ovok.session](/web-sdk/core/namespaces/session): sign-in, registration, passwords, saved accounts and session changes. See also [Sign users in](/web-sdk/core/guides/sign-in). - [ovok.fhir](/web-sdk/core/namespaces/fhir) and [ovok.realtime](/web-sdk/core/namespaces/realtime): FHIR reads, searches and writes, and websocket subscriptions. - [ovok.patient](/web-sdk/core/namespaces/patient): the signed-in patient's appointments, care plans, questionnaires, devices and dashboard. - [ovok.measurements](/web-sdk/core/namespaces/measurements): saving and reading measurements, with the offline queue. - [ovok.questionnaires and ovok.questionnaireResponses](/web-sdk/core/namespaces/questionnaires): `$populate`, submit and `$extract`. - [ovok.slim](/web-sdk/core/namespaces/slim): the care-home dashboard API. - [ovok.signals](/web-sdk/core/namespaces/signals): Signals enablement, undeliverable residents and the Signals gateway. - [ovok.projects](/web-sdk/core/namespaces/projects), [ovok.accounts](/web-sdk/core/namespaces/accounts) and [ovok.locales and ovok.localizations](/web-sdk/core/namespaces/localization). - [ovok.cms](/web-sdk/core/namespaces/cms) and [ovok.content](/web-sdk/core/namespaces/content). - [ovok.consent](/web-sdk/core/namespaces/consent), [ovok.invites](/web-sdk/core/namespaces/invites) and [ovok.sharing](/web-sdk/core/namespaces/sharing). - [ovok.documents](/web-sdk/core/namespaces/documents), [ovok.videoCalls](/web-sdk/core/namespaces/videocalls), [ovok.ai](/web-sdk/core/namespaces/ai), [ovok.wearables](/web-sdk/core/namespaces/wearables), [ovok.email](/web-sdk/core/namespaces/email), [ovok.bots](/web-sdk/core/namespaces/bots) and [ovok.health](/web-sdk/core/namespaces/health). Methods follow Stripe's verbs: `list`, `retrieve`, `create`, `update` (PUT), `patch`, `delete`, and plain verbs such as `acknowledge`, `accept` or `revoke`. ## Paging and request options [#paging-and-request-options] - **Paging:** lists the server pages return a `PagePromise`. Await it for the first page, or `for await` over it for every item. - **Request options:** every method takes `{ signal, timeoutMs }` as its last argument. - **Errors:** every failure is an `OvokError`; see [Errors and retries](/web-sdk/core/errors-and-retries). ## Runtimes [#runtimes] - **Bundlers, React Native and Node:** import from `@ovok/core`. - **Existing imports:** `@ovok/core/next` remains an alias for the same client. - **Deep imports:** existing `@ovok/core/dist/*` imports remain available. - **React Native:** use `@ovok/native/next`, which supplies device storage and the `crypto.getRandomValues` polyfill that sign-in needs. - **Node:** version 22 or later. ## Reference [#reference] - [Ovok client API reference](/web-sdk/core/reference/core/ovok-client) and the [complete API reference](/web-sdk/core/reference/). # Offline measurement saves Canonical page: https://docs.ovok.com/web-sdk/core/offline-measurement-saves `ovok.measurements` queues a reading when the connection fails and retries it with `ovok.measurements.offlineQueue.flush()`. See [ovok.measurements](/web-sdk/core/namespaces/measurements). # Offline measurements Canonical page: https://docs.ovok.com/web-sdk/core/offline-measurements `ovok.measurements` queues a reading when the connection fails and retries it with `ovok.measurements.offlineQueue.flush()`. See [ovok.measurements](/web-sdk/core/namespaces/measurements). # React integration Canonical page: https://docs.ovok.com/web-sdk/core/react Create the client from `@ovok/core` and import React components and hooks from `@ovok/core/next/react`. ```tsx 'use client'; import { useState, type PropsWithChildren } from 'react'; import { Ovok } from '@ovok/core'; import { OvokProvider } from '@ovok/core/next/react'; export function AppProviders({ children }: PropsWithChildren) { const [client] = useState(() => new Ovok({ baseUrl: 'https://api.sandbox.ovok.com', tenantCode: 'your-tenant', })); return {children}; } ``` Components below the provider can use the session and FHIR hooks: ```tsx 'use client'; import { useSearch } from '@ovok/core/next/react'; export function PatientList() { const { data, loading, error, refetch } = useSearch('Patient', { _count: 10 }); if (loading) return

Loading patients…

; if (error) return ; return

{data?.data.length ?? 0} patients

; } ``` The React entry requires the host application's React installation. Keep the client stable across renders. In server-rendered applications, create user-specific clients in the correct request scope and keep machine secrets on the server. The provider and hooks manage access to the client; they do not grant server authorization. See the [API map](/web-sdk/core/api-surface) and [complete API reference](/web-sdk/core/reference/) for available exports. # accounts Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/accounts ## Interfaces [#interfaces] ### AccountsResource [#accountsresource] Lists the accounts the signed-in user can access. #### Methods [#methods] ##### list() [#list] ```ts list(options?): Promise; ``` Lists the accounts the signed-in user can access. Calls `GET accounts`. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`OvokAccount`](#ovokaccount)[]\> ## Type Aliases [#type-aliases] ### OvokAccount [#ovokaccount] ```ts type OvokAccount = object; ``` An account of the signed-in user. #### Properties [#properties] | Property | Type | Description | | ------ | ------ | ------ | | `email` | `string` | Email address of the account. | | `name` | `string` | Name of the account. | # ai Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/ai ## Classes [#classes] ### AiChatResource [#aichatresource] Chat sessions and messages of the AI assistant. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `messages` | `readonly` | [`ChatMessagesResource`](#chatmessagesresource) | Messages within chat sessions. | | `sessions` | `readonly` | [`ChatSessionsResource`](#chatsessionsresource) | Chat sessions. | *** ### ChatMessagesResource [#chatmessagesresource] Messages of an AI chat session. #### Methods [#methods] ##### list() [#list] ```ts list( sessionId, params?, options? ): Promise; ``` Lists the messages of a chat session. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `sessionId` | `string` | | `params?` | [`OvokChatMessageQuery`](#ovokchatmessagequery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`OvokChatMessagesResponse`](#ovokchatmessagesresponse)\> ##### send() [#send] ```ts send( sessionId, body, options? ): Promise; ``` Sends a message to a chat session and returns the reply. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `sessionId` | `string` | | `body` | [`OvokChatMessageInput`](#ovokchatmessageinput) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<[`OvokChatMessage`](#ovokchatmessage)\> *** ### ChatSessionsResource [#chatsessionsresource] Create, list and fetch AI chat sessions. #### Methods [#methods-1] ##### create() [#create] ```ts create(body, options?): Promise; ``` Creates a chat session. Calls `POST session`. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `body` | [`OvokCreateChatSession`](#ovokcreatechatsession) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<[`OvokChatSession`](#ovokchatsession)\> ##### list() [#list-1] ```ts list(params?, options?): Promise; ``` Lists chat sessions. Calls `GET session`. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `params?` | [`OvokChatSessionQuery`](#ovokchatsessionquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<[`OvokChatSessionsResponse`](#ovokchatsessionsresponse)\> ##### retrieve() [#retrieve] ```ts retrieve( sessionId, params?, options? ): Promise; ``` Fetches one chat session. Calls `GET session/{sessionId}`. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `sessionId` | `string` | | `params?` | [`ChatSessionRetrieveParams`](#chatsessionretrieveparams) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<[`OvokChatSession`](#ovokchatsession)\> ## Interfaces [#interfaces] ### AIFhirPlan [#aifhirplan] FHIR query plan generated by the language model for an AI FHIR search. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `child?` | [`AIFhirPlan`](#aifhirplan) | Follow-up plan that runs after this one, built from this plan's results. | | `requests` | [`AIFhirPlanRequest`](#aifhirplanrequest)[] | Search requests executed for this step of the plan. | | `visibleResults?` | `string`[] | Identifiers of the requests whose results are returned to the caller. | *** ### AIFhirPlanRequest [#aifhirplanrequest] One FHIR search a plan executes. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `identifier` | `string` | Key under which this search's resources appear in `AIFhirResponse.results`. | | `query` | `string` | FHIR search query string for the resource type. | | `resourceType` | `string` | FHIR resource type searched, e.g. `Observation`. | *** ### AIFhirRequest [#aifhirrequest] Request body for an AI FHIR search. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `text` | `string` | The text to search for. **Example** `"What is the blood pressure of John Doe?"` | *** ### AIFhirResponse [#aifhirresponse] Result of an AI FHIR search: summary, plan and matching resources. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `markdown` | `string` | Markdown formatted response summarizing the results | | `plan` | [`AIFhirPlan`](#aifhirplan) | The FHIR query plan generated by the LLM | | `results` | `Record`\<`string`, `object`[]\> | Results of the FHIR queries executed based on the plan Key is the identifier from the request, value is array of FHIR resources | *** ### AiResource [#airesource] AI features: chat, translation and natural-language FHIR search. Calls routes under `ai`. #### Properties [#properties-5] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `chat` | `readonly` | [`AiChatResource`](#aichatresource) | Chat sessions and messages. | #### Methods [#methods-2] ##### fhirSearch() [#fhirsearch] ```ts fhirSearch(body, options?): Promise; ``` An LLM plans and runs the FHIR queries, so the answer can be wrong or invented. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `body` | [`AiFhirSearchRequest`](#aifhirsearchrequest) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-5] `Promise`\<[`AIFhirResponse`](#aifhirresponse)\> ##### translate() [#translate] ```ts translate(body, options?): Promise; ``` Translates text. Calls `POST ai/translation`. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `body` | [`OvokTranslationRequest`](/web-sdk/core/reference/core/content#ovoktranslationrequest) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-6] `Promise`\<[`OvokTranslationRequest`](/web-sdk/core/reference/core/content#ovoktranslationrequest)\> ## Type Aliases [#type-aliases] ### AiFhirSearchRequest [#aifhirsearchrequest] ```ts type AiFhirSearchRequest = AIFhirRequest & object; ``` Request for an AI-assisted FHIR search, optionally pinned to a FHIR version. #### Type Declaration [#type-declaration] ##### fhirVersion? [#fhirversion] ```ts fhirVersion?: "R4" | "R5"; ``` FHIR version to search; the server default applies when omitted. *** ### ChatSessionRetrieveParams [#chatsessionretrieveparams] ```ts type ChatSessionRetrieveParams = object; ``` Options for fetching one chat session. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `messageCount?` | `number` | How many of the latest messages to include. | *** ### OvokAIFhirRequest [#ovokaifhirrequest] ```ts type OvokAIFhirRequest = Record; ``` Untyped body of an AI FHIR search. *** ### OvokAIFhirResponse [#ovokaifhirresponse] ```ts type OvokAIFhirResponse = Record; ``` Untyped result of an AI FHIR search. *** ### OvokChatAssistant [#ovokchatassistant] ```ts type OvokChatAssistant = object; ``` Settings of the AI assistant in a chat session. #### Properties [#properties-7] | Property | Type | Description | | ------ | ------ | ------ | | `context?` | `string`[] | Extra context passed to the assistant. | | `history?` | `number` | Number of earlier messages the assistant sees. | | `participant` | `string` | Reference to the assistant participant. | | `system` | `string` | System prompt. | *** ### OvokChatMessage [#ovokchatmessage] ```ts type OvokChatMessage = object; ``` A message of an AI chat session. #### Properties [#properties-8] | Property | Type | Description | | ------ | ------ | ------ | | `content` | `string` | Message text. | | `mode` | `"assistant"` \| `"user"` \| `"system"` | Role of the sender. | | `reference` | `string` | Reference to the message. | | `sender` | `string` | Reference to the sender. | | `sentAt` | `string` | ISO 8601 time the message was sent. | *** ### OvokChatMessageInput [#ovokchatmessageinput] ```ts type OvokChatMessageInput = object; ``` Request body that sends a chat message. #### Properties [#properties-9] | Property | Type | Description | | ------ | ------ | ------ | | `content` | `string` | Message text. | | `mode?` | `"assistant"` \| `"user"` \| `"system"` | Role of the sender. | | `replyTo?` | `string` | Reference to the message this one answers. | | `sender` | `string` | Reference to the sender. | *** ### OvokChatMessageQuery [#ovokchatmessagequery] ```ts type OvokChatMessageQuery = object; ``` Sorting and paging of a chat message search. #### Properties [#properties-10] | Property | Type | Description | | ------ | ------ | ------ | | `_count?` | `number` | Page size. | | `_offset?` | `number` | Number of results to skip. | | `_sort?` | `"-sent"` \| `"sent"` | Sort by sent time, `-sent` for newest first. | *** ### OvokChatMessagesResponse [#ovokchatmessagesresponse] ```ts type OvokChatMessagesResponse = object; ``` A page of chat messages. #### Properties [#properties-11] | Property | Type | Description | | ------ | ------ | ------ | | `messages` | [`OvokChatMessage`](#ovokchatmessage)[] | Messages on this page. | *** ### OvokChatSession [#ovokchatsession] ```ts type OvokChatSession = object; ``` An AI chat session. #### Properties [#properties-12] | Property | Type | Description | | ------ | ------ | ------ | | `assistant` | [`OvokChatAssistant`](#ovokchatassistant) | Assistant settings. | | `messages?` | [`OvokChatMessage`](#ovokchatmessage)[] | Messages of the session, when requested. | | `participant` | `string` | Reference to the user. | | `reference?` | `string` | Reference to the session. | | `title?` | `string` | Session title. | *** ### OvokChatSessionQuery [#ovokchatsessionquery] ```ts type OvokChatSessionQuery = object; ``` Filters, sorting and paging of a chat session search. #### Properties [#properties-13] | Property | Type | Description | | ------ | ------ | ------ | | `_count?` | `number` | Page size. | | `_id?` | `string` | Only the session with this id. | | `_offset?` | `number` | Number of results to skip. | | `_sort?` | `"-sent"` \| `"sent"` | Sort by sent time, `-sent` for newest first. | | `messageCount?` | `number` | Number of latest messages to include per session. | *** ### OvokChatSessionsResponse [#ovokchatsessionsresponse] ```ts type OvokChatSessionsResponse = object; ``` A page of chat sessions. #### Properties [#properties-14] | Property | Type | Description | | ------ | ------ | ------ | | `sessions` | [`OvokChatSession`](#ovokchatsession)[] | Sessions on this page. | *** ### OvokCreateChatSession [#ovokcreatechatsession] ```ts type OvokCreateChatSession = object; ``` Request body that creates an AI chat session. #### Properties [#properties-15] | Property | Type | Description | | ------ | ------ | ------ | | `assistant` | [`OvokChatAssistant`](#ovokchatassistant) | Assistant settings. | | `messages` | `object`[] | Opening messages. | | `participant` | `string` | Reference to the user. | | `title?` | `string` | Session title. | # auth Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/auth ## Enumerations [#enumerations] ### AppleAuthenticationUserDetectionStatus [#appleauthenticationuserdetectionstatus] Whether Apple considers the user a real person. #### Enumeration Members [#enumeration-members] | Enumeration Member | Value | Description | | ------ | ------ | ------ | | `LIKELY_REAL` | `2` | The user appears to be a real person. | | `UNKNOWN` | `1` | The system has not determined whether the user might be a real person. | | `UNSUPPORTED` | `0` | The system does not support this determination and there is no data. | ## Classes [#classes] ### AuthSessionsResource [#authsessionsresource] The account's sessions on the server. #### Methods [#methods] ##### list() [#list] ```ts list(options?): Promise; ``` Lists the account's sessions. Calls `GET auth/session`. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`OvokSession`](#ovoksession)[]\> ##### revoke() [#revoke] ```ts revoke(option, options?): Promise; ``` Revoking the current session also ends it here. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `option` | [`SessionRevokeOption`](#sessionrevokeoption) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<`void`\> ## Interfaces [#interfaces] ### AppleLoginBody [#appleloginbody] Credential returned by Sign in with Apple, sent to log the user in. #### Properties [#properties] | Property | Type | Description | | ------ | ------ | ------ | | `authorizationCode` | `string` \| `null` | A short-lived session token used by your app for proof of authorization when interacting with the app's server counterpart. Unlike `user`, this is ephemeral and will change each session. | | `email` | `string` | The user's email address. Might not be present if you didn't request the `EMAIL` scope. May also be null if this is not the first time the user has signed into your app. If the user chose to withhold their email address, this field will instead contain an obscured email address with an Apple domain. | | `fullName` | \| \{ `familyName`: `string` \| `null`; `givenName`: `string` \| `null`; `middleName`: `string` \| `null`; `namePrefix`: `string` \| `null`; `nameSuffix`: `string` \| `null`; `nickname`: `string` \| `null`; \} \| `null` | The user's name. May be `null` or contain `null` values if you didn't request the `FULL_NAME` scope, if the user denied access, or if this is not the first time the user has signed into your app. | | `identityToken` | `string` | A JSON Web Token (JWT) that securely communicates information about the user to your app. | | `internalId` | `string` | The internal ID of the extension with url "https://api.ovok.com/StructureDefinition/external-auth-internal-id" | | `realUserStatus` | [`AppleAuthenticationUserDetectionStatus`](#appleauthenticationuserdetectionstatus) | A value that indicates whether the user appears to the system to be a real person. | | `state` | `string` \| `null` | An arbitrary string that your app provided as `state` in the request that generated the credential. Used to verify that the response was from the request you made. Can be used to avoid replay attacks. If you did not provide `state` when making the sign-in request, this field will be `null`. | | `user` | `string` | An identifier associated with the authenticated user. You can use this to check if the user is still authenticated later. This is stable and can be shared across apps released under the same development team. The same user will have a different identifier for apps released by other developers. | *** ### AuthResource [#authresource] Sign-in, registration, password and session management. Routes are under `auth` and `v2/auth`. #### Properties [#properties-1] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `sessions` | `readonly` | [`AuthSessionsResource`](#authsessionsresource) | Server-side sessions of the signed-in account. | #### Methods [#methods-1] ##### adoptSession() [#adoptsession] ```ts adoptSession(adopted): Promise; ``` Continues a sign-in made elsewhere, such as the session an earlier client stored, as if the user had just signed in. It replaces any current session, is saved and announced like a login, and refreshes like one. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `adopted` | [`AdoptedSession`](#adoptedsession) | ###### Returns [#returns-2] `Promise`\<[`Session`](/web-sdk/core/reference/core/session#session)\> ###### Example [#example] ```ts const session = await ovok.auth.adoptSession({ accessToken, refreshToken, profile: { reference: "Patient/123" }, }); ``` ###### Throws [#throws] OvokValidationError when the access token or profile reference is missing or malformed, or another field is invalid. ###### Throws [#throws-1] OvokConfigError when the client was created with `clientSecret`. ##### changePassword() [#changepassword] ```ts changePassword(change, options?): Promise; ``` The confirmation is the app's to check; Ovok Core never receives it. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `change` | [`ChangePasswordBody`](#changepasswordbody) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<[`ChangePasswordResponse`](#changepasswordresponse)\> ##### completePasswordReset() [#completepasswordreset] ```ts completePasswordReset(body, options?): Promise; ``` Sets a new password using the token from the reset email. Calls `POST v2/auth/reset-password/process`. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `body` | [`CompletePasswordResetBody`](#completepasswordresetbody) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<`OperationOutcome`\> ##### current() [#current] ```ts current(): Promise; ``` Returns the current session, or null when signed out. ###### Returns [#returns-5] `Promise`\<[`Session`](/web-sdk/core/reference/core/session#session) \| `null`\> ##### deleteAccount() [#deleteaccount] ```ts deleteAccount(request, options?): Promise; ``` Schedules the deletion; the account stays signed in until then. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `request` | [`RequestDeleteUserBody`](#requestdeleteuserbody) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-6] `Promise`\<[`RequestDeleteUserResponse`](#requestdeleteuserresponse)\> ##### login() [#login] ```ts login(credentials, options?): Promise; ``` Signs in with email and password. Calls `POST auth/tenant/{profileType}/login/start`, then `.../token` unless MFA is required. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `credentials` | [`LoginCredentials`](#logincredentials) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-7] `Promise`\<[`LoginResult`](#loginresult)\> ###### Example [#example-1] ```ts const result = await ovok.auth.login({ profileType: "Patient", email, password }); if (result.status === "mfa-required") await ovok.auth.verifyMfa(result.challenge, code); ``` ##### logout() [#logout] ```ts logout(options?): Promise; ``` Ends the session on the server, and always locally, even when the server cannot be reached. ###### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-8] `Promise`\<`void`\> ##### me() [#me] ```ts me(options?): Promise; ``` Fetches the signed-in user's profile. Calls `GET auth/me`. ###### Parameters [#parameters-8] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-9] `Promise`\<[`OvokCurrentPatientProfile`](/web-sdk/core/reference/core/patient#ovokcurrentpatientprofile)\> ##### register() [#register] ```ts register(details, options?): Promise; ``` A project that routes the email to a clinician invitation signs no one in. ###### Parameters [#parameters-9] | Parameter | Type | | ------ | ------ | | `details` | [`PatientRegistration`](#patientregistration) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-10] `Promise`\<[`RegisterResult`](#registerresult)\> ##### registerPractitioner() [#registerpractitioner] ```ts registerPractitioner(details, options?): Promise; ``` Registers a practitioner in the client's tenant and signs them in. Calls `POST auth/tenant/Practitioner/register`. ###### Parameters [#parameters-10] | Parameter | Type | | ------ | ------ | | `details` | [`PractitionerRegistration`](#practitionerregistration) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-11] `Promise`\<[`Session`](/web-sdk/core/reference/core/session#session)\> ###### Throws [#throws-2] OvokValidationError when `password` and `passwordConfirm` differ. ##### resetPassword() [#resetpassword] ```ts resetPassword(request, options?): Promise; ``` Sends a password-reset email. Calls `POST v2/auth/reset-password`. ###### Parameters [#parameters-11] | Parameter | Type | | ------ | ------ | | `request` | [`ResetPasswordBody`](#resetpasswordbody) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-12] `Promise`\<`OperationOutcome`\> ##### socialLogin() [#sociallogin] ```ts socialLogin

( provider, credential, options? ): Promise; ``` Signs in with an Apple or Google token. Calls `POST auth/external/{provider}`. ###### Type Parameters [#type-parameters] | Type Parameter | | ------ | | `P` *extends* keyof [`SocialCredentials`](#socialcredentials) | ###### Parameters [#parameters-12] | Parameter | Type | | ------ | ------ | | `provider` | `P` | | `credential` | [`SocialCredentials`](#socialcredentials)\[`P`\] | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-13] `Promise`\<[`Session`](/web-sdk/core/reference/core/session#session)\> ##### verifyMfa() [#verifymfa] ```ts verifyMfa( challenge, code, options? ): Promise; ``` Completes an MFA sign-in with the code. Calls `POST auth/tenant/{profileType}/login/mfa`, then `.../token`. ###### Parameters [#parameters-13] | Parameter | Type | | ------ | ------ | | `challenge` | [`MfaChallenge`](#mfachallenge) | | `code` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-14] `Promise`\<[`LoginResult`](#loginresult)\> *** ### ChangePasswordBody [#changepasswordbody] Request body for changing the signed-in user's password. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `confirmPassword?` | `string` | Optional client-side confirmation; Ovok Core does not receive this field. | | `newPassword` | `string` | The new password. | | `oldPassword` | `string` | The current password. | *** ### CompletePasswordResetBody [#completepasswordresetbody] Body to finish a password reset with the ID and secret from the reset link. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `id` | `string` | ID of the password reset request. | | `password` | `string` | The new password. | | `secret` | `string` | Secret from the reset link. | *** ### GoogleLoginBody [#googleloginbody] Body to sign in with a Google OAuth token. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `access_token?` | `string` | The access token obtained from Google OAuth | | `expires_in?` | `number` | Token expiration time in seconds | | `idToken` | `string` | The ID token obtained from Google OAuth | | `internalId` | `string` | The internal ID of the extension with url "https://api.ovok.com/StructureDefinition/external-auth-internal-id" | | `scope?` | `string` | OAuth scope (e.g. "openid") | | `token_type?` | `string` | Type of token (e.g. "bearer") | *** ### OvokSession [#ovoksession] A server-side login session for the current account. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `authMethod?` | `string` | How the session was authenticated. | | `id` | `string` | Session identifier. | | `lastUpdated?` | `string` | ISO 8601 time the session was last updated. | | `remoteAddress?` | `string` | Client address that created the session. | *** ### RegisterBody [#registerbody] Request body for registering a new patient account. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `continueAsPatientToken?` | `string` | Token from an invite that lets a clinician continue as a patient. | | `email` | `string` | Email address of the new account. | | `name` | `string` | Given name. | | `password` | `string` | Chosen password. | | `passwordConfirm` | `string` | Must equal `password`; checked before any request is sent. | | `surname` | `string` | Family name. | | `tenantCode` | `string` | Code of the project to register in. | *** ### RequestDeleteUserBody [#requestdeleteuserbody] Body for scheduling the signed-in user's account deletion. #### Properties [#properties-7] | Property | Type | Description | | ------ | ------ | ------ | | `days` | `number` | Days until the account is deleted, between 0 and 90. | | `wipe` | `boolean` | When true, the user's medical data is deleted with the account. Defaults to false. | *** ### RequestDeleteUserResponse [#requestdeleteuserresponse] Result of requesting deletion of the signed-in user. #### Properties [#properties-8] | Property | Type | Description | | ------ | ------ | ------ | | `scheduled` | `string` | When the deletion is scheduled to happen. | | `user` | `object` | The user the deletion applies to. | | `user.email` | `string` | Email address of the user. | | `user.firstName` | `string` | First name of the user. | | `user.id` | `string` | ID of the user. | | `user.lastName` | `string` | Last name of the user. | | `user.meta` | `Record`\<`string`, `unknown`\> | Resource metadata of the user. | | `user.project` | `Record`\<`string`, `unknown`\> | Reference to the project the user belongs to. | | `user.resourceType` | `string` | FHIR resource type of the user. | *** ### ResetPasswordBody [#resetpasswordbody] Request body for sending a password-reset email. #### Properties [#properties-9] | Property | Type | Description | | ------ | ------ | ------ | | `clientId?` | `string` | The client ID to use for the request | | `email` | `string` | The email address of the user to reset the password for | | `type` | `"Practitioner"` \| `"Patient"` \| `"RelatedPerson"` | The type of user to reset the password for | ## Type Aliases [#type-aliases] ### AdoptedSession [#adoptedsession] ```ts type AdoptedSession = object; ``` A sign-in made elsewhere, such as the session an earlier client stored, for `ovok.auth.adoptSession` to continue. #### Properties [#properties-10] | Property | Type | Description | | ------ | ------ | ------ | | `accessToken` | `string` | Bearer token for API requests. | | `expiresIn?` | `number` | Seconds until `accessToken` expires. Omit it when unknown: the first request then refreshes the session. | | `profile` | `object` | The signed-in profile. | | `profile.display?` | `string` \| `null` | Display name, if known. | | `profile.reference` | `string` | FHIR reference, such as `Patient/123`. | | `project?` | `object` | The project the session belongs to. Omit it when unknown. | | `project.display?` | `string` \| `null` | Display name, if known. | | `project.reference` | `string` | FHIR reference, such as `Project/123`. | | `refreshToken?` | `string` \| `null` | Token that renews the session; null or omitted when there is none. | *** ### ChangePasswordResponse [#changepasswordresponse] ```ts type ChangePasswordResponse = Omit; ``` The updated user record, without the password hash. *** ### LoginCredentials [#logincredentials] ```ts type LoginCredentials = object; ``` Email and password for one profile type. #### Properties [#properties-11] | Property | Type | Description | | ------ | ------ | ------ | | `email` | `string` | Account email address. | | `password` | `string` | Account password. | | `profileType` | [`ProfileType`](#profiletype) | Which kind of account to sign in to. | *** ### LoginResult [#loginresult] ```ts type LoginResult = | { session: Session; status: "signed-in"; } | { challenge: MfaChallenge; status: "mfa-required"; }; ``` Either a signed-in session, or an MFA challenge to complete with `verifyMfa`. #### Union Members [#union-members] ##### Type Literal [#type-literal] ```ts { session: Session; status: "signed-in"; } ``` ###### session [#session] ```ts session: Session; ``` The new session. ###### status [#status] ```ts status: "signed-in"; ``` Sign-in finished. *** ##### Type Literal [#type-literal-1] ```ts { challenge: MfaChallenge; status: "mfa-required"; } ``` ###### challenge [#challenge] ```ts challenge: MfaChallenge; ``` Pass to `verifyMfa` with the code. ###### status [#status-1] ```ts status: "mfa-required"; ``` A second factor is needed. *** ### MfaChallenge [#mfachallenge] ```ts type MfaChallenge = object; ``` Hand it back to `verifyMfa`: it carries the PKCE verifier the token exchange needs. #### Properties [#properties-12] | Property | Type | Description | | ------ | ------ | ------ | | `codeVerifier` | `string` | PKCE verifier for the token exchange. | | `loginId` | `string` | Server id of the pending login. | | `profileType` | [`ProfileType`](#profiletype) | Account kind being signed in. | *** ### PatientRegistration [#patientregistration] ```ts type PatientRegistration = Omit; ``` The tenant comes from the client's config, as it does for login. *** ### PractitionerRegistration [#practitionerregistration] ```ts type PractitionerRegistration = Omit; ``` Details for registering a practitioner; the tenant comes from the client's config. *** ### ProfileType [#profiletype] ```ts type ProfileType = "Patient" | "Practitioner" | "RelatedPerson"; ``` The kind of account that signs in. *** ### RegisterPractitionerBody [#registerpractitionerbody] ```ts type RegisterPractitionerBody = Omit; ``` Request body for registering a practitioner account. *** ### RegisterResult [#registerresult] ```ts type RegisterResult = | { session: Session; status: "signed-in"; } | { status: "clinician-invite"; }; ``` Either a signed-in session, or a notice that a clinician invitation was started. #### Union Members [#union-members-1] ##### Type Literal [#type-literal-2] ```ts { session: Session; status: "signed-in"; } ``` ###### session [#session-1] ```ts session: Session; ``` The new session. ###### status [#status-2] ```ts status: "signed-in"; ``` The new account is signed in. *** ##### Type Literal [#type-literal-3] ```ts { status: "clinician-invite"; } ``` ###### status [#status-3] ```ts status: "clinician-invite"; ``` No session was issued; the person must accept a clinician invitation. *** ### SessionRevokeOption [#sessionrevokeoption] ```ts type SessionRevokeOption = "current" | "other" | "all" | string & object; ``` Session selector accepted by the session revocation endpoint. *** ### SocialCredentials [#socialcredentials] ```ts type SocialCredentials = object; ``` Provider token bodies, keyed by provider. #### Properties [#properties-13] | Property | Type | Description | | ------ | ------ | ------ | | `apple` | [`AppleLoginBody`](#appleloginbody) | Credential from Apple sign-in. | | `google` | [`GoogleLoginBody`](#googleloginbody) | Credential from Google sign-in. | *** ### SocialProvider [#socialprovider] ```ts type SocialProvider = keyof SocialCredentials; ``` Supported social sign-in providers. # bots Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/bots ## Interfaces [#interfaces] ### BotsResource [#botsresource] Runs server-side bots. #### Methods [#methods] ##### execute() [#execute] ```ts execute( identifier, input, options? ): Promise; ``` `identifier` is the bot's "system|value" identifier. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `identifier` | `string` | | `input` | [`BotInput`](#botinput) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`BotOutput`](#botoutput)\> ## Type Aliases [#type-aliases] ### BotInput [#botinput] ```ts type BotInput = Record; ``` JSON input passed to a bot. *** ### BotOutput [#botoutput] ```ts type BotOutput = Record; ``` JSON output returned by a bot. # cms Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/cms ## Classes [#classes] ### CmsDocumentsResource [#cmsdocumentsresource] Published documents of any collection, merged with the shared tenant's. #### Methods [#methods] ##### list() [#list] ```ts list( collection, params?, options? ): PagePromise; ``` Lists published documents of a collection, page by page. ###### Type Parameters [#type-parameters] | Type Parameter | Default type | | ------ | ------ | | `T` *extends* `object` | [`OvokCmsDocument`](#ovokcmsdocument) | ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `collection` | `string` | | `params?` | [`CmsListParams`](#cmslistparams) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<`T`\> ##### retrieve() [#retrieve] ```ts retrieve( collection, slug, params?, options? ): Promise; ``` Reads one published document of a collection by slug. ###### Type Parameters [#type-parameters-1] | Type Parameter | Default type | | ------ | ------ | | `T` *extends* `object` | [`OvokCmsDocument`](#ovokcmsdocument) | ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `collection` | `string` | | `slug` | `string` | | `params?` | [`CmsReadParams`](#cmsreadparams) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<`T`\> *** ### ReleaseNotesResource [#releasenotesresource] Published release notes. #### Methods [#methods-1] ##### list() [#list-1] ```ts list(params?, options?): PagePromise; ``` Lists release notes, newest first unless `sort` says otherwise. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `params?` | [`CmsListParams`](#cmslistparams) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`OvokCmsDocument`](#ovokcmsdocument)\> ## Interfaces [#interfaces] ### CmsResource [#cmsresource] Published CMS content: documents, legal pages, release notes and translations. Calls routes under `v1/public/cms`. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `documents` | `readonly` | [`CmsDocumentsResource`](#cmsdocumentsresource) | Reads documents from any collection. | | `releaseNotes` | `readonly` | [`ReleaseNotesResource`](#releasenotesresource) | Reads release notes. | #### Methods [#methods-2] ##### legalPage() [#legalpage] ```ts legalPage( slug, params?, options? ): Promise; ``` "terms-and-conditions", "data-privacy", …: readable before sign-in. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `slug` | `string` | | `params?` | [`CmsReadParams`](#cmsreadparams) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<[`OvokCmsDocument`](#ovokcmsdocument)\> ##### translations() [#translations] ```ts translations(locale?, options?): Promise; ``` The `translations` collection as one tree, readable before sign-in; nothing is kept on the device. Reads every page of the collection. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `locale?` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<[`OvokTranslations`](#ovoktranslations)\> ###### Throws [#throws] OvokError with code `cms_translations_page_limit` when the CMS is still offering pages after 500, rather than return a partial tree. ## Type Aliases [#type-aliases] ### CmsListParams [#cmslistparams] ```ts type CmsListParams = CmsReadParams & object; ``` `limit` is at most 50; `sort` is a top-level field, "-" for descending. #### Type Declaration [#type-declaration] ##### limit? [#limit] ```ts limit?: number; ``` Documents per page, at most 50. ##### page? [#page] ```ts page?: number; ``` Page number to fetch. ##### sort? [#sort] ```ts sort?: string; ``` Top-level field to sort by; prefix with `-` for descending. *** ### CmsReadParams [#cmsreadparams] ```ts type CmsReadParams = object; ``` `locale` takes an app language ("de-DE") or a CMS locale ("de"); omitted, the CMS answers in its default. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `locale?` | `string` | An app language such as `de-DE` or a CMS locale such as `de`. | *** ### OvokCmsDocument [#ovokcmsdocument] ```ts type OvokCmsDocument = object; ``` A published document of an Ovok CMS collection (`legal-pages`, `release-notes`, …). Fields beyond these depend on the collection. #### Indexable [#indexable] ```ts [field: string]: unknown ``` #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `body?` | `unknown` | Lexical rich text (JSON), as the CMS stores it. | | `effectiveAt?` | `string` \| `null` | ISO 8601 time the content takes effect. | | `excerpt?` | `string` \| `null` | Short summary text. | | `id` | `number` \| `string` | Document id. | | `publishedAt?` | `string` \| `null` | ISO 8601 publication time. | | `slug?` | `string` \| `null` | URL slug, unique within the collection. | | `status` | `string` | Publication status, e.g. `published`. | | `tags?` | `string`[] \| `null` | Free-form tags. | | `title?` | `string` \| `null` | Display title. | | `updatedAt?` | `string` \| `null` | ISO 8601 time of the last change. | *** ### OvokCmsListOptions [#ovokcmslistoptions] ```ts type OvokCmsListOptions = OvokCmsOptions & object; ``` Options for listing documents of a CMS collection. #### Type Declaration [#type-declaration-1] ##### limit? [#limit-1] ```ts limit?: number; ``` At most 50. ##### page? [#page-1] ```ts page?: number; ``` 1-based page number to read. ##### sort? [#sort-1] ```ts sort?: string; ``` A top-level field, "-" for descending, e.g. "-publishedAt". *** ### OvokCmsOptions [#ovokcmsoptions] ```ts type OvokCmsOptions = object; ``` Options shared by every CMS read. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `allowSignedOut?` | `boolean` | Read signed out. Only for collections the backend serves without a key or session: legal pages and translations, which turn it on by default. It needs `tenantCode`; without both, a signed-out read is refused before a request, because a 401 makes the client clear its storage. | | `environment?` | `"dev"` \| `"staging"` \| `"prod"` | Omitted, the backend's own. | | `locale?` | `string` | An app language ("de-DE") or a CMS locale ("de"), mapped with `toCmsLocale`. Omitted or "", the CMS answers in its default locale; the hooks send the runtime's language instead. | | `tenantCode?` | `string` | The tenant's code. Signed out, a read needs this and `allowSignedOut`. Signed in, the session's own tenant is read; naming another tenant is refused (403). | *** ### OvokCmsPage [#ovokcmspage] ```ts type OvokCmsPage = object; ``` A page of published documents (the CMS list envelope). #### Type Parameters [#type-parameters-2] | Type Parameter | Default type | | ------ | ------ | | `T` | [`OvokCmsDocument`](#ovokcmsdocument) | #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `docs` | `T`[] | Documents on this page. | | `hasNextPage` | `boolean` | `true` when a later page exists. | | `hasPrevPage` | `boolean` | `true` when an earlier page exists. | | `limit` | `number` | Page size used. | | `nextPage` | `number` \| `null` | `null` on the last page. | | `page` | `number` | 1-based number of this page. | | `pagingCounter` | `number` | The 1-based position of this page's first document in the whole list. | | `prevPage` | `number` \| `null` | `null` on the first page. | | `totalDocs` | `number` | Number of documents in the whole list. | | `totalPages` | `number` | Number of pages in the whole list. | *** ### OvokTranslations [#ovoktranslations] ```ts type OvokTranslations = object; ``` The `translations` collection: a tree per group, named by the document's slug ("sign-in"). #### Index Signature [#index-signature] ```ts [group: string]: OvokTranslationTree ``` *** ### OvokTranslationTree [#ovoktranslationtree] ```ts type OvokTranslationTree = object; ``` Translation keys, nested at their dots, down to the text in one locale. #### Index Signature [#index-signature-1] ```ts [key: string]: string | OvokTranslationTree ``` # consent Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/consent ## Classes [#classes] ### LegalConsentResource [#legalconsentresource] Terms-and-conditions consent of the signed-in user. #### Methods [#methods] ##### retrieve() [#retrieve] ```ts retrieve(options?): Promise; ``` Reads the current legal consent. Calls `GET v1/me/consent/legal`. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`LegalConsentResponse`](#legalconsentresponse)\> ##### set() [#set] ```ts set(accepted, options?): Promise; ``` Records whether the user accepts legal consent. Calls `POST v1/me/consent/legal`. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `accepted` | `boolean` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<[`LegalConsentResponse`](#legalconsentresponse)\> *** ### MedicalConsentResource [#medicalconsentresource] Medical-notification consent of the signed-in user. #### Methods [#methods-1] ##### retrieve() [#retrieve-1] ```ts retrieve(options?): Promise; ``` Reads the current medical consent. Calls `GET v1/me/consent/medical`. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<[`MedicalConsentResponse`](#medicalconsentresponse)\> ##### set() [#set-1] ```ts set(accepted, options?): Promise; ``` Records whether the user accepts medical consent. Calls `POST v1/me/consent/medical`. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `accepted` | `boolean` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<[`MedicalConsentResponse`](#medicalconsentresponse)\> ## Interfaces [#interfaces] ### ConsentResource [#consentresource] Legal and medical consent, and consent signatures. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `legal` | `readonly` | [`LegalConsentResource`](#legalconsentresource) | Terms-and-conditions consent. | | `medical` | `readonly` | [`MedicalConsentResource`](#medicalconsentresource) | Medical-notification consent. | #### Methods [#methods-2] ##### requestSignature() [#requestsignature] ```ts requestSignature(consentId, options?): Promise; ``` Requests a signature for a consent. Calls `POST consent/signature/{consentId}`. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `consentId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<[`OvokConsentSignatureResponse`](#ovokconsentsignatureresponse)\> ## Type Aliases [#type-aliases] ### LegalConsentRecord [#legalconsentrecord] ```ts type LegalConsentRecord = object; ``` Stored terms-and-conditions consent of a user. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `acceptedAt?` | `string` \| `null` | ISO 8601 time the user accepted. | | `consentId` | `string` | Id of the consent record. | | `revokedAt?` | `string` \| `null` | ISO 8601 time the consent was revoked. | | `revokedReason?` | `"tos-updated"` \| `"withdrawn"` \| `null` | Why it was revoked: `tos-updated` when the terms changed, `withdrawn` when the user withdrew. | | `status` | `"active"` \| `"revoked"` | `active` while accepted, `revoked` once withdrawn or superseded. | | `termsUpdatedAt?` | `string` \| `null` | ISO 8601 time the terms last changed. | | `termsUrl?` | `string` \| `null` | URL of the terms version the consent refers to. | *** ### LegalConsentResponse [#legalconsentresponse] ```ts type LegalConsentResponse = object; ``` Response of the legal consent routes. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `legal` | [`LegalConsentRecord`](#legalconsentrecord) \| `null` | The user's consent, or `null` when none exists. | *** ### LegalConsentUpdate [#legalconsentupdate] ```ts type LegalConsentUpdate = object; ``` Request body that accepts or withdraws the legal consent. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `termsAndConditionsConsent` | `boolean` | `true` to accept, `false` to withdraw. | *** ### MedicalConsentRecord [#medicalconsentrecord] ```ts type MedicalConsentRecord = object; ``` Stored medical-notifications consent of a user. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `acceptedAt` | `string` \| `null` | ISO 8601 time the user accepted, or `null`. | | `consentId` | `string` | Id of the consent record. | *** ### MedicalConsentResponse [#medicalconsentresponse] ```ts type MedicalConsentResponse = object; ``` Response of the medical consent routes. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `medical` | [`MedicalConsentRecord`](#medicalconsentrecord) \| `null` | The user's consent, or `null` when none exists. | *** ### MedicalConsentUpdate [#medicalconsentupdate] ```ts type MedicalConsentUpdate = object; ``` Request body that grants or withdraws the medical consent. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `medicalSettingsNotificationsConsent` | `boolean` | `true` to grant, `false` to withdraw. | *** ### OvokConsentSignatureResponse [#ovokconsentsignatureresponse] ```ts type OvokConsentSignatureResponse = object; ``` Metadata of the signed consent PDF. #### Properties [#properties-7] | Property | Type | Description | | ------ | ------ | ------ | | `author` | `string` | PDF author. | | `documentId` | `string` | Id of the stored document. | | `email` | `string` | Email address the PDF was sent to. | | `numberOfPages` | `number` | Number of pages in the PDF. | | `subject` | `string` | PDF subject. | | `title` | `string` | PDF title. | ## Functions [#functions] ### needsLegalConsentReacceptance() [#needslegalconsentreacceptance] ```ts function needsLegalConsentReacceptance(legal): boolean; ``` Tells whether the user must accept the terms again: no consent yet, or it was revoked because the terms changed. #### Parameters [#parameters-5] | Parameter | Type | Description | | ------ | ------ | ------ | | `legal` | [`LegalConsentRecord`](#legalconsentrecord) \| `null` \| `undefined` | Consent record from `getLegalConsent`. | #### Returns [#returns-5] `boolean` # content Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/content ## Interfaces [#interfaces] ### ContentResource [#contentresource] Managed content items, grouped by type and language. Calls routes under `cms`. #### Methods [#methods] ##### copyAllFromParent() [#copyallfromparent] ```ts copyAllFromParent( type, language, options? ): Promise; ``` Copies every item of a type and language from the parent project. Calls `POST cms/{type}/{language}/copy-from-parent-project`. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `type` | `string` | | `language` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`CopyFromParentResult`](#copyfromparentresult)\> ##### copyFromParent() [#copyfromparent] ```ts copyFromParent( type, language, key, options? ): Promise; ``` Copies one item from the parent project. Calls `POST cms/{type}/{language}/{key}/copy-from-parent-project`. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `type` | `string` | | `language` | `string` | | `key` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<[`CopyFromParentResult`](#copyfromparentresult)\> ##### create() [#create] ```ts create( type, language, body, options? ): Promise; ``` Creates a content item. Calls `POST cms/{type}/{language}`. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `type` | `string` | | `language` | `string` | | `body` | [`OvokContentBody`](#ovokcontentbody) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<[`OvokContent`](#ovokcontent)\> ##### delete() [#delete] ```ts delete( type, language, key, options? ): Promise; ``` Deletes a content item. Calls `DELETE cms/{type}/{language}/{key}`. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `type` | `string` | | `language` | `string` | | `key` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<`void`\> ##### map() [#map] ```ts map( type, language, params?, options? ): Promise; ``` Pairs each default-language item with its `language` translation. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `type` | `string` | | `language` | `string` | | `params?` | [`OvokContentQuery`](#ovokcontentquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<[`OvokMappedContentSearchResponse`](#ovokmappedcontentsearchresponse)\> ##### retrieve() [#retrieve] ```ts retrieve( type, language, key, options? ): Promise; ``` Reads one content item. Calls `GET cms/{type}/{language}/{key}`. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `type` | `string` | | `language` | `string` | | `key` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-5] `Promise`\<[`OvokContent`](#ovokcontent)\> ##### search() [#search] ```ts search( type, language, params?, options? ): Promise; ``` Searches content of a type in a language. Calls `GET cms/{type}/{language}`. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `type` | `string` | | `language` | `string` | | `params?` | [`OvokContentQuery`](#ovokcontentquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-6] `Promise`\<[`OvokContentSearchResponse`](#ovokcontentsearchresponse)\> ##### update() [#update] ```ts update( type, language, key, body, options? ): Promise; ``` Replaces a content item. Calls `PUT cms/{type}/{language}/{key}`. ###### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `type` | `string` | | `language` | `string` | | `key` | `string` | | `body` | [`OvokContentBody`](#ovokcontentbody) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-7] `Promise`\<[`OvokContent`](#ovokcontent)\> ## Type Aliases [#type-aliases] ### CopyFromParentResult [#copyfromparentresult] ```ts type CopyFromParentResult = object; ``` Result of copying content from the parent project. #### Properties [#properties] | Property | Type | Description | | ------ | ------ | ------ | | `success` | `boolean` | Whether the copy succeeded. | *** ### OvokContent [#ovokcontent] ```ts type OvokContent = object; ``` A CMS content item. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `author` | `object` | Who wrote the content. | | `author.display?` | `string` | Display name of the author. | | `author.reference` | `string` | Reference to the author, e.g. `Practitioner/123`. | | `category?` | `string`[] | Categories of the content. | | `code?` | `string` | Code the content is tagged with. | | `date` | `string` | ISO 8601 date of the content. | | `id?` | `string` | Content id. | | `key` | `string` | Key that identifies the item within its type and language. | | `language` | `string` | Language code of the content. | | `projectId?` | `string` | Id of the project that owns the content. | | `section?` | [`OvokContentSection`](#ovokcontentsection)[] | Sections that make up the body. | | `title` | `string` | Content title. | | `type` | [`OvokContentType`](#ovokcontenttype) | Kind of content. | *** ### OvokContentBody [#ovokcontentbody] ```ts type OvokContentBody = Pick; ``` Fields accepted when creating or updating a content item. *** ### OvokContentQuery [#ovokcontentquery] ```ts type OvokContentQuery = object; ``` Filters and paging of a content search. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `_count?` | `number` | Page size. | | `_offset?` | `number` | Number of results to skip. | | `code?` | `string` | Only content with this code. | | `search?` | `string` | Free-text search. | *** ### OvokContentSearchResponse [#ovokcontentsearchresponse] ```ts type OvokContentSearchResponse = object; ``` A page of content items. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `resources` | [`OvokContent`](#ovokcontent)[] | Items on this page. | | `total` | `number` | Number of matching items. | *** ### OvokContentSection [#ovokcontentsection] ```ts type OvokContentSection = object; ``` One section of a content item. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `code?` | `string`[] | Codes the section is tagged with. | | `extension?` | `Record`\<`string`, `string`\> | Extra key/value fields of the section. | | `text?` | `string` | Section text. | | `title?` | `string` | Section heading. | *** ### OvokContentType [#ovokcontenttype] ```ts type OvokContentType = "blog" | "video" | "audio" | "template" | "export-template"; ``` Kind of CMS content. *** ### OvokMappedContent [#ovokmappedcontent] ```ts type OvokMappedContent = object; ``` A content item paired with its counterpart in the parent project. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `source?` | [`OvokContent`](#ovokcontent) | Content of the parent project. | | `target?` | [`OvokContent`](#ovokcontent) | Content of this project. | *** ### OvokMappedContentSearchResponse [#ovokmappedcontentsearchresponse] ```ts type OvokMappedContentSearchResponse = object; ``` A page of mapped content pairs. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `resources` | [`OvokMappedContent`](#ovokmappedcontent)[] | Pairs on this page. | | `total` | `number` | Number of matching pairs. | *** ### OvokTranslationRequest [#ovoktranslationrequest] ```ts type OvokTranslationRequest = object; ``` Texts to translate. #### Properties [#properties-7] | Property | Type | Description | | ------ | ------ | ------ | | `sourceLanguage` | `string` | Language code of the texts. | | `targetLanguage` | `string` | Language code to translate into. | | `text` | `string`[] | Texts to translate. | *** ### OvokTranslationResponse [#ovoktranslationresponse] ```ts type OvokTranslationResponse = OvokTranslationRequest; ``` Translated texts, in the shape of the request. # documents Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/documents ## Interfaces [#interfaces] ### DocumentsResource [#documentsresource] Uploaded documents and their download URLs. Calls routes under `document`. #### Methods [#methods] ##### createUpload() [#createupload] ```ts createUpload(body, options?): Promise; ``` Registers a document upload. Calls `POST document`. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `body` | [`OvokDocumentUploadRequest`](#ovokdocumentuploadrequest) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`OvokDocumentFile`](#ovokdocumentfile)\> ##### delete() [#delete] ```ts delete(documentId, options?): Promise; ``` Deletes a document. Calls `DELETE document/{documentId}`. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `documentId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<[`DeletedDocument`](#deleteddocument)\> ##### downloadUrl() [#downloadurl] ```ts downloadUrl(documentId, params?): string; ``` The signed-in route: fetched with the bearer, it redirects to a signed download URL. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `documentId` | `string` | | `params?` | [`DocumentDownloadParams`](#documentdownloadparams) | ###### Returns [#returns-2] `string` ##### list() [#list] ```ts list(params?, options?): Promise; ``` Lists documents. Calls `GET document`. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `params?` | [`OvokDocumentSearchQuery`](#ovokdocumentsearchquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<[`OvokDocumentSearchResponse`](#ovokdocumentsearchresponse)\> ##### publicDownloadUrl() [#publicdownloadurl] ```ts publicDownloadUrl(publicToken, params?): string; ``` Needs no bearer, so it fits an image, download or media element. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `publicToken` | `string` | | `params?` | [`DocumentDownloadParams`](#documentdownloadparams) | ###### Returns [#returns-4] `string` ##### replaceUpload() [#replaceupload] ```ts replaceUpload( documentId, body, options? ): Promise; ``` Replaces the file of a document. Calls `POST document/{documentId}`. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `documentId` | `string` | | `body` | [`OvokDocumentReplacement`](#ovokdocumentreplacement) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-5] `Promise`\<[`OvokDocumentFile`](#ovokdocumentfile)\> ##### updateMetadata() [#updatemetadata] ```ts updateMetadata( documentId, body, options? ): Promise; ``` Updates a document's metadata. Calls `PATCH document/{documentId}`. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `documentId` | `string` | | `body` | [`OvokDocumentMetadataUpdate`](#ovokdocumentmetadataupdate) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-6] `Promise`\<[`OvokDocumentFile`](#ovokdocumentfile)\> ## Type Aliases [#type-aliases] ### DeletedDocument [#deleteddocument] ```ts type DeletedDocument = object; ``` Confirmation returned after a document is deleted. #### Properties [#properties] | Property | Type | Description | | ------ | ------ | ------ | | `message` | `string` | Server confirmation message. | *** ### DocumentDownloadParams [#documentdownloadparams] ```ts type DocumentDownloadParams = object; ``` Optional image resizing for a download URL. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `fit?` | `string` | How the image fits the target size. | | `height?` | `string` \| `number` | Target height for an image download. | | `width?` | `string` \| `number` | Target width for an image download. | *** ### OvokDocumentFile [#ovokdocumentfile] ```ts type OvokDocumentFile = object; ``` A stored document. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `author?` | `object` | Who uploaded the document. | | `author.display?` | `string` | Display name of the author. | | `author.reference?` | `string` | Reference to the author, e.g. `Practitioner/123`. | | `contentType?` | `string` | MIME type of the file. | | `fileName?` | `string` | Name of the file. | | `id` | `string` | Document id. | | `meta?` | `object` | Resource metadata. | | `meta.lastUpdated` | `string` | ISO 8601 time of the last change. | | `publicToken?` | `string` | Token for the public download URL, when the document is public. | | `uploadOptions?` | [`OvokDocumentUploadOptions`](#ovokdocumentuploadoptions) | Upload target, present when the file still has to be uploaded. | *** ### OvokDocumentMetadataUpdate [#ovokdocumentmetadataupdate] ```ts type OvokDocumentMetadataUpdate = object; ``` Fields of a document that can be changed. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `contentType?` | `string` | New MIME type. | | `fileName?` | `string` | New file name. | | `isPublic?` | `boolean` | New visibility. | *** ### OvokDocumentReplacement [#ovokdocumentreplacement] ```ts type OvokDocumentReplacement = object; ``` Request body that replaces a document's file. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `contentType` | `string` | MIME type of the new file. | | `fileName` | `string` | Name of the new file. | | `isPublic?` | `boolean` | Whether the document is reachable through a public token. | *** ### OvokDocumentSearchQuery [#ovokdocumentsearchquery] ```ts type OvokDocumentSearchQuery = object; ``` Paging and sorting of a document search. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `_count?` | `number` | Page size. | | `_offset?` | `number` | Number of results to skip. | | `_sort?` | `string` | Field to sort by; prefix `-` for descending. | *** ### OvokDocumentSearchResponse [#ovokdocumentsearchresponse] ```ts type OvokDocumentSearchResponse = object; ``` A page of documents. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `resources` | [`OvokDocumentFile`](#ovokdocumentfile)[] | Documents on this page. | | `total` | `number` | Number of matching documents. | *** ### OvokDocumentUploadOptions [#ovokdocumentuploadoptions] ```ts type OvokDocumentUploadOptions = object; ``` Pre-signed upload target for a document's file. #### Properties [#properties-7] | Property | Type | Description | | ------ | ------ | ------ | | `fields` | `Record`\<`string`, `string`\> | Form fields to send with the file. | | `url` | `string` | URL to post the file to. | *** ### OvokDocumentUploadRequest [#ovokdocumentuploadrequest] ```ts type OvokDocumentUploadRequest = object; ``` Request body that registers a new document. #### Properties [#properties-8] | Property | Type | Description | | ------ | ------ | ------ | | `contentType` | `string` | MIME type of the file. | | `fileName` | `string` | Name of the file. | | `isPublic?` | `boolean` | Whether the document is reachable through a public token. | # email Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/email ## Classes [#classes] ### EmailTemplatesResource [#emailtemplatesresource] Email templates of the project. #### Methods [#methods] ##### list() [#list] ```ts list(options?): Promise; ``` Lists the email templates. Calls `GET v1/email/templates`. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`OvokEmailTemplates`](#ovokemailtemplates)\> ## Interfaces [#interfaces] ### EmailResource [#emailresource] Email settings of the project. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `templates` | `readonly` | [`EmailTemplatesResource`](#emailtemplatesresource) | Email templates. | ## Type Aliases [#type-aliases] ### OvokEmailAudience [#ovokemailaudience] ```ts type OvokEmailAudience = "patient" | "practitioner"; ``` Who an email template is sent to. *** ### OvokEmailTemplate [#ovokemailtemplate] ```ts type OvokEmailTemplate = object; ``` An email template. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `audience` | [`OvokEmailAudience`](#ovokemailaudience) | Recipient kind of the template. | | `example` | `Record`\<`string`, `unknown`\> | Example parameter values. | | `name` | `string` | Template name. | | `params` | [`OvokEmailTemplateParam`](#ovokemailtemplateparam)[] | Parameters the template accepts. | | `syntax` | `object` | Placeholder syntax of the template for each email provider. | | `syntax.brevo` | `string` | Syntax for Brevo. | | `syntax.resend` | `string` | Syntax for Resend. | | `syntax.sendgrid` | `string` | Syntax for SendGrid. | | `syntax.smtp` | `string` | Syntax for SMTP. | *** ### OvokEmailTemplateParam [#ovokemailtemplateparam] ```ts type OvokEmailTemplateParam = object; ``` A parameter a template accepts. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `name` | `string` | Parameter name. | | `nullable` | `boolean` | Whether the parameter may be null. | | `type` | `string` | Parameter type. | *** ### OvokEmailTemplates [#ovokemailtemplates] ```ts type OvokEmailTemplates = object; ``` Response of `getEmailTemplates`. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `templates` | [`OvokEmailTemplate`](#ovokemailtemplate)[] | The email templates. | # Errors Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/errors ## Classes [#classes] ### OvokAccountError [#ovokaccounterror] A saved account is missing or its session expired. #### Extends [#extends] - `Error` #### Constructors [#constructors] ##### Constructor [#constructor] ```ts new OvokAccountError(code): OvokAccountError; ``` ###### Parameters [#parameters] | Parameter | Type | Description | | ------ | ------ | ------ | | `code` | [`OvokAccountErrorCode`](#ovokaccounterrorcode) | `account_not_found` when no saved account matches, `account_expired` when its session ended. | ###### Returns [#returns] [`OvokAccountError`](#ovokaccounterror) ###### Overrides [#overrides] `Error.constructor` #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `code` | `readonly` | [`OvokAccountErrorCode`](#ovokaccounterrorcode) | `account_not_found` when no saved account matches, `account_expired` when its session ended. | *** ### OvokAuthenticationError [#ovokauthenticationerror] Credentials were missing or invalid (401). #### Extends [#extends-1] - [`OvokError`](#ovokerror) #### Constructors [#constructors-1] ##### Constructor [#constructor-1] ```ts new OvokAuthenticationError(details, cause?): OvokAuthenticationError; ``` Creates an error from normalized details. ###### Parameters [#parameters-1] | Parameter | Type | Description | | ------ | ------ | ------ | | `details` | [`OvokErrorDetails`](#ovokerrordetails) | Normalized failure description. | | `cause?` | `unknown` | Underlying error. | ###### Returns [#returns-1] [`OvokAuthenticationError`](#ovokauthenticationerror) ###### Inherited from [#inherited-from] [`OvokError`](#ovokerror).[`constructor`](#constructor-5) #### Properties [#properties-1] | Property | Modifier | Type | Description | Inherited from | | ------ | ------ | ------ | ------ | ------ | | `cause` | `readonly` | `unknown` | Underlying error, if any. | [`OvokError`](#ovokerror).[`cause`](#property-cause-4) | | `code` | `readonly` | `string` \| `null` | Machine-readable error code from the API, if any. | [`OvokError`](#ovokerror).[`code`](#property-code-5) | | `fieldErrors` | `readonly` | [`ValidationError`](/web-sdk/core/reference/core/fhir#validationerror)[] | Per-field validation failures. | [`OvokError`](#ovokerror).[`fieldErrors`](#property-fielderrors-4) | | `requestId` | `readonly` | `string` \| `null` | Request id, for support. | [`OvokError`](#ovokerror).[`requestId`](#property-requestid-4) | | `retryAfterMs` | `readonly` | `number` \| `null` | Milliseconds to wait before retrying, from `Retry-After`. | [`OvokError`](#ovokerror).[`retryAfterMs`](#property-retryafterms-4) | | `status` | `readonly` | `number` \| `null` | HTTP status, or `null` when there was no response. | [`OvokError`](#ovokerror).[`status`](#property-status-4) | | `traceId` | `readonly` | `string` \| `null` | Trace id of the request, for support. | [`OvokError`](#ovokerror).[`traceId`](#property-traceid-4) | | `type` | `readonly` | `string` \| `null` | Error type from the API, if any. | [`OvokError`](#ovokerror).[`type`](#property-type-4) | *** ### OvokConfigError [#ovokconfigerror] The client is misconfigured. #### Extends [#extends-2] - [`OvokError`](#ovokerror) #### Constructors [#constructors-2] ##### Constructor [#constructor-2] ```ts new OvokConfigError(details, cause?): OvokConfigError; ``` Creates an error from normalized details. ###### Parameters [#parameters-2] | Parameter | Type | Description | | ------ | ------ | ------ | | `details` | [`OvokErrorDetails`](#ovokerrordetails) | Normalized failure description. | | `cause?` | `unknown` | Underlying error. | ###### Returns [#returns-2] [`OvokConfigError`](#ovokconfigerror) ###### Inherited from [#inherited-from-1] [`OvokError`](#ovokerror).[`constructor`](#constructor-5) #### Properties [#properties-2] | Property | Modifier | Type | Description | Inherited from | | ------ | ------ | ------ | ------ | ------ | | `cause` | `readonly` | `unknown` | Underlying error, if any. | [`OvokError`](#ovokerror).[`cause`](#property-cause-4) | | `code` | `readonly` | `string` \| `null` | Machine-readable error code from the API, if any. | [`OvokError`](#ovokerror).[`code`](#property-code-5) | | `fieldErrors` | `readonly` | [`ValidationError`](/web-sdk/core/reference/core/fhir#validationerror)[] | Per-field validation failures. | [`OvokError`](#ovokerror).[`fieldErrors`](#property-fielderrors-4) | | `requestId` | `readonly` | `string` \| `null` | Request id, for support. | [`OvokError`](#ovokerror).[`requestId`](#property-requestid-4) | | `retryAfterMs` | `readonly` | `number` \| `null` | Milliseconds to wait before retrying, from `Retry-After`. | [`OvokError`](#ovokerror).[`retryAfterMs`](#property-retryafterms-4) | | `status` | `readonly` | `number` \| `null` | HTTP status, or `null` when there was no response. | [`OvokError`](#ovokerror).[`status`](#property-status-4) | | `traceId` | `readonly` | `string` \| `null` | Trace id of the request, for support. | [`OvokError`](#ovokerror).[`traceId`](#property-traceid-4) | | `type` | `readonly` | `string` \| `null` | Error type from the API, if any. | [`OvokError`](#ovokerror).[`type`](#property-type-4) | *** ### OvokConflictError [#ovokconflicterror] The request conflicts with the current state (409). #### Extends [#extends-3] - [`OvokError`](#ovokerror) #### Constructors [#constructors-3] ##### Constructor [#constructor-3] ```ts new OvokConflictError(details, cause?): OvokConflictError; ``` Creates an error from normalized details. ###### Parameters [#parameters-3] | Parameter | Type | Description | | ------ | ------ | ------ | | `details` | [`OvokErrorDetails`](#ovokerrordetails) | Normalized failure description. | | `cause?` | `unknown` | Underlying error. | ###### Returns [#returns-3] [`OvokConflictError`](#ovokconflicterror) ###### Inherited from [#inherited-from-2] [`OvokError`](#ovokerror).[`constructor`](#constructor-5) #### Properties [#properties-3] | Property | Modifier | Type | Description | Inherited from | | ------ | ------ | ------ | ------ | ------ | | `cause` | `readonly` | `unknown` | Underlying error, if any. | [`OvokError`](#ovokerror).[`cause`](#property-cause-4) | | `code` | `readonly` | `string` \| `null` | Machine-readable error code from the API, if any. | [`OvokError`](#ovokerror).[`code`](#property-code-5) | | `fieldErrors` | `readonly` | [`ValidationError`](/web-sdk/core/reference/core/fhir#validationerror)[] | Per-field validation failures. | [`OvokError`](#ovokerror).[`fieldErrors`](#property-fielderrors-4) | | `requestId` | `readonly` | `string` \| `null` | Request id, for support. | [`OvokError`](#ovokerror).[`requestId`](#property-requestid-4) | | `retryAfterMs` | `readonly` | `number` \| `null` | Milliseconds to wait before retrying, from `Retry-After`. | [`OvokError`](#ovokerror).[`retryAfterMs`](#property-retryafterms-4) | | `status` | `readonly` | `number` \| `null` | HTTP status, or `null` when there was no response. | [`OvokError`](#ovokerror).[`status`](#property-status-4) | | `traceId` | `readonly` | `string` \| `null` | Trace id of the request, for support. | [`OvokError`](#ovokerror).[`traceId`](#property-traceid-4) | | `type` | `readonly` | `string` \| `null` | Error type from the API, if any. | [`OvokError`](#ovokerror).[`type`](#property-type-4) | *** ### OvokConnectionError [#ovokconnectionerror] The server could not be reached. #### Extends [#extends-4] - [`OvokError`](#ovokerror) #### Constructors [#constructors-4] ##### Constructor [#constructor-4] ```ts new OvokConnectionError(details, cause?): OvokConnectionError; ``` Creates an error from normalized details. ###### Parameters [#parameters-4] | Parameter | Type | Description | | ------ | ------ | ------ | | `details` | [`OvokErrorDetails`](#ovokerrordetails) | Normalized failure description. | | `cause?` | `unknown` | Underlying error. | ###### Returns [#returns-4] [`OvokConnectionError`](#ovokconnectionerror) ###### Inherited from [#inherited-from-3] [`OvokError`](#ovokerror).[`constructor`](#constructor-5) #### Properties [#properties-4] | Property | Modifier | Type | Description | Inherited from | | ------ | ------ | ------ | ------ | ------ | | `cause` | `readonly` | `unknown` | Underlying error, if any. | [`OvokError`](#ovokerror).[`cause`](#property-cause-4) | | `code` | `readonly` | `string` \| `null` | Machine-readable error code from the API, if any. | [`OvokError`](#ovokerror).[`code`](#property-code-5) | | `fieldErrors` | `readonly` | [`ValidationError`](/web-sdk/core/reference/core/fhir#validationerror)[] | Per-field validation failures. | [`OvokError`](#ovokerror).[`fieldErrors`](#property-fielderrors-4) | | `requestId` | `readonly` | `string` \| `null` | Request id, for support. | [`OvokError`](#ovokerror).[`requestId`](#property-requestid-4) | | `retryAfterMs` | `readonly` | `number` \| `null` | Milliseconds to wait before retrying, from `Retry-After`. | [`OvokError`](#ovokerror).[`retryAfterMs`](#property-retryafterms-4) | | `status` | `readonly` | `number` \| `null` | HTTP status, or `null` when there was no response. | [`OvokError`](#ovokerror).[`status`](#property-status-4) | | `traceId` | `readonly` | `string` \| `null` | Trace id of the request, for support. | [`OvokError`](#ovokerror).[`traceId`](#property-traceid-4) | | `type` | `readonly` | `string` \| `null` | Error type from the API, if any. | [`OvokError`](#ovokerror).[`type`](#property-type-4) | *** ### OvokError [#ovokerror] Base class of every error the `next` clients throw; the subclass reflects the HTTP status. #### Example [#example] ```ts try { await request(); } catch (error) { if (error instanceof OvokNotFoundError) { showMissing(); } } ``` #### Extends [#extends-5] - `Error` #### Extended by [#extended-by] - [`OvokAuthenticationError`](#ovokauthenticationerror) - [`OvokConfigError`](#ovokconfigerror) - [`OvokConflictError`](#ovokconflicterror) - [`OvokConnectionError`](#ovokconnectionerror) - [`OvokNotFoundError`](#ovoknotfounderror) - [`OvokPermissionError`](#ovokpermissionerror) - [`OvokRateLimitError`](#ovokratelimiterror) - [`OvokServiceError`](#ovokserviceerror) - [`OvokValidationError`](#ovokvalidationerror) #### Constructors [#constructors-5] ##### Constructor [#constructor-5] ```ts new OvokError(details, cause?): OvokError; ``` Creates an error from normalized details. ###### Parameters [#parameters-5] | Parameter | Type | Description | | ------ | ------ | ------ | | `details` | [`OvokErrorDetails`](#ovokerrordetails) | Normalized failure description. | | `cause?` | `unknown` | Underlying error. | ###### Returns [#returns-5] [`OvokError`](#ovokerror) ###### Overrides [#overrides-1] `Error.constructor` #### Properties [#properties-5] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `cause` | `readonly` | `unknown` | Underlying error, if any. | | `code` | `readonly` | `string` \| `null` | Machine-readable error code from the API, if any. | | `fieldErrors` | `readonly` | [`ValidationError`](/web-sdk/core/reference/core/fhir#validationerror)[] | Per-field validation failures. | | `requestId` | `readonly` | `string` \| `null` | Request id, for support. | | `retryAfterMs` | `readonly` | `number` \| `null` | Milliseconds to wait before retrying, from `Retry-After`. | | `status` | `readonly` | `number` \| `null` | HTTP status, or `null` when there was no response. | | `traceId` | `readonly` | `string` \| `null` | Trace id of the request, for support. | | `type` | `readonly` | `string` \| `null` | Error type from the API, if any. | *** ### OvokNotFoundError [#ovoknotfounderror] The resource does not exist (404). #### Extends [#extends-6] - [`OvokError`](#ovokerror) #### Constructors [#constructors-6] ##### Constructor [#constructor-6] ```ts new OvokNotFoundError(details, cause?): OvokNotFoundError; ``` Creates an error from normalized details. ###### Parameters [#parameters-6] | Parameter | Type | Description | | ------ | ------ | ------ | | `details` | [`OvokErrorDetails`](#ovokerrordetails) | Normalized failure description. | | `cause?` | `unknown` | Underlying error. | ###### Returns [#returns-6] [`OvokNotFoundError`](#ovoknotfounderror) ###### Inherited from [#inherited-from-4] [`OvokError`](#ovokerror).[`constructor`](#constructor-5) #### Properties [#properties-6] | Property | Modifier | Type | Description | Inherited from | | ------ | ------ | ------ | ------ | ------ | | `cause` | `readonly` | `unknown` | Underlying error, if any. | [`OvokError`](#ovokerror).[`cause`](#property-cause-4) | | `code` | `readonly` | `string` \| `null` | Machine-readable error code from the API, if any. | [`OvokError`](#ovokerror).[`code`](#property-code-5) | | `fieldErrors` | `readonly` | [`ValidationError`](/web-sdk/core/reference/core/fhir#validationerror)[] | Per-field validation failures. | [`OvokError`](#ovokerror).[`fieldErrors`](#property-fielderrors-4) | | `requestId` | `readonly` | `string` \| `null` | Request id, for support. | [`OvokError`](#ovokerror).[`requestId`](#property-requestid-4) | | `retryAfterMs` | `readonly` | `number` \| `null` | Milliseconds to wait before retrying, from `Retry-After`. | [`OvokError`](#ovokerror).[`retryAfterMs`](#property-retryafterms-4) | | `status` | `readonly` | `number` \| `null` | HTTP status, or `null` when there was no response. | [`OvokError`](#ovokerror).[`status`](#property-status-4) | | `traceId` | `readonly` | `string` \| `null` | Trace id of the request, for support. | [`OvokError`](#ovokerror).[`traceId`](#property-traceid-4) | | `type` | `readonly` | `string` \| `null` | Error type from the API, if any. | [`OvokError`](#ovokerror).[`type`](#property-type-4) | *** ### OvokPermissionError [#ovokpermissionerror] The caller is signed in but not allowed (403). #### Extends [#extends-7] - [`OvokError`](#ovokerror) #### Constructors [#constructors-7] ##### Constructor [#constructor-7] ```ts new OvokPermissionError(details, cause?): OvokPermissionError; ``` Creates an error from normalized details. ###### Parameters [#parameters-7] | Parameter | Type | Description | | ------ | ------ | ------ | | `details` | [`OvokErrorDetails`](#ovokerrordetails) | Normalized failure description. | | `cause?` | `unknown` | Underlying error. | ###### Returns [#returns-7] [`OvokPermissionError`](#ovokpermissionerror) ###### Inherited from [#inherited-from-5] [`OvokError`](#ovokerror).[`constructor`](#constructor-5) #### Properties [#properties-7] | Property | Modifier | Type | Description | Inherited from | | ------ | ------ | ------ | ------ | ------ | | `cause` | `readonly` | `unknown` | Underlying error, if any. | [`OvokError`](#ovokerror).[`cause`](#property-cause-4) | | `code` | `readonly` | `string` \| `null` | Machine-readable error code from the API, if any. | [`OvokError`](#ovokerror).[`code`](#property-code-5) | | `fieldErrors` | `readonly` | [`ValidationError`](/web-sdk/core/reference/core/fhir#validationerror)[] | Per-field validation failures. | [`OvokError`](#ovokerror).[`fieldErrors`](#property-fielderrors-4) | | `requestId` | `readonly` | `string` \| `null` | Request id, for support. | [`OvokError`](#ovokerror).[`requestId`](#property-requestid-4) | | `retryAfterMs` | `readonly` | `number` \| `null` | Milliseconds to wait before retrying, from `Retry-After`. | [`OvokError`](#ovokerror).[`retryAfterMs`](#property-retryafterms-4) | | `status` | `readonly` | `number` \| `null` | HTTP status, or `null` when there was no response. | [`OvokError`](#ovokerror).[`status`](#property-status-4) | | `traceId` | `readonly` | `string` \| `null` | Trace id of the request, for support. | [`OvokError`](#ovokerror).[`traceId`](#property-traceid-4) | | `type` | `readonly` | `string` \| `null` | Error type from the API, if any. | [`OvokError`](#ovokerror).[`type`](#property-type-4) | *** ### OvokRateLimitError [#ovokratelimiterror] The caller was rate limited (429); see `retryAfterMs`. #### Extends [#extends-8] - [`OvokError`](#ovokerror) #### Constructors [#constructors-8] ##### Constructor [#constructor-8] ```ts new OvokRateLimitError(details, cause?): OvokRateLimitError; ``` Creates an error from normalized details. ###### Parameters [#parameters-8] | Parameter | Type | Description | | ------ | ------ | ------ | | `details` | [`OvokErrorDetails`](#ovokerrordetails) | Normalized failure description. | | `cause?` | `unknown` | Underlying error. | ###### Returns [#returns-8] [`OvokRateLimitError`](#ovokratelimiterror) ###### Inherited from [#inherited-from-6] [`OvokError`](#ovokerror).[`constructor`](#constructor-5) #### Properties [#properties-8] | Property | Modifier | Type | Description | Inherited from | | ------ | ------ | ------ | ------ | ------ | | `cause` | `readonly` | `unknown` | Underlying error, if any. | [`OvokError`](#ovokerror).[`cause`](#property-cause-4) | | `code` | `readonly` | `string` \| `null` | Machine-readable error code from the API, if any. | [`OvokError`](#ovokerror).[`code`](#property-code-5) | | `fieldErrors` | `readonly` | [`ValidationError`](/web-sdk/core/reference/core/fhir#validationerror)[] | Per-field validation failures. | [`OvokError`](#ovokerror).[`fieldErrors`](#property-fielderrors-4) | | `requestId` | `readonly` | `string` \| `null` | Request id, for support. | [`OvokError`](#ovokerror).[`requestId`](#property-requestid-4) | | `retryAfterMs` | `readonly` | `number` \| `null` | Milliseconds to wait before retrying, from `Retry-After`. | [`OvokError`](#ovokerror).[`retryAfterMs`](#property-retryafterms-4) | | `status` | `readonly` | `number` \| `null` | HTTP status, or `null` when there was no response. | [`OvokError`](#ovokerror).[`status`](#property-status-4) | | `traceId` | `readonly` | `string` \| `null` | Trace id of the request, for support. | [`OvokError`](#ovokerror).[`traceId`](#property-traceid-4) | | `type` | `readonly` | `string` \| `null` | Error type from the API, if any. | [`OvokError`](#ovokerror).[`type`](#property-type-4) | *** ### OvokServiceError [#ovokserviceerror] The server failed (5xx). #### Extends [#extends-9] - [`OvokError`](#ovokerror) #### Constructors [#constructors-9] ##### Constructor [#constructor-9] ```ts new OvokServiceError(details, cause?): OvokServiceError; ``` Creates an error from normalized details. ###### Parameters [#parameters-9] | Parameter | Type | Description | | ------ | ------ | ------ | | `details` | [`OvokErrorDetails`](#ovokerrordetails) | Normalized failure description. | | `cause?` | `unknown` | Underlying error. | ###### Returns [#returns-9] [`OvokServiceError`](#ovokserviceerror) ###### Inherited from [#inherited-from-7] [`OvokError`](#ovokerror).[`constructor`](#constructor-5) #### Properties [#properties-9] | Property | Modifier | Type | Description | Inherited from | | ------ | ------ | ------ | ------ | ------ | | `cause` | `readonly` | `unknown` | Underlying error, if any. | [`OvokError`](#ovokerror).[`cause`](#property-cause-4) | | `code` | `readonly` | `string` \| `null` | Machine-readable error code from the API, if any. | [`OvokError`](#ovokerror).[`code`](#property-code-5) | | `fieldErrors` | `readonly` | [`ValidationError`](/web-sdk/core/reference/core/fhir#validationerror)[] | Per-field validation failures. | [`OvokError`](#ovokerror).[`fieldErrors`](#property-fielderrors-4) | | `requestId` | `readonly` | `string` \| `null` | Request id, for support. | [`OvokError`](#ovokerror).[`requestId`](#property-requestid-4) | | `retryAfterMs` | `readonly` | `number` \| `null` | Milliseconds to wait before retrying, from `Retry-After`. | [`OvokError`](#ovokerror).[`retryAfterMs`](#property-retryafterms-4) | | `status` | `readonly` | `number` \| `null` | HTTP status, or `null` when there was no response. | [`OvokError`](#ovokerror).[`status`](#property-status-4) | | `traceId` | `readonly` | `string` \| `null` | Trace id of the request, for support. | [`OvokError`](#ovokerror).[`traceId`](#property-traceid-4) | | `type` | `readonly` | `string` \| `null` | Error type from the API, if any. | [`OvokError`](#ovokerror).[`type`](#property-type-4) | *** ### OvokValidationError [#ovokvalidationerror] The request was invalid (400 or 422). #### Extends [#extends-10] - [`OvokError`](#ovokerror) #### Constructors [#constructors-10] ##### Constructor [#constructor-10] ```ts new OvokValidationError(details, cause?): OvokValidationError; ``` Creates an error from normalized details. ###### Parameters [#parameters-10] | Parameter | Type | Description | | ------ | ------ | ------ | | `details` | [`OvokErrorDetails`](#ovokerrordetails) | Normalized failure description. | | `cause?` | `unknown` | Underlying error. | ###### Returns [#returns-10] [`OvokValidationError`](#ovokvalidationerror) ###### Inherited from [#inherited-from-8] [`OvokError`](#ovokerror).[`constructor`](#constructor-5) #### Properties [#properties-10] | Property | Modifier | Type | Description | Inherited from | | ------ | ------ | ------ | ------ | ------ | | `cause` | `readonly` | `unknown` | Underlying error, if any. | [`OvokError`](#ovokerror).[`cause`](#property-cause-4) | | `code` | `readonly` | `string` \| `null` | Machine-readable error code from the API, if any. | [`OvokError`](#ovokerror).[`code`](#property-code-5) | | `fieldErrors` | `readonly` | [`ValidationError`](/web-sdk/core/reference/core/fhir#validationerror)[] | Per-field validation failures. | [`OvokError`](#ovokerror).[`fieldErrors`](#property-fielderrors-4) | | `requestId` | `readonly` | `string` \| `null` | Request id, for support. | [`OvokError`](#ovokerror).[`requestId`](#property-requestid-4) | | `retryAfterMs` | `readonly` | `number` \| `null` | Milliseconds to wait before retrying, from `Retry-After`. | [`OvokError`](#ovokerror).[`retryAfterMs`](#property-retryafterms-4) | | `status` | `readonly` | `number` \| `null` | HTTP status, or `null` when there was no response. | [`OvokError`](#ovokerror).[`status`](#property-status-4) | | `traceId` | `readonly` | `string` \| `null` | Trace id of the request, for support. | [`OvokError`](#ovokerror).[`traceId`](#property-traceid-4) | | `type` | `readonly` | `string` \| `null` | Error type from the API, if any. | [`OvokError`](#ovokerror).[`type`](#property-type-4) | ## Type Aliases [#type-aliases] ### OvokAccountErrorCode [#ovokaccounterrorcode] ```ts type OvokAccountErrorCode = "account_not_found" | "account_expired"; ``` Why a saved account cannot be used. *** ### OvokErrorDetails [#ovokerrordetails] ```ts type OvokErrorDetails = object; ``` Normalized description of a failed Ovok call. #### Properties [#properties-11] | Property | Type | Description | | ------ | ------ | ------ | | `code` | `string` \| `null` | Machine-readable error code from the API, if any. | | `fieldErrors` | [`ValidationError`](/web-sdk/core/reference/core/fhir#validationerror)[] | Per-field validation failures. | | `message` | `string` | Human-readable message. | | `requestId` | `string` \| `null` | Request id, for support. | | `retryAfterMs` | `number` \| `null` | Milliseconds to wait before retrying, from `Retry-After`. | | `status` | `number` \| `null` | HTTP status, or `null` when there was no response. | | `traceId` | `string` \| `null` | Trace id of the request, for support. | | `type` | `string` \| `null` | Error type from the API, if any. | # fhir Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/fhir ## Interfaces [#interfaces] ### FhirResource [#fhirresource] Reads and writes FHIR resources through the Ovok API. #### Methods [#methods] ##### batch() [#batch] ```ts batch(bundle, options?): Promise>; ``` Submits a batch or transaction bundle. Calls `POST` on the FHIR base path. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `bundle` | `Bundle` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<`Bundle`\<`Resource`\>\> ##### create() [#create] ```ts create(resource, options?): Promise; ``` With `ifNoneExist`, a retry cannot create a duplicate, so the request is safe to repeat. ###### Type Parameters [#type-parameters] | Type Parameter | | ------ | | `T` *extends* `Resource` | ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `resource` | `T` | | `options?` | [`CreateOptions`](#createoptions) | ###### Returns [#returns-1] `Promise`\<`T`\> ##### delete() [#delete] ```ts delete( type, id, options? ): Promise; ``` Deletes a resource. Calls `DELETE {type}/{id}`. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `type` | \| `"Project"` \| `"Practitioner"` \| `"User"` \| `"ProjectMembership"` \| `"AccessPolicy"` \| `"Patient"` \| `"RelatedPerson"` \| `"Appointment"` \| `"UserConfiguration"` \| `"Bundle"` \| `"Observation"` \| `"Account"` \| `"ActivityDefinition"` \| `"AdverseEvent"` \| `"Agent"` \| `"AllergyIntolerance"` \| `"AppointmentResponse"` \| `"AsyncJob"` \| `"AuditEvent"` \| `"Basic"` \| `"Binary"` \| `"BiologicallyDerivedProduct"` \| `"BodyStructure"` \| `"Bot"` \| `"BulkDataExport"` \| `"CapabilityStatement"` \| `"CarePlan"` \| `"CareTeam"` \| `"CatalogEntry"` \| `"ChargeItem"` \| `"ChargeItemDefinition"` \| `"Claim"` \| `"ClaimResponse"` \| `"ClientApplication"` \| `"ClinicalImpression"` \| `"CodeSystem"` \| `"Communication"` \| `"CommunicationRequest"` \| `"CompartmentDefinition"` \| `"Composition"` \| `"ConceptMap"` \| `"Condition"` \| `"Consent"` \| `"Contract"` \| `"Coverage"` \| `"CoverageEligibilityRequest"` \| `"CoverageEligibilityResponse"` \| `"DetectedIssue"` \| `"Device"` \| `"DeviceDefinition"` \| `"DeviceMetric"` \| `"DeviceRequest"` \| `"DeviceUseStatement"` \| `"DiagnosticReport"` \| `"DicomInstance"` \| `"DicomSeries"` \| `"DicomStudy"` \| `"DocumentManifest"` \| `"DocumentReference"` \| `"DomainConfiguration"` \| `"EffectEvidenceSynthesis"` \| `"Encounter"` \| `"Endpoint"` \| `"EnrollmentRequest"` \| `"EnrollmentResponse"` \| `"EpisodeOfCare"` \| `"EventDefinition"` \| `"Evidence"` \| `"EvidenceVariable"` \| `"ExampleScenario"` \| `"ExplanationOfBenefit"` \| `"FamilyMemberHistory"` \| `"Flag"` \| `"Goal"` \| `"GraphDefinition"` \| `"Group"` \| `"GuidanceResponse"` \| `"HealthcareService"` \| `"ImagingStudy"` \| `"Immunization"` \| `"ImmunizationEvaluation"` \| `"ImmunizationRecommendation"` \| `"ImplementationGuide"` \| `"InsurancePlan"` \| `"Invoice"` \| `"JsonWebKey"` \| `"Library"` \| `"Linkage"` \| `"List"` \| `"Location"` \| `"Login"` \| `"Measure"` \| `"MeasureReport"` \| `"Media"` \| `"Medication"` \| `"MedicationAdministration"` \| `"MedicationDispense"` \| `"MedicationKnowledge"` \| `"MedicationRequest"` \| `"MedicationStatement"` \| `"MedicinalProduct"` \| `"MedicinalProductAuthorization"` \| `"MedicinalProductContraindication"` \| `"MedicinalProductIndication"` \| `"MedicinalProductIngredient"` \| `"MedicinalProductInteraction"` \| `"MedicinalProductManufactured"` \| `"MedicinalProductPackaged"` \| `"MedicinalProductPharmaceutical"` \| `"MedicinalProductUndesirableEffect"` \| `"MessageDefinition"` \| `"MessageHeader"` \| `"MolecularSequence"` \| `"NamingSystem"` \| `"NutritionOrder"` \| `"ObservationDefinition"` \| `"OperationDefinition"` \| `"OperationOutcome"` \| `"Organization"` \| `"OrganizationAffiliation"` \| `"Package"` \| `"PackageInstallation"` \| `"PackageRelease"` \| `"Parameters"` \| `"PaymentNotice"` \| `"PaymentReconciliation"` \| `"Person"` \| `"PlanDefinition"` \| `"PractitionerRole"` \| `"Procedure"` \| `"Provenance"` \| `"Questionnaire"` \| `"QuestionnaireResponse"` \| `"RequestGroup"` \| `"ResearchDefinition"` \| `"ResearchElementDefinition"` \| `"ResearchStudy"` \| `"ResearchSubject"` \| `"RiskAssessment"` \| `"RiskEvidenceSynthesis"` \| `"Schedule"` \| `"SearchParameter"` \| `"ServiceRequest"` \| `"Slot"` \| `"SmartAppLaunch"` \| `"SmartHealthLink"` \| `"Specimen"` \| `"SpecimenDefinition"` \| `"StructureDefinition"` \| `"StructureMap"` \| `"Subscription"` \| `"SubscriptionStatus"` \| `"Substance"` \| `"SubstanceNucleicAcid"` \| `"SubstancePolymer"` \| `"SubstanceProtein"` \| `"SubstanceReferenceInformation"` \| `"SubstanceSourceMaterial"` \| `"SubstanceSpecification"` \| `"SupplyDelivery"` \| `"SupplyRequest"` \| `"Task"` \| `"TerminologyCapabilities"` \| `"TestReport"` \| `"TestScript"` \| `"UserSecurityRequest"` \| `"ValueSet"` \| `"VerificationResult"` \| `"VisionPrescription"` | | `id` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<`void`\> ##### patch() [#patch] ```ts patch( type, id, operations, options? ): Promise>; ``` Applies JSON Patch operations to a resource. Calls `PATCH {type}/{id}`. ###### Type Parameters [#type-parameters-1] | Type Parameter | | ------ | | `K` *extends* \| `"Project"` \| `"Practitioner"` \| `"User"` \| `"ProjectMembership"` \| `"AccessPolicy"` \| `"Patient"` \| `"RelatedPerson"` \| `"Appointment"` \| `"UserConfiguration"` \| `"Bundle"` \| `"Observation"` \| `"Account"` \| `"ActivityDefinition"` \| `"AdverseEvent"` \| `"Agent"` \| `"AllergyIntolerance"` \| `"AppointmentResponse"` \| `"AsyncJob"` \| `"AuditEvent"` \| `"Basic"` \| `"Binary"` \| `"BiologicallyDerivedProduct"` \| `"BodyStructure"` \| `"Bot"` \| `"BulkDataExport"` \| `"CapabilityStatement"` \| `"CarePlan"` \| `"CareTeam"` \| `"CatalogEntry"` \| `"ChargeItem"` \| `"ChargeItemDefinition"` \| `"Claim"` \| `"ClaimResponse"` \| `"ClientApplication"` \| `"ClinicalImpression"` \| `"CodeSystem"` \| `"Communication"` \| `"CommunicationRequest"` \| `"CompartmentDefinition"` \| `"Composition"` \| `"ConceptMap"` \| `"Condition"` \| `"Consent"` \| `"Contract"` \| `"Coverage"` \| `"CoverageEligibilityRequest"` \| `"CoverageEligibilityResponse"` \| `"DetectedIssue"` \| `"Device"` \| `"DeviceDefinition"` \| `"DeviceMetric"` \| `"DeviceRequest"` \| `"DeviceUseStatement"` \| `"DiagnosticReport"` \| `"DicomInstance"` \| `"DicomSeries"` \| `"DicomStudy"` \| `"DocumentManifest"` \| `"DocumentReference"` \| `"DomainConfiguration"` \| `"EffectEvidenceSynthesis"` \| `"Encounter"` \| `"Endpoint"` \| `"EnrollmentRequest"` \| `"EnrollmentResponse"` \| `"EpisodeOfCare"` \| `"EventDefinition"` \| `"Evidence"` \| `"EvidenceVariable"` \| `"ExampleScenario"` \| `"ExplanationOfBenefit"` \| `"FamilyMemberHistory"` \| `"Flag"` \| `"Goal"` \| `"GraphDefinition"` \| `"Group"` \| `"GuidanceResponse"` \| `"HealthcareService"` \| `"ImagingStudy"` \| `"Immunization"` \| `"ImmunizationEvaluation"` \| `"ImmunizationRecommendation"` \| `"ImplementationGuide"` \| `"InsurancePlan"` \| `"Invoice"` \| `"JsonWebKey"` \| `"Library"` \| `"Linkage"` \| `"List"` \| `"Location"` \| `"Login"` \| `"Measure"` \| `"MeasureReport"` \| `"Media"` \| `"Medication"` \| `"MedicationAdministration"` \| `"MedicationDispense"` \| `"MedicationKnowledge"` \| `"MedicationRequest"` \| `"MedicationStatement"` \| `"MedicinalProduct"` \| `"MedicinalProductAuthorization"` \| `"MedicinalProductContraindication"` \| `"MedicinalProductIndication"` \| `"MedicinalProductIngredient"` \| `"MedicinalProductInteraction"` \| `"MedicinalProductManufactured"` \| `"MedicinalProductPackaged"` \| `"MedicinalProductPharmaceutical"` \| `"MedicinalProductUndesirableEffect"` \| `"MessageDefinition"` \| `"MessageHeader"` \| `"MolecularSequence"` \| `"NamingSystem"` \| `"NutritionOrder"` \| `"ObservationDefinition"` \| `"OperationDefinition"` \| `"OperationOutcome"` \| `"Organization"` \| `"OrganizationAffiliation"` \| `"Package"` \| `"PackageInstallation"` \| `"PackageRelease"` \| `"Parameters"` \| `"PaymentNotice"` \| `"PaymentReconciliation"` \| `"Person"` \| `"PlanDefinition"` \| `"PractitionerRole"` \| `"Procedure"` \| `"Provenance"` \| `"Questionnaire"` \| `"QuestionnaireResponse"` \| `"RequestGroup"` \| `"ResearchDefinition"` \| `"ResearchElementDefinition"` \| `"ResearchStudy"` \| `"ResearchSubject"` \| `"RiskAssessment"` \| `"RiskEvidenceSynthesis"` \| `"Schedule"` \| `"SearchParameter"` \| `"ServiceRequest"` \| `"Slot"` \| `"SmartAppLaunch"` \| `"SmartHealthLink"` \| `"Specimen"` \| `"SpecimenDefinition"` \| `"StructureDefinition"` \| `"StructureMap"` \| `"Subscription"` \| `"SubscriptionStatus"` \| `"Substance"` \| `"SubstanceNucleicAcid"` \| `"SubstancePolymer"` \| `"SubstanceProtein"` \| `"SubstanceReferenceInformation"` \| `"SubstanceSourceMaterial"` \| `"SubstanceSpecification"` \| `"SupplyDelivery"` \| `"SupplyRequest"` \| `"Task"` \| `"TerminologyCapabilities"` \| `"TestReport"` \| `"TestScript"` \| `"UserSecurityRequest"` \| `"ValueSet"` \| `"VerificationResult"` \| `"VisionPrescription"` | ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `type` | `K` | | `id` | `string` | | `operations` | [`PatchOperation`](#patchoperation)[] | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<`ExtractResource`\<`K`\>\> ##### read() [#read] ```ts read( type, id, options? ): Promise>; ``` Reads a resource by id. Calls `GET {type}/{id}`. ###### Type Parameters [#type-parameters-2] | Type Parameter | | ------ | | `K` *extends* \| `"Project"` \| `"Practitioner"` \| `"User"` \| `"ProjectMembership"` \| `"AccessPolicy"` \| `"Patient"` \| `"RelatedPerson"` \| `"Appointment"` \| `"UserConfiguration"` \| `"Bundle"` \| `"Observation"` \| `"Account"` \| `"ActivityDefinition"` \| `"AdverseEvent"` \| `"Agent"` \| `"AllergyIntolerance"` \| `"AppointmentResponse"` \| `"AsyncJob"` \| `"AuditEvent"` \| `"Basic"` \| `"Binary"` \| `"BiologicallyDerivedProduct"` \| `"BodyStructure"` \| `"Bot"` \| `"BulkDataExport"` \| `"CapabilityStatement"` \| `"CarePlan"` \| `"CareTeam"` \| `"CatalogEntry"` \| `"ChargeItem"` \| `"ChargeItemDefinition"` \| `"Claim"` \| `"ClaimResponse"` \| `"ClientApplication"` \| `"ClinicalImpression"` \| `"CodeSystem"` \| `"Communication"` \| `"CommunicationRequest"` \| `"CompartmentDefinition"` \| `"Composition"` \| `"ConceptMap"` \| `"Condition"` \| `"Consent"` \| `"Contract"` \| `"Coverage"` \| `"CoverageEligibilityRequest"` \| `"CoverageEligibilityResponse"` \| `"DetectedIssue"` \| `"Device"` \| `"DeviceDefinition"` \| `"DeviceMetric"` \| `"DeviceRequest"` \| `"DeviceUseStatement"` \| `"DiagnosticReport"` \| `"DicomInstance"` \| `"DicomSeries"` \| `"DicomStudy"` \| `"DocumentManifest"` \| `"DocumentReference"` \| `"DomainConfiguration"` \| `"EffectEvidenceSynthesis"` \| `"Encounter"` \| `"Endpoint"` \| `"EnrollmentRequest"` \| `"EnrollmentResponse"` \| `"EpisodeOfCare"` \| `"EventDefinition"` \| `"Evidence"` \| `"EvidenceVariable"` \| `"ExampleScenario"` \| `"ExplanationOfBenefit"` \| `"FamilyMemberHistory"` \| `"Flag"` \| `"Goal"` \| `"GraphDefinition"` \| `"Group"` \| `"GuidanceResponse"` \| `"HealthcareService"` \| `"ImagingStudy"` \| `"Immunization"` \| `"ImmunizationEvaluation"` \| `"ImmunizationRecommendation"` \| `"ImplementationGuide"` \| `"InsurancePlan"` \| `"Invoice"` \| `"JsonWebKey"` \| `"Library"` \| `"Linkage"` \| `"List"` \| `"Location"` \| `"Login"` \| `"Measure"` \| `"MeasureReport"` \| `"Media"` \| `"Medication"` \| `"MedicationAdministration"` \| `"MedicationDispense"` \| `"MedicationKnowledge"` \| `"MedicationRequest"` \| `"MedicationStatement"` \| `"MedicinalProduct"` \| `"MedicinalProductAuthorization"` \| `"MedicinalProductContraindication"` \| `"MedicinalProductIndication"` \| `"MedicinalProductIngredient"` \| `"MedicinalProductInteraction"` \| `"MedicinalProductManufactured"` \| `"MedicinalProductPackaged"` \| `"MedicinalProductPharmaceutical"` \| `"MedicinalProductUndesirableEffect"` \| `"MessageDefinition"` \| `"MessageHeader"` \| `"MolecularSequence"` \| `"NamingSystem"` \| `"NutritionOrder"` \| `"ObservationDefinition"` \| `"OperationDefinition"` \| `"OperationOutcome"` \| `"Organization"` \| `"OrganizationAffiliation"` \| `"Package"` \| `"PackageInstallation"` \| `"PackageRelease"` \| `"Parameters"` \| `"PaymentNotice"` \| `"PaymentReconciliation"` \| `"Person"` \| `"PlanDefinition"` \| `"PractitionerRole"` \| `"Procedure"` \| `"Provenance"` \| `"Questionnaire"` \| `"QuestionnaireResponse"` \| `"RequestGroup"` \| `"ResearchDefinition"` \| `"ResearchElementDefinition"` \| `"ResearchStudy"` \| `"ResearchSubject"` \| `"RiskAssessment"` \| `"RiskEvidenceSynthesis"` \| `"Schedule"` \| `"SearchParameter"` \| `"ServiceRequest"` \| `"Slot"` \| `"SmartAppLaunch"` \| `"SmartHealthLink"` \| `"Specimen"` \| `"SpecimenDefinition"` \| `"StructureDefinition"` \| `"StructureMap"` \| `"Subscription"` \| `"SubscriptionStatus"` \| `"Substance"` \| `"SubstanceNucleicAcid"` \| `"SubstancePolymer"` \| `"SubstanceProtein"` \| `"SubstanceReferenceInformation"` \| `"SubstanceSourceMaterial"` \| `"SubstanceSpecification"` \| `"SupplyDelivery"` \| `"SupplyRequest"` \| `"Task"` \| `"TerminologyCapabilities"` \| `"TestReport"` \| `"TestScript"` \| `"UserSecurityRequest"` \| `"ValueSet"` \| `"VerificationResult"` \| `"VisionPrescription"` | ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `type` | `K` | | `id` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<`ExtractResource`\<`K`\>\> ##### search() [#search] ```ts search( type, params?, options? ): PagePromise>; ``` Searches a resource type; the result pages lazily. Calls `GET {type}?...`. ###### Type Parameters [#type-parameters-3] | Type Parameter | | ------ | | `K` *extends* \| `"Project"` \| `"Practitioner"` \| `"User"` \| `"ProjectMembership"` \| `"AccessPolicy"` \| `"Patient"` \| `"RelatedPerson"` \| `"Appointment"` \| `"UserConfiguration"` \| `"Bundle"` \| `"Observation"` \| `"Account"` \| `"ActivityDefinition"` \| `"AdverseEvent"` \| `"Agent"` \| `"AllergyIntolerance"` \| `"AppointmentResponse"` \| `"AsyncJob"` \| `"AuditEvent"` \| `"Basic"` \| `"Binary"` \| `"BiologicallyDerivedProduct"` \| `"BodyStructure"` \| `"Bot"` \| `"BulkDataExport"` \| `"CapabilityStatement"` \| `"CarePlan"` \| `"CareTeam"` \| `"CatalogEntry"` \| `"ChargeItem"` \| `"ChargeItemDefinition"` \| `"Claim"` \| `"ClaimResponse"` \| `"ClientApplication"` \| `"ClinicalImpression"` \| `"CodeSystem"` \| `"Communication"` \| `"CommunicationRequest"` \| `"CompartmentDefinition"` \| `"Composition"` \| `"ConceptMap"` \| `"Condition"` \| `"Consent"` \| `"Contract"` \| `"Coverage"` \| `"CoverageEligibilityRequest"` \| `"CoverageEligibilityResponse"` \| `"DetectedIssue"` \| `"Device"` \| `"DeviceDefinition"` \| `"DeviceMetric"` \| `"DeviceRequest"` \| `"DeviceUseStatement"` \| `"DiagnosticReport"` \| `"DicomInstance"` \| `"DicomSeries"` \| `"DicomStudy"` \| `"DocumentManifest"` \| `"DocumentReference"` \| `"DomainConfiguration"` \| `"EffectEvidenceSynthesis"` \| `"Encounter"` \| `"Endpoint"` \| `"EnrollmentRequest"` \| `"EnrollmentResponse"` \| `"EpisodeOfCare"` \| `"EventDefinition"` \| `"Evidence"` \| `"EvidenceVariable"` \| `"ExampleScenario"` \| `"ExplanationOfBenefit"` \| `"FamilyMemberHistory"` \| `"Flag"` \| `"Goal"` \| `"GraphDefinition"` \| `"Group"` \| `"GuidanceResponse"` \| `"HealthcareService"` \| `"ImagingStudy"` \| `"Immunization"` \| `"ImmunizationEvaluation"` \| `"ImmunizationRecommendation"` \| `"ImplementationGuide"` \| `"InsurancePlan"` \| `"Invoice"` \| `"JsonWebKey"` \| `"Library"` \| `"Linkage"` \| `"List"` \| `"Location"` \| `"Login"` \| `"Measure"` \| `"MeasureReport"` \| `"Media"` \| `"Medication"` \| `"MedicationAdministration"` \| `"MedicationDispense"` \| `"MedicationKnowledge"` \| `"MedicationRequest"` \| `"MedicationStatement"` \| `"MedicinalProduct"` \| `"MedicinalProductAuthorization"` \| `"MedicinalProductContraindication"` \| `"MedicinalProductIndication"` \| `"MedicinalProductIngredient"` \| `"MedicinalProductInteraction"` \| `"MedicinalProductManufactured"` \| `"MedicinalProductPackaged"` \| `"MedicinalProductPharmaceutical"` \| `"MedicinalProductUndesirableEffect"` \| `"MessageDefinition"` \| `"MessageHeader"` \| `"MolecularSequence"` \| `"NamingSystem"` \| `"NutritionOrder"` \| `"ObservationDefinition"` \| `"OperationDefinition"` \| `"OperationOutcome"` \| `"Organization"` \| `"OrganizationAffiliation"` \| `"Package"` \| `"PackageInstallation"` \| `"PackageRelease"` \| `"Parameters"` \| `"PaymentNotice"` \| `"PaymentReconciliation"` \| `"Person"` \| `"PlanDefinition"` \| `"PractitionerRole"` \| `"Procedure"` \| `"Provenance"` \| `"Questionnaire"` \| `"QuestionnaireResponse"` \| `"RequestGroup"` \| `"ResearchDefinition"` \| `"ResearchElementDefinition"` \| `"ResearchStudy"` \| `"ResearchSubject"` \| `"RiskAssessment"` \| `"RiskEvidenceSynthesis"` \| `"Schedule"` \| `"SearchParameter"` \| `"ServiceRequest"` \| `"Slot"` \| `"SmartAppLaunch"` \| `"SmartHealthLink"` \| `"Specimen"` \| `"SpecimenDefinition"` \| `"StructureDefinition"` \| `"StructureMap"` \| `"Subscription"` \| `"SubscriptionStatus"` \| `"Substance"` \| `"SubstanceNucleicAcid"` \| `"SubstancePolymer"` \| `"SubstanceProtein"` \| `"SubstanceReferenceInformation"` \| `"SubstanceSourceMaterial"` \| `"SubstanceSpecification"` \| `"SupplyDelivery"` \| `"SupplyRequest"` \| `"Task"` \| `"TerminologyCapabilities"` \| `"TestReport"` \| `"TestScript"` \| `"UserSecurityRequest"` \| `"ValueSet"` \| `"VerificationResult"` \| `"VisionPrescription"` | ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `type` | `K` | | `params?` | [`QueryParams`](/web-sdk/core/reference/core/ovok-client#queryparams) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-5] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<`ExtractResource`\<`K`\>\> ###### Example [#example] ```ts const page = await ovok.fhir.search("Patient", { family: "Smith" }); ``` ##### searchOne() [#searchone] ```ts searchOne( type, params?, options? ): Promise | null>; ``` Returns the first match of a search, or null when there is none. ###### Type Parameters [#type-parameters-4] | Type Parameter | | ------ | | `K` *extends* \| `"Project"` \| `"Practitioner"` \| `"User"` \| `"ProjectMembership"` \| `"AccessPolicy"` \| `"Patient"` \| `"RelatedPerson"` \| `"Appointment"` \| `"UserConfiguration"` \| `"Bundle"` \| `"Observation"` \| `"Account"` \| `"ActivityDefinition"` \| `"AdverseEvent"` \| `"Agent"` \| `"AllergyIntolerance"` \| `"AppointmentResponse"` \| `"AsyncJob"` \| `"AuditEvent"` \| `"Basic"` \| `"Binary"` \| `"BiologicallyDerivedProduct"` \| `"BodyStructure"` \| `"Bot"` \| `"BulkDataExport"` \| `"CapabilityStatement"` \| `"CarePlan"` \| `"CareTeam"` \| `"CatalogEntry"` \| `"ChargeItem"` \| `"ChargeItemDefinition"` \| `"Claim"` \| `"ClaimResponse"` \| `"ClientApplication"` \| `"ClinicalImpression"` \| `"CodeSystem"` \| `"Communication"` \| `"CommunicationRequest"` \| `"CompartmentDefinition"` \| `"Composition"` \| `"ConceptMap"` \| `"Condition"` \| `"Consent"` \| `"Contract"` \| `"Coverage"` \| `"CoverageEligibilityRequest"` \| `"CoverageEligibilityResponse"` \| `"DetectedIssue"` \| `"Device"` \| `"DeviceDefinition"` \| `"DeviceMetric"` \| `"DeviceRequest"` \| `"DeviceUseStatement"` \| `"DiagnosticReport"` \| `"DicomInstance"` \| `"DicomSeries"` \| `"DicomStudy"` \| `"DocumentManifest"` \| `"DocumentReference"` \| `"DomainConfiguration"` \| `"EffectEvidenceSynthesis"` \| `"Encounter"` \| `"Endpoint"` \| `"EnrollmentRequest"` \| `"EnrollmentResponse"` \| `"EpisodeOfCare"` \| `"EventDefinition"` \| `"Evidence"` \| `"EvidenceVariable"` \| `"ExampleScenario"` \| `"ExplanationOfBenefit"` \| `"FamilyMemberHistory"` \| `"Flag"` \| `"Goal"` \| `"GraphDefinition"` \| `"Group"` \| `"GuidanceResponse"` \| `"HealthcareService"` \| `"ImagingStudy"` \| `"Immunization"` \| `"ImmunizationEvaluation"` \| `"ImmunizationRecommendation"` \| `"ImplementationGuide"` \| `"InsurancePlan"` \| `"Invoice"` \| `"JsonWebKey"` \| `"Library"` \| `"Linkage"` \| `"List"` \| `"Location"` \| `"Login"` \| `"Measure"` \| `"MeasureReport"` \| `"Media"` \| `"Medication"` \| `"MedicationAdministration"` \| `"MedicationDispense"` \| `"MedicationKnowledge"` \| `"MedicationRequest"` \| `"MedicationStatement"` \| `"MedicinalProduct"` \| `"MedicinalProductAuthorization"` \| `"MedicinalProductContraindication"` \| `"MedicinalProductIndication"` \| `"MedicinalProductIngredient"` \| `"MedicinalProductInteraction"` \| `"MedicinalProductManufactured"` \| `"MedicinalProductPackaged"` \| `"MedicinalProductPharmaceutical"` \| `"MedicinalProductUndesirableEffect"` \| `"MessageDefinition"` \| `"MessageHeader"` \| `"MolecularSequence"` \| `"NamingSystem"` \| `"NutritionOrder"` \| `"ObservationDefinition"` \| `"OperationDefinition"` \| `"OperationOutcome"` \| `"Organization"` \| `"OrganizationAffiliation"` \| `"Package"` \| `"PackageInstallation"` \| `"PackageRelease"` \| `"Parameters"` \| `"PaymentNotice"` \| `"PaymentReconciliation"` \| `"Person"` \| `"PlanDefinition"` \| `"PractitionerRole"` \| `"Procedure"` \| `"Provenance"` \| `"Questionnaire"` \| `"QuestionnaireResponse"` \| `"RequestGroup"` \| `"ResearchDefinition"` \| `"ResearchElementDefinition"` \| `"ResearchStudy"` \| `"ResearchSubject"` \| `"RiskAssessment"` \| `"RiskEvidenceSynthesis"` \| `"Schedule"` \| `"SearchParameter"` \| `"ServiceRequest"` \| `"Slot"` \| `"SmartAppLaunch"` \| `"SmartHealthLink"` \| `"Specimen"` \| `"SpecimenDefinition"` \| `"StructureDefinition"` \| `"StructureMap"` \| `"Subscription"` \| `"SubscriptionStatus"` \| `"Substance"` \| `"SubstanceNucleicAcid"` \| `"SubstancePolymer"` \| `"SubstanceProtein"` \| `"SubstanceReferenceInformation"` \| `"SubstanceSourceMaterial"` \| `"SubstanceSpecification"` \| `"SupplyDelivery"` \| `"SupplyRequest"` \| `"Task"` \| `"TerminologyCapabilities"` \| `"TestReport"` \| `"TestScript"` \| `"UserSecurityRequest"` \| `"ValueSet"` \| `"VerificationResult"` \| `"VisionPrescription"` | ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `type` | `K` | | `params?` | [`QueryParams`](/web-sdk/core/reference/core/ovok-client#queryparams) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-6] `Promise`\<`ExtractResource`\<`K`\> \| `null`\> ##### update() [#update] ```ts update(resource, options?): Promise; ``` Replaces a resource, which must have an `id`. Calls `PUT {type}/{id}`. ###### Type Parameters [#type-parameters-5] | Type Parameter | | ------ | | `T` *extends* `Resource` | ###### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `resource` | `T` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-7] `Promise`\<`T`\> ###### Throws [#throws] OvokValidationError when the resource has no `id`. ## Type Aliases [#type-aliases] ### CreateOptions [#createoptions] ```ts type CreateOptions = RequestOptions & object; ``` Request options plus an optional conditional-create query. #### Type Declaration [#type-declaration] ##### ifNoneExist? [#ifnoneexist] ```ts ifNoneExist?: string; ``` FHIR search query; the resource is created only when nothing matches it. *** ### PatchOperation [#patchoperation] ```ts type PatchOperation = object; ``` One JSON Patch operation. #### Properties [#properties] | Property | Type | Description | | ------ | ------ | ------ | | `from?` | `string` | Source location for `copy` and `move`. | | `op` | `"add"` \| `"remove"` \| `"replace"` \| `"copy"` \| `"move"` \| `"test"` | The JSON Patch operation. | | `path` | `string` | JSON Pointer to the target location. | | `value?` | `unknown` | Value to add, replace or test. | *** ### ValidationError [#validationerror] ```ts type ValidationError = object; ``` A validation failure reported by a request. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `code?` | `string` | Machine-readable error code. | | `message` | `string` | Human-readable error message. | | `path` | `string`[] | Path to the invalid field. | | `validation?` | `string` | Name of the failed validation rule. | # health Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/health ## Interfaces [#interfaces] ### HealthResource [#healthresource] API health. Calls `GET healthcheck`. #### Methods [#methods] ##### check() [#check] ```ts check(options?): Promise; ``` Always answers 200: read `ok`, not the status. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`HealthCheck`](#healthcheck)\> ## Type Aliases [#type-aliases] ### HealthCheck [#healthcheck] ```ts type HealthCheck = object; ``` Result of the health check. #### Properties [#properties] | Property | Type | Description | | ------ | ------ | ------ | | `buildEnv?` | `string` \| `null` | Build environment, when reported. | | `commitHash?` | `string` \| `null` | Git commit of the deployed build, when reported. | | `dependencies` | `Record`\<`string`, \{ `ok`: `boolean`; \}\> | Health of each dependency, by name. | | `ok` | `boolean` | Whether the service and its dependencies are healthy. | | `version?` | `string` \| `null` | Deployed version, when reported. | # @ovok/core Canonical page: https://docs.ovok.com/web-sdk/core/reference/core ## Modules [#modules] - [accounts](/web-sdk/core/reference/core/accounts) - [ai](/web-sdk/core/reference/core/ai) - [auth](/web-sdk/core/reference/core/auth) - [bots](/web-sdk/core/reference/core/bots) - [cms](/web-sdk/core/reference/core/cms) - [consent](/web-sdk/core/reference/core/consent) - [content](/web-sdk/core/reference/core/content) - [documents](/web-sdk/core/reference/core/documents) - [email](/web-sdk/core/reference/core/email) - [Errors](/web-sdk/core/reference/core/errors) - [fhir](/web-sdk/core/reference/core/fhir) - [health](/web-sdk/core/reference/core/health) - [invites](/web-sdk/core/reference/core/invites) - [localization](/web-sdk/core/reference/core/localization) - [measurements](/web-sdk/core/reference/core/measurements) - [Ovok client](/web-sdk/core/reference/core/ovok-client) - [patient](/web-sdk/core/reference/core/patient) - [projects](/web-sdk/core/reference/core/projects) - [questionnaires](/web-sdk/core/reference/core/questionnaires) - [realtime](/web-sdk/core/reference/core/realtime) - [session](/web-sdk/core/reference/core/session) - [sharing](/web-sdk/core/reference/core/sharing) - [signals](/web-sdk/core/reference/core/signals) - [slim](/web-sdk/core/reference/core/slim) - [videoCalls](/web-sdk/core/reference/core/videocalls) - [wearables](/web-sdk/core/reference/core/wearables) # invites Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/invites ## Classes [#classes] ### InviteFlowResource [#inviteflowresource] One invite kind: `create` sends it to `path`, `accept` redeems it at `path/accept`. #### Type Parameters [#type-parameters] | Type Parameter | | ------ | | `Invite` | | `Acceptance` | | `Accepted` | #### Methods [#methods] ##### accept() [#accept] ```ts accept(body, options?): Promise; ``` Redeems an invite. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `body` | `Acceptance` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<`Accepted`\> ##### create() [#create] ```ts create(body, options?): Promise; ``` Sends an invite. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `body` | `Invite` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<[`InviteSent`](#invitesent)\> ## Interfaces [#interfaces] ### InvitesResource [#invitesresource] Invitations to share a record or enter a care relationship. Calls routes under `v1/invites`. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `care` | `readonly` | [`PersonInviteFlow`](#personinviteflow) | A practitioner invites a patient into their care. | | ~~`patients`~~ | `readonly` | [`PersonInviteFlow`](#personinviteflow) | **Deprecated** Use `care`; the route sunsets on 2026-12-01. | | ~~`practitioners`~~ | `readonly` | [`PersonInviteFlow`](#personinviteflow) | **Deprecated** Use `recordShares` with `recipient: "practitioner"`; the route sunsets on 2026-12-01. | | `recordShares` | `readonly` | [`RecordShareFlow`](#recordshareflow) | A patient shares their record with a practitioner, or some codes with a carer. | #### Methods [#methods-1] ##### accept() [#accept-1] ```ts accept(body, options?): Promise; ``` Accepts a record share as a practitioner or a care invite as a patient. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `body` | [`AcceptInviteBody`](#acceptinvitebody) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<[`PatientSharingPractitionerShare`](/web-sdk/core/reference/core/sharing#patientsharingpractitionershare)\> ## Type Aliases [#type-aliases] ### AcceptInviteBody [#acceptinvitebody] ```ts type AcceptInviteBody = object; ``` Credentials of an invite to accept. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `code` | `string` | Code from the invite. | | `inviteId` | `string` | ID of the invite. | *** ### AcceptInviteResult [#acceptinviteresult] ```ts type AcceptInviteResult = PatientSharingPractitionerShare; ``` Result of accepting an invite. *** ### AcceptRecordShareBody [#acceptrecordsharebody] ```ts type AcceptRecordShareBody = AcceptInviteBody & object; ``` Request to accept a record share. #### Type Declaration [#type-declaration] ##### password? [#password] ```ts password?: string | null; ``` Only for a carer whose account the invite creates; they accept signed out. *** ### InviteBody [#invitebody] ```ts type InviteBody = object; ``` Recipient of an invite. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `email` | `string` | Email address to invite. | | `firstName` | `string` | First name of the invitee. | | `lastName` | `string` | Last name of the invitee. | *** ### InviteSent [#invitesent] ```ts type InviteSent = object; ``` Result of a sent invite. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `status` | `"sent"` | Always `sent`. | *** ### PersonInviteFlow [#personinviteflow] ```ts type PersonInviteFlow = InviteFlowResource; ``` The invite flow between a practitioner and a patient. *** ### RecordShareAccepted [#recordshareaccepted] ```ts type RecordShareAccepted = | PatientSharingPractitionerShare | PatientSharingRelatedPersonShare; ``` Result of accepting a record share. *** ### RecordShareBody [#recordsharebody] ```ts type RecordShareBody = | InviteBody & object | InviteBody & object; ``` Request to share a record with a practitioner or a related person. *** ### RecordShareFlow [#recordshareflow] ```ts type RecordShareFlow = InviteFlowResource; ``` The invite flow for sharing a record with a practitioner or carer. ## Variables [#variables] ### OVOK\_INVITE\_ERROR\_CODES [#ovok_invite_error_codes] ```ts const OVOK_INVITE_ERROR_CODES: object; ``` Error codes returned by the invite routes. #### Type Declaration [#type-declaration-1] ##### addressHasAccount [#addresshasaccount] ```ts readonly addressHasAccount: "address_has_account" = "address_has_account"; ``` The address already has an account. ##### appUrlNotConfigured [#appurlnotconfigured] ```ts readonly appUrlNotConfigured: "app_url_not_configured" = "app_url_not_configured"; ``` No app URL is configured for the invite link. ##### invitationNotConfigured [#invitationnotconfigured] ```ts readonly invitationNotConfigured: "invitation_not_configured" = "invitation_not_configured"; ``` Invitations are not set up for the project. ##### passwordRequired [#passwordrequired] ```ts readonly passwordRequired: "password_required" = "password_required"; ``` A password is required to accept. ##### practitionerWithoutAccessPolicy [#practitionerwithoutaccesspolicy] ```ts readonly practitionerWithoutAccessPolicy: "practitioner_without_access_policy" = "practitioner_without_access_policy"; ``` The practitioner has no access policy. ##### relatedPersonWithoutAccessPolicy [#relatedpersonwithoutaccesspolicy] ```ts readonly relatedPersonWithoutAccessPolicy: "related_person_without_access_policy" = "related_person_without_access_policy"; ``` The related person has no access policy. ##### sharingNotConfigured [#sharingnotconfigured] ```ts readonly sharingNotConfigured: "sharing_not_configured" = "sharing_not_configured"; ``` Record sharing is not set up for the project. # localization Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/localization ## Classes [#classes] ### I18nextResource [#i18nextresource] Translation documents in i18next format. #### Methods [#methods] ##### retrieve() [#retrieve] ```ts retrieve(language, options?): Promise; ``` Fetches the i18next translations of a language. Calls `GET localization/i18next/{language}`. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `language` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`OvokI18nDocument`](#ovoki18ndocument)\> ##### update() [#update] ```ts update( language, document, options? ): Promise; ``` The server queues the write (202), so a read right after may not show it yet. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `language` | `string` | | `document` | `Record`\<`string`, [`OvokI18nValue`](#ovoki18nvalue)\> | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<`void`\> ## Interfaces [#interfaces] ### LocalesResource [#localesresource] The languages the project supports. Calls routes under `locales`. #### Methods [#methods-1] ##### retrieve() [#retrieve-1] ```ts retrieve(options?): Promise; ``` Reads the supported languages. Calls `GET locales`. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<[`OvokLocales`](#ovoklocales)\> ##### update() [#update-1] ```ts update(locales, options?): Promise; ``` Updates the supported languages. Calls `PATCH locales`. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `locales` | [`OvokLocales`](#ovoklocales) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<[`OvokLocales`](#ovoklocales)\> *** ### LocalizationsResource [#localizationsresource] Translation entries per language. Calls routes under `localization`. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `i18next` | `readonly` | [`I18nextResource`](#i18nextresource) | Translations in i18next format. | #### Methods [#methods-2] ##### delete() [#delete] ```ts delete( language, key, options? ): Promise; ``` Deletes an entry. Calls `DELETE localization/{language}/{key}`. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `language` | `string` | | `key` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<`void`\> ##### list() [#list] ```ts list( language, query?, options? ): Promise; ``` Lists entries of a language. Calls `GET localization/{language}`. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `language` | `string` | | `query?` | [`OvokLocalizationQuery`](#ovoklocalizationquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-5] `Promise`\<[`LocalizationList`](#localizationlist)\> ##### retrieve() [#retrieve-2] ```ts retrieve( language, key, options? ): Promise; ``` Reads one entry. Calls `GET localization/{language}/{key}`. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `language` | `string` | | `key` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-6] `Promise`\<[`OvokLocalization`](#ovoklocalization)\> ##### update() [#update-2] ```ts update( language, key, body, options? ): Promise; ``` Sets an entry. Calls `PUT localization/{language}/{key}`. ###### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `language` | `string` | | `key` | `string` | | `body` | [`OvokLocalizationUpdate`](#ovoklocalizationupdate) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-7] `Promise`\<[`OvokLocalization`](#ovoklocalization)\> ## Type Aliases [#type-aliases] ### LocalizationList [#localizationlist] ```ts type LocalizationList = object; ``` A list of localization entries. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `resources` | [`OvokLocalization`](#ovoklocalization)[] | The entries returned. | | `total` | `number` | Total entries matching the query. | *** ### OvokI18nDocument [#ovoki18ndocument] ```ts type OvokI18nDocument = object; ``` A language's translations as an i18next document. #### Indexable [#indexable] ```ts [key: string]: unknown ``` #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `key` | `string` | Document key. | | `language` | `string` | Language code. | *** ### OvokI18nValue [#ovoki18nvalue] ```ts type OvokI18nValue = | string | { [key: string]: OvokI18nValue; }; ``` A value in an i18next document: text or a nested object. *** ### OvokLocales [#ovoklocales] ```ts type OvokLocales = object; ``` Languages of a project. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `defaultLanguage` | `string` | Default language code. | | `languages` | `string`[] | Supported language codes. | *** ### OvokLocalization [#ovoklocalization] ```ts type OvokLocalization = object; ``` A translation of one key. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `author` | `object` | Who last changed the translation. | | `author.display?` | `string` | Display name of the author. | | `author.reference` | `string` | Reference to the author. | | `date?` | `string` | ISO 8601 time of the last change. | | `id?` | `string` | ID of the translation. | | `key` | `string` | Translation key. | | `language` | `string` | Language code. | | `projectId?` | `string` | ID of the project. | | `value` | `string` | Translated text. | *** ### OvokLocalizationQuery [#ovoklocalizationquery] ```ts type OvokLocalizationQuery = object; ``` Query of `listLocalizations`. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `_count?` | `number` | Maximum number of results. | | `_offset?` | `number` | Number of results to skip. | | `_sort?` | `string` | Sort order. | | `search?` | `string` | Text to search for. | *** ### OvokLocalizationUpdate [#ovoklocalizationupdate] ```ts type OvokLocalizationUpdate = object; ``` Request to set a translation. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `value` | `string` | Translated text. | # measurements Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/measurements ## Enumerations [#enumerations] ### BloodPressureStates [#bloodpressurestates] Status reported by the blood pressure monitor for a reading. #### Enumeration Members [#enumeration-members] | Enumeration Member | Value | Description | | ------ | ------ | ------ | | `DEVICE_ERROR` | `"Unknown device error."` | The device reported an unknown error. | | `DISTURB_DETECTED` | `"Disturb Detected."` | Movement or interference was detected during the reading. | | `LOOSE_SLEEVE` | `"The sleeve is loose. Unable to analyze."` | The cuff is loose and the reading could not be analyzed. | | `REGULAR` | `"Regular"` | The reading is normal. | | `WEAK_SIGNAL` | `"Weak Signal."` | The signal was too weak. | *** ### EcgDiagnosticFlag [#ecgdiagnosticflag] Diagnostic result reported by an ECG device. #### Enumeration Members [#enumeration-members-1] | Enumeration Member | Value | Description | | ------ | ------ | ------ | | `ATRIAL_FIBRILLATION` | `"AFIB"` | Atrial fibrillation. | | `CARDIAC_ARREST` | `"Cardiac Arrest"` | Cardiac arrest. | | `ERROR` | `"ERROR"` | Device reported an error. | | `HIGH_HR` | `"High HR"` | High heart rate. | | `LEAD_OFF` | `"Lead Off"` | Electrode lead disconnected. | | `LOW_HR` | `"Low HR"` | Low heart rate. | | `POOR_WAVEFORM` | `"Poor Waveform"` | Waveform quality too poor to evaluate. | | `PVC` | `"PVC"` | Premature ventricular contraction. | | `QRS_WIDE` | `"QRS Wide"` | Wide QRS complex. | | `QTC_LONG` | `"QRS Long"` | Long QT interval, as reported by the device. | | `QTC_SHORT` | `"QRS Short"` | Short QT interval, as reported by the device. | | `REGULAR` | `"Regular"` | Regular rhythm. | | `RR_IRREGULAR` | `"Irregular RR"` | Irregular RR intervals. | *** ### MeasurementTypeKey [#measurementtypekey] Identifies the kind of a measurement; the value is the measurement type slug. #### Enumeration Members [#enumeration-members-2] | Enumeration Member | Value | Description | | ------ | ------ | ------ | | `babySleep` | `"baby-sleep"` | Baby sleep data. | | `bloodGlucose` | `"blood-glucose"` | Blood glucose reading. | | `bloodOxygenPulseRate` | `"blood-oxygen-pulse-rate"` | Pulse oximeter reading (SpO2 and pulse rate). | | `bloodPressure` | `"blood-pressure"` | Blood pressure reading. | | `bodyWeight` | `"body-weight"` | Body weight. | | `cosinussMultiParam` | `"cosinuss-multi-param"` | Cosinuss multi-parameter sensor reading. | | `ecg` | `"ecg"` | Electrocardiogram recording. | | `heartRate` | `"heart-rate"` | Heart rate. | | `heartRateVariability` | `"heart-rate-variability"` | Heart rate variability. | | `lipidPanel` | `"lipid-panel"` | Lipid panel (cholesterol and triglycerides). | | `photoUpload` | `"photo-upload"` | Uploaded photo. | | `respiratoryRate` | `"respiratory-rate"` | Respiratory rate. | | `respiratoryTherapy` | `"respiratory-therapy"` | Respiratory therapy session. | | `restingHeartRate` | `"resting-heart-rate"` | Resting heart rate. | | `spirometryPanel` | `"spirometry-panel"` | Spirometry panel. | | `stepCount` | `"step-count"` | Step count over a period. | | `symptomQuestionnaire` | `"symptom-questionnaire"` | Symptom questionnaire answers. | | `temperature` | `"body-temperature"` | Body temperature. | | `uricAcid` | `"uric-acid"` | **Deprecated** Use urineAnalysis. | | `urineAnalysis` | `"urine-analysis"` | Urine test strip analysis. | | `vo2Max` | `"vo2-max"` | VO2 max estimate. | | `walkingHeartRateAverage` | `"walking-heart-rate-average"` | Average heart rate while walking. | *** ### ObservationCode [#observationcode] LOINC (or Ovok) codes that identify observation types. #### Enumeration Members [#enumeration-members-3] | Enumeration Member | Value | Description | | ------ | ------ | ------ | | `BABY_SLEEP` | `"baby-sleep"` | Baby sleep (Ovok code). | | `BLOOD_GLUCOSE` | `"2340-8"` | Blood glucose. | | `BLOOD_PRESSURE_HEART_RATE` | `"8885-6"` | Heart rate measured with a blood pressure panel. | | `BODY_HEIGHT` | `"8302-2"` | Body height. | | `BODY_TEMPERATURE` | `"8310-5"` | Body temperature. | | `BODY_WEIGHT` | `"29463-7"` | Body weight. | | `BURNED_CALORIES` | `"41981-2"` | Burned calories. | | `CHOLESTEROL` | `"12183-0"` | Cholesterol. | | `DIASTOLIC_BLOOD_PRESSURE` | `"8462-4"` | Diastolic blood pressure. | | `ECG` | `"131328"` | ECG waveform. | | `ECG_HEART_RATE` | `"8886-4"` | Heart rate from an ECG. | | `FATIGUE` | `"94085-9"` | Fatigue level. | | `GRATITUDE` | `"91262-6"` | Gratitude. | | `HDL_CHOLESTEROL_MASS` | `"2085-9"` | HDL cholesterol, mass concentration. | | `HDL_CHOLESTEROL_MOLAR` | `"14646-4"` | HDL cholesterol, molar concentration. | | `HEART_RATE` | `"8867-4"` | Heart rate. | | `HEART_RATE_VARIABILITY` | `"80404-7"` | Heart rate variability. | | `KETONE` | `"33903-6"` | Ketones. | | `LACTATE` | `"32693-4"` | Lactate. | | `LDL_CHOLESTEROL_MASS` | `"13457-7"` | LDL cholesterol, mass concentration. | | `LDL_CHOLESTEROL_MOLAR` | `"39469-2"` | LDL cholesterol, molar concentration. | | `LIPID_PANEL` | `"100898-6"` | Lipid panel. | | `MEAN_BLOOD_PRESSURE` | `"8478-0"` | Mean blood pressure. | | `MOOD` | `"52497-5"` | Mood. | | `MUSCLE_SORENESS` | `"94086-3"` | Muscle soreness. | | `OXYGEN_SATURATION` | `"2708-6"` | Oxygen saturation (SpO2). | | `OXYGEN_SATURATION_GRAPH` | `"2708"` | Oxygen saturation waveform. | | `OXYGEN_SATURATION_HEART_RATE` | `"8889-8"` | Heart rate measured with a pulse oximeter. | | `PAIN` | `"94085-8"` | Pain level. | | `PHENX_RESPIRATORY` | `"62628-3"` | PhenX respiratory questionnaire. | | `PHOTOGRAPHIC_IMAGE` | `"72170-4"` | Photographic image. | | `PULSE_WAVE` | `"150452"` | A pulse oximeter's pulse wave (plethysmogram). | | `RESPIRATORY_RATE` | `"9279-1"` | Respiratory rate. | | `RESPIRATORY_THERAPY` | `"respiratory-therapy"` | Respiratory therapy session (Ovok code). | | `RESTING_HEART_RATE` | `"40443-4"` | Resting heart rate. | | `SLEEP_QUALITY` | `"94086-1"` | Sleep quality. | | `SPIROMETRY_PANEL` | `"62639-0"` | Spirometry panel. | | `STEPS` | `"41950-7"` | Step count. | | `STRESS_LEVEL` | `"94086-2"` | Stress level. | | `SYMPTOM` | `"45853-9"` | Symptom. | | `SYSTOLIC_BLOOD_PRESSURE` | `"8480-6"` | Systolic blood pressure. | | `TOTAL_CHOLESTEROL_HDL_RATIO` | `"9830-1"` | Ratio of total to HDL cholesterol. | | `TOTAL_CHOLESTEROL_MASS` | `"2093-3"` | Total cholesterol, mass concentration. | | `TOTAL_CHOLESTEROL_MOLAR` | `"14647-2"` | Total cholesterol, molar concentration. | | `TRIGLYCERIDES_MASS` | `"2571-8"` | Triglycerides, mass concentration. | | `TRIGLYCERIDES_MOLAR` | `"14927-8"` | Triglycerides, molar concentration. | | `URIC_ACID` | `"25548-9"` | Uric acid. | | `VO2_MAX` | `"60842-2"` | VO2 max. | | `WALKING_HEART_RATE_AVERAGE` | `"40442-6"` | Average heart rate while walking. | ## Interfaces [#interfaces] ### MeasurementsResource [#measurementsresource] Builds, saves and reads measurements as FHIR Observations, with an offline queue. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `offlineQueue` | `readonly` | [`OfflineMeasurementQueueApi`](#offlinemeasurementqueueapi) | The offline queue of measurements waiting to be sent. | #### Methods [#methods] ##### build() [#build] ```ts build(params): Promise; ``` Builds the Observations for a measurement without saving them. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `params` | [`GenerateObservationBodyParams`](#generateobservationbodyparams) | ###### Returns [#returns] `Promise`\<`Observation`[]\> ##### codesFor() [#codesfor] ```ts codesFor(types): string; ``` The comma-joined codes the types are saved under, as `latest` and FHIR `code` searches take them. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `types` | readonly [`SupportedType`](#supportedtype)[] | ###### Returns [#returns-1] `string` ##### lastForPatient() [#lastforpatient] ```ts lastForPatient( patientId, query, options? ): Promise>; ``` Reads a patient's recent observations. Calls `GET patient/{patientId}/observation`. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `patientId` | `string` | | `query` | [`LastObservationsQuery`](#lastobservationsquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<`Bundle`\<`Observation`\>\> ##### lastn() [#lastn] ```ts lastn( patientId, query, options? ): Promise>; ``` The patient's newest `max` observations of each code, in one request. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `patientId` | `string` | | `query` | [`LastnQuery`](#lastnquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<`Bundle`\<`Observation`\>\> ##### latest() [#latest] ```ts latest(params, options?): Promise>; ``` Reads the latest observation of each code for a patient. Calls `GET fhir/Observation/$lastn`. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `params` | [`GetLatestObservationsByCodeParams`](#getlatestobservationsbycodeparams) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<`Bundle`\<`Observation`\>\> ##### save() [#save] ```ts save(params, options?): Promise; ``` Builds Observations from a measurement and saves them; queued offline when they cannot be sent. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `params` | [`GenerateObservationBodyParams`](#generateobservationbodyparams) | | `options?` | [`SaveObservationsOptions`](#saveobservationsoptions) | ###### Returns [#returns-5] `Promise`\<[`SaveObservationsResult`](#saveobservationsresult)\> ###### Example [#example] ```ts const result = await ovok.measurements.save({ measurement, device }); ``` ##### saveObservationGroups() [#saveobservationgroups] ```ts saveObservationGroups(groups, options?): Promise>; ``` Many readings, each main observation first, in as few requests as fit. A request holding one reading is a transaction, atomic when the project enables FHIR transactions. A request holding several is two batches, main observations first: if it fails, some readings may be saved and others not, and saving them again is safe. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `groups` | `Observation`[][] | | `options?` | [`SaveObservationsOptions`](#saveobservationsoptions) | ###### Returns [#returns-6] `Promise`\<`Bundle`\<`Resource`\>\> ##### saveObservations() [#saveobservations] ```ts saveObservations(observations, options?): Promise; ``` One reading, main observation first, created conditionally so a retry cannot duplicate it. ###### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `observations` | `Observation`[] | | `options?` | [`SaveObservationsOptions`](#saveobservationsoptions) | ###### Returns [#returns-7] `Promise`\<[`SaveObservationsResult`](#saveobservationsresult)\> *** ### Sample [#sample] HealthKit quantity sample, as delivered by Apple Health. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `device?` | [`HKDevice`](#hkdevice) | HealthKit device that produced the sample. | | `endDate` | `string` | ISO 8601 end of the sample. | | `metadata` | `object` | Sample metadata. | | `quantity` | `number` | Sampled value, in `unit`. | | `quantityType` | `string` | HealthKit quantity type identifier. | | `sourceRevision` | `object` | App and OS that recorded the sample. | | `sourceRevision.operatingSystemVersion` | `string` | Operating system version of the source. | | `sourceRevision.productType` | `string` | Hardware product type of the source. | | `sourceRevision.source` | `object` | The app that wrote the sample. | | `sourceRevision.source.bundleIdentifier` | `string` | Bundle identifier of the source app. | | `sourceRevision.source.name` | `string` | Name of the source app. | | `sourceRevision.version` | `string` | Version of the source app. | | `startDate` | `string` | ISO 8601 start of the sample. | | `unit` | `string` | Unit of `quantity`. | | `uuid` | `string` | HealthKit sample UUID. | ## Type Aliases [#type-aliases] ### BabySleepMeasurement [#babysleepmeasurement] ```ts type BabySleepMeasurement = Measurement & object; ``` One BabySleep observation, such as a clip sample or a session summary. Core preserves the coded components supplied by the device adapter rather than assigning vendor-specific meaning to sleep states, posture, or device status. * #### Type Declaration [#type-declaration] ##### components [#components] ```ts components: ObservationComponent[]; ``` Coded observation values supplied by the device adapter. ##### measurementTypeKey [#measurementtypekey-1] ```ts measurementTypeKey: babySleep; ``` Always `babySleep`. *** ### BloodGlucoseMeasurement [#bloodglucosemeasurement] ```ts type BloodGlucoseMeasurement = Measurement & object; ``` Blood glucose measurement. #### Type Declaration [#type-declaration-1] ##### bloodGlucose? [#bloodglucose] ```ts bloodGlucose?: number; ``` Blood glucose value as reported by the device. ##### measurementTypeKey [#measurementtypekey-2] ```ts measurementTypeKey: bloodGlucose; ``` Always `bloodGlucose`. *** ### BloodPressureMeasurement [#bloodpressuremeasurement] ```ts type BloodPressureMeasurement = Measurement & object; ``` Blood pressure measurement. #### Type Declaration [#type-declaration-2] ##### diastolic? [#diastolic] ```ts diastolic?: number; ``` Diastolic pressure, in mmHg. ##### heartRate? [#heartrate] ```ts heartRate?: number; ``` Heart rate, in beats per minute. ##### irregularHeartbeat? [#irregularheartbeat] ```ts irregularHeartbeat?: boolean; ``` Whether the device detected an irregular heartbeat during the reading. ##### meanArterialPressure? [#meanarterialpressure] ```ts meanArterialPressure?: number; ``` Mean arterial pressure, in mmHg. Reported by the device rather than derived. ##### measurementTypeKey [#measurementtypekey-3] ```ts measurementTypeKey: bloodPressure; ``` Always `bloodPressure`. ##### memorySlot? [#memoryslot] ```ts memorySlot?: number; ``` User memory slot reported by a device, when available. ##### status? [#status] ```ts status?: BloodPressureStates; ``` Device status of the reading. ##### systolic? [#systolic] ```ts systolic?: number; ``` Systolic pressure, in mmHg. *** ### BodyTemperatureMeasurement [#bodytemperaturemeasurement] ```ts type BodyTemperatureMeasurement = Measurement & object; ``` Body temperature measurement. #### Type Declaration [#type-declaration-3] ##### bodyTemp? [#bodytemp] ```ts bodyTemp?: number; ``` Body temperature as reported by the device. ##### measurementTypeKey [#measurementtypekey-4] ```ts measurementTypeKey: temperature; ``` Always `temperature`. *** ### BodyWeightMeasurement [#bodyweightmeasurement] ```ts type BodyWeightMeasurement = Measurement & object; ``` Body weight measurement. #### Type Declaration [#type-declaration-4] ##### bodyWeight? [#bodyweight] ```ts bodyWeight?: number; ``` Body weight value as reported by the device. ##### measurementTypeKey [#measurementtypekey-5] ```ts measurementTypeKey: bodyWeight; ``` Always `bodyWeight`. ##### timestamp? [#timestamp] ```ts timestamp?: number; ``` Device timestamp of the reading, as a number. *** ### BuildObservationsParams [#buildobservationsparams] ```ts type BuildObservationsParams = GenerateObservationBodyParams; ``` Describes one measurement to turn into Observations: its type, values, device and time. *** ### EcgMeasurement [#ecgmeasurement] ```ts type EcgMeasurement = Measurement & object; ``` ECG measurement. #### Type Declaration [#type-declaration-5] ##### diagnosticResult? [#diagnosticresult] ```ts diagnosticResult?: EcgDiagnosticFlag; ``` Diagnostic result reported by the device. ##### diagramPoints? [#diagrampoints] ```ts diagramPoints?: number[]; ``` Waveform sample points. ##### duration? [#duration] ```ts duration?: number; ``` Duration of the ECG in seconds ##### heartRate? [#heartrate-1] ```ts heartRate?: number; ``` Heart rate, in beats per minute. ##### measurementTypeKey [#measurementtypekey-6] ```ts measurementTypeKey: ecg; ``` Always `ecg`. ##### recordedAt? [#recordedat] ```ts recordedAt?: Date; ``` Time at which the device started recording the ECG. *** ### GenerateObservationBodyParams [#generateobservationbodyparams] ```ts type GenerateObservationBodyParams = object; ``` Input for building an Observation body from a measurement. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `device?` | [`MeasurementDevice`](#measurementdevice) | Device that took the measurement. | | `effectiveDateTime?` | `Date` | When the measurement was taken. | | `measurement` | [`Measurement`](#measurement) | The measurement to convert. | | `patientId?` | `string` | ID of the patient the measurement belongs to. | | `sourceId?` | `string` | Stable ID from the originating device reading. | *** ### GetLatestObservationsByCodeParams [#getlatestobservationsbycodeparams] ```ts type GetLatestObservationsByCodeParams = object & ( | { me: true; } | { me: false; patientId: string; }); ``` Parameters of `getLatestObservationsByCodes`: either the signed-in user (`me`) or a patient. #### Type Declaration [#type-declaration-6] ##### codes [#codes] ```ts codes: string[]; ``` Observation codes to fetch the latest of. ##### date? [#date] ```ts date?: string; ``` Only observations on or after this date. *** ### HeartRateMeasurement [#heartratemeasurement] ```ts type HeartRateMeasurement = Measurement & object; ``` Heart rate measurement. #### Type Declaration [#type-declaration-7] ##### heartRate? [#heartrate-2] ```ts heartRate?: number; ``` Heart rate, in beats per minute. ##### measurementTypeKey [#measurementtypekey-7] ```ts measurementTypeKey: heartRate; ``` Always `heartRate`. *** ### HeartRateVariabilityMeasurement [#heartratevariabilitymeasurement] ```ts type HeartRateVariabilityMeasurement = Measurement & object; ``` Heart rate variability measurement. #### Type Declaration [#type-declaration-8] ##### heartRateVariability? [#heartratevariability] ```ts heartRateVariability?: number; ``` Heart rate variability value as reported by the device. ##### measurementTypeKey [#measurementtypekey-8] ```ts measurementTypeKey: heartRateVariability; ``` Always `heartRateVariability`. *** ### HKDevice [#hkdevice] ```ts type HKDevice = object; ``` HealthKit device description. #### Properties [#properties-3] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `firmwareVersion` | `readonly` | `string` \| `null` | Firmware version, or null if unknown. | | `hardwareVersion` | `readonly` | `string` | Hardware version. | | `localIdentifier` | `readonly` | `string` \| `null` | Manufacturer-local identifier, or null. | | `manufacturer` | `readonly` | `string` | Device manufacturer. | | `model` | `readonly` | `string` | Device model. | | `name` | `readonly` | `string` | Device name. | | `softwareVersion` | `readonly` | `string` | Software version. | | `udiDeviceIdentifier` | `readonly` | `string` \| `null` | Unique device identifier (UDI), or null. | *** ### LastnQuery [#lastnquery] ```ts type LastnQuery = QueryParams & object; ``` `$lastn` search parameters: the comma-joined codes, how many of each, and any others such as `_elements`. #### Type Declaration [#type-declaration-9] ##### code [#code] ```ts code: string; ``` Comma-joined observation codes. ##### max? [#max] ```ts max?: number; ``` Most observations to return per code. *** ### LastObservationsQuery [#lastobservationsquery] ```ts type LastObservationsQuery = object; ``` Codes and an optional per-code limit for a patient's recent observations. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `code` | `string` | Comma-joined observation codes. | | `max?` | `number` | Most observations to return per code. | *** ### LatestObservationsParams [#latestobservationsparams] ```ts type LatestObservationsParams = GetLatestObservationsByCodeParams; ``` Which patient and codes to read the latest observations for. *** ### LipidPanelMeasurement [#lipidpanelmeasurement] ```ts type LipidPanelMeasurement = Measurement & object; ``` Lipid panel measurement. #### Type Declaration [#type-declaration-10] ##### hdlCholesterol? [#hdlcholesterol] ```ts hdlCholesterol?: number; ``` HDL cholesterol, in `unit`. ##### ldlCholesterol? [#ldlcholesterol] ```ts ldlCholesterol?: number; ``` LDL cholesterol, in `unit`. ##### measurementTypeKey [#measurementtypekey-9] ```ts measurementTypeKey: lipidPanel; ``` Always `lipidPanel`. ##### totalCholesterol? [#totalcholesterol] ```ts totalCholesterol?: number; ``` Total cholesterol, in `unit`. ##### totalCholesterolHdlRatio? [#totalcholesterolhdlratio] ```ts totalCholesterolHdlRatio?: number; ``` Ratio of total to HDL cholesterol. ##### triglycerides? [#triglycerides] ```ts triglycerides?: number; ``` Triglycerides, in `unit`. ##### unit [#unit] ```ts unit: "mg/dL" | "mmol/L"; ``` Concentration unit of the lipid values. *** ### Measurement [#measurement] ```ts type Measurement = object; ``` Fields shared by every measurement. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `device?` | `Reference` | Reference to the device that took the reading. | | `id?` | `string` | Observation ID, when the measurement is stored. | | `measurementTypeKey` | [`MeasurementTypeKey`](#measurementtypekey) | Kind of measurement. | | `recordedAt?` | `Date` | Time the reading was recorded. | *** ### MeasurementCodeTypes [#measurementcodetypes] ```ts type MeasurementCodeTypes = Parameters[0]; ``` The measurement types to resolve to observation codes. *** ### MeasurementDevice [#measurementdevice] ```ts type MeasurementDevice = object; ``` Metadata attached to generated FHIR Observations. `id` is a runtime identifier used to associate measurements with a device. It is not persisted as `Observation.device.identifier`, because its meaning can vary by platform (for example, a Bluetooth address on Android and a local UUID on iOS). The manufacturer-reported serial number (`sn`) is used for that FHIR identifier when available; otherwise, the identifier is omitted. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `batteryPercentage?` | `number` | Remaining charge, 0 to 100. Device state rather than a patient observation, so it travels with the device on an observation instead of becoming a measurement of its own. | | `id` | `string` | Runtime association key; not written to the FHIR device identifier. | | `localName` | `string` | Local name the device advertises. | | `manufacturerData` | `string` | Raw manufacturer data advertised by the device. | | `manufacturerName?` | `string` | Manufacturer name reported by the device. | | `model?` | `string` | Model reported by the device. | | `name` | `string` | Advertised device name. | | `sn` | `string` | Manufacturer-reported serial number. | | `variant?` | `object` | The brand and model the advertised name identified, when one decoder serves several products (the mobile SDK's `deviceData.variant`). Preferred over `manufacturerName` and `model`, which often describe the Bluetooth module rather than the product. | | `variant.manufacturer` | `string` | Brand of the identified product. | | `variant.model` | `string` | Model of the identified product. | *** ### MeasurementSeries [#measurementseries] ```ts type MeasurementSeries = object; ``` One kind of measurement taken at a fixed interval, such as the heart rate a strap sends every second: one value per slot for each measured property, and `null` for a slot nothing arrived in. * #### Properties [#properties-7] | Property | Type | Description | | ------ | ------ | ------ | | `measurementTypeKey` | [`MeasurementTypeKey`](#measurementtypekey) | Kind of measurement the series holds. | | `periodMs` | `number` | Milliseconds from one slot to the next. | | `start` | `Date` | When the first slot starts. | | `values` | `Partial`\<`Record`\<`string`, `ReadonlyArray`\<`number` \| `null`\>\>\> | By measured property (the keys `MEASUREMENT_FIELDS` lists), one value per slot. | *** ### OfflineMeasurementFailure [#offlinemeasurementfailure] ```ts type OfflineMeasurementFailure = object; ``` A summary of why the last attempt to send a measurement failed. #### Properties [#properties-8] | Property | Type | Description | | ------ | ------ | ------ | | `code?` | `string` | Error code, when it has one. | | `name` | `string` | Error name. | | `status?` | `number` | HTTP status, when the failure was a response. | *** ### OfflineMeasurementFlushOptions [#offlinemeasurementflushoptions] ```ts type OfflineMeasurementFlushOptions = object; ``` Options for retrying queued measurements. #### Properties [#properties-9] | Property | Type | Description | | ------ | ------ | ------ | | `includeExhausted?` | `boolean` | Also retry measurements that ran out of retries. | | `resetExhausted?` | `boolean` | Give exhausted measurements a fresh set of retries before flushing. | *** ### OfflineMeasurementFlushResult [#offlinemeasurementflushresult] ```ts type OfflineMeasurementFlushResult = object; ``` The outcome of a flush, with counts and per-measurement responses. #### Properties [#properties-10] | Property | Type | Description | | ------ | ------ | ------ | | `attempted` | `number` | Measurements a send was tried for. | | `exhausted` | `number` | Measurements that ran out of retries and are held back. | | `failures` | `Record`\<`string`, [`OfflineMeasurementFailure`](#offlinemeasurementfailure)\> | The last failure for each measurement that has one, by queue id. | | `queued` | `number` | Measurements still waiting to be retried. | | `responses` | `Record`\<`string`, `Bundle`\> | The server response for each saved measurement, by queue id. | | `saved` | `number` | Measurements sent and removed from the queue. | *** ### OfflineMeasurementQueueApi [#offlinemeasurementqueueapi] ```ts type OfflineMeasurementQueueApi = object; ``` Controls for the offline measurement queue. #### Properties [#properties-11] | Property | Type | Description | | ------ | ------ | ------ | | `flush` | (`options?`, `requestOptions?`) => `Promise`\<[`OfflineMeasurementFlushResult`](#offlinemeasurementflushresult)\> | Sends queued measurements that are due and the signed-in account owns. | *** ### PulseOximeterMeasurement [#pulseoximetermeasurement] ```ts type PulseOximeterMeasurement = Measurement & object; ``` Pulse oximeter measurement. #### Type Declaration [#type-declaration-11] ##### bloodOxygen? [#bloodoxygen] ```ts bloodOxygen?: number; ``` Blood oxygen saturation (SpO2), in percent. ##### measurementTypeKey [#measurementtypekey-10] ```ts measurementTypeKey: bloodOxygenPulseRate; ``` Always `bloodOxygenPulseRate`. ##### perfusionIndex? [#perfusionindex] ```ts perfusionIndex?: number; ``` Perfusion index. ##### pulseRate? [#pulserate] ```ts pulseRate?: number; ``` Pulse rate, in beats per minute. ##### pulseWave? [#pulsewave] ```ts pulseWave?: number; ``` One pulse wave sample, in the sensor's own units; a series holds the wave at the sensor's rate. ##### rrInterval? [#rrinterval] ```ts rrInterval?: number; ``` Interval between consecutive heartbeats. *** ### RespiratoryRateMeasurement [#respiratoryratemeasurement] ```ts type RespiratoryRateMeasurement = Measurement & object; ``` Respiratory rate measurement. #### Type Declaration [#type-declaration-12] ##### measurementTypeKey [#measurementtypekey-11] ```ts measurementTypeKey: respiratoryRate; ``` Always `respiratoryRate`. ##### respiratoryRate? [#respiratoryrate] ```ts respiratoryRate?: number; ``` Respiratory rate, in breaths per minute. *** ### RespiratoryTherapyMeasurement [#respiratorytherapymeasurement] ```ts type RespiratoryTherapyMeasurement = Measurement & object; ``` A coded set of respiratory-therapy observations. Keeping the values as FHIR components lets devices and consuming applications add their own metrics without Core assigning device-specific meaning to them. * #### Type Declaration [#type-declaration-13] ##### components [#components-1] ```ts components: ObservationComponent[]; ``` Coded observation values. ##### measurementTypeKey [#measurementtypekey-12] ```ts measurementTypeKey: respiratoryTherapy; ``` Always `respiratoryTherapy`. *** ### RestingHeartRateMeasurement [#restingheartratemeasurement] ```ts type RestingHeartRateMeasurement = Measurement & object; ``` Resting heart rate measurement. #### Type Declaration [#type-declaration-14] ##### measurementTypeKey [#measurementtypekey-13] ```ts measurementTypeKey: restingHeartRate; ``` Always `restingHeartRate`. ##### restingHeartRate? [#restingheartrate] ```ts restingHeartRate?: number; ``` Resting heart rate, in beats per minute. *** ### SaveObservationsOptions [#saveobservationsoptions] ```ts type SaveObservationsOptions = RequestOptions & object; ``` Request options plus how to identify and write the readings. #### Type Declaration [#type-declaration-15] ##### identifierSystems? [#identifiersystems] ```ts identifierSystems?: readonly string[]; ``` Identifier systems that name a reading for good; the SDK's device-reading id always counts. ##### replace? [#replace] ```ts replace?: boolean; ``` Write over the observation saved under the same reading identifiers, for a value that changes. *** ### SaveObservationsResult [#saveobservationsresult] ```ts type SaveObservationsResult = | { response: Bundle; status: "saved"; } | { queueId: string; status: "queued"; }; ``` Either the saved bundle, or the queue id of a reading kept for a later retry. #### Union Members [#union-members] ##### Type Literal [#type-literal] ```ts { response: Bundle; status: "saved"; } ``` ###### response [#response] ```ts response: Bundle; ``` The server's response bundle. ###### status [#status-1] ```ts status: "saved"; ``` The server accepted the reading. *** ##### Type Literal [#type-literal-1] ```ts { queueId: string; status: "queued"; } ``` ###### queueId [#queueid] ```ts queueId: string; ``` Id of the queued reading, as used in a flush result. ###### status [#status-2] ```ts status: "queued"; ``` The reading is stored offline and will be retried. *** ### SpirometerValue [#spirometervalue] ```ts type SpirometerValue = object; ``` One coded spirometer value. #### Properties [#properties-12] | Property | Type | Description | | ------ | ------ | ------ | | `code` | `CodeableConcept` | Code identifying the value. | | `value?` | `object` | The value. | | `value.string` | `string` | Value as a string. | *** ### SpirometryMeasurement [#spirometrymeasurement] ```ts type SpirometryMeasurement = Measurement & object; ``` Spirometry measurement. #### Type Declaration [#type-declaration-16] ##### fef25? [#fef25] ```ts fef25?: string; ``` Forced expiratory flow at 25% of FVC. ##### fef2575? [#fef2575] ```ts fef2575?: string; ``` Forced expiratory flow between 25% and 75% of FVC. ##### fef50? [#fef50] ```ts fef50?: string; ``` Forced expiratory flow at 50% of FVC. ##### fef75? [#fef75] ```ts fef75?: string; ``` Forced expiratory flow at 75% of FVC. ###### fev0.5? [#fev05] ```ts "fev0.5"?: string; ``` Forced expiratory volume in 0.5 seconds. ##### fev1? [#fev1] ```ts fev1?: string; ``` Forced expiratory volume in 1 second. ##### fev1/fvc? [#fev1fvc] ```ts "fev1/fvc"?: string; ``` FEV1 to FVC ratio. ##### fvc? [#fvc] ```ts fvc?: string; ``` Forced vital capacity. ##### pef? [#pef] ```ts pef?: string; ``` Peak expiratory flow. ##### spirometryValues [#spirometryvalues] ```ts spirometryValues: SpirometerValue[]; ``` Coded spirometry values. *** ### StepCountMeasurement [#stepcountmeasurement] ```ts type StepCountMeasurement = Measurement & object; ``` Step count measurement. #### Type Declaration [#type-declaration-17] ##### end? [#end] ```ts end?: Date; ``` End of the counted period. ##### measurementTypeKey [#measurementtypekey-14] ```ts measurementTypeKey: stepCount; ``` Always `stepCount`. ##### start? [#start] ```ts start?: Date; ``` Start of the counted period. ##### stepCount? [#stepcount] ```ts stepCount?: number; ``` Number of steps. *** ### SupportedType [#supportedtype] ```ts type SupportedType = Exclude; ``` Measurement types that can be built from observations. *** ### UrineAnalysisValue [#urineanalysisvalue] ```ts type UrineAnalysisValue = object; ``` One coded urine analysis value. #### Properties [#properties-13] | Property | Type | Description | | ------ | ------ | ------ | | `code` | `CodeableConcept` | Code identifying the value. | | `value?` | `object` | The value. | | `value.string` | `string` | Value as a string. | *** ### UrineAnalyteDefinition [#urineanalytedefinition] ```ts type UrineAnalyteDefinition = object; ``` Mapping of an analyte key to its LOINC code and display name. #### Properties [#properties-14] | Property | Type | Description | | ------ | ------ | ------ | | `code` | `string` | LOINC code of the analyte. | | `display` | `string` | Display name of the analyte. | | `key` | [`UrineAnalyteKey`](#urineanalytekey) | Analyte key. | | `presence?` | `boolean` | A presence test, saved as a positive or negative coded value instead of a quantity. | | `unit?` | `string` | Human-readable UCUM display unit, when the analyte has one. | | `unitCode?` | `string` | UCUM code sent in Observation.valueQuantity.code. | *** ### UrineAnalyteKey [#urineanalytekey] ```ts type UrineAnalyteKey = | "uro" | "bil" | "ket" | "glu" | "pro" | "ph" | "bld" | "nit" | "leu" | "sg" | "vc" | "mal" | "cr" | "uca"; ``` Short key of a urine test strip analyte. *** ### UrineAnalyzeMeasurement [#urineanalyzemeasurement] ```ts type UrineAnalyzeMeasurement = Measurement & object; ``` Urine test strip measurement. #### Type Declaration [#type-declaration-18] ##### bil? [#bil] ```ts bil?: number; ``` Bilirubin. ##### bld? [#bld] ```ts bld?: number; ``` Blood (hemoglobin). ##### cr? [#cr] ```ts cr?: number; ``` Creatinine. ##### glu? [#glu] ```ts glu?: number; ``` Glucose. ##### ket? [#ket] ```ts ket?: number; ``` Ketones. ##### leu? [#leu] ```ts leu?: number; ``` Leukocyte esterase. ##### mal? [#mal] ```ts mal?: number; ``` Microalbumin. ##### measurementTypeKey [#measurementtypekey-15] ```ts measurementTypeKey: | urineAnalysis | uricAcid; ``` `urineAnalysis` or the deprecated `uricAcid`. ##### nit? [#nit] ```ts nit?: number; ``` Nitrite. ##### ph? [#ph] ```ts ph?: number; ``` Urine pH. ##### pro? [#pro] ```ts pro?: number; ``` Protein. ##### recordedAt? [#recordedat-1] ```ts recordedAt?: Date; ``` Time at which the analyzer recorded the strip. ##### sg? [#sg] ```ts sg?: number; ``` Specific gravity. ##### uca? [#uca] ```ts uca?: number; ``` Urate. ##### urineValues [#urinevalues] ```ts urineValues: UrineAnalysisValue[]; ``` Coded analyte values. ##### uro? [#uro] ```ts uro?: number; ``` Urobilinogen. ##### vc? [#vc] ```ts vc?: number; ``` Ascorbate (vitamin C). *** ### Vo2MaxMeasurement [#vo2maxmeasurement] ```ts type Vo2MaxMeasurement = Measurement & object; ``` VO2 max measurement. #### Type Declaration [#type-declaration-19] ##### measurementTypeKey [#measurementtypekey-16] ```ts measurementTypeKey: vo2Max; ``` Always `vo2Max`. ##### vo2Max? [#vo2max] ```ts vo2Max?: number; ``` VO2 max value as reported by the device. *** ### WalkingHeartRateAverageMeasurement [#walkingheartrateaveragemeasurement] ```ts type WalkingHeartRateAverageMeasurement = Measurement & object; ``` Average walking heart rate measurement. #### Type Declaration [#type-declaration-20] ##### measurementTypeKey [#measurementtypekey-17] ```ts measurementTypeKey: walkingHeartRateAverage; ``` Always `walkingHeartRateAverage`. ##### walkingHeartRateAverage? [#walkingheartrateaverage] ```ts walkingHeartRateAverage?: number; ``` Average heart rate while walking, in beats per minute. ## Variables [#variables] ### PulseRhythmCoding [#pulserhythmcoding] ```ts const PulseRhythmCoding: object; ``` SNOMED CT concepts used to represent the result of a blood-pressure rhythm check. #### Type Declaration [#type-declaration-21] ##### irregular [#irregular] ```ts readonly irregular: "61086009" = "61086009"; ``` Irregular rhythm. ##### irregularlyIrregular [#irregularlyirregular] ```ts readonly irregularlyIrregular: "271637005" = "271637005"; ``` Irregularly irregular rhythm. ##### observation [#observation] ```ts readonly observation: "364095004" = "364095004"; ``` Code of the rhythm observation. ##### regular [#regular] ```ts readonly regular: "271636001" = "271636001"; ``` Regular rhythm. ##### regularlyIrregular [#regularlyirregular] ```ts readonly regularlyIrregular: "271638000" = "271638000"; ``` Regularly irregular rhythm. ##### system [#system] ```ts readonly system: "http://snomed.info/sct" = "http://snomed.info/sct"; ``` Coding system URI (SNOMED CT). *** ### URINE\_ANALYTE\_DEFINITIONS [#urine_analyte_definitions] ```ts const URINE_ANALYTE_DEFINITIONS: readonly UrineAnalyteDefinition[]; ``` LOINC mappings for the analytes returned by Contec's BC401 strips. These are exported so Native declarations and consuming apps can describe the same analytes without maintaining a second, drifting table. * *** ### UrinePresenceCoding [#urinepresencecoding] ```ts const UrinePresenceCoding: object; ``` SNOMED CT results of a urine presence test such as nitrite. #### Type Declaration [#type-declaration-22] ##### negative [#negative] ```ts readonly negative: "260385009" = "260385009"; ``` Negative. ##### positive [#positive] ```ts readonly positive: "10828004" = "10828004"; ``` Positive. ##### system [#system-1] ```ts readonly system: "http://snomed.info/sct" = "http://snomed.info/sct"; ``` Coding system URI (SNOMED CT). ## Functions [#functions] ### observationCodesForTypes() [#observationcodesfortypes] ```ts function observationCodesForTypes(types): string; ``` Returns the comma-separated observation codes to search for the given measurement types. #### Parameters [#parameters-8] | Parameter | Type | | ------ | ------ | | `types` | readonly [`SupportedType`](#supportedtype)[] | #### Returns [#returns-8] `string` # Ovok client Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/ovok-client ## Classes [#classes] ### MemoryStorage [#memorystorage] In-memory `OvokStorage` that loses its data when the process ends. #### Implements [#implements] - [`OvokStorage`](#ovokstorage) #### Constructors [#constructors] ##### Constructor [#constructor] ```ts new MemoryStorage(): MemoryStorage; ``` ###### Returns [#returns] [`MemoryStorage`](#memorystorage) #### Methods [#methods] ##### getItem() [#getitem] ```ts getItem(key): string | null; ``` Returns the stored value, or `null` when the key is absent. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `key` | `string` | ###### Returns [#returns-1] `string` \| `null` ###### Implementation of [#implementation-of] [`OvokStorage`](#ovokstorage).[`getItem`](#getitem-1) ##### removeItem() [#removeitem] ```ts removeItem(key): void; ``` Deletes a key. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `key` | `string` | ###### Returns [#returns-2] `void` ###### Implementation of [#implementation-of-1] [`OvokStorage`](#ovokstorage).[`removeItem`](#removeitem-1) ##### setItem() [#setitem] ```ts setItem(key, value): void; ``` Stores a value under a key. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `key` | `string` | | `value` | `string` | ###### Returns [#returns-3] `void` ###### Implementation of [#implementation-of-2] [`OvokStorage`](#ovokstorage).[`setItem`](#setitem-1) *** ### Ovok [#ovok] One client per tenant; each namespace mirrors an area of the Ovok API. #### Constructors [#constructors-1] ##### Constructor [#constructor-1] ```ts new Ovok(config): Ovok; ``` ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `config` | [`OvokConfig`](#ovokconfig) | ###### Returns [#returns-4] [`Ovok`](#ovok) #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `accounts` | `readonly` | [`AccountsResource`](/web-sdk/core/reference/core/accounts#accountsresource) | Accounts of the signed-in user. | | `ai` | `readonly` | [`AiResource`](/web-sdk/core/reference/core/ai#airesource) | AI sessions. | | `auth` | `readonly` | [`AuthResource`](/web-sdk/core/reference/core/auth#authresource) | Sign-in, registration and password routes. | | `bots` | `readonly` | [`BotsResource`](/web-sdk/core/reference/core/bots#botsresource) | Bot execution. | | `cms` | `readonly` | [`CmsResource`](/web-sdk/core/reference/core/cms#cmsresource) | Content management. | | `consent` | `readonly` | [`ConsentResource`](/web-sdk/core/reference/core/consent#consentresource) | Consent of the signed-in user. | | `content` | `readonly` | [`ContentResource`](/web-sdk/core/reference/core/content#contentresource) | Project content. | | `documents` | `readonly` | [`DocumentsResource`](/web-sdk/core/reference/core/documents#documentsresource) | Documents. | | `email` | `readonly` | [`EmailResource`](/web-sdk/core/reference/core/email#emailresource) | Email templates. | | `fhir` | `readonly` | [`FhirResource`](/web-sdk/core/reference/core/fhir#fhirresource) | FHIR resource operations. | | `health` | `readonly` | [`HealthResource`](/web-sdk/core/reference/core/health#healthresource) | Server health check. | | `invites` | `readonly` | [`InvitesResource`](/web-sdk/core/reference/core/invites#invitesresource) | Invites to share records or join care. | | `locales` | `readonly` | [`LocalesResource`](/web-sdk/core/reference/core/localization#localesresource) | Project languages. | | `localizations` | `readonly` | [`LocalizationsResource`](/web-sdk/core/reference/core/localization#localizationsresource) | Translations. | | `measurements` | `readonly` | [`MeasurementsResource`](/web-sdk/core/reference/core/measurements#measurementsresource) | Saving and reading measurements. | | `patient` | `readonly` | [`PatientResource`](/web-sdk/core/reference/core/patient#patientresource) | The signed-in patient's data. | | `projects` | `readonly` | [`ProjectsResource`](/web-sdk/core/reference/core/projects#projectsresource) | Project administration. | | `questionnaireResponses` | `readonly` | [`QuestionnaireResponsesResource`](/web-sdk/core/reference/core/questionnaires#questionnaireresponsesresource) | Questionnaire responses. | | `questionnaires` | `readonly` | [`QuestionnairesResource`](/web-sdk/core/reference/core/questionnaires#questionnairesresource) | Questionnaires. | | `realtime` | `readonly` | [`RealtimeResource`](/web-sdk/core/reference/core/realtime#realtimeresource) | Real-time subscriptions. | | `session` | `readonly` | [`SessionResource`](/web-sdk/core/reference/core/session#sessionresource) | The current user session. | | `sharing` | `readonly` | [`SharingResource`](/web-sdk/core/reference/core/sharing#sharingresource) | Patient sharing. | | `signals` | `readonly` | [`SignalsResource`](/web-sdk/core/reference/core/signals#signalsresource) | Signals data. | | `slim` | `readonly` | [`SlimResource`](/web-sdk/core/reference/core/slim#slimresource) | Slim API routes. | | `videoCalls` | `readonly` | [`VideoCallsResource`](/web-sdk/core/reference/core/videocalls#videocallsresource) | Video calls. | | `wearables` | `readonly` | [`WearablesResource`](/web-sdk/core/reference/core/wearables#wearablesresource) | Wearable connections. | ## Interfaces [#interfaces] ### OvokStorage [#ovokstorage] Key-value storage the client keeps sessions in; every method may be sync or async. #### Methods [#methods-1] ##### getItem() [#getitem-1] ```ts getItem(key): string | Promise | null; ``` Returns the stored value, or `null` when the key is absent. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `key` | `string` | ###### Returns [#returns-5] `string` \| `Promise`\<`string` \| `null`\> \| `null` ##### removeItem() [#removeitem-1] ```ts removeItem(key): void | Promise; ``` Deletes a key. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `key` | `string` | ###### Returns [#returns-6] `void` \| `Promise`\<`void`\> ##### setItem() [#setitem-1] ```ts setItem(key, value): void | Promise; ``` Stores a value under a key. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `key` | `string` | | `value` | `string` | ###### Returns [#returns-7] `void` \| `Promise`\<`void`\> ## Type Aliases [#type-aliases] ### HttpMethod [#httpmethod] ```ts type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE"; ``` HTTP methods the client sends. *** ### OvokBaseConfig [#ovokbaseconfig] ```ts type OvokBaseConfig = object; ``` Options shared by every client configuration. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `baseUrl` | `string` | Absolute http(s) URL of the Ovok API. | | `fetch?` | [`OvokFetch`](#ovokfetch) | Custom fetch implementation. Defaults to the global `fetch`. | | `fhirPath?` | `string` | Path of the FHIR API under `baseUrl`. Defaults to `fhir`. | | `maxNetworkRetries?` | `number` | Retries after a network failure. Defaults to 2. | | `onUnauthenticated?` | (`reason`) => `void` | Called when the session can no longer be refreshed. | | `storage?` | [`OvokStorage`](#ovokstorage) | Where the session is kept. Defaults to in-memory storage. | | `tenantCode` | `string` | Code of the tenant the client works in. | | `timeoutMs?` | `number` | Request timeout, in milliseconds. Defaults to 30000. | *** ### OvokConfig [#ovokconfig] ```ts type OvokConfig = OvokBaseConfig & ( | OvokUserClientConfig | OvokMachineClientConfig); ``` Configuration of the `Ovok` client. A `clientSecret` (with `clientId`) selects server-side machine credentials, which are rejected in a browser. *** ### OvokFetch [#ovokfetch] ```ts type OvokFetch = (url, init) => Promise; ``` Fetch implementation used for every request. #### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `url` | `string` | | `init` | `RequestInit` | #### Returns [#returns-8] `Promise`\<`Response`\> *** ### OvokMachineClientConfig [#ovokmachineclientconfig] ```ts type OvokMachineClientConfig = object; ``` Client configuration for server-side machine credentials. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `clientId` | `string` | ID of the client application. | | `clientSecret` | `string` | Secret of the client application. | *** ### OvokUnauthenticatedReason [#ovokunauthenticatedreason] ```ts type OvokUnauthenticatedReason = object; ``` Why the client lost its session. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `status` | `number` | HTTP status of the rejection. | | `type` | `"refresh-rejected"` | The refresh token was rejected by the server. | *** ### OvokUserClientConfig [#ovokuserclientconfig] ```ts type OvokUserClientConfig = object; ``` Client configuration for end users, without a secret. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `clientId?` | `string` | ID of the client application, when one is used. | | `clientSecret?` | `undefined` | Not allowed for user clients. | *** ### Page [#page] ```ts type Page = object; ``` One page of a list result. #### Type Parameters [#type-parameters] | Type Parameter | | ------ | | `T` | #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `data` | `T`[] | Items on this page. | | `hasMore` | `boolean` | `true` when another page follows. | | `total` | `number` \| `null` | Total number of items, or `null` when the server does not report it. | *** ### PagePromise [#pagepromise] ```ts type PagePromise = Promise> & AsyncIterable; ``` Await it for the first page, or `for await` over it to walk every page. #### Type Parameters [#type-parameters-1] | Type Parameter | | ------ | | `T` | *** ### QueryParams [#queryparams] ```ts type QueryParams = Record; ``` Query parameters by name. *** ### QueryValue [#queryvalue] ```ts type QueryValue = string | number | boolean | readonly string[] | undefined; ``` A query parameter value; an array repeats the parameter, and undefined omits it. *** ### RequestOptions [#requestoptions] ```ts type RequestOptions = object; ``` Per-request options. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `signal?` | `AbortSignal` | Aborts the request when signalled. | | `timeoutMs?` | `number` | Timeout in milliseconds; overrides the client's default. | # patient Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/patient ## Classes [#classes] ### AppointmentsResource [#appointmentsresource] Appointments of the patient. #### Extends [#extends] - [`FhirRecordsResource`](#fhirrecordsresource)\<`"Appointment"`\> #### Methods [#methods] ##### create() [#create] ```ts create(appointment, options?): Promise; ``` Creates an appointment. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `appointment` | `Appointment` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<`Appointment`\> ##### list() [#list] ```ts list(params?, options?): Promise; ``` Lists the first page of matching resources. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `params?` | [`QueryParams`](/web-sdk/core/reference/core/ovok-client#queryparams) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<`Appointment`[]\> ###### Inherited from [#inherited-from] [`FhirRecordsResource`](#fhirrecordsresource).[`list`](#list-2) ##### retrieve() [#retrieve] ```ts retrieve(id, options?): Promise; ``` Reads one resource by ID. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `id` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<`Appointment`\> ###### Inherited from [#inherited-from-1] [`FhirRecordsResource`](#fhirrecordsresource).[`retrieve`](#retrieve-1) ##### update() [#update] ```ts update( id, appointment, options? ): Promise; ``` Replaces the appointment with the given ID. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `id` | `string` | | `appointment` | `Appointment` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<`Appointment`\> *** ### FhirListResource [#fhirlistresource] FHIR resources of one type that can be listed; a list resolves to the first page's resources. #### Extended by [#extended-by] - [`FhirRecordsResource`](#fhirrecordsresource) #### Type Parameters [#type-parameters] | Type Parameter | | ------ | | `K` *extends* `ResourceType` | #### Methods [#methods-1] ##### list() [#list-1] ```ts list(params?, options?): Promise[]>; ``` Lists the first page of matching resources. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `params?` | [`QueryParams`](/web-sdk/core/reference/core/ovok-client#queryparams) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<`ExtractResource`\<`K`\>[]\> *** ### FhirRecordsResource [#fhirrecordsresource] FHIR resources of one type that can be read by ID. #### Extends [#extends-1] - [`FhirListResource`](#fhirlistresource)\<`K`\> #### Extended by [#extended-by-1] - [`AppointmentsResource`](#appointmentsresource) #### Type Parameters [#type-parameters-1] | Type Parameter | | ------ | | `K` *extends* `ResourceType` | #### Methods [#methods-2] ##### list() [#list-2] ```ts list(params?, options?): Promise[]>; ``` Lists the first page of matching resources. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `params?` | [`QueryParams`](/web-sdk/core/reference/core/ovok-client#queryparams) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-5] `Promise`\<`ExtractResource`\<`K`\>[]\> ###### Inherited from [#inherited-from-2] [`FhirListResource`](#fhirlistresource).[`list`](#list-1) ##### retrieve() [#retrieve-1] ```ts retrieve(id, options?): Promise>; ``` Reads one resource by ID. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `id` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-6] `Promise`\<`ExtractResource`\<`K`\>\> ## Interfaces [#interfaces] ### PatientResource [#patientresource] The signed-in patient's own records. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `appointments` | `readonly` | [`AppointmentsResource`](#appointmentsresource) | Appointments. | | `carePlans` | `readonly` | [`FhirRecordsResource`](#fhirrecordsresource)\<`"CarePlan"`\> | Care plans. | | `devices` | `readonly` | [`FhirRecordsResource`](#fhirrecordsresource)\<`"Device"`\> | Devices. | | `measurements` | `readonly` | [`FhirRecordsResource`](#fhirrecordsresource)\<`"Observation"`\> | Measurements, stored as Observations. | | `notifications` | `readonly` | [`FhirRecordsResource`](#fhirrecordsresource)\<`"CommunicationRequest"`\> | Notifications, stored as CommunicationRequests. | | `questionnaireResponses` | `readonly` | [`FhirRecordsResource`](#fhirrecordsresource)\<`"QuestionnaireResponse"`\> | Questionnaire responses. | | `questionnaires` | `readonly` | [`FhirRecordsResource`](#fhirrecordsresource)\<`"Questionnaire"`\> | Questionnaires. | | `schedules` | `readonly` | [`FhirListResource`](#fhirlistresource)\<`"Schedule"`\> | Schedules. | | `slots` | `readonly` | [`FhirListResource`](#fhirlistresource)\<`"Slot"`\> | Bookable slots. | #### Methods [#methods-3] ##### dashboard() [#dashboard] ```ts dashboard(params?, options?): Promise; ``` Every read is scoped to the signed-in patient unless its query names another. ###### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `params?` | [`OvokPatientDashboardQuery`](#ovokpatientdashboardquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-7] `Promise`\<[`OvokPatientDashboard`](#ovokpatientdashboard)\> ##### latestObservations() [#latestobservations] ```ts latestObservations(params?, options?): Promise; ``` Reads the latest observations. Calls `GET fhir/Observation/$lastn`. ###### Parameters [#parameters-8] | Parameter | Type | | ------ | ------ | | `params?` | [`OvokPatientLatestObservationsQuery`](#ovokpatientlatestobservationsquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-8] `Promise`\<[`OvokPatientObservationBundle`](#ovokpatientobservationbundle)\> ## Type Aliases [#type-aliases] ### OvokCurrentPatientProfile [#ovokcurrentpatientprofile] ```ts type OvokCurrentPatientProfile = object; ``` Response of `getCurrentPatientProfile`. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `accessPolicy` | `object` | The patient's access policy. | | `accessPolicy.ipAccessRule` | `object`[] | IP rules the policy applies. | | `accessPolicy.resource` | `object`[] | Resource types the policy covers. | | `accessPolicy.resourceType` | `"AccessPolicy"` | Always `AccessPolicy`. | | `config` | `object` | User interface configuration. | | `config.menu` | `object`[] | Menu sections. | | `config.resourceType` | `"UserConfiguration"` | Always `UserConfiguration`. | | `membership` | `object` | The patient's project membership. | | `membership.id` | `string` | ID of the membership. | | `membership.resourceType` | `"ProjectMembership"` | Always `ProjectMembership`. | | `membership.user` | `object` | Reference to the user. | | `membership.user.display` | `string` | Display name of the user. | | `membership.user.reference` | `string` | Reference string of the user. | | `profile` | `object` | The patient's own Patient resource. | | `profile.id` | `string` | ID of the patient. | | `profile.name` | `object`[] | Names of the patient. | | `profile.resourceType` | `"Patient"` | Always `Patient`. | | `profile.telecom` | `object`[] | Contact points of the patient. | | `project` | `object` | Project the patient belongs to. | | `project.id` | `string` | ID of the project. | | `project.name` | `string` | Project name. | | `project.resourceType` | `"Project"` | Always `Project`. | | `project.strictMode` | `boolean` | Whether the project runs in strict mode. | | `security` | `object` | Security state of the account. | | `security.mfaEnrolled` | `boolean` | Whether multi-factor authentication is enrolled. | | `security.sessions` | `object`[] | Active sessions. | *** ### OvokPatientAppointment [#ovokpatientappointment] ```ts type OvokPatientAppointment = Appointment; ``` An appointment of the patient. *** ### OvokPatientCarePlan [#ovokpatientcareplan] ```ts type OvokPatientCarePlan = CarePlan; ``` A care plan. *** ### OvokPatientDashboard [#ovokpatientdashboard] ```ts type OvokPatientDashboard = object; ``` Response of `getPatientDashboard`. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `carePlans` | [`OvokPatientCarePlan`](#ovokpatientcareplan)[] | Care plans. | | `latestObservations` | [`OvokPatientObservationBundle`](#ovokpatientobservationbundle) | Latest observations per code. | | `measurementHistory` | [`OvokPatientMeasurement`](#ovokpatientmeasurement)[] | Measurement history. | | `profile` | [`OvokCurrentPatientProfile`](#ovokcurrentpatientprofile) | The patient's profile. | *** ### OvokPatientDashboardQuery [#ovokpatientdashboardquery] ```ts type OvokPatientDashboardQuery = object; ``` Query of `getPatientDashboard`. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `carePlans?` | [`OvokPatientResourceQuery`](#ovokpatientresourcequery) | Query for the care plans. | | `latestObservations?` | [`OvokPatientLatestObservationsQuery`](#ovokpatientlatestobservationsquery) | Query for the latest observations. | | `measurementHistory?` | [`OvokPatientResourceQuery`](#ovokpatientresourcequery) | Query for the measurement history. | *** ### OvokPatientDevice [#ovokpatientdevice] ```ts type OvokPatientDevice = Device; ``` A device. *** ### OvokPatientLatestObservationsQuery [#ovokpatientlatestobservationsquery] ```ts type OvokPatientLatestObservationsQuery = object; ``` Query of `getPatientLatestObservations`. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `code?` | `string` \| `string`[] | Observation code or codes to read. | | `max?` | `number` | Maximum number of observations per code. | | `patient?` | `string` | Patient reference to read observations of. | *** ### OvokPatientMeasurement [#ovokpatientmeasurement] ```ts type OvokPatientMeasurement = Observation; ``` A measurement, stored as an Observation. *** ### OvokPatientNotification [#ovokpatientnotification] ```ts type OvokPatientNotification = CommunicationRequest; ``` A notification, stored as a CommunicationRequest. *** ### OvokPatientObservationBundle [#ovokpatientobservationbundle] ```ts type OvokPatientObservationBundle = Bundle; ``` Bundle of Observations. *** ### OvokPatientObservationQuery [#ovokpatientobservationquery] ```ts type OvokPatientObservationQuery = object; ``` Query for a patient's latest observations. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `code` | `string` | Observation code. | | `max?` | `number` | Maximum number of observations. | *** ### OvokPatientObservations [#ovokpatientobservations] ```ts type OvokPatientObservations = Bundle; ``` Bundle of a patient's observations. *** ### OvokPatientQuestionnaire [#ovokpatientquestionnaire] ```ts type OvokPatientQuestionnaire = Questionnaire; ``` A questionnaire. *** ### OvokPatientQuestionnaireResponse [#ovokpatientquestionnaireresponse] ```ts type OvokPatientQuestionnaireResponse = QuestionnaireResponse; ``` A questionnaire response. *** ### OvokPatientResourceQuery [#ovokpatientresourcequery] ```ts type OvokPatientResourceQuery = OvokPatientSchedulingQuery; ``` Search parameters for patient resources. *** ### OvokPatientSchedule [#ovokpatientschedule] ```ts type OvokPatientSchedule = Schedule; ``` A schedule. *** ### OvokPatientSchedulingQuery [#ovokpatientschedulingquery] ```ts type OvokPatientSchedulingQuery = Record; ``` Search parameters for scheduling resources. *** ### OvokPatientSlot [#ovokpatientslot] ```ts type OvokPatientSlot = Slot; ``` A bookable slot. # projects Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/projects ## Classes [#classes] ### ProjectFeaturesResource [#projectfeaturesresource] Features enabled on the current project. #### Methods [#methods] ##### retrieve() [#retrieve] ```ts retrieve(options?): Promise; ``` Reads the project's features. Calls `GET v1/projects/me/features`. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`OvokProjectFeatures`](#ovokprojectfeatures)\> ##### update() [#update] ```ts update(features, options?): Promise; ``` Updates the project's features. Calls `PATCH v1/projects/me/features`. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `features` | ( \| `"email"` \| `"ai"` \| `"aws-comprehend"` \| `"aws-textract"` \| `"bots"` \| `"cron"` \| `"google-auth-required"` \| `"graphql-introspection"` \| `"websocket-subscriptions"` \| `"transaction-bundles"` \| `"validate-terminology"`)[] | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<[`OvokProjectFeatures`](#ovokprojectfeatures)\> *** ### ProjectMembersResource [#projectmembersresource] Members of the current project. #### Methods [#methods-1] ##### invite() [#invite] ```ts invite(body, options?): Promise; ``` Invites a member to the project. Calls `POST v1/projects/me/members`. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `body` | [`OvokInviteProjectMember`](#ovokinviteprojectmember) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<[`OvokProjectMemberResponse`](#ovokprojectmemberresponse)\> ##### list() [#list] ```ts list(query?, options?): PagePromise; ``` Lists project members page by page. Calls `GET v1/projects/me/members`. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `query?` | [`ProjectMemberListQuery`](#projectmemberlistquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`OvokProjectMember`](#ovokprojectmember)\> ##### remove() [#remove] ```ts remove(membershipId, options?): Promise; ``` Removes a member from the project. Calls `DELETE v1/projects/me/members/{membershipId}`. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `membershipId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<[`OvokRemoveProjectMemberResponse`](#ovokremoveprojectmemberresponse)\> ##### update() [#update-1] ```ts update( membershipId, body, options? ): Promise; ``` Updates a membership. Calls `PATCH v1/projects/me/members/{membershipId}`. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `membershipId` | `string` | | `body` | [`OvokUpdateProjectMember`](#ovokupdateprojectmember) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-5] `Promise`\<[`OvokProjectMemberResponse`](#ovokprojectmemberresponse)\> *** ### ProjectSettingsResource [#projectsettingsresource] Settings of the current project. #### Methods [#methods-2] ##### retrieve() [#retrieve-1] ```ts retrieve(options?): Promise; ``` Reads all project settings. Calls `GET v1/project/settings`. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-6] `Promise`\<[`OvokProjectSettings`](#ovokprojectsettings)\> ##### update() [#update-2] ```ts update( key, enabled, options? ): Promise; ``` Turns a project setting on or off. Calls `PUT v1/project/settings/{key}`. ###### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `key` | \| `"CONTENT_ENABLED"` \| `"MAILING_ENABLED"` \| `"PATIENT_INVITATION_ENABLED"` \| `"PATIENT_REGISTRATION_ENABLED"` \| `"PATIENT_LOGIN_ENABLED"` \| `"PRACTITIONER_INVITATION_ENABLED"` \| `"PRACTITIONER_REGISTRATION_ENABLED"` \| `"PRACTITIONER_LOGIN_ENABLED"` \| `"CLINICIAN_INVITE_ON_BUSINESS_EMAIL"` | | `enabled` | `boolean` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-7] `Promise`\<[`OvokProjectSettings`](#ovokprojectsettings)\> ##### updateText() [#updatetext] ```ts updateText( key, value, options? ): Promise; ``` Sets or clears a text setting. Calls `PUT v1/project/settings/values/{key}`. ###### Parameters [#parameters-8] | Parameter | Type | | ------ | ------ | | `key` | \| `"PATIENT_APP_URL"` \| `"PRACTITIONER_APP_URL"` \| `"PATIENT_SIGNUP_URL"` \| `"CLINICIAN_DASHBOARD_URL"` \| `"DEFAULT_PRACTITIONER_ACCESS_POLICY"` \| `"CLINICIAN_INVITE_ACCESS_POLICY"` | | `value` | `string` \| `null` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-8] `Promise`\<[`OvokProjectSettings`](#ovokprojectsettings)\> ## Interfaces [#interfaces] ### ProjectsResource [#projectsresource] The projects the signed-in user administers, with their members, features and settings. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `features` | `readonly` | [`ProjectFeaturesResource`](#projectfeaturesresource) | Features enabled for the current project. | | `members` | `readonly` | [`ProjectMembersResource`](#projectmembersresource) | Members of the current project. | | `settings` | `readonly` | [`ProjectSettingsResource`](#projectsettingsresource) | Settings of the current project. | #### Methods [#methods-3] ##### list() [#list-1] ```ts list(query?, options?): PagePromise; ``` The projects the caller administers, wherever they are signed in. ###### Parameters [#parameters-9] | Parameter | Type | | ------ | ------ | | `query?` | [`ProjectListQuery`](#projectlistquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-9] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`OvokAdministeredProject`](#ovokadministeredproject)\> ## Type Aliases [#type-aliases] ### OvokAdministeredProject [#ovokadministeredproject] ```ts type OvokAdministeredProject = object; ``` A project the user administers. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `isMainProject` | `boolean` \| `null` | Whether this is the main project, or null when unknown. | | `name` | `string` \| `null` | Name of the project, or null. | | `parentProjectId` | `string` \| `null` | ID of the parent project, or null. | | `projectId` | `string` | ID of the project. | | `tenantCode` | `string` \| `null` | Tenant code of the project, or null. | *** ### OvokInviteProjectMember [#ovokinviteprojectmember] ```ts type OvokInviteProjectMember = object; ``` Request to invite a project member. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `admin` | `boolean` \| `null` | Whether to make the member an admin, or null. | | `email` | `string` | Email address to invite. | | `firstName` | `string` \| `null` | First name, or null. | | `lastName` | `string` \| `null` | Last name, or null. | *** ### OvokPage [#ovokpage] ```ts type OvokPage = SlimPage; ``` A page of results, the same shape as `SlimPage`. #### Type Parameters [#type-parameters] | Type Parameter | | ------ | | `T` | *** ### OvokProjectFeature [#ovokprojectfeature] ```ts type OvokProjectFeature = typeof OVOK_PROJECT_FEATURE_VALUES[number]; ``` A project feature. *** ### OvokProjectFeatures [#ovokprojectfeatures] ```ts type OvokProjectFeatures = object; ``` Enabled features of a project. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `features` | `string`[] | Enabled features. | *** ### OvokProjectFeaturesUpdate [#ovokprojectfeaturesupdate] ```ts type OvokProjectFeaturesUpdate = object; ``` Request to set the enabled features. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `features` | [`OvokProjectFeature`](#ovokprojectfeature)[] | Features to enable. | *** ### OvokProjectMember [#ovokprojectmember] ```ts type OvokProjectMember = object; ``` A member of a project. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `accessPolicy?` | [`OvokProjectMemberReference`](#ovokprojectmemberreference) | The member's access policy. | | `admin?` | `boolean` | Whether the member is a project admin. | | `membershipId` | `string` | ID of the ProjectMembership. | | `profile?` | [`OvokProjectMemberReference`](#ovokprojectmemberreference) | The member's profile. | | `userId?` | `string` | ID of the user. | *** ### OvokProjectMemberReference [#ovokprojectmemberreference] ```ts type OvokProjectMemberReference = object; ``` A reference to a resource, with display text. #### Indexable [#indexable] ```ts [key: string]: unknown ``` #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `display?` | `string` | Display text. | | `reference?` | `string` | Reference string, such as `Practitioner/123`. | *** ### OvokProjectMemberResponse [#ovokprojectmemberresponse] ```ts type OvokProjectMemberResponse = object; ``` A project member as returned by the member routes. #### Properties [#properties-7] | Property | Type | Description | | ------ | ------ | ------ | | `admin` | `boolean` | Whether the member is an admin. | | `displayName` | `string` \| `null` | Display name, or null. | | `email` | `string` \| `null` | Email address, or null. | | `firstName` | `string` \| `null` | First name, or null. | | `id` | `string` | ID of the membership. | | `invitedAt` | `string` \| `null` | ISO 8601 time of the invite, or null. | | `lastName` | `string` \| `null` | Last name, or null. | | `pending` | `boolean` | Whether the invite has not been accepted yet. | | `profileId` | `string` \| `null` | ID of the member's profile, or null. | | `profileType` | `"Practitioner"` \| `"Patient"` \| `"RelatedPerson"` \| `null` | Resource type of the member's profile, or null. | *** ### OvokProjectSettingKey [#ovokprojectsettingkey] ```ts type OvokProjectSettingKey = typeof OVOK_PROJECT_SETTING_KEYS[number]; ``` A boolean project setting key. *** ### OvokProjectSettings [#ovokprojectsettings] ```ts type OvokProjectSettings = object; ``` Settings of a project. #### Properties [#properties-8] | Property | Type | Description | | ------ | ------ | ------ | | `projectId` | `string` | ID of the project. | | `settings` | `Record`\<[`OvokProjectSettingKey`](#ovokprojectsettingkey), `boolean`\> | Boolean settings by key. | | `values` | `Record`\<[`OvokProjectTextSettingKey`](#ovokprojecttextsettingkey), `string` \| `null`\> | Text settings by key; null when unset. | *** ### OvokProjectTextSettingKey [#ovokprojecttextsettingkey] ```ts type OvokProjectTextSettingKey = typeof OVOK_PROJECT_TEXT_SETTING_KEYS[number]; ``` A text project setting key. *** ### OvokRemoveProjectMemberResponse [#ovokremoveprojectmemberresponse] ```ts type OvokRemoveProjectMemberResponse = object; ``` Result of removing a project member. #### Properties [#properties-9] | Property | Type | Description | | ------ | ------ | ------ | | `success` | `true` | Always `true`. | *** ### OvokUpdateProjectMember [#ovokupdateprojectmember] ```ts type OvokUpdateProjectMember = object; ``` Request to update a project member. #### Properties [#properties-10] | Property | Type | Description | | ------ | ------ | ------ | | `admin` | `boolean` \| `null` | Whether the member is an admin, or null. | *** ### ProjectListQuery [#projectlistquery] ```ts type ProjectListQuery = object; ``` Paging for listing administered projects. #### Properties [#properties-11] | Property | Type | Description | | ------ | ------ | ------ | | `count?` | `number` | Projects per page. | | `page?` | `number` | Page number to fetch. | *** ### ProjectMemberListQuery [#projectmemberlistquery] ```ts type ProjectMemberListQuery = object; ``` Filters and paging for listing project members. #### Properties [#properties-12] | Property | Type | Description | | ------ | ------ | ------ | | `accessPolicyId?` | `string` | Only members with this access policy. | | `count?` | `number` | Members per page. | | `page?` | `number` | Page number to fetch. | | `profileId?` | `string` | Only the member with this profile id. | | `userId?` | `string` | Only the member with this user id. | ## Variables [#variables] ### OVOK\_PROJECT\_FEATURE\_VALUES [#ovok_project_feature_values] ```ts const OVOK_PROJECT_FEATURE_VALUES: readonly ["ai", "aws-comprehend", "aws-textract", "bots", "cron", "email", "google-auth-required", "graphql-introspection", "websocket-subscriptions", "transaction-bundles", "validate-terminology"]; ``` Project features that can be switched on. *** ### OVOK\_PROJECT\_SETTING\_KEYS [#ovok_project_setting_keys] ```ts const OVOK_PROJECT_SETTING_KEYS: readonly ["CONTENT_ENABLED", "MAILING_ENABLED", "PATIENT_INVITATION_ENABLED", "PATIENT_REGISTRATION_ENABLED", "PATIENT_LOGIN_ENABLED", "PRACTITIONER_INVITATION_ENABLED", "PRACTITIONER_REGISTRATION_ENABLED", "PRACTITIONER_LOGIN_ENABLED", "CLINICIAN_INVITE_ON_BUSINESS_EMAIL"]; ``` Keys of the boolean project settings. *** ### OVOK\_PROJECT\_TEXT\_SETTING\_ERROR\_CODES [#ovok_project_text_setting_error_codes] ```ts const OVOK_PROJECT_TEXT_SETTING_ERROR_CODES: object; ``` Error codes returned when a text setting is rejected. #### Type Declaration [#type-declaration] ##### appUrlNotAllowed [#appurlnotallowed] ```ts readonly appUrlNotAllowed: "APP_URL_NOT_ALLOWED" = "APP_URL_NOT_ALLOWED"; ``` The app URL is not allowed. ##### appUrlNotConfigured [#appurlnotconfigured] ```ts readonly appUrlNotConfigured: "app_url_not_configured" = "app_url_not_configured"; ``` No app URL is configured. ##### invalidValue [#invalidvalue] ```ts readonly invalidValue: "INVALID_SETTING_VALUE" = "INVALID_SETTING_VALUE"; ``` The value is not valid for the setting. ##### unknownSetting [#unknownsetting] ```ts readonly unknownSetting: "UNKNOWN_SETTING" = "UNKNOWN_SETTING"; ``` The setting does not exist. *** ### OVOK\_PROJECT\_TEXT\_SETTING\_KEYS [#ovok_project_text_setting_keys] ```ts const OVOK_PROJECT_TEXT_SETTING_KEYS: readonly ["PATIENT_APP_URL", "PRACTITIONER_APP_URL", "PATIENT_SIGNUP_URL", "CLINICIAN_DASHBOARD_URL", "DEFAULT_PRACTITIONER_ACCESS_POLICY", "CLINICIAN_INVITE_ACCESS_POLICY"]; ``` Keys of the text project settings. # questionnaires Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/questionnaires ## Interfaces [#interfaces] ### QuestionnaireResponsesResource [#questionnaireresponsesresource] Saves and processes QuestionnaireResponses. #### Methods [#methods] ##### extract() [#extract] ```ts extract(questionnaireResponseId, options?): Promise; ``` Runs `$extract` on a stored QuestionnaireResponse. Calls `POST fhir/QuestionnaireResponse/{id}/$extract`. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `questionnaireResponseId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<`Parameters`\> ##### submit() [#submit] ```ts submit(response, options?): Promise>; ``` Saves a QuestionnaireResponse. Calls the FHIR base path as a transaction. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `response` | `QuestionnaireResponse` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<`Bundle`\<`Resource`\>\> ##### submitWithObservations() [#submitwithobservations] ```ts submitWithObservations( response, observations, options? ): Promise>; ``` One transaction, so the response is never saved without its observations. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `response` | `QuestionnaireResponse` | | `observations` | `Observation`[] | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<`Bundle`\<`Resource`\>\> *** ### QuestionnairesResource [#questionnairesresource] Questionnaire operations. #### Methods [#methods-1] ##### populate() [#populate] ```ts populate( questionnaireId, parameters?, options? ): Promise; ``` Pre-fills a Questionnaire with `$populate`. Calls `POST fhir/Questionnaire/{questionnaireId}/$populate`. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `questionnaireId` | `string` | | `parameters?` | `Parameters` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<`Parameters`\> # realtime Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/realtime ## Interfaces [#interfaces] ### RealtimeResource [#realtimeresource] Live notifications of resource changes over a websocket. #### Methods [#methods] ##### subscribe() [#subscribe] ```ts subscribe(criteria, handler): Promise; ``` Subscribes to resources matching the FHIR search `criteria` and calls `handler` for each change. Creates a `Subscription` resource and opens a websocket. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `criteria` | `string` | | `handler` | [`RealtimeNotificationHandler`](#realtimenotificationhandler) | ###### Returns [#returns] `Promise`\<[`RealtimeUnsubscribe`](#realtimeunsubscribe)\> A function that unsubscribes. ###### Throws [#throws] OvokValidationError when `criteria` is empty. ## Type Aliases [#type-aliases] ### RealtimeNotification [#realtimenotification] ```ts type RealtimeNotification = SubscriptionStatus & object; ``` A notification that a resource matching a subscription changed. #### Type Declaration [#type-declaration] ##### resources [#resources] ```ts resources: Resource[]; ``` The changed resources sent with the notification, in the order the server sent them. ##### type [#type] ```ts type: "event-notification"; ``` Always `"event-notification"`. *** ### RealtimeNotificationHandler [#realtimenotificationhandler] ```ts type RealtimeNotificationHandler = (notification) => void; ``` Callback invoked for each realtime notification. #### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `notification` | [`RealtimeNotification`](#realtimenotification) | #### Returns [#returns-1] `void` *** ### RealtimeUnsubscribe [#realtimeunsubscribe] ```ts type RealtimeUnsubscribe = () => Promise; ``` Ends a realtime subscription. #### Returns [#returns-2] `Promise`\<`void`\> # session Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/session ## Interfaces [#interfaces] ### SavedAccountsResource [#savedaccountsresource] Accounts saved on this device, for switching between them. #### Methods [#methods] ##### list() [#list] ```ts list(): Promise; ``` Lists the saved accounts, marking the active one. ###### Returns [#returns] `Promise`\<[`SavedAccount`](#savedaccount)[]\> ##### remove() [#remove] ```ts remove(accountId, options?): Promise; ``` Signs a saved account out and removes it. Calls `DELETE auth/session/current` for that account unless it has expired. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `accountId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<`void`\> ###### Throws [#throws] OvokAccountError when the account is not saved. ##### switch() [#switch] ```ts switch(accountId): Promise; ``` Makes a saved account the active session. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `accountId` | `string` | ###### Returns [#returns-2] `Promise`\<`void`\> ###### Throws [#throws-1] OvokAccountError when the account is missing or its session has expired. *** ### SessionResource [#sessionresource] The current user session and the accounts saved on this device. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `savedAccounts` | `readonly` | [`SavedAccountsResource`](#savedaccountsresource) | Accounts saved on this device. | #### Methods [#methods-1] ##### current() [#current] ```ts current(): Promise; ``` Returns the current session, or null when signed out. ###### Returns [#returns-3] `Promise`\<[`Session`](#session) \| `null`\> ##### onChange() [#onchange] ```ts onChange(listener): () => void; ``` Calls `listener` whenever the session starts, changes or ends; returns a function that stops listening. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `listener` | [`SessionChangeListener`](#sessionchangelistener) | ###### Returns [#returns-4] () => `void` ## Type Aliases [#type-aliases] ### OvokReference [#ovokreference] ```ts type OvokReference = object; ``` A FHIR reference with an optional display name. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `display` | `string` \| `null` | Display name, or null when none is known. | | `reference` | `string` | FHIR reference, such as `Patient/123`. | *** ### SavedAccount [#savedaccount] ```ts type SavedAccount = object; ``` An account saved on this device, without its tokens. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `active` | `boolean` | Whether this is the account currently signed in. | | `expired` | `boolean` | Whether the saved session has expired and needs a new sign-in. | | `id` | `string` | Stable account id: the profile reference. | | `profile` | [`OvokReference`](#ovokreference) | The account's profile. | | `project` | [`OvokReference`](#ovokreference) | The account's project. | *** ### Session [#session] ```ts type Session = object; ``` A signed-in session: tokens, expiry, project and profile. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `accessToken` | `string` | Bearer token for API requests. | | `expiresAt` | `number` | Access token expiry, in milliseconds since the Unix epoch. | | `profile` | [`OvokReference`](#ovokreference) | The signed-in profile. | | `project` | [`OvokReference`](#ovokreference) | The project the session belongs to. | | `refreshToken` | `string` \| `null` | Token used to renew the session, or null when it cannot be renewed. | *** ### SessionChangeListener [#sessionchangelistener] ```ts type SessionChangeListener = (session) => void; ``` Called with the new session, or null when the user signs out. #### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `session` | [`Session`](#session) \| `null` | #### Returns [#returns-5] `void` # sharing Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/sharing ## Classes [#classes] ### SharingInvitesResource [#sharinginvitesresource] Invites to share a patient's records. #### Methods [#methods] ##### create() [#create] ```ts create(body, options?): Promise; ``` Creates a sharing invite. Calls `POST v1/patient-sharing/invites`. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `body` | [`CreatePatientSharingInvite`](#createpatientsharinginvite) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`PatientSharingInvite`](#patientsharinginvite)\> ##### redeem() [#redeem] ```ts redeem(body, options?): Promise; ``` Redeems a sharing invite. Calls `POST v1/patient-sharing/invites/redeem`. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `body` | [`RedeemPatientSharingInvite`](#redeempatientsharinginvite) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<[`PatientSharingShare`](#patientsharingshare)\> *** ### SharingSettingsResource [#sharingsettingsresource] Patient sharing settings. #### Methods [#methods-1] ##### retrieve() [#retrieve] ```ts retrieve(options?): Promise; ``` Reads the sharing settings. Calls `GET v1/patient-sharing/settings`. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<[`PatientSharingSettings`](#patientsharingsettings)\> ##### update() [#update] ```ts update(settings, options?): Promise; ``` Replaces the sharing settings. Calls `PUT v1/patient-sharing/settings`. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `settings` | [`PatientSharingSettingsUpdate`](#patientsharingsettingsupdate) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<[`PatientSharingSettings`](#patientsharingsettings)\> *** ### SharingSharesResource [#sharingsharesresource] Patient data shares the signed-in user gave and received. #### Methods [#methods-2] ##### list() [#list] ```ts list(options?): Promise; ``` Lists shares, given and received. Calls `GET v1/patient-sharing/shares`. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<[`PatientSharingShares`](#patientsharingshares)\> ##### revoke() [#revoke] ```ts revoke(consentId, options?): Promise; ``` Revokes a share. Calls `DELETE v1/patient-sharing/shares/{consentId}`. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `consentId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-5] `Promise`\<`void`\> ## Interfaces [#interfaces] ### SharingResource [#sharingresource] Record sharing: invites, shares and sharing settings. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `invites` | `readonly` | [`SharingInvitesResource`](#sharinginvitesresource) | Sharing invites. | | `settings` | `readonly` | [`SharingSettingsResource`](#sharingsettingsresource) | Sharing settings. | | `shares` | `readonly` | [`SharingSharesResource`](#sharingsharesresource) | Active shares. | ## Type Aliases [#type-aliases] ### CreatePatientSharingInvite [#createpatientsharinginvite] ```ts type CreatePatientSharingInvite = object; ``` Request to create a patient sharing invite. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `codes` | `string`[] | Observation codes to share. | | `endsAt` | `string` \| `null` | ISO 8601 end of the share, or null for no end. | *** ### PatientSharingInvite [#patientsharinginvite] ```ts type PatientSharingInvite = object; ``` A created patient sharing invite. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `code` | `string` | Code the recipient redeems the invite with. | | `expiresAt` | `string` | ISO 8601 time the invite expires. | | `inviteId` | `string` | ID of the invite. | *** ### PatientSharingParty [#patientsharingparty] ```ts type PatientSharingParty = object; ``` A patient taking part in a share. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `name` | `string` \| `null` | Display name, or null when unknown. | | `patientId` | `string` | ID of the patient. | *** ### PatientSharingPractitionerShare [#patientsharingpractitionershare] ```ts type PatientSharingPractitionerShare = object; ``` A patient's share of their record with a practitioner. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `consentId` | `string` | ID of the Consent that records the share. | | `endsAt` | `string` \| `null` | ISO 8601 end of the share, or null when open-ended. | | `practitioner` | `object` | Practitioner who receives. | | `practitioner.name` | `string` \| `null` | Display name, or null when unknown. | | `practitioner.practitionerId` | `string` | ID of the practitioner. | | `sharer` | [`PatientSharingParty`](#patientsharingparty) | Patient who shares. | | `startedAt` | `string` \| `null` | ISO 8601 start of the share, or null when not set. | *** ### PatientSharingRelatedPersonShare [#patientsharingrelatedpersonshare] ```ts type PatientSharingRelatedPersonShare = object; ``` Observation codes a patient shares with a related person (a carer). #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `codes` | `string`[] | Observation codes that are shared. | | `consentId` | `string` | ID of the Consent that records the share. | | `endsAt` | `string` \| `null` | ISO 8601 end of the share, or null when open-ended. | | `relatedPerson` | `object` | Carer who receives. | | `relatedPerson.name` | `string` \| `null` | Display name, or null when unknown. | | `relatedPerson.relatedPersonId` | `string` | ID of the related person. | | `sharer` | [`PatientSharingParty`](#patientsharingparty) | Patient who shares. | | `startedAt` | `string` \| `null` | ISO 8601 start of the share, or null when not set. | *** ### PatientSharingSettings [#patientsharingsettings] ```ts type PatientSharingSettings = object; ``` Project settings for patient sharing. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `accessPolicyId` | `string` \| `null` | ID of the access policy applied to shares, or null. | | `enabled` | `boolean` | Whether patient sharing is on. | | `practitionerSharingEnabled` | `boolean` | Whether patients may share with practitioners. | *** ### PatientSharingSettingsUpdate [#patientsharingsettingsupdate] ```ts type PatientSharingSettingsUpdate = object; ``` Request to update patient sharing settings. #### Properties [#properties-7] | Property | Type | Description | | ------ | ------ | ------ | | `enabled` | `boolean` | Whether patient sharing is on. | | `practitionerSharingEnabled?` | `boolean` \| `null` | Whether patients may share with practitioners; null leaves it unchanged. | *** ### PatientSharingShare [#patientsharingshare] ```ts type PatientSharingShare = object; ``` Observation codes one patient shares with another. #### Properties [#properties-8] | Property | Type | Description | | ------ | ------ | ------ | | `codes` | `string`[] | Observation codes that are shared. | | `consentId` | `string` | ID of the Consent that records the share. | | `endsAt` | `string` \| `null` | ISO 8601 end of the share, or null when open-ended. | | `recipient` | [`PatientSharingParty`](#patientsharingparty) | Patient who receives. | | `sharer` | [`PatientSharingParty`](#patientsharingparty) | Patient who shares. | | `startedAt` | `string` \| `null` | ISO 8601 start of the share, or null when not set. | *** ### PatientSharingShares [#patientsharingshares] ```ts type PatientSharingShares = object; ``` The signed-in user's shares. #### Properties [#properties-9] | Property | Type | Description | | ------ | ------ | ------ | | `incoming` | [`PatientSharingShare`](#patientsharingshare)[] | Shares other patients gave to the user. | | `outgoing` | [`PatientSharingShare`](#patientsharingshare)[] | Shares the user gave to other patients. | | `practitioners` | [`PatientSharingPractitionerShare`](#patientsharingpractitionershare)[] | Shares with practitioners. | | `received` | [`PatientSharingRelatedPersonShare`](#patientsharingrelatedpersonshare)[] | For a signed-in carer: the shares patients gave them. Empty for a patient. | | `relatedPersons` | [`PatientSharingRelatedPersonShare`](#patientsharingrelatedpersonshare)[] | Shares with carers. | *** ### RedeemPatientSharingInvite [#redeempatientsharinginvite] ```ts type RedeemPatientSharingInvite = object; ``` Request to redeem a patient sharing invite. #### Properties [#properties-10] | Property | Type | Description | | ------ | ------ | ------ | | `code` | `string` | Code from the invite. | | `inviteId` | `string` | ID of the invite. | # signals Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/signals ## Classes [#classes] ### SignalsGatewayResource [#signalsgatewayresource] Gateway to the Signals API. #### Methods [#methods] ##### request() [#request] ```ts request(request, options?): Promise; ``` Forwards a request to `v1/signals/api/{path}`. ###### Type Parameters [#type-parameters] | Type Parameter | Default type | | ------ | ------ | | `T` | `unknown` | ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `request` | [`SignalsGatewayRequest`](#signalsgatewayrequest) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<`T`\> *** ### UndeliverableResource [#undeliverableresource] Residents whose limits could not be delivered to Signals. #### Methods [#methods-1] ##### list() [#list] ```ts list(options?): Promise; ``` Lists undeliverable residents. Calls `GET signals/config/undeliverable`. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<[`SignalsUndeliverable`](#signalsundeliverable)\> ##### repair() [#repair] ```ts repair(request?, options?): Promise; ``` Without `patientIds`, repairs the residents `list` shows. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `request?` | [`SignalsDeliveryRepair`](#signalsdeliveryrepair) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<[`SignalsDeliveryRepairResult`](#signalsdeliveryrepairresult)\> ## Interfaces [#interfaces] ### SignalsResource [#signalsresource] Access to Signals: forwarded API calls and delivery repair. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `gateway` | `readonly` | [`SignalsGatewayResource`](#signalsgatewayresource) | Sends requests to the Signals API through Ovok. | | `undeliverable` | `readonly` | [`UndeliverableResource`](#undeliverableresource) | Residents whose limits could not be delivered to Signals. | #### Methods [#methods-2] ##### enable() [#enable] ```ts enable(patientId, options?): Promise; ``` Idempotent: retry after 409 or 503. Readings saved through Ovok reach Signals without a second submit. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `patientId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<[`EnableSignalsResponse`](#enablesignalsresponse)\> ## Type Aliases [#type-aliases] ### EnableSignalsResponse [#enablesignalsresponse] ```ts type EnableSignalsResponse = object; ``` Result of enabling Signals for a patient. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `enabled` | `true` | Always `true` on success. | | `patientId` | `string` | Patient id in Ovok. | | `signalsPatientId` | `string` | Patient id in Signals. | *** ### SignalsDeliveryRepair [#signalsdeliveryrepair] ```ts type SignalsDeliveryRepair = object; ``` Request body for repairing delivery. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `patientIds?` | `string`[] | Only repair these patients; omit to repair all listed residents. | *** ### SignalsDeliveryRepairResult [#signalsdeliveryrepairresult] ```ts type SignalsDeliveryRepairResult = object; ``` Outcome of a repair run. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `attempted` | `number` | Residents the repair tried. | | `notReached` | `number` | Residents not reached before the run ended. | | `repaired` | `number` | Residents now delivered. | | `skipped` | `number` | Residents skipped. | | `stillUndeliverable` | `number` | Residents that still could not be delivered. | *** ### SignalsGatewayRequest [#signalsgatewayrequest] ```ts type SignalsGatewayRequest = object; ``` A request to forward to the Signals API. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `body?` | `unknown` | JSON request body. | | `method` | [`HttpMethod`](/web-sdk/core/reference/core/ovok-client#httpmethod) | HTTP method. | | `path` | readonly `string`[] | Path segments after `v1/signals/api`; each must be non-empty and free of slashes and control characters. | | `query?` | [`QueryParams`](/web-sdk/core/reference/core/ovok-client#queryparams) | Query parameters. | *** ### SignalsUndeliverable [#signalsundeliverable] ```ts type SignalsUndeliverable = object; ``` Residents whose limits could not be delivered to Signals. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `count` | `number` | Number of residents. | | `residents` | [`SignalsUndeliverableResident`](#signalsundeliverableresident)[] | The affected residents. | *** ### SignalsUndeliverableResident [#signalsundeliverableresident] ```ts type SignalsUndeliverableResident = object; ``` A resident whose limits could not be delivered to Signals. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `patientId` | `string` | Patient id of the resident. | # slim Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/slim ## Classes [#classes] ### SlimAlarmsResource [#slimalarmsresource] Alarm notifications. #### Methods [#methods] ##### acknowledge() [#acknowledge] ```ts acknowledge(notificationId, options?): Promise; ``` Can take about 12 s; the server makes it safe to repeat, so a 503 is retried. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `notificationId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`SlimNotification`](#slimnotification)\> ##### list() [#list] ```ts list(params?, options?): Promise; ``` Lists alarm notifications. Calls `GET v1/slim/notifications/alarms`. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimAlarmQuery`](#slimalarmquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<[`SlimAlarmsPage`](#slimalarmspage)\> ##### recent() [#recent] ```ts recent(params?, options?): Promise; ``` Reads the recent alarms. Calls `GET v1/slim/notifications/recent/alarms`. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimRecentQuery`](#slimrecentquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<[`SlimRecentAlarms`](#slimrecentalarms)\> *** ### SlimChangeHistoryResource [#slimchangehistoryresource] Change history of slim records. #### Methods [#methods-1] ##### list() [#list-1] ```ts list(params?, options?): PagePromise; ``` Lists change-history rows page by page. Calls `GET v1/slim/change-history`. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `params?` | [`ChangeHistoryQuery`](#changehistoryquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`ChangeHistoryRow`](#changehistoryrow)\> *** ### SlimChildProjectsResource [#slimchildprojectsresource] Child projects of the current project. #### Methods [#methods-2] ##### create() [#create] ```ts create(body, options?): Promise; ``` Creates a child project. Calls `POST v1/slim/project/child`. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `body` | [`SlimChildProjectInput`](#slimchildprojectinput) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<[`SlimChildProjectCreated`](#slimchildprojectcreated)\> ##### delete() [#delete] ```ts delete(subProjectId, options?): Promise; ``` Deletes a child project. Calls `DELETE v1/slim/project/child/{subProjectId}`. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `subProjectId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-5] `Promise`\<[`SlimChildProjectDeleted`](#slimchildprojectdeleted)\> ##### list() [#list-2] ```ts list(options?): Promise; ``` Lists the project's relationships. Calls `GET v2/slim/project/child`. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-6] `Promise`\<[`SlimProjectRelationshipsV2`](#slimprojectrelationshipsv2)\> *** ### SlimDevicesResource [#slimdevicesresource] Devices of the project, with live values and telemetry. #### Methods [#methods-3] ##### assignToProject() [#assigntoproject] ```ts assignToProject(body, options?): Promise; ``` Assigns a device to a project. Calls `PUT v1/slim/device/assign/project`. ###### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `body` | [`SlimAssignDevice`](#slimassigndevice) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-7] `Promise`\<[`SlimDevice`](#slimdevice)\> ##### create() [#create-1] ```ts create(body, options?): Promise; ``` 409 when another customer holds the serial; 422 when this project already uses it. ###### Parameters [#parameters-8] | Parameter | Type | | ------ | ------ | | `body` | [`SlimCreateDevice`](#slimcreatedevice) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-8] `Promise`\<[`SlimDevice`](#slimdevice)\> ##### delete() [#delete-1] ```ts delete(deviceId, options?): Promise; ``` Deletes a device. Calls `DELETE v1/slim/device/{deviceId}`. ###### Parameters [#parameters-9] | Parameter | Type | | ------ | ------ | | `deviceId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-9] `Promise`\<`void`\> ##### effectiveObservationIds() [#effectiveobservationids] ```ts effectiveObservationIds(deviceId, options?): Promise; ``` Reads the effective observation IDs of a device. Calls `GET v1/slim/telemetry/{deviceId}/effectiveIds`. ###### Parameters [#parameters-10] | Parameter | Type | | ------ | ------ | | `deviceId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-10] `Promise`\<[`SlimDeviceObservationIds`](#slimdeviceobservationids)\> ##### effectiveObservationIdsByDevice() [#effectiveobservationidsbydevice] ```ts effectiveObservationIdsByDevice(options?): Promise; ``` Reads the effective observation IDs of every device. Calls `GET v1/slim/telemetry/effectiveIds`. ###### Parameters [#parameters-11] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-11] `Promise`\<[`SlimObservationIdsByDevice`](#slimobservationidsbydevice)\> ##### lastObservationIds() [#lastobservationids] ```ts lastObservationIds(deviceId, options?): Promise; ``` Reads the last observation IDs of a device. Calls `GET v1/slim/telemetry/{deviceId}/lastIds`. ###### Parameters [#parameters-12] | Parameter | Type | | ------ | ------ | | `deviceId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-12] `Promise`\<[`SlimObservationIds`](#slimobservationids)\> ##### lastObservationIdsByDevice() [#lastobservationidsbydevice] ```ts lastObservationIdsByDevice(options?): Promise; ``` Reads the last observation IDs of every device. Calls `GET v1/slim/telemetry/lastIds`. ###### Parameters [#parameters-13] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-13] `Promise`\<[`SlimObservationIdsByDevice`](#slimobservationidsbydevice)\> ##### list() [#list-3] ```ts list(params?, options?): PagePromise; ``` Lists devices. Calls `GET v1/slim/device`. ###### Parameters [#parameters-14] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimDeviceListQuery`](#slimdevicelistquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-14] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`SlimDeviceListItem`](#slimdevicelistitem)\> ##### live() [#live] ```ts live(params?, options?): PagePromise; ``` Lists devices with live values. Calls `GET v1/slim/device/live`; `count` is 1 to 100. ###### Parameters [#parameters-15] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimLiveQuery`](#slimlivequery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-15] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`SlimLiveDevice`](#slimlivedevice)\> ##### liveTelemetry() [#livetelemetry] ```ts liveTelemetry(params?, options?): Promise; ``` Reads live telemetry keyed by device. Calls `GET v1/slim/device/live/telemetry`; `count` is 1 to 100. ###### Parameters [#parameters-16] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimLiveQuery`](#slimlivequery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-16] `Promise`\<[`SlimLiveTelemetry`](#slimlivetelemetry)\> ##### retrieve() [#retrieve] ```ts retrieve(deviceId, options?): Promise; ``` Reads one device. Calls `GET v1/slim/device/{deviceId}`. ###### Parameters [#parameters-17] | Parameter | Type | | ------ | ------ | | `deviceId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-17] `Promise`\<[`SlimDevice`](#slimdevice)\> ##### telemetry() [#telemetry] ```ts telemetry(deviceId, options?): Promise; ``` Reads the telemetry of one device. Calls `GET v1/slim/telemetry/{deviceId}`. ###### Parameters [#parameters-18] | Parameter | Type | | ------ | ------ | | `deviceId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-18] `Promise`\<[`SlimDeviceTelemetry`](#slimdevicetelemetry)\> ##### update() [#update] ```ts update( deviceId, body, options? ): Promise; ``` Renaming moves the serial: live values return only after a reading under the new serial. ###### Parameters [#parameters-19] | Parameter | Type | | ------ | ------ | | `deviceId` | `string` | | `body` | [`SlimUpdateDevice`](#slimupdatedevice) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-19] `Promise`\<[`SlimDevice`](#slimdevice)\> *** ### SlimExportsResource [#slimexportsresource] Exports of slim data. #### Methods [#methods-4] ##### patientPdf() [#patientpdf] ```ts patientPdf(body, options?): Promise; ``` Generates a patient PDF export. Calls `POST v1/slim/export/pdf`. ###### Parameters [#parameters-20] | Parameter | Type | | ------ | ------ | | `body` | [`SlimExportPdfRequest`](#slimexportpdfrequest) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-20] `Promise`\<[`SlimExportPdf`](#slimexportpdf)\> *** ### SlimLocationsResource [#slimlocationsresource] Locations such as rooms and zones. #### Methods [#methods-5] ##### create() [#create-2] ```ts create(body, options?): Promise; ``` Creates a location. Calls `POST v1/slim/location`. ###### Parameters [#parameters-21] | Parameter | Type | | ------ | ------ | | `body` | [`SlimCreateLocation`](#slimcreatelocation) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-21] `Promise`\<[`SlimLocation`](#slimlocation)\> ##### delete() [#delete-2] ```ts delete(locationId, options?): Promise; ``` Deletes a location. Calls `DELETE v1/slim/location/{locationId}`. ###### Parameters [#parameters-22] | Parameter | Type | | ------ | ------ | | `locationId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-22] `Promise`\<`void`\> ##### list() [#list-4] ```ts list(params?, options?): PagePromise; ``` Lists locations page by page. Calls `GET v1/slim/location`. ###### Parameters [#parameters-23] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimLocationQuery`](#slimlocationquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-23] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`SlimLocation`](#slimlocation)\> ##### retrieve() [#retrieve-1] ```ts retrieve(locationId, options?): Promise; ``` Fetches one location. Calls `GET v1/slim/location/{locationId}`. ###### Parameters [#parameters-24] | Parameter | Type | | ------ | ------ | | `locationId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-24] `Promise`\<[`SlimLocation`](#slimlocation)\> ##### update() [#update-1] ```ts update( locationId, body, options? ): Promise; ``` A 422 "Device not found" means the requested device is unreadable and nothing was saved. ###### Parameters [#parameters-25] | Parameter | Type | | ------ | ------ | | `locationId` | `string` | | `body` | [`SlimUpdateLocation`](#slimupdatelocation) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-25] `Promise`\<[`SlimLocation`](#slimlocation)\> *** ### SlimMedicalNotificationsResource [#slimmedicalnotificationsresource] Medical notification episodes. #### Methods [#methods-6] ##### acknowledge() [#acknowledge-1] ```ts acknowledge(episodeId, options?): Promise; ``` Can take about 12 s; the server makes it safe to repeat, so a 503 is retried. ###### Parameters [#parameters-26] | Parameter | Type | | ------ | ------ | | `episodeId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-26] `Promise`\<[`SlimMedicalNotificationRow`](#slimmedicalnotificationrow)\> ##### list() [#list-5] ```ts list(params?, options?): PagePromise; ``` `params.cursor` is where the first page starts. ###### Parameters [#parameters-27] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimMedicalNotificationsQuery`](#slimmedicalnotificationsquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-27] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`SlimMedicalNotificationRow`](#slimmedicalnotificationrow)\> ##### recent() [#recent-1] ```ts recent(params?, options?): Promise; ``` During a Signals outage this may answer the last good page from up to 10 minutes ago. ###### Parameters [#parameters-28] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimRecentQuery`](#slimrecentquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-28] `Promise`\<[`SlimRecentNotificationsResponse`](#slimrecentnotificationsresponse)\> ##### retrieve() [#retrieve-2] ```ts retrieve(episodeId, options?): Promise; ``` Reads one medical notification episode. Calls `GET v1/slim/notifications/medical/{episodeId}`. ###### Parameters [#parameters-29] | Parameter | Type | | ------ | ------ | | `episodeId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-29] `Promise`\<[`SlimMedicalNotificationDetail`](#slimmedicalnotificationdetail)\> *** ### SlimNotificationNotesResource [#slimnotificationnotesresource] Notes attached to notifications. #### Methods [#methods-7] ##### create() [#create-3] ```ts create(body, options?): Promise; ``` Adds a note. Calls `POST v1/slim/notifications/notes`. ###### Parameters [#parameters-30] | Parameter | Type | | ------ | ------ | | `body` | [`CreateNotificationNote`](#createnotificationnote) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-30] `Promise`\<[`NotificationNote`](#notificationnote)\> ##### delete() [#delete-3] ```ts delete(noteId, options?): Promise; ``` Deletes a note. Calls `DELETE v1/slim/notifications/notes/{noteId}`. ###### Parameters [#parameters-31] | Parameter | Type | | ------ | ------ | | `noteId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-31] `Promise`\<`void`\> ##### list() [#list-6] ```ts list( kind, targetId, options? ): Promise; ``` Lists the notes of a notification. Calls `GET v1/slim/notifications/{kind}/{targetId}/notes`. ###### Parameters [#parameters-32] | Parameter | Type | | ------ | ------ | | `kind` | [`NotificationTargetKind`](#notificationtargetkind) | | `targetId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-32] `Promise`\<[`NotificationNotes`](#notificationnotes)\> ##### patch() [#patch] ```ts patch( noteId, body, options? ): Promise; ``` Updates part of a note. Calls `PATCH v1/slim/notifications/notes/{noteId}`. ###### Parameters [#parameters-33] | Parameter | Type | | ------ | ------ | | `noteId` | `string` | | `body` | [`UpdateNotificationNote`](#updatenotificationnote) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-33] `Promise`\<[`NotificationNote`](#notificationnote)\> ##### update() [#update-2] ```ts update( noteId, body, options? ): Promise; ``` Replaces a note. Calls `PUT v1/slim/notifications/notes/{noteId}`. ###### Parameters [#parameters-34] | Parameter | Type | | ------ | ------ | | `noteId` | `string` | | `body` | [`UpdateNotificationNote`](#updatenotificationnote) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-34] `Promise`\<[`NotificationNote`](#notificationnote)\> *** ### SlimNotificationsResource [#slimnotificationsresource] Notifications, by kind. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `alarms` | `readonly` | [`SlimAlarmsResource`](#slimalarmsresource) | Alarm notifications. | | `medical` | `readonly` | [`SlimMedicalNotificationsResource`](#slimmedicalnotificationsresource) | Medical notification episodes. | | `notes` | `readonly` | [`SlimNotificationNotesResource`](#slimnotificationnotesresource) | Notes on notifications. | | `outOfBed` | `readonly` | [`SlimOutOfBedResource`](#slimoutofbedresource) | Out-of-bed notifications. | #### Methods [#methods-8] ##### ~~list()~~ [#list-7] ```ts list(params?, options?): Promise; ``` ###### Parameters [#parameters-35] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimNotificationsQuery`](#slimnotificationsquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-35] `Promise`\<[`SlimNotificationsResponse`](#slimnotificationsresponse)\> ###### Deprecated [#deprecated] Use outOfBed.list, alarms.list or medical.list. ##### recent() [#recent-2] ```ts recent(params?, options?): Promise; ``` Reads the recent notifications. Calls `GET v1/slim/notifications/recent`. ###### Parameters [#parameters-36] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimRecentQuery`](#slimrecentquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-36] `Promise`\<[`SlimRecentNotificationsResponse`](#slimrecentnotificationsresponse)\> *** ### SlimOrganizationsResource [#slimorganizationsresource] Organizations. #### Methods [#methods-9] ##### create() [#create-4] ```ts create(body, options?): Promise; ``` Creates an organization. Calls `POST v1/slim/organization`. ###### Parameters [#parameters-37] | Parameter | Type | | ------ | ------ | | `body` | [`SlimOrganizationInput`](#slimorganizationinput) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-37] `Promise`\<[`SlimOrganization`](#slimorganization)\> ##### delete() [#delete-4] ```ts delete(organizationId, options?): Promise; ``` Deletes an organization. Calls `DELETE v1/slim/organization/{organizationId}`. ###### Parameters [#parameters-38] | Parameter | Type | | ------ | ------ | | `organizationId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-38] `Promise`\<`void`\> ##### retrieve() [#retrieve-3] ```ts retrieve(organizationId, options?): Promise; ``` Fetches one organization. Calls `GET v1/slim/organization/{organizationId}`. ###### Parameters [#parameters-39] | Parameter | Type | | ------ | ------ | | `organizationId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-39] `Promise`\<[`SlimOrganization`](#slimorganization)\> ##### update() [#update-3] ```ts update( organizationId, body, options? ): Promise; ``` Replaces an organization. Calls `PUT v1/slim/organization/{organizationId}`. ###### Parameters [#parameters-40] | Parameter | Type | | ------ | ------ | | `organizationId` | `string` | | `body` | [`SlimOrganizationInput`](#slimorganizationinput) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-40] `Promise`\<[`SlimOrganization`](#slimorganization)\> *** ### SlimOutOfBedResource [#slimoutofbedresource] Out-of-bed notifications. #### Methods [#methods-10] ##### list() [#list-8] ```ts list(params?, options?): Promise; ``` Lists out-of-bed notifications. Calls `GET v1/slim/notifications/oob`. ###### Parameters [#parameters-41] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimOutOfBedQuery`](#slimoutofbedquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-41] `Promise`\<[`SlimNotificationsResponse`](#slimnotificationsresponse)\> ##### recent() [#recent-3] ```ts recent(params?, options?): Promise; ``` Reads the recent out-of-bed notifications. Calls `GET v1/slim/notifications/recent/oob`. ###### Parameters [#parameters-42] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimRecentQuery`](#slimrecentquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-42] `Promise`\<[`SlimRecentOutOfBed`](#slimrecentoutofbed)\> *** ### SlimPatientsResource [#slimpatientsresource] Patients (residents). #### Properties [#properties-1] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `thresholds` | `readonly` | [`SlimPatientThresholdsResource`](#slimpatientthresholdsresource) | Per-patient thresholds. | #### Methods [#methods-11] ##### create() [#create-5] ```ts create(body, options?): Promise; ``` Creates a patient. Calls `POST v1/slim/patient`. ###### Parameters [#parameters-43] | Parameter | Type | | ------ | ------ | | `body` | [`SlimCreatePatient`](#slimcreatepatient) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-43] `Promise`\<[`SlimPatient`](#slimpatient)\> ##### currentVitals() [#currentvitals] ```ts currentVitals(patientId, options?): Promise>; ``` Fetches the patient's latest vitals. Calls `GET v1/slim/patient/{patientId}/current-vitals`. ###### Parameters [#parameters-44] | Parameter | Type | | ------ | ------ | | `patientId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-44] `Promise`\<`Record`\<`string`, `unknown`\>\> ##### delete() [#delete-5] ```ts delete(patientId, options?): Promise; ``` 409 while the resident has a device: unassign it first with an update that omits locationId. ###### Parameters [#parameters-45] | Parameter | Type | | ------ | ------ | | `patientId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-45] `Promise`\<`void`\> ##### everything() [#everything] ```ts everything(patientId, options?): Promise>; ``` Fetches the patient's records as a bundle. Calls `GET v1/slim/patient/{patientId}/$everything`. ###### Parameters [#parameters-46] | Parameter | Type | | ------ | ------ | | `patientId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-46] `Promise`\<`Bundle`\<`Resource`\>\> ##### list() [#list-9] ```ts list(params?, options?): PagePromise; ``` Lists patients page by page. Calls `GET v1/slim/patient`. ###### Parameters [#parameters-47] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimPatientListQuery`](#slimpatientlistquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-47] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`SlimPatientListItem`](#slimpatientlistitem)\> ##### retrieve() [#retrieve-4] ```ts retrieve(patientId, options?): Promise; ``` Fetches one patient. Calls `GET v1/slim/patient/{patientId}`. ###### Parameters [#parameters-48] | Parameter | Type | | ------ | ------ | | `patientId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-48] `Promise`\<[`SlimPatient`](#slimpatient)\> ##### update() [#update-4] ```ts update( patientId, body, options? ): Promise; ``` Replaces the editable fields: omitting locationId unassigns the resident's devices. ###### Parameters [#parameters-49] | Parameter | Type | | ------ | ------ | | `patientId` | `string` | | `body` | [`SlimUpdatePatient`](#slimupdatepatient) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-49] `Promise`\<[`SlimPatient`](#slimpatient)\> *** ### SlimPatientThresholdsResource [#slimpatientthresholdsresource] Per-patient vital thresholds. #### Methods [#methods-12] ##### retrieve() [#retrieve-5] ```ts retrieve(patientId, options?): Promise; ``` Reads a patient's thresholds. Calls `GET v2/slim/threshold/patient/{patientId}`. ###### Parameters [#parameters-50] | Parameter | Type | | ------ | ------ | | `patientId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-50] `Promise`\<[`SlimPatientThresholdV2`](#slimpatientthresholdv2)\> ##### update() [#update-5] ```ts update( patientId, body, options? ): Promise; ``` Never retried: a 409 means another save for this resident is running and nothing changed. ###### Parameters [#parameters-51] | Parameter | Type | | ------ | ------ | | `patientId` | `string` | | `body` | [`SlimThresholdV2Update`](#slimthresholdv2update) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-51] `Promise`\<[`SlimPatientThresholdV2`](#slimpatientthresholdv2)\> *** ### SlimPoliciesResource [#slimpoliciesresource] Access policies. #### Methods [#methods-13] ##### create() [#create-6] ```ts create(body, options?): Promise; ``` Creates a policy. Calls `POST v1/slim/policy`. ###### Parameters [#parameters-52] | Parameter | Type | | ------ | ------ | | `body` | [`SlimCreatePolicy`](#slimcreatepolicy) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-52] `Promise`\<[`SlimPolicyResponse`](#slimpolicyresponse)\> ##### delete() [#delete-6] ```ts delete(policyId, options?): Promise; ``` Deletes a policy. Calls `DELETE v1/slim/policy/{policyId}`. ###### Parameters [#parameters-53] | Parameter | Type | | ------ | ------ | | `policyId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-53] `Promise`\<`void`\> ##### list() [#list-10] ```ts list(params?, options?): Promise; ``` Lists policies. Calls `GET v1/slim/policy`. ###### Parameters [#parameters-54] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimPolicyListQuery`](#slimpolicylistquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-54] `Promise`\<[`SlimPolicyList`](#slimpolicylist)\> ##### retrieve() [#retrieve-6] ```ts retrieve(policyId, options?): Promise; ``` Reads one policy. Calls `GET v1/slim/policy/{policyId}`. ###### Parameters [#parameters-55] | Parameter | Type | | ------ | ------ | | `policyId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-55] `Promise`\<[`SlimPolicyResponse`](#slimpolicyresponse)\> ##### update() [#update-6] ```ts update( policyId, body, options? ): Promise; ``` Replaces a policy. Calls `PUT v1/slim/policy/{policyId}`. ###### Parameters [#parameters-56] | Parameter | Type | | ------ | ------ | | `policyId` | `string` | | `body` | [`SlimUpdatePolicy`](#slimupdatepolicy) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-56] `Promise`\<[`SlimPolicyResponse`](#slimpolicyresponse)\> *** ### SlimPractitionersResource [#slimpractitionersresource] Practitioners. #### Methods [#methods-14] ##### invite() [#invite] ```ts invite(body, options?): Promise; ``` Invites a practitioner by email. Calls `POST v1/slim/invite/practitioner`. ###### Parameters [#parameters-57] | Parameter | Type | | ------ | ------ | | `body` | [`SlimPractitionerInviteInput`](#slimpractitionerinviteinput) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-57] `Promise`\<[`SlimPractitionerInviteResponse`](#slimpractitionerinviteresponse)\> *** ### SlimProjectsResource [#slimprojectsresource] Projects and their users and counts. #### Properties [#properties-2] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `children` | `readonly` | [`SlimChildProjectsResource`](#slimchildprojectsresource) | Child projects. | #### Methods [#methods-15] ##### currentUsers() [#currentusers] ```ts currentUsers(params?, options?): PagePromise; ``` Lists the users of the current project. Calls `GET v1/slim/project/users`. ###### Parameters [#parameters-58] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimProjectUsersQuery`](#slimprojectusersquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-58] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`SlimProjectUser`](#slimprojectuser)\> ##### deviceCounts() [#devicecounts] ```ts deviceCounts(projectId, options?): Promise; ``` Counts a project's devices. Calls `GET v1/slim/project/{projectId}/device-counts`. ###### Parameters [#parameters-59] | Parameter | Type | | ------ | ------ | | `projectId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-59] `Promise`\<[`SlimProjectDeviceCounts`](#slimprojectdevicecounts)\> ##### patientCounts() [#patientcounts] ```ts patientCounts(projectId, options?): Promise; ``` Counts a project's patients. Calls `GET v1/slim/project/{projectId}/patient-counts`. ###### Parameters [#parameters-60] | Parameter | Type | | ------ | ------ | | `projectId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-60] `Promise`\<[`SlimProjectPatientCounts`](#slimprojectpatientcounts)\> ##### retrieve() [#retrieve-7] ```ts retrieve(projectId, options?): Promise; ``` Reads a project. Calls `GET v1/slim/project/{projectId}`. ###### Parameters [#parameters-61] | Parameter | Type | | ------ | ------ | | `projectId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-61] `Promise`\<[`SlimProject`](#slimproject)\> ##### update() [#update-7] ```ts update( projectId, body, options? ): Promise; ``` Replaces a project. Calls `PUT v1/slim/project/{projectId}`. ###### Parameters [#parameters-62] | Parameter | Type | | ------ | ------ | | `projectId` | `string` | | `body` | [`SlimChildProjectInput`](#slimchildprojectinput) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-62] `Promise`\<[`SlimProject`](#slimproject)\> ##### users() [#users] ```ts users( projectId, params?, options? ): PagePromise; ``` Lists the users of a project. Calls `GET v1/slim/project/{projectId}/users`. ###### Parameters [#parameters-63] | Parameter | Type | | ------ | ------ | | `projectId` | `string` | | `params?` | [`SlimProjectUsersQuery`](#slimprojectusersquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-63] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`SlimProjectUser`](#slimprojectuser)\> *** ### SlimSleepResource [#slimsleepresource] Sleep data. #### Methods [#methods-16] ##### statistics() [#statistics] ```ts statistics(params, options?): Promise; ``` Fetches sleep statistics. Calls `GET v1/slim/sleep/statistics`. ###### Parameters [#parameters-64] | Parameter | Type | | ------ | ------ | | `params` | [`SlimSleepStatisticsQuery`](#slimsleepstatisticsquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-64] `Promise`\<[`SlimSleepStatistics`](#slimsleepstatistics)\> *** ### SlimThresholdsResource [#slimthresholdsresource] Vital-sign thresholds of the current project. #### Methods [#methods-17] ##### retrieve() [#retrieve-8] ```ts retrieve(options?): Promise; ``` A home with no stored limits reads as the default template, not as unset. ###### Parameters [#parameters-65] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-65] `Promise`\<[`SlimThresholdV2`](#slimthresholdv2)\> ##### update() [#update-8] ```ts update(body, options?): Promise; ``` Never retried: a 502 means Signals did not take every resident's limits and nothing was written. ###### Parameters [#parameters-66] | Parameter | Type | | ------ | ------ | | `body` | [`SlimThresholdV2Update`](#slimthresholdv2update) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-66] `Promise`\<[`SlimThresholdV2`](#slimthresholdv2)\> *** ### SlimTrendsResource [#slimtrendsresource] Vital-sign trends. #### Methods [#methods-18] ##### graphs() [#graphs] ```ts graphs(params, options?): Promise>>>; ``` Fetches trend graphs. Calls `GET v1/slim/trends/graphs`. ###### Parameters [#parameters-67] | Parameter | Type | | ------ | ------ | | `params` | [`SlimTrendsQuery`](#slimtrendsquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-67] `Promise`\<`Partial`\<`Record`\<[`SlimGraphType`](#slimgraphtype), `Record`\<`string`, [`SlimTrendDeviceData`](#slimtrenddevicedata)\>\>\>\> ##### realtime() [#realtime] ```ts realtime(params, options?): Promise>>>; ``` At most 20 calls per minute per caller: load once per view and wait retryAfterMs after a 503. ###### Parameters [#parameters-68] | Parameter | Type | | ------ | ------ | | `params` | [`SlimRealtimeTrendsQuery`](#slimrealtimetrendsquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-68] `Promise`\<`Partial`\<`Record`\<[`SlimGraphType`](#slimgraphtype), `Record`\<`string`, [`SlimTrendDeviceData`](#slimtrenddevicedata)\>\>\>\> *** ### SlimUsersResource [#slimusersresource] Users. #### Methods [#methods-19] ##### delete() [#delete-7] ```ts delete( profileType, profileId, options? ): Promise; ``` Deletes a user by profile type and id. Calls `DELETE v1/slim/user/{profileType}/{profileId}`. ###### Parameters [#parameters-69] | Parameter | Type | | ------ | ------ | | `profileType` | [`SlimUserProfileType`](#slimuserprofiletype) | | `profileId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-69] `Promise`\<[`SlimUserDeleted`](#slimuserdeleted)\> *** ### SlimZonesResource [#slimzonesresource] Zones. #### Methods [#methods-20] ##### deviceCounts() [#devicecounts-1] ```ts deviceCounts(params?, options?): Promise>; ``` Counts devices per zone. Calls `GET v1/slim/zones/device-counts`. ###### Parameters [#parameters-70] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimZoneDeviceCountsQuery`](#slimzonedevicecountsquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-70] `Promise`\<`Record`\<`string`, `unknown`\>\> ##### list() [#list-11] ```ts list(params?, options?): PagePromise; ``` Lists zones. Calls `GET v1/slim/zones`. ###### Parameters [#parameters-71] | Parameter | Type | | ------ | ------ | | `params?` | [`SlimZoneListQuery`](#slimzonelistquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-71] [`PagePromise`](/web-sdk/core/reference/core/ovok-client#pagepromise)\<[`SlimZone`](#slimzone)\> ##### retrieve() [#retrieve-9] ```ts retrieve(zoneId, options?): Promise; ``` Reads one zone. Calls `GET v1/slim/zones/{zoneId}`. ###### Parameters [#parameters-72] | Parameter | Type | | ------ | ------ | | `zoneId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-72] `Promise`\<[`SlimZoneDetail`](#slimzonedetail)\> ## Interfaces [#interfaces] ### SlimResource [#slimresource] Care-home resources: residents, devices, notifications, thresholds, trends, sleep, places and staff. Calls routes under `v1/slim`. #### Properties [#properties-3] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `changeHistory` | `readonly` | [`SlimChangeHistoryResource`](#slimchangehistoryresource) | The change history. | | `devices` | `readonly` | [`SlimDevicesResource`](#slimdevicesresource) | Devices. | | `exports` | `readonly` | [`SlimExportsResource`](#slimexportsresource) | Report exports. | | `locations` | `readonly` | [`SlimLocationsResource`](#slimlocationsresource) | Locations. | | `notifications` | `readonly` | [`SlimNotificationsResource`](#slimnotificationsresource) | Alarms, out-of-bed and medical notifications. | | `organizations` | `readonly` | [`SlimOrganizationsResource`](#slimorganizationsresource) | Organizations. | | `patients` | `readonly` | [`SlimPatientsResource`](#slimpatientsresource) | Residents. | | `policies` | `readonly` | [`SlimPoliciesResource`](#slimpoliciesresource) | Access policies. | | `practitioners` | `readonly` | [`SlimPractitionersResource`](#slimpractitionersresource) | Practitioners. | | `projects` | `readonly` | [`SlimProjectsResource`](#slimprojectsresource) | Projects. | | `sleep` | `readonly` | [`SlimSleepResource`](#slimsleepresource) | Sleep statistics. | | `thresholds` | `readonly` | [`SlimThresholdsResource`](#slimthresholdsresource) | Alert thresholds. | | `trends` | `readonly` | [`SlimTrendsResource`](#slimtrendsresource) | Historical and realtime trends. | | `users` | `readonly` | [`SlimUsersResource`](#slimusersresource) | Users. | | `zones` | `readonly` | [`SlimZonesResource`](#slimzonesresource) | Zones. | #### Methods [#methods-21] ##### health() [#health] ```ts health(options?): Promise; ``` Checks the slim API health. Calls `GET v1/slim/health`. ###### Parameters [#parameters-73] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-73] `Promise`\<[`SlimHealth`](#slimhealth)\> ## Type Aliases [#type-aliases] ### ChangeHistoryAction [#changehistoryaction] ```ts type ChangeHistoryAction = | "created" | "deleted" | "renamed" | "moved" | "assigned" | "unassigned" | "discharged" | "reactivated" | "thresholdChanged"; ``` What happened to the record. *** ### ChangeHistoryKey [#changehistorykey] ```ts type ChangeHistoryKey = | "residentDeleted" | "residentMaidenNameChanged" | "orgThresholdRangeChanged" | "patientSignalsThresholdSet" | "patientSignalsThresholdRemoved" | "orgSignalsSettingsChanged" | "userInvited" | "userRenamed" | "userRoleChanged" | "userRemoved" | "roleCreated" | "roleDeleted" | "rolePermissionsChanged" | "residentAssignedToDeviceAndLocation" | "residentUnassignedFromDevicesAndLocation" | "residentUnassignedFromDevicesAndLocationWithZone" | "residentUnassignedFromDeviceAndLocation" | "residentDeviceAssigned" | "residentDeviceUnassigned" | "residentMovedToLocation" | "residentRemovedFromLocation" | "residentMovedToZone" | "residentRemovedFromZone" | "patientThresholdMetricSetToIndividual" | "patientThresholdMetricSetToGlobal" | "patientTimeOutOfBedMetricSetToIndividual" | "patientTimeOutOfBedMetricSetToGlobal" | "orgTimeOutOfBedMetricUpdated" | "residentDischarged" | "residentReactivated" | "residentArchived" | "residentNameChanged" | "orgThresholdMetricUpdated" | "patientThresholdMetricUpdated" | "deviceCreated" | "deviceDeleted" | "deviceProjectChanged" | "deviceLocationChanged" | "deviceZoneChanged" | "deviceRenamed" | "locationCreated" | "locationDeleted" | "locationRenamed" | "locationZoneChanged" | "locationFloorChanged" | "locationRoomChanged" | "locationBedChanged" | "zoneCreated" | "zoneDeleted" | "zoneRenamed"; ``` Identifies what changed; it selects the wording and the keys of `values`. *** ### ChangeHistoryPage [#changehistorypage] ```ts type ChangeHistoryPage = object; ``` One page of change-history rows. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `count` | `number` | Rows per page. | | `page` | `number` | This page's number. | | `resources` | [`ChangeHistoryRow`](#changehistoryrow)[] | The rows on this page. | | `total` | `number` | Total rows matching the filters. | *** ### ChangeHistoryQuery [#changehistoryquery] ```ts type ChangeHistoryQuery = object; ``` Filters and paging for a change-history list. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `actions?` | \| [`ChangeHistoryAction`](#changehistoryaction) \| readonly [`ChangeHistoryAction`](#changehistoryaction)[] | Only these actions. | | `count?` | `number` | Rows per page. | | `deviceId?` | `string` \| readonly `string`[] | Only changes for these devices. | | `endDate?` | `string` | Only changes at or before this ISO 8601 date. | | `locationId?` | `string` \| readonly `string`[] | Only changes for these locations. | | `page?` | `number` | Page number to fetch. | | `relatedTo?` | \| [`ChangeHistoryReference`](#changehistoryreference) \| readonly [`ChangeHistoryReference`](#changehistoryreference)[] | Only changes related to these references. | | `residentId?` | `string` \| readonly `string`[] | Only changes for these residents. | | `scope?` | [`ChangeHistoryScope`](#changehistoryscope) | `"global"` limits to global changes; `"all"` includes the rest. | | `sort?` | [`ChangeHistorySort`](#changehistorysort) | Sort direction by time. | | `startDate?` | `string` | Only changes at or after this ISO 8601 date. | | `types?` | readonly [`ChangeHistoryType`](#changehistorytype)[] | Only these record types. | | `userId?` | `string` \| readonly `string`[] | Only changes made by these users. | | `zoneId?` | `string` \| readonly `string`[] | Only changes for these zones. | *** ### ChangeHistoryReference [#changehistoryreference] ```ts type ChangeHistoryReference = | `Patient/${string}` | `Device/${string}` | `Location/${string}` | `Organization/${string}` | `Practitioner/${string}` | `AccessPolicy/${string}`; ``` A FHIR reference that filters changes to those related to it. *** ### ChangeHistoryResident [#changehistoryresident] ```ts type ChangeHistoryResident = object; ``` A resident referenced by a change. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `patientId` | `string` | Patient id of the resident. | | `residentId` | `string` \| `null` | Resident id, or null when the patient has none. | *** ### ChangeHistoryRow [#changehistoryrow] ```ts type ChangeHistoryRow = object; ``` One recorded change. #### Properties [#properties-7] | Property | Type | Description | | ------ | ------ | ------ | | `details` | `object` | What changed. | | `details.key` | [`ChangeHistoryKey`](#changehistorykey) \| `string` & `object` | What kind of change this was. | | `details.values` | `Record`\<`string`, `string` \| `number` \| `null`\> | Values for the change; keys depend on `key`. | | `deviceId` | `string` | Device the change concerns. | | `id` | `string` | Change identifier. | | `locationId?` | `string` \| `null` | Location the change concerns, if any. | | `resident` | [`ChangeHistoryResident`](#changehistoryresident) \| `null` | The resident, or null when the change has none. | | `residentId` | `string` | Resident the change concerns. | | `time` | `string` | ISO 8601 time of the change. | | `type` | [`ChangeHistoryType`](#changehistorytype) | The kind of record changed. | | `user` | `string` | The user who made the change. | | `zoneId?` | `string` \| `null` | Zone the change concerns, if any. | *** ### ChangeHistoryScope [#changehistoryscope] ```ts type ChangeHistoryScope = "all" | "global"; ``` Whether to list all changes or only global ones. *** ### ChangeHistorySort [#changehistorysort] ```ts type ChangeHistorySort = "asc" | "desc"; ``` Sort direction by time. *** ### ChangeHistoryType [#changehistorytype] ```ts type ChangeHistoryType = "Threshold" | "Location" | "Zone" | "Device" | "Resident" | "Access"; ``` The kind of record a change concerns. *** ### CreateNotificationNote [#createnotificationnote] ```ts type CreateNotificationNote = object; ``` Request body for adding a note. #### Properties [#properties-8] | Property | Type | Description | | ------ | ------ | ------ | | `id` | `string` | Id of the notification to annotate. | | `kind` | [`NotificationTargetKind`](#notificationtargetkind) | The kind of notification to annotate. | | `text` | `string` | Note text. | *** ### NotificationNote [#notificationnote] ```ts type NotificationNote = object; ``` A note attached to a notification. #### Properties [#properties-9] | Property | Type | Description | | ------ | ------ | ------ | | `author` | `object` | Who wrote the note. | | `author.name` | `string` \| `null` | Display name of the author, or null. | | `author.practitionerId` | `string` \| `null` | Practitioner id of the author, or null. | | `createdAt` | `string` \| `null` | ISO 8601 creation time, or null. | | `id` | `string` | Note id. | | `patientId` | `string` \| `null` | Patient the notification concerns, or null. | | `target` | `object` | The notification the note belongs to. | | `target.id` | `string` | Id of the notification. | | `target.kind` | [`NotificationTargetKind`](#notificationtargetkind) | The kind of notification. | | `text` | `string` | Note text. | | `updatedAt` | `string` \| `null` | ISO 8601 time of the last edit, or null. | *** ### NotificationNotes [#notificationnotes] ```ts type NotificationNotes = object; ``` The notes on one notification. #### Properties [#properties-10] | Property | Type | Description | | ------ | ------ | ------ | | `resources` | [`NotificationNote`](#notificationnote)[] | The notes. | | `total` | `number` | Number of notes. | *** ### NotificationTargetKind [#notificationtargetkind] ```ts type NotificationTargetKind = "oob" | "alarm" | "medical" | "alert"; ``` The kind of notification a note is attached to. *** ### SignalsSyncStatus [#signalssyncstatus] ```ts type SignalsSyncStatus = | { status: "ok"; } | { reason: string; status: "pending"; } | { reason: string; status: "unverified"; } | null; ``` Whether a resident's limits reached the Signals service; null when not applicable. #### Union Members [#union-members] ##### Type Literal [#type-literal] ```ts { status: "ok"; } ``` ###### status [#status] ```ts status: "ok"; ``` Always `ok`: the limits reached Signals. *** ##### Type Literal [#type-literal-1] ```ts { reason: string; status: "pending"; } ``` ###### reason [#reason] ```ts reason: string; ``` Why the sync is pending. ###### status [#status-1] ```ts status: "pending"; ``` Always `pending`: the limits are not yet confirmed by Signals. *** ##### Type Literal [#type-literal-2] ```ts { reason: string; status: "unverified"; } ``` ###### reason [#reason-1] ```ts reason: string; ``` Why delivery could not be verified. ###### status [#status-2] ```ts status: "unverified"; ``` Always `unverified`: delivery to Signals could not be checked. *** `null` *** ### SlimAlarm [#slimalarm] ```ts type SlimAlarm = SlimNotification & object; ``` A notification with its alarm details, or null when it has none. #### Type Declaration [#type-declaration] ##### alarm [#alarm] ```ts alarm: SlimAlarmDetails | null; ``` Alarm details, or null when the notification is not an alarm. *** ### SlimAlarmDetails [#slimalarmdetails] ```ts type SlimAlarmDetails = object; ``` Alarm-specific fields of an alarm notification. #### Properties [#properties-11] | Property | Type | Description | | ------ | ------ | ------ | | `episodeId` | `string` | Id of the alarm episode. | | `severity` | [`SlimAlarmSeverity`](#slimalarmseverity) | Alarm severity. | | `text` | `string` \| `null` | Alarm text, or null. | | `type` | `string` | The server forwards the device's alarm type without normalizing it. | *** ### SlimAlarmQuery [#slimalarmquery] ```ts type SlimAlarmQuery = object; ``` Filters, paging and sort for listing alarms. #### Properties [#properties-12] | Property | Type | Description | | ------ | ------ | ------ | | `count?` | `number` | Alarms per page. | | `device?` | `string` | Only alarms for this device id. | | `endDate?` | `string` | Only alarms at or before this ISO 8601 date. | | `page?` | `number` | Page number to fetch. | | `patient?` | `string` | Only alarms for this patient id. | | `severity?` | \| [`SlimAlarmSeverity`](#slimalarmseverity) \| readonly [`SlimAlarmSeverity`](#slimalarmseverity)[] | Only these severities. | | `sort?` | `"newest"` \| `"oldest"` | Order by time, newest first by default. | | `startDate?` | `string` | Only alarms at or after this ISO 8601 date. | | `status?` | [`SlimAlarmStatus`](#slimalarmstatus) | Only active or completed alarms. | | `type?` | \| [`SlimAlarmType`](#slimalarmtype) \| readonly [`SlimAlarmType`](#slimalarmtype)[] | Only these alarm types. | *** ### SlimAlarmSeverity [#slimalarmseverity] ```ts type SlimAlarmSeverity = "RED" | "YELLOW" | "ATTENTION"; ``` Alarm severity. *** ### SlimAlarmsPage [#slimalarmspage] ```ts type SlimAlarmsPage = object; ``` One page of alarms. #### Properties [#properties-13] | Property | Type | Description | | ------ | ------ | ------ | | `count` | `number` | Alarms per page. | | `page` | `number` | This page's number. | | `resources` | [`SlimAlarm`](#slimalarm)[] | The alarms on this page. | | `total` | `number` | Total alarms matching the filters. | | `truncated` | \| \{ `limit`: `number`; `reason`: `"result-cap"` \| `"scan-budget"`; \} \| `null` | Set when the server capped the result, with the reason and limit; null otherwise. | *** ### SlimAlarmStatus [#slimalarmstatus] ```ts type SlimAlarmStatus = "active" | "completed"; ``` Whether the alarm is still open. *** ### SlimAlarmType [#slimalarmtype] ```ts type SlimAlarmType = "deviceAlarm" | "attention"; ``` Alarm category: a device alarm or an attention alert. *** ### SlimAlertSummary [#slimalertsummary] ```ts type SlimAlertSummary = Record; ``` Alert state of a device, keyed by vital. *** ### SlimAssignDevice [#slimassigndevice] ```ts type SlimAssignDevice = object; ``` Body of `assignSlimDeviceToProject`. #### Properties [#properties-14] | Property | Type | Description | | ------ | ------ | ------ | | `deviceId` | `string` | Id of the device to assign. | | `locationId?` | `string` | Location in the target project, when placing it. | | `projectId` | `string` | Id of the target project. | *** ### SlimChildProjectCreated [#slimchildprojectcreated] ```ts type SlimChildProjectCreated = object; ``` Result of creating a child project. #### Properties [#properties-15] | Property | Type | Description | | ------ | ------ | ------ | | `projectId` | `string` | Id of the new child project. | | `success` | `true` | Always true on success. | *** ### SlimChildProjectDeleted [#slimchildprojectdeleted] ```ts type SlimChildProjectDeleted = object; ``` Result of deleting a child project. #### Properties [#properties-16] | Property | Type | Description | | ------ | ------ | ------ | | `success` | `true` | Always true on success. | *** ### SlimChildProjectInput [#slimchildprojectinput] ```ts type SlimChildProjectInput = object; ``` Body of the child-project create and project update calls. #### Properties [#properties-17] | Property | Type | Description | | ------ | ------ | ------ | | `address?` | [`SlimProjectAddress`](#slimprojectaddress)[] | Addresses. | | `contact?` | [`SlimProjectContact`](#slimprojectcontact)[] | Contacts. | | `extension?` | `unknown` | Extra extension data, passed through. | | `id?` | `string` | Project id, when updating. | | `name` | `string` | Project name. | | `settings?` | [`SlimProject`](#slimproject)\[`"settings"`\] | Project settings. | *** ### SlimCreateDevice [#slimcreatedevice] ```ts type SlimCreateDevice = object; ``` Body of `createSlimDevice`. #### Properties [#properties-18] | Property | Type | Description | | ------ | ------ | ------ | | `locationId?` | `string` | Location to place the device in. | | `name` | `string` | Device name (its serial). | | `organizationId?` | `string` | Zone of the device. | | `patientId?` | `string` | Resident to assign. | | `thingsboardId?` | `string` | Id of the device on the IoT platform. | *** ### SlimCreateLocation [#slimcreatelocation] ```ts type SlimCreateLocation = object; ``` Body of `createSlimLocation`. #### Properties [#properties-19] | Property | Type | Description | | ------ | ------ | ------ | | `bed?` | `string` | Bed label. | | `floor?` | `string` | Floor label. | | `name` | `string` | Location name. | | `organizationId?` | `string` | Zone of the location. | | `room?` | `string` | Room label. | *** ### SlimCreatePatient [#slimcreatepatient] ```ts type SlimCreatePatient = object; ``` Body of `createSlimPatient`. #### Properties [#properties-20] | Property | Type | Description | | ------ | ------ | ------ | | `admissionDate?` | `string` | Admission date, ISO 8601. | | `birthDate?` | `string` | Birth date, ISO 8601 date. | | `deviceId?` | `string` \| `null` | Device to assign; null for none. | | `gender?` | `"male"` \| `"female"` \| `"other"` \| `"unknown"` | Administrative gender. | | `locationId?` | `string` | Location to place the resident in. | | `name` | [`SlimHumanName`](#slimhumanname)[] | Names, one entry per use. | | `organizationId?` | `string` | Zone of the resident; requires a location or device. | *** ### SlimCreatePolicy [#slimcreatepolicy] ```ts type SlimCreatePolicy = object; ``` Body of `createSlimPolicy`. #### Properties [#properties-21] | Property | Type | Description | | ------ | ------ | ------ | | `members` | [`SlimPolicyMember`](#slimpolicymember)[] | Members of the policy. | | `policy` | `object` | The access policy. | | `policy.name` | `string` | Policy name. | | `policy.resource` | `object`[] | Rules per resource type. | | `policy.resourceType` | `"AccessPolicy"` | Always `AccessPolicy`. | *** ### SlimDevice [#slimdevice] ```ts type SlimDevice = object; ``` A device as returned by `getSlimDevice`. #### Properties [#properties-22] | Property | Type | Description | | ------ | ------ | ------ | | `bed?` | `string` | Bed label. | | `floor?` | `string` | Floor label. | | `locationId?` | `string` | Id of the location. | | `locationName` | `string` \| `null` | Name of the location, or null. | | `name` | `string` | Device name (its serial). | | `organizationId?` | `string` | Id of the zone. | | `organizationName` | `string` \| `null` | Name of the zone, or null. | | `patientId?` | `string` | Id of the assigned resident. | | `patientName` | `string` \| `null` | Name of the assigned resident, or null. | | `room?` | `string` | Room label. | | `status?` | `"active"` \| `"inactive"` \| `"entered-in-error"` \| `"unknown"` | Device status. | | `statusReason` | `object`[] | Reasons for the status. | | `thingsboardId?` | `string` | Id of the device on the IoT platform. | *** ### SlimDeviceListItem [#slimdevicelistitem] ```ts type SlimDeviceListItem = object; ``` A device row in `listSlimDevices`. #### Properties [#properties-23] | Property | Type | Description | | ------ | ------ | ------ | | `createdAt?` | `string` \| `null` | ISO 8601 creation time, or null. | | `id` | `string` | Resource id. | | `lastActivityTime?` | `string` \| `null` | ISO 8601 time of the last activity, or null. | | `locationId` | `string` \| `null` | Id of the location, or null. | | `locationName` | `string` \| `null` | Name of the location. | | `name` | `string` | Device name (its serial). | | `organizationId` | `string` \| `null` | Id of the zone, or null. | | `organizationName` | `string` \| `null` | Name of the organization. | | `patientId` | `string` \| `null` | Id of the assigned resident, or null. | | `patientName` | `string` \| `null` | Name of the resident. | | `status` | `"active"` \| `"inactive"` | Whether the device is active. | | `thingsboardId?` | `string` | Id of the device on the IoT platform. | *** ### SlimDeviceListQuery [#slimdevicelistquery] ```ts type SlimDeviceListQuery = object; ``` Filters, sorting and paging for `listSlimDevices`. #### Properties [#properties-24] | Property | Type | Description | | ------ | ------ | ------ | | `active?` | `boolean` | Filter by active or inactive devices. | | `count?` | `number` | Rows per page. | | `locationId?` | `string` | Only devices at this location. | | `orderBy?` | `"ASC"` \| `"DESC"` | Sort direction. | | `organizationId?` | `string` | Only devices in this zone. | | `page?` | `number` | 1-based page number. | | `patientId?` | `string` | Only the device of this resident. | | `patientSearch?` | `string` | Free-text search on the resident name. | | `search?` | `string` | Free-text search. | | `sortBy?` | `string` | Field to sort by. | *** ### SlimDeviceObservationIds [#slimdeviceobservationids] ```ts type SlimDeviceObservationIds = Omit; ``` Observation IDs of one device, without the batch ID. *** ### SlimDeviceTelemetry [#slimdevicetelemetry] ```ts type SlimDeviceTelemetry = object; ``` Latest telemetry and alerts of one device. #### Properties [#properties-25] | Property | Type | Description | | ------ | ------ | ------ | | `alerts?` | [`SlimAlertSummary`](#slimalertsummary) | Alert state, when available. | | `deviceId` | `string` | Id of the device. | | `telemetry?` | [`SlimTelemetrySummary`](#slimtelemetrysummary) | Latest readings, when available. | *** ### SlimEpisodeCloseReason [#slimepisodeclosereason] ```ts type SlimEpisodeCloseReason = | "RECOVERED" | "TIMEOUT" | "ACKNOWLEDGED" | "CROSSED" | "THRESHOLD_CHANGED" | "AWAY" | "STALE" | "MANUAL"; ``` STALE closes an out-of-bed episode that stayed open for 48 hours. *** ### SlimExportPdf [#slimexportpdf] ```ts type SlimExportPdf = object; ``` A generated PDF report and its download link. #### Properties [#properties-26] | Property | Type | Description | | ------ | ------ | ------ | | `binary` | `Record`\<`string`, `unknown`\> | Stored PDF content record. | | `documentReference` | `Record`\<`string`, `unknown`\> | Stored document record. | | `downloadUrl` | `string` | URL to download the PDF. | | `expiresAt?` | `string` | ISO 8601 time the download link expires. | *** ### SlimExportPdfRequest [#slimexportpdfrequest] ```ts type SlimExportPdfRequest = object; ``` Body of `exportSlimPatientPdf`. #### Properties [#properties-27] | Property | Type | Description | | ------ | ------ | ------ | | `code` | `string` | Report code. | | `language` | `string` | Report language code. | | `mailTo?` | `string`[] | Email addresses to send the PDF to. | | `patientId` | `string` | Id of the resident to report on. | | `period` | `object` | Reporting period. | | `period.end` | `string` | End of the period, ISO 8601. | | `period.start` | `string` | Start of the period, ISO 8601. | | `timeZone?` | `string` | IANA time zone. | *** ### SlimGraphType [#slimgraphtype] ```ts type SlimGraphType = | "heartRate" | "respiratoryRate" | "oxygenSaturation" | "pulseRate" | "perfusionIndex" | "bodyTemperature" | "systolicBloodPressure" | "diastolicBloodPressure" | "heartRateVariability"; ``` Vital that a real-time trend graph can show. *** ### SlimHealth [#slimhealth] ```ts type SlimHealth = object; ``` Service health report. #### Properties [#properties-28] | Property | Type | Description | | ------ | ------ | ------ | | `cache?` | `object` | Cache statistics. | | `cache.errors` | `number` | Cache errors. | | `cache.hitRate?` | `number` | Cache hit ratio. | | `cache.hits` | `number` | Cache hits. | | `cache.misses` | `number` | Cache misses. | | `endpoints` | `object` | Public endpoints. | | `endpoints.api` | `string` | API base URL. | | `endpoints.fhir` | `string` | FHIR base URL. | | `environment` | `string` | Deployment environment name. | | `externalSystems` | `object` | Dependency health. | | `externalSystems.fhirStore` | [`SlimHealthDependency`](#slimhealthdependency) | FHIR store health. | | `externalSystems.redis` | [`SlimHealthDependency`](#slimhealthdependency) | Whether the cache is reachable. | | `observability` | `object` | Observability links. | | `observability.signoz` | `string` \| `null` | Observability dashboard link, or null. | | `ovok?` | `object` | Process metrics. | | `ovok.cpuUsage?` | `number` | CPU usage. | | `ovok.eventLoopLagMs?` | `number` | Event-loop lag in milliseconds. | | `ovok.memoryUsageBytes?` | `number` | Memory in use, in bytes. | | `status` | `"healthy"` \| `"degraded"` \| `"unhealthy"` | Overall service status. | | `system?` | `object` | Host system metrics. | | `system.cpuUtilization?` | `number` | CPU utilization. | | `system.loadAverage15m?` | `number` | 15-minute load average. | | `system.loadAverage1m?` | `number` | 1-minute load average. | | `system.loadAverage5m?` | `number` | 5-minute load average. | | `system.memoryUsageBytes?` | `number` | Memory in use, in bytes. | | `timestamp` | `string` | ISO 8601 time of the report. | | `uptimeSeconds` | `number` | Uptime in seconds. | | `version` | `string` \| `null` | Deployed version, or null. | *** ### SlimHealthDependency [#slimhealthdependency] ```ts type SlimHealthDependency = object; ``` Health of one dependency; fields present depend on the dependency. #### Properties [#properties-29] | Property | Type | Description | | ------ | ------ | ------ | | `blockedClients?` | `number` | Blocked clients. | | `connectedClients?` | `number` | Connected clients. | | `evictedKeys?` | `number` | Evicted keys. | | `hitRate?` | `number` | Cache hit ratio. | | `opsPerSecond?` | `number` | Operations per second. | | `peakMemoryBytes?` | `number` | Peak memory, in bytes. | | `peakMemoryHuman?` | `string` | Peak memory, human-readable. | | `platform?` | `string` | Host platform. | | `postgres?` | `boolean` | Whether the database is reachable. | | `redis?` | `boolean` | Whether the cache is reachable. | | `responseTimeMs?` | `number` | Response time in milliseconds. | | `runtime?` | `string` | Runtime version. | | `serverMetrics?` | `object` | Server metrics. | | `serverMetrics.db` | `object` | Database metrics. | | `serverMetrics.db.healthcheckRttSeconds?` | `number` | Health-check round trip, in seconds. | | `serverMetrics.db.idleConnections?` | `number` | Idle database connections. | | `serverMetrics.db.queriesAwaitingClient?` | `number` | Queries waiting for a client connection. | | `serverMetrics.fhirOps?` | `object` | FHIR operation counts. | | `serverMetrics.fhirOps.createCount?` | `number` | Create operations. | | `serverMetrics.fhirOps.deleteCount?` | `number` | Delete operations. | | `serverMetrics.fhirOps.patchCount?` | `number` | Patch operations. | | `serverMetrics.fhirOps.readCount?` | `number` | Read operations. | | `serverMetrics.fhirOps.searchCount?` | `number` | Search operations. | | `serverMetrics.fhirOps.updateCount?` | `number` | Update operations. | | `serverMetrics.memory` | `object` | Memory metrics. | | `serverMetrics.memory.newSpaceBytes?` | `number` | New-space size, in bytes. | | `serverMetrics.memory.oldSpaceBytes?` | `number` | Old-space size, in bytes. | | `serverMetrics.memory.usedHeapBytes?` | `number` | Used heap, in bytes. | | `serverMetrics.queues` | `object` | Job queue depths. | | `serverMetrics.queues.batchDelayed?` | `number` | Batch jobs delayed. | | `serverMetrics.queues.batchWaiting?` | `number` | Batch jobs waiting. | | `serverMetrics.queues.cronDelayed?` | `number` | Cron jobs delayed. | | `serverMetrics.queues.cronWaiting?` | `number` | Cron jobs waiting. | | `serverMetrics.queues.subscriptionDelayed?` | `number` | Subscription jobs delayed. | | `serverMetrics.queues.subscriptionWaiting?` | `number` | Subscription jobs waiting. | | `serverMetrics.server?` | `object` | Server timing metrics. | | `serverMetrics.server.indexingDurationMsMax?` | `number` | Longest indexing duration, in milliseconds. | | `serverMetrics.server.validationDurationMsMax?` | `number` | Longest validation duration, in milliseconds. | | `status` | `"up"` \| `"down"` | Whether the dependency is up. | | `uptimeSeconds?` | `number` | Uptime in seconds. | | `usedMemoryBytes?` | `number` | Used memory, in bytes. | | `usedMemoryHuman?` | `string` | Used memory, human-readable. | | `version?` | `string` | Version. | *** ### SlimHistoricalGraphType [#slimhistoricalgraphtype] ```ts type SlimHistoricalGraphType = "heartRate" | "respiratoryRate"; ``` Vital that a historical trend graph can show. *** ### SlimHumanName [#slimhumanname] ```ts type SlimHumanName = object; ``` A resident's name of one kind. #### Properties [#properties-30] | Property | Type | Description | | ------ | ------ | ------ | | `family?` | `string` | Family name. | | `given?` | `string`[] | Given names. | | `use` | `"official"` \| `"nickname"` \| `"maiden"` | Kind of name. | *** ### SlimLiveDevice [#slimlivedevice] ```ts type SlimLiveDevice = Record; ``` One row of the live device list; the shape is defined by the server. *** ### SlimLiveQuery [#slimlivequery] ```ts type SlimLiveQuery = object; ``` Filters, sorting and paging for the live device reads. #### Properties [#properties-31] | Property | Type | Description | | ------ | ------ | ------ | | `count?` | `number` | Rows per page. | | `deviceId?` | `string` | Only this device. | | `effectiveSleepStatus?` | `string` | Filter by effective sleep status. | | `includeUnassigned?` | `boolean` | Include devices without a resident. | | `orderBy?` | `"ASC"` \| `"DESC"` | Sort direction. | | `organizationId?` | `string` | Only devices in this zone. | | `page?` | `number` | 1-based page number. | | `residentState?` | [`SlimResidentState`](#slimresidentstate) | Only devices of residents in this state. | | `search?` | `string` | Free-text search. | | `sortBy?` | `string` | Field to sort by. | *** ### SlimLiveTelemetry [#slimlivetelemetry] ```ts type SlimLiveTelemetry = object; ``` Latest telemetry and alerts for a page of devices, keyed by device id. #### Properties [#properties-32] | Property | Type | Description | | ------ | ------ | ------ | | `alerts` | `Record`\<`string`, [`SlimAlertSummary`](#slimalertsummary)\> | Alerts per device id. | | `count` | `number` | Rows per page. | | `page` | `number` | 1-based page number. | | `telemetry` | `Record`\<`string`, [`SlimTelemetrySummary`](#slimtelemetrysummary)\> | Telemetry per device id. | | `total` | `number` | Total matching devices. | *** ### SlimLocation [#slimlocation] ```ts type SlimLocation = object; ``` A location (floor, room, bed) with its device and resident. #### Properties [#properties-33] | Property | Type | Description | | ------ | ------ | ------ | | `bed?` | `string` | Bed label. | | `deviceId?` | `string` | Id of the device here. | | `deviceName?` | `string` | Name of the device here. | | `floor?` | `string` | Floor label. | | `id` | `string` | Location id. | | `name` | `string` | Location name. | | `organizationId?` | `string` | Id of the zone. | | `organizationName?` | `string` | Name of the zone. | | `patientId?` | `string` | Id of the resident here. | | `patientName?` | `string` | Name of the resident here. | | `room?` | `string` | Room label. | *** ### SlimLocationQuery [#slimlocationquery] ```ts type SlimLocationQuery = object; ``` Filters and paging for `listSlimLocations`. #### Properties [#properties-34] | Property | Type | Description | | ------ | ------ | ------ | | `bed?` | `string` | Bed label. | | `count?` | `number` | Rows per page. | | `deviceId?` | `string` | Only the location of this device. | | `floor?` | `string` | Floor label. | | `organizationId?` | `string` | Only locations in this zone. | | `page?` | `number` | 1-based page number. | | `room?` | `string` | Room label. | | `search?` | `string` | Free-text search. | *** ### SlimMedicalEpisodeCore [#slimmedicalepisodecore] ```ts type SlimMedicalEpisodeCore = object; ``` The core fields of a medical episode. #### Properties [#properties-35] | Property | Type | Description | | ------ | ------ | ------ | | `avgValue` | `number` \| `null` | Average value, or null. | | `closedAt` | `string` \| `null` | ISO 8601 time the episode closed, or null while open. | | `closeReason` | \| [`SlimEpisodeCloseReason`](#slimepisodeclosereason) \| `string` & `object` \| `null` | Why the episode closed, or null while open. | | `code` | `string` | Observation code the episode tracks. | | `display` | `string` \| `null` | Display text of `code`, or null. | | `durationMs` | `number` \| `null` | Episode duration in milliseconds, or null. | | `firedBand` | \| \{ `max`: `number` \| `null`; `min`: `number` \| `null`; `triggerVersion`: `number` \| `null`; \} \| `null` | The limit band that fired, or null. | | `firingCount` | `number` \| `null` | Number of times the limit fired, or null. | | `id` | `string` | Episode id. | | `lastFiringAt` | `string` \| `null` | ISO 8601 time of the latest firing, or null. | | `lastFiringValue` | `number` \| `null` | Value at the latest firing, or null. | | `lastObservationId` | `string` \| `null` | Id of the latest observation, or null. | | `lastSampleAt` | `string` \| `null` | ISO 8601 time of the latest sample, or null. | | `lastValue` | `number` \| `null` | Latest value, or null. | | `maxValue` | `number` \| `null` | Highest value seen, or null. | | `minValue` | `number` \| `null` | Lowest value seen, or null. | | `observationCount` | `number` \| `null` | Number of observations in the episode, or null. | | `openedAt` | `string` | ISO 8601 time the episode opened. | | `patientId` | `string` | Patient id. | | `peakAt` | `string` \| `null` | ISO 8601 time of the peak, or null. | | `peakValue` | `number` \| `null` | Most extreme value, or null. | | `status` | `string` | Episode status. | | `system` | `string` \| `null` | Code system of `code`, or null. | *** ### SlimMedicalEpisodeValue [#slimmedicalepisodevalue] ```ts type SlimMedicalEpisodeValue = object; ``` One observation recorded within a medical episode. #### Properties [#properties-36] | Property | Type | Description | | ------ | ------ | ------ | | `note` | `string` \| `null` | Note attached to the observation, or null. | | `observationId` | `string` | Id of the observation. | | `observedAt` | `string` \| `null` | ISO 8601 time the value was measured, or null. | | `recordedAt` | `string` | ISO 8601 time the value was recorded. | | `valueNumber` | `number` \| `null` | Numeric value, or null. | | `valueString` | `string` \| `null` | Text value, or null. | | `valueUnit` | `string` \| `null` | Unit of the value, or null. | *** ### SlimMedicalNotificationAcknowledgement [#slimmedicalnotificationacknowledgement] ```ts type SlimMedicalNotificationAcknowledgement = object; ``` Who acknowledged a medical notification and when. #### Properties [#properties-37] | Property | Type | Description | | ------ | ------ | ------ | | `acknowledgedActor` | [`SlimMedicalNotificationActor`](#slimmedicalnotificationactor) \| `null` | The acknowledging user, or null. | | `acknowledgedAt` | `string` \| `null` | ISO 8601 acknowledgement time, or null. | | `acknowledgedBy` | `string` \| `null` | Reference of the acknowledging user, or null. | *** ### SlimMedicalNotificationActor [#slimmedicalnotificationactor] ```ts type SlimMedicalNotificationActor = object; ``` Mirrors the response DTO in Ovok Core's medical-notification contract. #### Properties [#properties-38] | Property | Type | Description | | ------ | ------ | ------ | | `display` | `string` \| `null` | Display name, or null. | | `reference` | `string` | FHIR reference of the user. | *** ### SlimMedicalNotificationContext [#slimmedicalnotificationcontext] ```ts type SlimMedicalNotificationContext = object; ``` Where a medical notification occurred: patient, place and device. #### Properties [#properties-39] | Property | Type | Description | | ------ | ------ | ------ | | `bed` | `string` \| `null` | Bed name. | | `deviceId` | `string` \| `null` | Device id. | | `deviceName` | `string` \| `null` | Device name. | | `floor` | `string` \| `null` | Floor name. | | `locationId` | `string` \| `null` | Location id. | | `locationName` | `string` \| `null` | Location name. | | `organizationId` | `string` \| `null` | Organization id. | | `organizationName` | `string` \| `null` | Organization name. | | `patientId` | `string` \| `null` | Patient id. | | `patientName` | `string` \| `null` | Patient name. | | `room` | `string` \| `null` | Room name. | *** ### SlimMedicalNotificationDetail [#slimmedicalnotificationdetail] ```ts type SlimMedicalNotificationDetail = Omit & object; ``` A medical notification with the full list of episode values. #### Type Declaration [#type-declaration-1] ##### episode [#episode] ```ts episode: SlimMedicalEpisodeCore & object; ``` The episode, with its recorded values. ###### Type Declaration [#type-declaration-2] ###### truncated [#truncated] ```ts truncated: boolean; ``` Whether `values` was cut short. ###### values [#values] ```ts values: SlimMedicalEpisodeValue[]; ``` Observations recorded in the episode. *** ### SlimMedicalNotificationRow [#slimmedicalnotificationrow] ```ts type SlimMedicalNotificationRow = object; ``` A medical notification: its episode, context, acknowledgement and note count. #### Properties [#properties-40] | Property | Type | Description | | ------ | ------ | ------ | | `acknowledgement` | \| [`SlimMedicalNotificationAcknowledgement`](#slimmedicalnotificationacknowledgement) \| `null` | Acknowledgement, or null when unacknowledged. | | `carehub` | [`SlimMedicalNotificationContext`](#slimmedicalnotificationcontext) | Where the episode occurred. | | `episode` | [`SlimMedicalEpisodeCore`](#slimmedicalepisodecore) | The episode. | | `noteCount` | `number` \| `null` | Number of notes, or null when not computed. | *** ### SlimMedicalNotificationsCollection [#slimmedicalnotificationscollection] ```ts type SlimMedicalNotificationsCollection = SlimMedicalNotificationsPage & object; ``` A page of medical notifications with totals. #### Type Declaration [#type-declaration-3] ##### total [#total] ```ts total: number; ``` Total notifications matching the filters. ##### truncated [#truncated-1] ```ts truncated: boolean; ``` Whether the server capped the result. *** ### SlimMedicalNotificationsPage [#slimmedicalnotificationspage] ```ts type SlimMedicalNotificationsPage = object; ``` One page of medical notifications. #### Properties [#properties-41] | Property | Type | Description | | ------ | ------ | ------ | | `items` | [`SlimMedicalNotificationRow`](#slimmedicalnotificationrow)[] | The notifications on this page. | | `nextCursor` | `string` \| `null` | Cursor for the next page, or null at the end. | *** ### SlimMedicalNotificationsQuery [#slimmedicalnotificationsquery] ```ts type SlimMedicalNotificationsQuery = object; ``` Filters and paging for listing medical notifications. #### Properties [#properties-42] | Property | Type | Description | | ------ | ------ | ------ | | `acknowledged?` | `boolean` | Only acknowledged or only unacknowledged episodes. | | `codes?` | readonly `string`[] | Only these observation codes. | | `cursor?` | `string` | Cursor from the previous page's `nextCursor`. | | `limit?` | `number` | Maximum items to return. | | `patient?` | `string` | Only this patient id. | | `since?` | `string` | Only episodes since this ISO 8601 time. | | `status?` | `"OPEN"` \| `"CLOSED"` | Only open or closed episodes. | *** ### SlimNotification [#slimnotification] ```ts type SlimNotification = object; ``` A notification (alarm or out-of-bed episode); extra fields depend on its type. #### Indexable [#indexable] ```ts [key: string]: unknown ``` #### Properties [#properties-43] | Property | Type | Description | | ------ | ------ | ------ | | `authoredOn` | `string` | ISO 8601 time the notification was raised. | | `commId` | `string` | Id of the notification. | | `noteCount` | `number` \| `null` | Number of notes on the notification, or null when not counted. | | `status` | `string` | Notification status. | | `type` | `string` | Notification type. | *** ### SlimNotificationsQuery [#slimnotificationsquery] ```ts type SlimNotificationsQuery = object; ``` Filters and paging for the notification list reads. #### Properties [#properties-44] | Property | Type | Description | | ------ | ------ | ------ | | `count?` | `number` | Rows per page. | | `cursor?` | `string` | Cursor from the previous response. | | `device?` | `string` | Only notifications of this device. | | `endDate?` | `string` | End of the date range, ISO 8601. | | `page?` | `number` | 1-based page number. | | `patient?` | `string` | Only notifications of this resident. | | `startDate?` | `string` | Start of the date range, ISO 8601. | | `status?` | `string` | Only this status. | | `type?` | `string` | Only this notification type. | *** ### SlimNotificationsResponse [#slimnotificationsresponse] ```ts type SlimNotificationsResponse = SlimPage & object; ``` A page of notifications, with the reason when the result was cut short. #### Type Declaration [#type-declaration-4] ##### truncated [#truncated-2] ```ts truncated: | { limit: number; reason: "result-cap" | "scan-budget"; } | null; ``` Set when the result was cut short, otherwise null. ###### Union Members [#union-members-1] ###### Type Literal [#type-literal-3] ```ts { limit: number; reason: "result-cap" | "scan-budget"; } ``` ###### limit [#limit] ```ts limit: number; ``` The limit that was reached. ###### reason [#reason-2] ```ts reason: "result-cap" | "scan-budget"; ``` `result-cap` when the row cap was reached, `scan-budget` when the scan budget ran out. *** `null` *** ### SlimObservationIds [#slimobservationids] ```ts type SlimObservationIds = object; ``` Ids of the observations holding each vital's value. #### Properties [#properties-45] | Property | Type | Description | | ------ | ------ | ------ | | `batch?` | `string` \| `null` | Observation id of the latest batch, or null. | | `heartRate` | `string` \| `null` | Observation id for heart rate, or null. | | `presenceStatus` | `string` \| `null` | Observation id for presence status, or null. | | `respiratoryRate` | `string` \| `null` | Observation id for respiratory rate, or null. | | `sleepStatus` | `string` \| `null` | Observation id for sleep status, or null. | *** ### SlimObservationIdsByDevice [#slimobservationidsbydevice] ```ts type SlimObservationIdsByDevice = Record; ``` Observation IDs keyed by device ID. *** ### SlimOrganization [#slimorganization] ```ts type SlimOrganization = object; ``` An organization. #### Properties [#properties-46] | Property | Type | Description | | ------ | ------ | ------ | | `description?` | `string` | Description. | | `id` | `string` | Organization id. | | `name` | `string` | Organization name. | | `parentOrganizationId?` | `string` | Id of the parent organization. | *** ### SlimOrganizationInput [#slimorganizationinput] ```ts type SlimOrganizationInput = object; ``` Body of the organization create and update calls. #### Properties [#properties-47] | Property | Type | Description | | ------ | ------ | ------ | | `description?` | `string` \| `null` | Description; null clears it. | | `name` | `string` | Organization name. | | `parentOrganizationId?` | `string` | Id of the parent organization. | *** ### SlimOutOfBedQuery [#slimoutofbedquery] ```ts type SlimOutOfBedQuery = Omit; ``` Query for out-of-bed notifications; the type is fixed by the route. *** ### SlimPage [#slimpage] ```ts type SlimPage = object; ``` One numbered page of a Slim list. #### Type Parameters [#type-parameters] | Type Parameter | | ------ | | `T` | #### Properties [#properties-48] | Property | Type | Description | | ------ | ------ | ------ | | `count` | `number` | Rows per page requested. | | `page` | `number` | 1-based number of this page. | | `resources` | `T`[] | Rows on this page. | | `total` | `number` | Total number of matching rows. | *** ### SlimPatient [#slimpatient] ```ts type SlimPatient = object; ``` A resident (patient) as returned by `getSlimPatient`. #### Properties [#properties-49] | Property | Type | Description | | ------ | ------ | ------ | | `admissionDate?` | `string` | Admission date, ISO 8601. | | `bed?` | `string` | Bed label. | | `birthDate?` | `string` | Birth date, ISO 8601 date. | | `deviceId` | `string` \| `null` | Id of the assigned device, or null. | | `dischargeDate?` | `string` | Discharge date, ISO 8601. | | `floor?` | `string` | Floor label. | | `gender?` | `"male"` \| `"female"` \| `"other"` \| `"unknown"` | Administrative gender. | | `id` | `string` | Resource id. | | `locationId?` | `string` | Id of the location. | | `name` | [`SlimHumanName`](#slimhumanname)[] | Names, one entry per use. | | `organizationId?` | `string` | Id of the zone the resident lives in. | | `residentState` | [`SlimResidentState`](#slimresidentstate) | Lifecycle state of the resident. | | `room?` | `string` | Room label. | *** ### SlimPatientListItem [#slimpatientlistitem] ```ts type SlimPatientListItem = object; ``` A resident row in `listSlimPatients`. #### Properties [#properties-50] | Property | Type | Description | | ------ | ------ | ------ | | `admissionDate` | `string` \| `null` | Admission date, or null. | | `bedActivitySettings` | [`SlimSettingsScope`](#slimsettingsscope) \| `null` | Scope of the bed-activity (out-of-bed) settings, or null when unset. | | `deviceId` | `string` \| `null` | Id of the assigned device, or null. | | `deviceName` | `string` \| `null` | Name of the device. | | `dischargeDate` | `string` \| `null` | Discharge date, or null. | | `id` | `string` | Resident id. | | `locationId` | `string` \| `null` | Id of the location, or null. | | `locationName` | `string` \| `null` | Name of the location. | | `medicalSettings` | [`SlimSettingsScope`](#slimsettingsscope) \| `null` | Scope of the medical-notification settings, or null when unset. | | `name` | `string` | Official name. | | `nickname` | `string` \| `null` | Nickname, or null when none. | | `organizationId` | `string` \| `null` | Id of the zone, or null. | | `organizationName` | `string` \| `null` | Name of the organization. | | `residentState` | [`SlimResidentState`](#slimresidentstate) | Lifecycle state of the resident. | *** ### SlimPatientListQuery [#slimpatientlistquery] ```ts type SlimPatientListQuery = object; ``` Filters, sorting and paging for `listSlimPatients`. #### Properties [#properties-51] | Property | Type | Description | | ------ | ------ | ------ | | `bedActivitySettings?` | [`SlimSettingsScope`](#slimsettingsscope) | Only residents with this bed-activity-settings scope. | | `count?` | `number` | Rows per page. | | `hasDevice?` | `boolean` | Filter by whether the resident has a device. | | `includeDischargedRecent?` | `boolean` | Include recently discharged residents. | | `medicalSettings?` | [`SlimSettingsScope`](#slimsettingsscope) | Only residents with this medical-settings scope. | | `orderBy?` | `"ASC"` \| `"DESC"` | Sort direction. | | `organizationId?` | `string` | Only residents in this zone. | | `page?` | `number` | 1-based page number. | | `residentState?` | [`SlimResidentState`](#slimresidentstate) \| `"all"` | Resident state to list, or `all`. | | `search?` | `string` | Free-text search. | | `sortBy?` | `string` | Field to sort by. | *** ### SlimPatientThresholdV2 [#slimpatientthresholdv2] ```ts type SlimPatientThresholdV2 = object; ``` A resident's v2 limits and their Signals sync state. #### Indexable [#indexable-1] ```ts [key: string]: unknown ``` #### Properties [#properties-52] | Property | Type | Description | | ------ | ------ | ------ | | `patientId` | `string` | Id of the resident. | | `settings` | `Record`\<`string`, [`SlimThresholdV2Setting`](#slimthresholdv2setting)\> | Limits per vital. | | `signalsSync` | [`SignalsSyncStatus`](#signalssyncstatus) | Whether the limits reached Signals. | *** ### SlimPolicy [#slimpolicy] ```ts type SlimPolicy = object; ``` An access policy. #### Properties [#properties-53] | Property | Type | Description | | ------ | ------ | ------ | | `id` | `string` | Policy id. | | `meta?` | `object` | Resource metadata. | | `meta.author?` | `object` | Author of the policy. | | `meta.author.reference` | `string` | Reference to the author. | | `meta.lastUpdated?` | `string` | ISO 8601 time of the last update. | | `meta.project?` | `string` | Id of the owning project. | | `name` | `string` | Policy name. | | `resource?` | [`SlimPolicyResource`](#slimpolicyresource)[] | Rules per resource type. | | `resourceType` | `"AccessPolicy"` | Always `AccessPolicy`. | *** ### SlimPolicyList [#slimpolicylist] ```ts type SlimPolicyList = object; ``` A page of access policies. #### Properties [#properties-54] | Property | Type | Description | | ------ | ------ | ------ | | `resources` | [`SlimPolicyResponse`](#slimpolicyresponse)[] | Policies on this page. | | `total` | `number` | Total number of policies. | *** ### SlimPolicyListQuery [#slimpolicylistquery] ```ts type SlimPolicyListQuery = object; ``` Filters, sorting and paging for `listSlimPolicies`. #### Properties [#properties-55] | Property | Type | Description | | ------ | ------ | ------ | | `count?` | `number` | Rows per page. | | `orderBy?` | `"ASC"` \| `"DESC"` | Sort direction. | | `page?` | `number` | 1-based page number. | | `profile?` | `string` | Only policies of this profile. | | `projectId?` | `string` | Only policies of this project. | | `search?` | `string` | Free-text search. | | `sortBy?` | `"_id"` \| `"_lastUpdated"` \| `"name"` | Field to sort by. | *** ### SlimPolicyMember [#slimpolicymember] ```ts type SlimPolicyMember = object; ``` A user or profile bound to an access policy. #### Properties [#properties-56] | Property | Type | Description | | ------ | ------ | ------ | | `display?` | `string` | Display name of the member. | | `reference` | `string` | Reference to the member. | *** ### SlimPolicyResource [#slimpolicyresource] ```ts type SlimPolicyResource = object; ``` Access rule for one resource type; further keys are passed through. #### Indexable [#indexable-2] ```ts [key: string]: unknown ``` #### Properties [#properties-57] | Property | Type | Description | | ------ | ------ | ------ | | `criteria?` | `string` | Search criteria limiting the rule. | | `interaction?` | `string`[] | Allowed interactions, such as read or write. | | `readonly?` | `boolean` | Whether matching resources are read-only. | | `resourceType` | `string` | Resource type the rule covers. | *** ### SlimPolicyResponse [#slimpolicyresponse] ```ts type SlimPolicyResponse = object; ``` An access policy with its members. #### Properties [#properties-58] | Property | Type | Description | | ------ | ------ | ------ | | `members` | [`SlimPolicyMember`](#slimpolicymember)[] | Members of the policy. | | `policy` | [`SlimPolicy`](#slimpolicy) | The access policy. | *** ### SlimPractitionerInviteInput [#slimpractitionerinviteinput] ```ts type SlimPractitionerInviteInput = object; ``` Body of `inviteSlimPractitioner`. #### Properties [#properties-59] | Property | Type | Description | | ------ | ------ | ------ | | `accessPolicyId` | `string` | Id of the access policy. | | `admin?` | `boolean` | Whether to invite as an administrator. | | `email` | `string` | Email address of the invitee. | | `name` | `string` | Given name. | | `projectId?` | `string` | Project to invite to; defaults to the current project. | | `surname` | `string` | Surname. | *** ### SlimPractitionerInviteResponse [#slimpractitionerinviteresponse] ```ts type SlimPractitionerInviteResponse = object; ``` The pending membership and profile created by an invite. #### Properties [#properties-60] | Property | Type | Description | | ------ | ------ | ------ | | `membership` | `object` | The project membership. | | `membership.accessPolicy?` | `object` | The access policy. | | `membership.accessPolicy.display` | `string` | Human-readable text. | | `membership.accessPolicy.reference` | `string` | Resource reference. | | `membership.id` | `string` | Membership id. | | `membership.meta?` | `object` | Resource metadata. | | `membership.meta.author?` | `object` | Author reference. | | `membership.meta.author.reference` | `string` | Resource reference. | | `membership.meta.lastUpdated?` | `string` | ISO 8601 time of the last update. | | `membership.meta.project?` | `string` | Id of the owning project. | | `membership.profile?` | `object` | The profile. | | `membership.profile.reference` | `string` | Resource reference. | | `membership.project?` | `object` | Project reference. | | `membership.project.display?` | `string` | Human-readable text. | | `membership.project.reference` | `string` | Resource reference. | | `membership.resourceType` | `"ProjectMembership"` | Always `ProjectMembership`. | | `membership.user?` | `object` | The user. | | `membership.user.reference` | `string` | Resource reference. | | `profile` | `object` | The profile. | | `profile.id` | `string` | Profile id. | | `profile.meta?` | `object` | Resource metadata. | | `profile.meta.lastUpdated?` | `string` | ISO 8601 time of the last update. | | `profile.meta.project?` | `string` | Id of the owning project. | | `profile.name?` | `unknown`[] | Names of the practitioner. | | `profile.resourceType` | `"Practitioner"` | Always `Practitioner`. | | `status` | `"Pending"` | Always `Pending` until the invite is accepted. | *** ### SlimProject [#slimproject] ```ts type SlimProject = object; ``` A project. #### Properties [#properties-61] | Property | Type | Description | | ------ | ------ | ------ | | `address?` | [`SlimProjectAddress`](#slimprojectaddress)[] | Addresses. | | `contact?` | [`SlimProjectContact`](#slimprojectcontact)[] | Contacts. | | `id` | `string` | Project id. | | `name` | `string` | Project name. | | `resourceType` | `"Project"` | Always `Project`. | | `settings?` | `object` | Project settings. | | `settings.timeZone?` | `string` | IANA time zone of the project. | | `settings.trendsPeriod?` | `object` | Daily window used for trends. | | `settings.trendsPeriod.durationSeconds` | `number` | Window length in seconds. | | `settings.trendsPeriod.start` | `string` | Start of the daily window, as a time of day. | *** ### SlimProjectAddress [#slimprojectaddress] ```ts type SlimProjectAddress = object; ``` A project address. #### Properties [#properties-62] | Property | Type | Description | | ------ | ------ | ------ | | `city?` | `string` | City. | | `country?` | `string` | Country. | | `district?` | `string` | District. | | `line?` | `string`[] | Street address lines. | | `postalCode?` | `string` | Postal code. | | `state?` | `string` | State or region. | | `text?` | `string` | Full text. | | `type?` | `"postal"` \| `"physical"` \| `"both"` | Kind of address. | | `use?` | `"work"` \| `"temp"` \| `"old"` \| `"billing"` | Purpose of the address. | *** ### SlimProjectContact [#slimprojectcontact] ```ts type SlimProjectContact = object; ``` A project contact person. #### Properties [#properties-63] | Property | Type | Description | | ------ | ------ | ------ | | `address?` | [`SlimProjectAddress`](#slimprojectaddress) | Address of the contact. | | `name?` | `object` | Name of the contact. | | `name.family?` | `string` | Family name. | | `name.given?` | `string`[] | Given names. | | `name.prefix?` | `string`[] | Name prefixes. | | `name.suffix?` | `string`[] | Name suffixes. | | `name.use?` | \| `"temp"` \| `"old"` \| `"official"` \| `"usual"` \| `"nickname"` \| `"anonymous"` \| `"maiden"` | Kind of name. | | `telecom?` | `object`[] | Phone, email and other contact points. | *** ### SlimProjectDeviceCounts [#slimprojectdevicecounts] ```ts type SlimProjectDeviceCounts = object; ``` Device counts of a project. #### Properties [#properties-64] | Property | Type | Description | | ------ | ------ | ------ | | `activeDeviceCount` | `number` | Devices currently active. | | `assignedResidentDeviceCount` | `number` | Devices assigned to a resident. | | `inactiveDeviceCount` | `number` | Devices currently inactive. | | `projectId` | `string` | Id of the project. | | `radarDeviceCount` | `number` | Radar devices. | | `totalDeviceCount` | `number` | All devices in the project. | | `unassignedDeviceCount` | `number` | Devices without a resident. | | `withingsDeviceCount` | `number` | Withings devices. | *** ### SlimProjectPatientCounts [#slimprojectpatientcounts] ```ts type SlimProjectPatientCounts = object; ``` Resident counts of a project. #### Properties [#properties-65] | Property | Type | Description | | ------ | ------ | ------ | | `activePatientCount` | `number` | Active residents. | | `archivedPatientCount` | `number` | Archived residents. | | `dischargedPatientCount` | `number` | Discharged residents. | | `dischargedRecentPatientCount` | `number` | Recently discharged residents. | | `projectId` | `string` | Id of the project. | | `totalPatientCount` | `number` | All residents in the project. | *** ### SlimProjectRelationships [#slimprojectrelationships] ```ts type SlimProjectRelationships = object; ``` The current project with its parent and children. #### Properties [#properties-66] | Property | Type | Description | | ------ | ------ | ------ | | `childProjects` | [`SlimProject`](#slimproject)[] | Child projects. | | `currentProject` | [`SlimProject`](#slimproject) \| `null` | The project of the caller, or null. | | `parentProject` | [`SlimProject`](#slimproject) \| `null` | The parent project, or null. | *** ### SlimProjectRelationshipsV2 [#slimprojectrelationshipsv2] ```ts type SlimProjectRelationshipsV2 = object; ``` The current project with its parent and children, each with a device count. #### Properties [#properties-67] | Property | Type | Description | | ------ | ------ | ------ | | `childProjects` | ([`SlimProject`](#slimproject) & `object`)[] | Child projects. | | `currentProject` | [`SlimProject`](#slimproject) & `object` \| `null` | The project of the caller, or null. | | `parentProject` | [`SlimProject`](#slimproject) & `object` \| `null` | The parent project, or null. | *** ### SlimProjectUser [#slimprojectuser] ```ts type SlimProjectUser = object; ``` A project user with its profile, membership and access policy. #### Properties [#properties-68] | Property | Type | Description | | ------ | ------ | ------ | | `accessPolicy?` | `object` | The access policy. | | `accessPolicy.id` | `string` | Access policy id. | | `accessPolicy.name?` | `string` | Access policy name. | | `accessPolicy.resourceType` | `"AccessPolicy"` | Always `AccessPolicy`. | | `membership` | `object` | The project membership. | | `membership.accessPolicy?` | `object` | The access policy. | | `membership.accessPolicy.display?` | `string` | Human-readable text. | | `membership.accessPolicy.reference?` | `string` | Resource reference. | | `membership.id` | `string` | Membership id. | | `membership.meta?` | `object` | Resource metadata. | | `membership.meta.lastUpdated?` | `string` | ISO 8601 time of the last update. | | `membership.meta.project?` | `string` | Id of the owning project. | | `membership.profile?` | `object` | The profile. | | `membership.profile.display?` | `string` | Human-readable text. | | `membership.profile.reference?` | `string` | Resource reference. | | `membership.project?` | `object` | Project reference. | | `membership.project.display?` | `string` | Human-readable text. | | `membership.project.reference?` | `string` | Resource reference. | | `membership.resourceType` | `"ProjectMembership"` | Always `ProjectMembership`. | | `membership.user?` | `object` | The user. | | `membership.user.display?` | `string` | Human-readable text. | | `membership.user.reference?` | `string` | Resource reference. | | `profile` | `object` | The profile. | | `profile.id` | `string` | Profile id. | | `profile.meta?` | `object` | Resource metadata. | | `profile.meta.lastUpdated?` | `string` | ISO 8601 time of the last update. | | `profile.meta.project?` | `string` | Id of the owning project. | | `profile.name?` | `object`[] | Names of the practitioner. | | `profile.resourceType` | `"Practitioner"` | Always `Practitioner`. | | `status` | `"Active"` \| `"Pending"` | `Pending` until the invite is accepted. | | `user` | `object` | The user. | | `user.email?` | `string` | Email address. | | `user.firstName?` | `string` | First name. | | `user.id` | `string` | User id. | | `user.lastName?` | `string` | Last name. | | `user.meta?` | `object` | Resource metadata. | | `user.meta.lastUpdated?` | `string` | ISO 8601 time of the last update. | | `user.meta.project?` | `string` | Id of the owning project. | | `user.project?` | `object` | Project reference. | | `user.project.display?` | `string` | Human-readable text. | | `user.project.reference?` | `string` | Resource reference. | | `user.resourceType` | `"User"` | Always `User`. | *** ### SlimProjectUsersPage [#slimprojectuserspage] ```ts type SlimProjectUsersPage = SlimPage; ``` A page of project users. *** ### SlimProjectUsersQuery [#slimprojectusersquery] ```ts type SlimProjectUsersQuery = object; ``` Filters, sorting and paging for the project-user lists. #### Properties [#properties-69] | Property | Type | Description | | ------ | ------ | ------ | | `accessPolicyId?` | `string` | Only users with this access policy. | | `count?` | `number` | Rows per page. | | `orderBy?` | `"ASC"` \| `"DESC"` | Sort direction. | | `page?` | `number` | 1-based page number. | | `profileId?` | `string` | Only this profile. | | `profileType?` | `"Practitioner"` | Only this profile type. | | `search?` | `string` | Free-text search. | | `sortBy?` | `"profileName"` \| `"userName"` \| `"accessPolicyName"` | Field to sort by. | | `userId?` | `string` | Only this user. | *** ### SlimRealtimeTrendsQuery [#slimrealtimetrendsquery] ```ts type SlimRealtimeTrendsQuery = object; ``` Selects the patient, time range and graph types for realtime trends. #### Properties [#properties-70] | Property | Type | Description | | ------ | ------ | ------ | | `endTime` | `string` | End of the range, as a timestamp. | | `graphType` | \| [`SlimGraphType`](#slimgraphtype) \| readonly [`SlimGraphType`](#slimgraphtype)[] | Graph type or types to return. | | `patientId` | `string` | Patient to read trends for. | | `startTime` | `string` | Start of the range, as a timestamp. | *** ### SlimRecentAlarms [#slimrecentalarms] ```ts type SlimRecentAlarms = object; ``` The most recent alarms, read from a cache. #### Properties [#properties-71] | Property | Type | Description | | ------ | ------ | ------ | | `recent` | (`Omit`\<[`SlimAlarm`](#slimalarm), `"noteCount"`\> & `object`)[] | The alarms; note counts are not available here. | | `source` | `"redis"` \| `"fhirStore"` | Where the data came from. | | `total` | `number` | Number of alarms returned. | | `warm` | `false` | Always `false`. | *** ### SlimRecentNotificationsResponse [#slimrecentnotificationsresponse] ```ts type SlimRecentNotificationsResponse = object; ``` The most recent notifications. #### Properties [#properties-72] | Property | Type | Description | | ------ | ------ | ------ | | `recent` | [`SlimNotification`](#slimnotification)[] | Most recent notifications. | | `total` | `number` | Total number of recent notifications. | | `warm` | `boolean` | Whether the recent-notifications cache was already populated. | *** ### SlimRecentOutOfBed [#slimrecentoutofbed] ```ts type SlimRecentOutOfBed = object; ``` The most recent out-of-bed notifications, read from a cache. #### Properties [#properties-73] | Property | Type | Description | | ------ | ------ | ------ | | `recent` | ([`SlimNotification`](#slimnotification) & `object`)[] | The notifications; note counts are not available here. | | `total` | `number` | Number of notifications returned. | | `warm` | `boolean` | Whether the cache was warm. | *** ### SlimRecentQuery [#slimrecentquery] ```ts type SlimRecentQuery = object; ``` How many recent items to return. #### Properties [#properties-74] | Property | Type | Description | | ------ | ------ | ------ | | `count?` | `number` | Most items to return. | *** ### SlimResidentState [#slimresidentstate] ```ts type SlimResidentState = "active" | "archived" | "discharged" | "discharged-recent"; ``` Lifecycle state of a resident. *** ### SlimSettingsScope [#slimsettingsscope] ```ts type SlimSettingsScope = "inactive" | "global" | "individual"; ``` Where a monitoring setting applies: off, project-wide, or per resident. *** ### SlimSleepMetric [#slimsleepmetric] ```ts type SlimSleepMetric = object; ``` One sleep metric with its comparison to the average. #### Properties [#properties-75] | Property | Type | Description | | ------ | ------ | ------ | | `average` | `number` \| `string` \| `null` | Average over the compared nights, or null. | | `current` | `number` \| `string` \| `null` | Value for the night, or null. | | `diff` | `number` \| `null` | Difference from the average, or null. | *** ### SlimSleepStatistics [#slimsleepstatistics] ```ts type SlimSleepStatistics = Record>; ``` Sleep metrics keyed by night, then by metric name. *** ### SlimSleepStatisticsQuery [#slimsleepstatisticsquery] ```ts type SlimSleepStatisticsQuery = object; ``` Selects the patient and period for sleep statistics. #### Properties [#properties-76] | Property | Type | Description | | ------ | ------ | ------ | | `endDate` | `string` | Last day of the period. | | `lastDayCount?` | `number` | How many days back from `endDate` to include. | | `patientId` | `string` | Patient to read statistics for. | *** ### SlimTelemetrySummary [#slimtelemetrysummary] ```ts type SlimTelemetrySummary = Record; ``` Latest telemetry readings of a device, keyed by vital. *** ### SlimTelemetryValue [#slimtelemetryvalue] ```ts type SlimTelemetryValue = object; ``` One latest telemetry reading. #### Properties [#properties-77] | Property | Type | Description | | ------ | ------ | ------ | | `ts` | `number` \| `null` | Reading time as epoch milliseconds, or null. | | `value` | `string` \| `number` \| `boolean` \| `null` | Reading value, or null. | *** ### SlimThreshold [#slimthreshold] ```ts type SlimThreshold = object; ``` The project's v1 vital-sign limits. #### Properties [#properties-78] | Property | Type | Description | | ------ | ------ | ------ | | `date?` | `string` | ISO 8601 date of the limits. | | `id?` | `string` | Id of the stored limits, when any. | | `projectId?` | `string` | Id of the project. | | `settings` | `Record`\<`string`, [`SlimThresholdSettingV1`](#slimthresholdsettingv1)\> | Limits per vital. | | `status` | `"active"` \| `"retired"` | Whether the limits are in force. | *** ### SlimThresholdModeV1 [#slimthresholdmodev1] ```ts type SlimThresholdModeV1 = "organization" | "patient"; ``` Whether limits come from the organization or the resident. *** ### SlimThresholdReadableModeV1 [#slimthresholdreadablemodev1] ```ts type SlimThresholdReadableModeV1 = SlimThresholdModeV1 | "patient-auto"; ``` Limit mode as read: also `patient-auto` for limits derived automatically per resident. *** ### SlimThresholdSettingsUpdateV1 [#slimthresholdsettingsupdatev1] ```ts type SlimThresholdSettingsUpdateV1 = Record; ``` v1 limit updates, keyed by vital. *** ### SlimThresholdSettingUpdateV1 [#slimthresholdsettingupdatev1] ```ts type SlimThresholdSettingUpdateV1 = Omit & object; ``` Limits for one vital in a v1 update. #### Type Declaration [#type-declaration-5] ##### mode? [#mode] ```ts mode?: SlimThresholdModeV1; ``` Where the limits come from. *** ### SlimThresholdSettingV1 [#slimthresholdsettingv1] ```ts type SlimThresholdSettingV1 = object; ``` Limits for one vital in the v1 format; further keys carry the limit values. #### Indexable [#indexable-3] ```ts [key: string]: unknown ``` #### Properties [#properties-79] | Property | Type | Description | | ------ | ------ | ------ | | `mode?` | [`SlimThresholdReadableModeV1`](#slimthresholdreadablemodev1) | Where the limits come from. | | `relative?` | `object` | Relative (baseline-derived) limit settings. | | `relative.enabled` | `boolean` | Whether relative limits are on. | *** ### SlimThresholdV2 [#slimthresholdv2] ```ts type SlimThresholdV2 = object; ``` The project's v2 vital-sign limits. #### Properties [#properties-80] | Property | Type | Description | | ------ | ------ | ------ | | `date?` | `string` | ISO 8601 date. | | `id` | `string` \| `null` | Id of the stored limits, or null when none. | | `projectId?` | `string` | Id of the project. | | `settings` | `Record`\<`string`, [`SlimThresholdV2Setting`](#slimthresholdv2setting)\> | Limits per vital. | | `status?` | `"active"` \| `"retired"` | Whether the limits are in force. | *** ### SlimThresholdV2Setting [#slimthresholdv2setting] ```ts type SlimThresholdV2Setting = object; ``` Limits for one vital in the v2 format; further keys carry the limit values. #### Indexable [#indexable-4] ```ts [key: string]: unknown ``` #### Properties [#properties-81] | Property | Type | Description | | ------ | ------ | ------ | | `baselineAverage` | `number` \| `null` | Null when the bed window is 23 hours 59 minutes or longer. | | `deviationPercent` | `number` \| `null` | Allowed deviation from the baseline, in percent, or null. | | `effectiveBand` | \| \{ `max`: `number`; `min`: `number`; \} \| `null` | Band currently in force, or null. | | `mode` | `string` | Limit mode. | *** ### SlimThresholdV2Update [#slimthresholdv2update] ```ts type SlimThresholdV2Update = object; ``` Body of the v2 limit updates; send only the vitals to change. #### Properties [#properties-82] | Property | Type | Description | | ------ | ------ | ------ | | `settings` | `Record`\<`string`, `Partial`\<[`SlimThresholdV2Setting`](#slimthresholdv2setting)\>\> | Changed limits per vital. | *** ### SlimTrendDeviceData [#slimtrenddevicedata] ```ts type SlimTrendDeviceData = object; ``` Trend points and statistics of one device. #### Properties [#properties-83] | Property | Type | Description | | ------ | ------ | ------ | | `dataPoints` | [`SlimTrendPoint`](#slimtrendpoint)[] | Points in time order. | | `stats` | [`SlimTrendStats`](#slimtrendstats) | Summary statistics. | *** ### SlimTrendPoint [#slimtrendpoint] ```ts type SlimTrendPoint = object; ``` One data point of a trend graph. #### Properties [#properties-84] | Property | Type | Description | | ------ | ------ | ------ | | `data` | `number` \| `null` | Value, or null when there is no reading. | | `deviceId?` | `string` | Id of the device that produced the point. | | `deviceManufacturer?` | `string` | Device manufacturer. | | `deviceModel?` | `string` | Device model. | | `maxBaseLine?` | `number` | Upper baseline at this point. | | `maxThreshold?` | `number` | Upper limit at this point. | | `minBaseLine?` | `number` | Lower baseline at this point. | | `minThreshold?` | `number` | Lower limit at this point. | | `pointTimestamp?` | `string` | ISO 8601 time of the underlying reading. | | `pointTimestampRange?` | `object` | Time range the point aggregates. | | `pointTimestampRange.end?` | `string` | End of the aggregated range, ISO 8601. | | `pointTimestampRange.start?` | `string` | Start of the aggregated range, ISO 8601. | | `timestamp` | `string` | ISO 8601 time of the point. | | `timestampMs` | `number` | Time as epoch milliseconds. | *** ### SlimTrends [#slimtrends] ```ts type SlimTrends = Partial>>; ``` Trend graphs keyed by graph type, then by device id. *** ### SlimTrendsQuery [#slimtrendsquery] ```ts type SlimTrendsQuery = object; ``` Selects the patient, date range and graph types for historical trends. #### Properties [#properties-85] | Property | Type | Description | | ------ | ------ | ------ | | `endDate` | `string` | Last day of the range. | | `graphType` | \| [`SlimHistoricalGraphType`](#slimhistoricalgraphtype) \| readonly [`SlimHistoricalGraphType`](#slimhistoricalgraphtype)[] | Graph type or types to return. | | `patientId` | `string` | Patient to read trends for. | | `startDate` | `string` | First day of the range. | *** ### SlimTrendStats [#slimtrendstats] ```ts type SlimTrendStats = object; ``` Summary statistics of a trend series. #### Properties [#properties-86] | Property | Type | Description | | ------ | ------ | ------ | | `average` | `number` \| `null` | Average, or null without data. | | `max` | `number` \| `null` | Maximum, or null without data. | | `min` | `number` \| `null` | Minimum, or null without data. | | `total` | `number` | Number of points. | *** ### SlimUpdateDevice [#slimupdatedevice] ```ts type SlimUpdateDevice = object; ``` Body of `updateSlimDevice`. #### Properties [#properties-87] | Property | Type | Description | | ------ | ------ | ------ | | `locationId?` | `string` \| `null` | Location of the device; null unassigns it. | | `name` | `string` | New device name; renaming moves the serial. | | `organizationId?` | `string` \| `null` | Zone of the device; null clears it. | | `patientId?` | `string` \| `null` | Resident to assign; null unassigns. | | `thingsboardId?` | `string` | Id of the device on the IoT platform. | *** ### SlimUpdateLocation [#slimupdatelocation] ```ts type SlimUpdateLocation = SlimCreateLocation & object; ``` Body of `updateSlimLocation`. #### Type Declaration [#type-declaration-6] ##### deviceId? [#deviceid] ```ts deviceId?: string | null; ``` Device to place here; null removes it. ##### organizationId? [#organizationid] ```ts organizationId?: string | null; ``` Zone of the location; null clears it. ##### patientId? [#patientid] ```ts patientId?: string; ``` Resident to place here. *** ### SlimUpdatePatient [#slimupdatepatient] ```ts type SlimUpdatePatient = Partial & object; ``` Replaces the editable fields; omitting locationId unassigns the resident's devices. #### Type Declaration [#type-declaration-7] ##### dischargeDate? [#dischargedate] ```ts dischargeDate?: string; ``` Discharge date, ISO 8601. ##### residentState? [#residentstate] ```ts residentState?: SlimResidentState; ``` New lifecycle state. *** ### SlimUpdatePolicy [#slimupdatepolicy] ```ts type SlimUpdatePolicy = Omit & object; ``` Body of `updateSlimPolicy`; the policy must carry its id. #### Type Declaration [#type-declaration-8] ##### policy [#policy] ```ts policy: SlimCreatePolicy["policy"] & object; ``` The policy to save. ###### Type Declaration [#type-declaration-9] ###### id [#id] ```ts id: string; ``` Id of the policy to update. *** ### SlimUserDeleted [#slimuserdeleted] ```ts type SlimUserDeleted = object; ``` Result of deleting a user. #### Properties [#properties-88] | Property | Type | Description | | ------ | ------ | ------ | | `success` | `boolean` | Whether the user was deleted. | *** ### SlimUserProfileType [#slimuserprofiletype] ```ts type SlimUserProfileType = "Patient" | "Practitioner"; ``` Kind of user profile. *** ### SlimZone [#slimzone] ```ts type SlimZone = object; ``` A zone with its device counts. #### Properties [#properties-89] | Property | Type | Description | | ------ | ------ | ------ | | `activeDeviceCount` | `number` | Devices currently active. | | `assignedResidentDeviceCount` | `number` | Devices assigned to a resident. | | `deviceCount` | `number` | All devices in the zone. | | `inactiveDeviceCount` | `number` | Devices currently inactive. | | `zoneId` | `string` | Id of the zone. | | `zoneName` | `string` | Name of the zone. | *** ### SlimZoneDetail [#slimzonedetail] ```ts type SlimZoneDetail = object; ``` A zone with its locations, devices and residents. #### Properties [#properties-90] | Property | Type | Description | | ------ | ------ | ------ | | `id` | `string` | Zone id. | | `locations` | `object`[] | Locations in the zone. | | `name` | `string` | Zone name. | *** ### SlimZoneDeviceCountsQuery [#slimzonedevicecountsquery] ```ts type SlimZoneDeviceCountsQuery = object; ``` Options for counting devices per zone. #### Properties [#properties-91] | Property | Type | Description | | ------ | ------ | ------ | | `all?` | `boolean` | Count across all zones rather than only the current page. | | `effectiveSleepStatus?` | `string` | Only devices with this effective sleep status. | | `includeEmpty?` | `boolean` | Also list zones that have no devices. | | `includeUnassigned?` | `boolean` | Also count devices not assigned to a zone. | *** ### SlimZoneListQuery [#slimzonelistquery] ```ts type SlimZoneListQuery = object; ``` Paging, sorting and search for listing zones. #### Properties [#properties-92] | Property | Type | Description | | ------ | ------ | ------ | | `count?` | `number` | Zones per page. | | `orderBy?` | `"ASC"` \| `"DESC"` | Sort direction. | | `page?` | `number` | Page number to fetch. | | `search?` | `string` | Text to search for in zone names. | | `sortBy?` | `string` | Field to sort by. | *** ### UpdateNotificationNote [#updatenotificationnote] ```ts type UpdateNotificationNote = object; ``` Request body for editing a note. #### Properties [#properties-93] | Property | Type | Description | | ------ | ------ | ------ | | `text` | `string` | New note text. | # videoCalls Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/videocalls ## Classes [#classes] ### VideoCallAccessResource [#videocallaccessresource] Access to video calls. #### Methods [#methods] ##### createGuest() [#createguest] ```ts createGuest( appointmentId, body, options? ): Promise; ``` Creates guest access to a call. Calls `POST guest-access/{appointmentId}`. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `appointmentId` | `string` | | `body` | [`OvokVideoCallGuestAccess`](#ovokvideocallguestaccess) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`OvokVideoCallAccess`](#ovokvideocallaccess)\> ##### createUser() [#createuser] ```ts createUser(appointmentId, options?): Promise; ``` Creates access to a call for the signed-in user. Calls `POST user-access/{appointmentId}`. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `appointmentId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<[`OvokVideoCallAccess`](#ovokvideocallaccess)\> ##### permission() [#permission] ```ts permission(appointmentId, options?): Promise; ``` Checks how the caller may join a call. Calls `GET access-permission/{appointmentId}`. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `appointmentId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<[`VideoCallAccessPermission`](#videocallaccesspermission)\> *** ### VideoCallAppointmentsResource [#videocallappointmentsresource] Video call appointments. #### Methods [#methods-1] ##### create() [#create] ```ts create(body, options?): Promise; ``` Creates an appointment. Calls `POST appointment`. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `body` | [`OvokVideoCallAppointmentInput`](#ovokvideocallappointmentinput) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<[`OvokVideoCallAppointment`](#ovokvideocallappointment)\> ##### list() [#list] ```ts list(params?, options?): Promise; ``` Lists appointments. Calls `GET appointment`. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `params?` | [`OvokVideoCallAppointmentQuery`](#ovokvideocallappointmentquery) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<[`OvokVideoCallAppointment`](#ovokvideocallappointment)[]\> ##### update() [#update] ```ts update( appointmentId, body, options? ): Promise; ``` Replaces an appointment. Calls `PUT appointment/{appointmentId}`. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `appointmentId` | `string` | | `body` | [`OvokVideoCallAppointmentInput`](#ovokvideocallappointmentinput) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-5] `Promise`\<[`OvokVideoCallAppointment`](#ovokvideocallappointment)\> *** ### VideoCallEmailsResource [#videocallemailsresource] Emails about video calls. #### Methods [#methods-2] ##### cancel() [#cancel] ```ts cancel(body, options?): Promise; ``` Emails a call cancellation. Calls `POST mail/cancel`. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `body` | [`OvokVideoCallMailRequest`](#ovokvideocallmailrequest) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-6] `Promise`\<[`OvokVideoCallMailResponse`](#ovokvideocallmailresponse)\> ##### invite() [#invite] ```ts invite(body, options?): Promise; ``` Emails a call invitation. Calls `POST mail/invite`. ###### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `body` | [`OvokVideoCallMailRequest`](#ovokvideocallmailrequest) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-7] `Promise`\<[`OvokVideoCallMailResponse`](#ovokvideocallmailresponse)\> ##### update() [#update-1] ```ts update(body, options?): Promise; ``` Emails a call update. Calls `POST mail/update`. ###### Parameters [#parameters-8] | Parameter | Type | | ------ | ------ | | `body` | [`OvokVideoCallMailRequest`](#ovokvideocallmailrequest) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-8] `Promise`\<[`OvokVideoCallMailResponse`](#ovokvideocallmailresponse)\> ## Interfaces [#interfaces] ### VideoCallsResource [#videocallsresource] Video-call appointments, access and emails. Calls routes under `video-call/livekit`. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `access` | `readonly` | [`VideoCallAccessResource`](#videocallaccessresource) | Access to a call. | | `appointments` | `readonly` | [`VideoCallAppointmentsResource`](#videocallappointmentsresource) | Video-call appointments. | | `emails` | `readonly` | [`VideoCallEmailsResource`](#videocallemailsresource) | Call invitation emails. | #### Methods [#methods-3] ##### notifyActive() [#notifyactive] ```ts notifyActive(appointmentId, options?): Promise; ``` Notifies that a call is active. Calls `POST video-call/livekit/notification/active-call/{appointmentId}`. ###### Parameters [#parameters-9] | Parameter | Type | | ------ | ------ | | `appointmentId` | `string` | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-9] `Promise`\<[`ActiveCallNotification`](#activecallnotification)\> ## Type Aliases [#type-aliases] ### ActiveCallNotification [#activecallnotification] ```ts type ActiveCallNotification = Record; ``` The server's response to an active-call notification. *** ### OvokVideoCallAccess [#ovokvideocallaccess] ```ts type OvokVideoCallAccess = object; ``` Details needed to join a video call. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `livekitJwt` | `string` | Access token for the call room. | | `passphrase` | `string` | Passphrase of the call. | | `videoCallUrl` | `string` | URL of the call. | *** ### OvokVideoCallAppointment [#ovokvideocallappointment] ```ts type OvokVideoCallAppointment = object; ``` A video-call appointment. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `comment` | `string` | Comment shown on the appointment. | | `description?` | `string` | Longer description. | | `end` | `string` | ISO 8601 end time. | | `id` | `string` | Appointment id. | | `passphrase` | `string` | Passphrase of the call. | | `resourceType` | `"Appointment"` | Always `Appointment`. | | `start` | `string` | ISO 8601 start time. | | `status` | [`OvokVideoCallAppointmentStatus`](#ovokvideocallappointmentstatus) | Appointment status. | | `videoCallParticipants` | `object`[] | Participants and their responses. | *** ### OvokVideoCallAppointmentInput [#ovokvideocallappointmentinput] ```ts type OvokVideoCallAppointmentInput = object; ``` Request body that creates or updates a video-call appointment. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `comment` | `string` | Comment shown on the appointment. | | `description?` | `string` | Longer description. | | `end` | `string` | ISO 8601 end time. | | `id?` | `string` | Appointment id, when updating. | | `start` | `string` | ISO 8601 start time. | | `videoCallParticipants` | `object`[] | Invited participants. | *** ### OvokVideoCallAppointmentQuery [#ovokvideocallappointmentquery] ```ts type OvokVideoCallAppointmentQuery = object; ``` Date range filter for listing appointments. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `endDate?` | `string` | Only appointments up to this date. | | `startDate?` | `string` | Only appointments from this date. | *** ### OvokVideoCallAppointmentStatus [#ovokvideocallappointmentstatus] ```ts type OvokVideoCallAppointmentStatus = | "proposed" | "pending" | "booked" | "arrived" | "fulfilled" | "cancelled" | "noshow" | "entered-in-error" | "checked-in" | "waitlist"; ``` FHIR Appointment status of a video call. *** ### OvokVideoCallGuestAccess [#ovokvideocallguestaccess] ```ts type OvokVideoCallGuestAccess = object; ``` Request body that creates guest access to a video call. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `guestEmail` | `string` | Email address of the guest. | *** ### OvokVideoCallMailRequest [#ovokvideocallmailrequest] ```ts type OvokVideoCallMailRequest = object; ``` Request body for emailing video-call participants. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `appointmentId` | `string` | Id of the appointment. | | `emailRecipients` | `object`[] | People to email. | *** ### OvokVideoCallMailResponse [#ovokvideocallmailresponse] ```ts type OvokVideoCallMailResponse = object; ``` Per-recipient outcome of a video-call email. #### Properties [#properties-7] | Property | Type | Description | | ------ | ------ | ------ | | `appointmentId` | `string` | Id of the appointment. | | `emailRecipientsResult` | `object`[] | Outcome per recipient. | *** ### VideoCallAccessPermission [#videocallaccesspermission] ```ts type VideoCallAccessPermission = Record; ``` Whether and how the caller may join a call, as the server describes it. # wearables Canonical page: https://docs.ovok.com/web-sdk/core/reference/core/wearables ## Classes [#classes] ### WearableConnectionsResource [#wearableconnectionsresource] Wearable provider connections. #### Methods [#methods] ##### authorize() [#authorize] ```ts authorize(provider, options?): Promise; ``` The provider's one-time consent page, where the patient grants access. ###### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `provider` | [`WearableProvider`](#wearableprovider) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns] `Promise`\<[`WearableConnectionAuthorization`](#wearableconnectionauthorization)\> ##### delete() [#delete] ```ts delete(provider, options?): Promise; ``` Disconnects a provider. Calls `DELETE connections/{provider}`. ###### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `provider` | [`WearableProvider`](#wearableprovider) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-1] `Promise`\<`void`\> ##### list() [#list] ```ts list(options?): Promise; ``` Lists the wearable connections. Calls `GET connections`. ###### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-2] `Promise`\<[`WearableConnections`](#wearableconnections)\> ##### sync() [#sync] ```ts sync(provider, options?): Promise; ``` Syncs data from a provider. Calls `POST connections/{provider}/sync`. ###### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `provider` | [`WearableProvider`](#wearableprovider) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-3] `Promise`\<[`WearableSyncResult`](#wearablesyncresult)\> *** ### WearableProvidersResource [#wearableprovidersresource] Wearable provider settings. #### Methods [#methods-1] ##### create() [#create] ```ts create(body, options?): Promise; ``` Creates provider settings. Calls `POST providers`. ###### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `body` | [`CreateWearableProviderRequest`](#createwearableproviderrequest) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-4] `Promise`\<[`WearableProviderSettings`](#wearableprovidersettings)\> ##### delete() [#delete-1] ```ts delete(provider, options?): Promise; ``` Deletes provider settings. Calls `DELETE providers/{provider}`. ###### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `provider` | [`WearableProvider`](#wearableprovider) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-5] `Promise`\<`void`\> ##### list() [#list-1] ```ts list(options?): Promise; ``` Lists provider settings. Calls `GET providers`. ###### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-6] `Promise`\<[`WearableProviderSettingsList`](#wearableprovidersettingslist)\> ##### patch() [#patch] ```ts patch( provider, body, options? ): Promise; ``` Updates provider settings. Calls `PATCH providers/{provider}`. ###### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `provider` | [`WearableProvider`](#wearableprovider) | | `body` | [`UpdateWearableProviderRequest`](#updatewearableproviderrequest) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-7] `Promise`\<[`WearableProviderSettings`](#wearableprovidersettings)\> ##### retrieve() [#retrieve] ```ts retrieve(provider, options?): Promise; ``` Fetches one provider's settings. Calls `GET providers/{provider}`. ###### Parameters [#parameters-8] | Parameter | Type | | ------ | ------ | | `provider` | [`WearableProvider`](#wearableprovider) | | `options?` | [`RequestOptions`](/web-sdk/core/reference/core/ovok-client#requestoptions) | ###### Returns [#returns-8] `Promise`\<[`WearableProviderSettings`](#wearableprovidersettings)\> ## Interfaces [#interfaces] ### WearablesResource [#wearablesresource] Wearable providers and the patient's connections to them. Calls routes under `v1/wearables`. #### Properties [#properties] | Property | Modifier | Type | Description | | ------ | ------ | ------ | ------ | | `connections` | `readonly` | [`WearableConnectionsResource`](#wearableconnectionsresource) | Wearable connections. | | `providers` | `readonly` | [`WearableProvidersResource`](#wearableprovidersresource) | Supported wearable providers. | ## Type Aliases [#type-aliases] ### CreateWearableProviderRequest [#createwearableproviderrequest] ```ts type CreateWearableProviderRequest = object; ``` Request body that configures a wearable provider. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `clientId` | `string` | OAuth client id. | | `enabled` | `boolean` | Whether patients can connect this provider. | | `provider` | [`WearableProvider`](#wearableprovider) | Provider to configure. | | `secret` | `string` | OAuth client secret. | | `subscriptionKey` | `string` \| `null` | Webhook subscription key, or `null` for providers that do not use one. | *** ### UpdateWearableProviderRequest [#updatewearableproviderrequest] ```ts type UpdateWearableProviderRequest = object; ``` Fields of a wearable provider configuration that can be changed. #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `clientId?` | `string` | New OAuth client id. | | `enabled?` | `boolean` | New enabled state. | | `secret?` | `string` | New OAuth client secret. | | `subscriptionKey?` | `string` \| `null` | New webhook subscription key, or `null` to clear it. | *** ### WearableConnection [#wearableconnection] ```ts type WearableConnection = object; ``` A patient's link to one wearable provider. #### Properties [#properties-3] | Property | Type | Description | | ------ | ------ | ------ | | `connection` | \| \{ `connectedAt`: `string`; \} \| `null` | Connection details, or `null` when not connected. | | `provider` | [`WearableProvider`](#wearableprovider) | Provider of the connection. | *** ### WearableConnectionAuthorization [#wearableconnectionauthorization] ```ts type WearableConnectionAuthorization = object; ``` Link that starts connecting a wearable provider. #### Properties [#properties-4] | Property | Type | Description | | ------ | ------ | ------ | | `authorizationUrl` | `string` | Provider page where the patient grants access. | | `provider` | [`WearableProvider`](#wearableprovider) | Provider to connect. | *** ### WearableConnections [#wearableconnections] ```ts type WearableConnections = object; ``` A patient's connections across providers. #### Properties [#properties-5] | Property | Type | Description | | ------ | ------ | ------ | | `connections` | [`WearableConnection`](#wearableconnection)[] | One entry per provider. | *** ### WearableErrorCode [#wearableerrorcode] ```ts type WearableErrorCode = | "PROVIDER_CONFIGURED" | "PROVIDER_NOT_CONFIGURED" | "SUBSCRIPTION_KEY_REQUIRED" | "SUBSCRIPTION_KEY_NOT_USED" | "PROVIDER_NOT_AVAILABLE" | "APP_URL_NOT_CONFIGURED" | "CONNECTION_NOT_FOUND" | "STATE_STORE_UNAVAILABLE" | "FEATURE_NOT_CONFIGURED" | "PROJECT_CONTEXT_REQUIRED" | "PATIENT_PROFILE_REQUIRED"; ``` Error codes returned by the wearables routes. *** ### WearableProvider [#wearableprovider] ```ts type WearableProvider = | "oura" | "whoop" | "strava" | "withings" | "polar" | "suunto" | "garmin" | "ultrahuman"; ``` Wearable vendor an app can connect. *** ### WearableProviderSettings [#wearableprovidersettings] ```ts type WearableProviderSettings = object; ``` Project-level configuration of one wearable provider. #### Properties [#properties-6] | Property | Type | Description | | ------ | ------ | ------ | | `clientId` | `string` \| `null` | OAuth client id, or `null` when not configured. | | `configured` | `boolean` | Whether credentials are stored. | | `enabled` | `boolean` | Whether patients can connect this provider. | | `provider` | [`WearableProvider`](#wearableprovider) | Provider the settings belong to. | | `redirectUri` | `string` \| `null` | OAuth redirect URI the provider must allow, or `null` when not configured. | *** ### WearableProviderSettingsList [#wearableprovidersettingslist] ```ts type WearableProviderSettingsList = object; ``` Settings of all wearable providers. #### Properties [#properties-7] | Property | Type | Description | | ------ | ------ | ------ | | `providers` | [`WearableProviderSettings`](#wearableprovidersettings)[] | One entry per provider. | *** ### WearableSyncResult [#wearablesyncresult] ```ts type WearableSyncResult = object; ``` Outcome of syncing a provider's data. #### Properties [#properties-8] | Property | Type | Description | | ------ | ------ | ------ | | `created` | `number` | Number of observations created. | | `provider` | [`WearableProvider`](#wearableprovider) | Provider that was synced. | | `syncedThrough` | `string` | ISO 8601 time up to which data was synced. | # API reference Canonical page: https://docs.ovok.com/web-sdk/core/reference ## Modules [#modules] - [@ovok/core](/web-sdk/core/reference/core/) - [@ovok/core/next/react](/web-sdk/core/reference/react/) # @ovok/core/next/react Canonical page: https://docs.ovok.com/web-sdk/core/reference/react ## Type Aliases [#type-aliases] ### OvokMutation [#ovokmutation] ```ts type OvokMutation = (client, variables) => Promise; ``` A function that writes with the client, given the variables passed to `mutate`. #### Type Parameters [#type-parameters] | Type Parameter | | ------ | | `TVariables` | | `TResult` | #### Parameters [#parameters] | Parameter | Type | | ------ | ------ | | `client` | [`Ovok`](/web-sdk/core/reference/core/ovok-client#ovok) | | `variables` | `TVariables` | #### Returns [#returns] `Promise`\<`TResult`\> *** ### OvokMutationState [#ovokmutationstate] ```ts type OvokMutationState = object; ``` The state returned by `useOvokMutation`. #### Type Parameters [#type-parameters-1] | Type Parameter | | ------ | | `TVariables` | | `TResult` | #### Properties [#properties] | Property | Type | Description | | ------ | ------ | ------ | | `data` | `TResult` \| `undefined` | The latest result, or undefined before the first one. | | `error` | `Error` \| `undefined` | The last error, or undefined. | | `loading` | `boolean` | Whether a mutation is in flight. | | `mutate` | (`variables`) => `Promise`\<`TResult`\> | Runs the mutation; rejects with the error it sets. | | `reset` | () => `void` | Clears `data` and `error`. | *** ### OvokProviderProps [#ovokproviderprops] ```ts type OvokProviderProps = React.PropsWithChildren<{ client: Ovok; }>; ``` Props for `OvokProvider`. *** ### OvokQuery [#ovokquery] ```ts type OvokQuery = (client, signal) => Promise; ``` A function that reads data with the client; it receives an abort signal. #### Type Parameters [#type-parameters-2] | Type Parameter | | ------ | | `T` | #### Parameters [#parameters-1] | Parameter | Type | | ------ | ------ | | `client` | [`Ovok`](/web-sdk/core/reference/core/ovok-client#ovok) | | `signal` | `AbortSignal` | #### Returns [#returns-1] `Promise`\<`T`\> *** ### OvokQueryOptions [#ovokqueryoptions] ```ts type OvokQueryOptions = object; ``` Options for `useOvokQuery`. #### Properties [#properties-1] | Property | Type | Description | | ------ | ------ | ------ | | `enabled?` | `boolean` | Set false to skip the query; defaults to true. | | `queryKey` | readonly `unknown`[] | Identifies the query; the query runs again when it changes. | *** ### OvokQueryState [#ovokquerystate] ```ts type OvokQueryState = object; ``` The state returned by the query hooks. #### Type Parameters [#type-parameters-3] | Type Parameter | | ------ | | `T` | #### Properties [#properties-2] | Property | Type | Description | | ------ | ------ | ------ | | `data` | `T` \| `undefined` | The latest result, or undefined before the first one. | | `error` | `Error` \| `undefined` | The last error, or undefined. | | `isRefreshing` | `boolean` | Whether a request is in flight while earlier data is still shown. | | `isStale` | `boolean` | Whether the shown data may be out of date, because a refresh is running or failed. | | `loading` | `boolean` | Whether a request is in flight. | | `refetch` | () => `void` | Runs the query again. | ## Functions [#functions] ### OvokProvider() [#ovokprovider] ```ts function OvokProvider(__namedParameters): ReactElement; ``` Makes `client` available to the hooks in its subtree. #### Parameters [#parameters-2] | Parameter | Type | | ------ | ------ | | `__namedParameters` | [`OvokProviderProps`](#ovokproviderprops) | #### Returns [#returns-2] `ReactElement` #### Example [#example] ```ts ``` *** ### useOvok() [#useovok] ```ts function useOvok(): Ovok; ``` Returns the Ovok client from the nearest `OvokProvider`. #### Returns [#returns-3] [`Ovok`](/web-sdk/core/reference/core/ovok-client#ovok) #### Throws [#throws] Error when used outside an `OvokProvider`. *** ### useOvokMutation() [#useovokmutation] ```ts function useOvokMutation(mutation): OvokMutationState; ``` Wraps a write so a component can call it and track its loading, error and data state. #### Type Parameters [#type-parameters-4] | Type Parameter | | ------ | | `TVariables` | | `TResult` | #### Parameters [#parameters-3] | Parameter | Type | | ------ | ------ | | `mutation` | [`OvokMutation`](#ovokmutation)\<`TVariables`, `TResult`\> | #### Returns [#returns-4] [`OvokMutationState`](#ovokmutationstate)\<`TVariables`, `TResult`\> #### Example [#example-1] ```ts const { mutate } = useOvokMutation((ovok, patient) => ovok.fhir.create(patient)); ``` *** ### useOvokQuery() [#useovokquery] ```ts function useOvokQuery(query, options): OvokQueryState; ``` Runs `query` and tracks its loading, error and data state; it runs again when `options.queryKey` changes. #### Type Parameters [#type-parameters-5] | Type Parameter | | ------ | | `T` | #### Parameters [#parameters-4] | Parameter | Type | | ------ | ------ | | `query` | [`OvokQuery`](#ovokquery)\<`T`\> | | `options` | [`OvokQueryOptions`](#ovokqueryoptions) | #### Returns [#returns-5] [`OvokQueryState`](#ovokquerystate)\<`T`\> #### Example [#example-2] ```ts const { data, loading } = useOvokQuery((ovok, signal) => ovok.health.check({ signal }), { queryKey: ["health"] }); ``` *** ### useProfile() [#useprofile] ```ts function useProfile(): OvokQueryState; ``` Returns the signed-in profile reference, or null when signed out. #### Returns [#returns-6] [`OvokQueryState`](#ovokquerystate)\<[`OvokReference`](/web-sdk/core/reference/core/session#ovokreference) \| `null`\> *** ### useResource() [#useresource] ```ts function useResource( type, id, options? ): OvokQueryState>; ``` Reads one FHIR resource by id; skipped while `id` is undefined. #### Type Parameters [#type-parameters-6] | Type Parameter | | ------ | | `K` *extends* \| `"Project"` \| `"Practitioner"` \| `"User"` \| `"ProjectMembership"` \| `"AccessPolicy"` \| `"Patient"` \| `"RelatedPerson"` \| `"Appointment"` \| `"UserConfiguration"` \| `"Bundle"` \| `"Observation"` \| `"Account"` \| `"ActivityDefinition"` \| `"AdverseEvent"` \| `"Agent"` \| `"AllergyIntolerance"` \| `"AppointmentResponse"` \| `"AsyncJob"` \| `"AuditEvent"` \| `"Basic"` \| `"Binary"` \| `"BiologicallyDerivedProduct"` \| `"BodyStructure"` \| `"Bot"` \| `"BulkDataExport"` \| `"CapabilityStatement"` \| `"CarePlan"` \| `"CareTeam"` \| `"CatalogEntry"` \| `"ChargeItem"` \| `"ChargeItemDefinition"` \| `"Claim"` \| `"ClaimResponse"` \| `"ClientApplication"` \| `"ClinicalImpression"` \| `"CodeSystem"` \| `"Communication"` \| `"CommunicationRequest"` \| `"CompartmentDefinition"` \| `"Composition"` \| `"ConceptMap"` \| `"Condition"` \| `"Consent"` \| `"Contract"` \| `"Coverage"` \| `"CoverageEligibilityRequest"` \| `"CoverageEligibilityResponse"` \| `"DetectedIssue"` \| `"Device"` \| `"DeviceDefinition"` \| `"DeviceMetric"` \| `"DeviceRequest"` \| `"DeviceUseStatement"` \| `"DiagnosticReport"` \| `"DicomInstance"` \| `"DicomSeries"` \| `"DicomStudy"` \| `"DocumentManifest"` \| `"DocumentReference"` \| `"DomainConfiguration"` \| `"EffectEvidenceSynthesis"` \| `"Encounter"` \| `"Endpoint"` \| `"EnrollmentRequest"` \| `"EnrollmentResponse"` \| `"EpisodeOfCare"` \| `"EventDefinition"` \| `"Evidence"` \| `"EvidenceVariable"` \| `"ExampleScenario"` \| `"ExplanationOfBenefit"` \| `"FamilyMemberHistory"` \| `"Flag"` \| `"Goal"` \| `"GraphDefinition"` \| `"Group"` \| `"GuidanceResponse"` \| `"HealthcareService"` \| `"ImagingStudy"` \| `"Immunization"` \| `"ImmunizationEvaluation"` \| `"ImmunizationRecommendation"` \| `"ImplementationGuide"` \| `"InsurancePlan"` \| `"Invoice"` \| `"JsonWebKey"` \| `"Library"` \| `"Linkage"` \| `"List"` \| `"Location"` \| `"Login"` \| `"Measure"` \| `"MeasureReport"` \| `"Media"` \| `"Medication"` \| `"MedicationAdministration"` \| `"MedicationDispense"` \| `"MedicationKnowledge"` \| `"MedicationRequest"` \| `"MedicationStatement"` \| `"MedicinalProduct"` \| `"MedicinalProductAuthorization"` \| `"MedicinalProductContraindication"` \| `"MedicinalProductIndication"` \| `"MedicinalProductIngredient"` \| `"MedicinalProductInteraction"` \| `"MedicinalProductManufactured"` \| `"MedicinalProductPackaged"` \| `"MedicinalProductPharmaceutical"` \| `"MedicinalProductUndesirableEffect"` \| `"MessageDefinition"` \| `"MessageHeader"` \| `"MolecularSequence"` \| `"NamingSystem"` \| `"NutritionOrder"` \| `"ObservationDefinition"` \| `"OperationDefinition"` \| `"OperationOutcome"` \| `"Organization"` \| `"OrganizationAffiliation"` \| `"Package"` \| `"PackageInstallation"` \| `"PackageRelease"` \| `"Parameters"` \| `"PaymentNotice"` \| `"PaymentReconciliation"` \| `"Person"` \| `"PlanDefinition"` \| `"PractitionerRole"` \| `"Procedure"` \| `"Provenance"` \| `"Questionnaire"` \| `"QuestionnaireResponse"` \| `"RequestGroup"` \| `"ResearchDefinition"` \| `"ResearchElementDefinition"` \| `"ResearchStudy"` \| `"ResearchSubject"` \| `"RiskAssessment"` \| `"RiskEvidenceSynthesis"` \| `"Schedule"` \| `"SearchParameter"` \| `"ServiceRequest"` \| `"Slot"` \| `"SmartAppLaunch"` \| `"SmartHealthLink"` \| `"Specimen"` \| `"SpecimenDefinition"` \| `"StructureDefinition"` \| `"StructureMap"` \| `"Subscription"` \| `"SubscriptionStatus"` \| `"Substance"` \| `"SubstanceNucleicAcid"` \| `"SubstancePolymer"` \| `"SubstanceProtein"` \| `"SubstanceReferenceInformation"` \| `"SubstanceSourceMaterial"` \| `"SubstanceSpecification"` \| `"SupplyDelivery"` \| `"SupplyRequest"` \| `"Task"` \| `"TerminologyCapabilities"` \| `"TestReport"` \| `"TestScript"` \| `"UserSecurityRequest"` \| `"ValueSet"` \| `"VerificationResult"` \| `"VisionPrescription"` | #### Parameters [#parameters-5] | Parameter | Type | | ------ | ------ | | `type` | `K` | | `id` | `string` \| `undefined` | | `options?` | `Pick`\<[`OvokQueryOptions`](#ovokqueryoptions), `"enabled"`\> | #### Returns [#returns-7] [`OvokQueryState`](#ovokquerystate)\<`ExtractResource`\<`K`\>\> *** ### useSearch() [#usesearch] ```ts function useSearch( type, params?, options? ): OvokQueryState>>; ``` Searches a FHIR resource type and returns the first page. #### Type Parameters [#type-parameters-7] | Type Parameter | | ------ | | `K` *extends* \| `"Project"` \| `"Practitioner"` \| `"User"` \| `"ProjectMembership"` \| `"AccessPolicy"` \| `"Patient"` \| `"RelatedPerson"` \| `"Appointment"` \| `"UserConfiguration"` \| `"Bundle"` \| `"Observation"` \| `"Account"` \| `"ActivityDefinition"` \| `"AdverseEvent"` \| `"Agent"` \| `"AllergyIntolerance"` \| `"AppointmentResponse"` \| `"AsyncJob"` \| `"AuditEvent"` \| `"Basic"` \| `"Binary"` \| `"BiologicallyDerivedProduct"` \| `"BodyStructure"` \| `"Bot"` \| `"BulkDataExport"` \| `"CapabilityStatement"` \| `"CarePlan"` \| `"CareTeam"` \| `"CatalogEntry"` \| `"ChargeItem"` \| `"ChargeItemDefinition"` \| `"Claim"` \| `"ClaimResponse"` \| `"ClientApplication"` \| `"ClinicalImpression"` \| `"CodeSystem"` \| `"Communication"` \| `"CommunicationRequest"` \| `"CompartmentDefinition"` \| `"Composition"` \| `"ConceptMap"` \| `"Condition"` \| `"Consent"` \| `"Contract"` \| `"Coverage"` \| `"CoverageEligibilityRequest"` \| `"CoverageEligibilityResponse"` \| `"DetectedIssue"` \| `"Device"` \| `"DeviceDefinition"` \| `"DeviceMetric"` \| `"DeviceRequest"` \| `"DeviceUseStatement"` \| `"DiagnosticReport"` \| `"DicomInstance"` \| `"DicomSeries"` \| `"DicomStudy"` \| `"DocumentManifest"` \| `"DocumentReference"` \| `"DomainConfiguration"` \| `"EffectEvidenceSynthesis"` \| `"Encounter"` \| `"Endpoint"` \| `"EnrollmentRequest"` \| `"EnrollmentResponse"` \| `"EpisodeOfCare"` \| `"EventDefinition"` \| `"Evidence"` \| `"EvidenceVariable"` \| `"ExampleScenario"` \| `"ExplanationOfBenefit"` \| `"FamilyMemberHistory"` \| `"Flag"` \| `"Goal"` \| `"GraphDefinition"` \| `"Group"` \| `"GuidanceResponse"` \| `"HealthcareService"` \| `"ImagingStudy"` \| `"Immunization"` \| `"ImmunizationEvaluation"` \| `"ImmunizationRecommendation"` \| `"ImplementationGuide"` \| `"InsurancePlan"` \| `"Invoice"` \| `"JsonWebKey"` \| `"Library"` \| `"Linkage"` \| `"List"` \| `"Location"` \| `"Login"` \| `"Measure"` \| `"MeasureReport"` \| `"Media"` \| `"Medication"` \| `"MedicationAdministration"` \| `"MedicationDispense"` \| `"MedicationKnowledge"` \| `"MedicationRequest"` \| `"MedicationStatement"` \| `"MedicinalProduct"` \| `"MedicinalProductAuthorization"` \| `"MedicinalProductContraindication"` \| `"MedicinalProductIndication"` \| `"MedicinalProductIngredient"` \| `"MedicinalProductInteraction"` \| `"MedicinalProductManufactured"` \| `"MedicinalProductPackaged"` \| `"MedicinalProductPharmaceutical"` \| `"MedicinalProductUndesirableEffect"` \| `"MessageDefinition"` \| `"MessageHeader"` \| `"MolecularSequence"` \| `"NamingSystem"` \| `"NutritionOrder"` \| `"ObservationDefinition"` \| `"OperationDefinition"` \| `"OperationOutcome"` \| `"Organization"` \| `"OrganizationAffiliation"` \| `"Package"` \| `"PackageInstallation"` \| `"PackageRelease"` \| `"Parameters"` \| `"PaymentNotice"` \| `"PaymentReconciliation"` \| `"Person"` \| `"PlanDefinition"` \| `"PractitionerRole"` \| `"Procedure"` \| `"Provenance"` \| `"Questionnaire"` \| `"QuestionnaireResponse"` \| `"RequestGroup"` \| `"ResearchDefinition"` \| `"ResearchElementDefinition"` \| `"ResearchStudy"` \| `"ResearchSubject"` \| `"RiskAssessment"` \| `"RiskEvidenceSynthesis"` \| `"Schedule"` \| `"SearchParameter"` \| `"ServiceRequest"` \| `"Slot"` \| `"SmartAppLaunch"` \| `"SmartHealthLink"` \| `"Specimen"` \| `"SpecimenDefinition"` \| `"StructureDefinition"` \| `"StructureMap"` \| `"Subscription"` \| `"SubscriptionStatus"` \| `"Substance"` \| `"SubstanceNucleicAcid"` \| `"SubstancePolymer"` \| `"SubstanceProtein"` \| `"SubstanceReferenceInformation"` \| `"SubstanceSourceMaterial"` \| `"SubstanceSpecification"` \| `"SupplyDelivery"` \| `"SupplyRequest"` \| `"Task"` \| `"TerminologyCapabilities"` \| `"TestReport"` \| `"TestScript"` \| `"UserSecurityRequest"` \| `"ValueSet"` \| `"VerificationResult"` \| `"VisionPrescription"` | #### Parameters [#parameters-6] | Parameter | Type | | ------ | ------ | | `type` | `K` | | `params?` | [`QueryParams`](/web-sdk/core/reference/core/ovok-client#queryparams) | | `options?` | `Pick`\<[`OvokQueryOptions`](#ovokqueryoptions), `"enabled"`\> | #### Returns [#returns-8] [`OvokQueryState`](#ovokquerystate)\<[`Page`](/web-sdk/core/reference/core/ovok-client#page)\<`ExtractResource`\<`K`\>\>\> *** ### useSession() [#usesession] ```ts function useSession(): OvokQueryState; ``` Returns the current session, or null when signed out, and updates when the session changes. #### Returns [#returns-9] [`OvokQueryState`](#ovokquerystate)\<[`Session`](/web-sdk/core/reference/core/session#session) \| `null`\> *** ### useSubscription() [#usesubscription] ```ts function useSubscription(subscribe): T | undefined; ``` Subscribes to a source of values and returns the latest one, or undefined before the first. #### Type Parameters [#type-parameters-8] | Type Parameter | | ------ | | `T` | #### Parameters [#parameters-7] | Parameter | Type | | ------ | ------ | | `subscribe` | (`listener`) => () => `void` | #### Returns [#returns-10] `T` \| `undefined` # JavaScript SDK Canonical page: https://docs.ovok.com/web-sdk Install `@ovok/core` to use the `Ovok` client. Its resource namespaces provide authentication, FHIR, measurements, projects, and other Ovok API operations. ```bash npm install @ovok/core ``` ```ts import { Ovok } from '@ovok/core'; export const ovok = new Ovok({ baseUrl: 'https://api.sandbox.ovok.com', tenantCode: 'your-tenant', }); ``` Use the package root for the client. React components and hooks are exported from `@ovok/core/next/react`. ## Start here [#start-here] - [Get started](/web-sdk/core/getting-started) to install and make a first request. - [Configure the client](/web-sdk/core/client-configuration) to select storage, runtime, and request settings. - [React integration](/web-sdk/core/react) to provide the client to a component tree. - [The Ovok client](/web-sdk/core/next-client) for its namespaces, paging and request options. - [Sign users in](/web-sdk/core/guides/sign-in) for login, saved accounts and machine clients. - [Errors and retries](/web-sdk/core/errors-and-retries) to handle failures. - [API map](/web-sdk/core/api-surface) and [complete API reference](/web-sdk/core/reference) for the exported contract. The SDK sends requests to Ovok APIs. The server controls authentication, authorization, project configuration, and data validation. # Signals with Ovok Canonical page: https://docs.ovok.com/signals/connected-ovok Build on Ovok's FHIR data and let Ovok run Signals for you. You write `Patient` and `Observation` resources as usual; Ovok sends the readings to your project's Signals tenant, and writes Signals' alerts back into FHIR. You never call Signals yourself. Two project settings turn the two directions on and off: | Setting | Direction | What it does | Default | | --- | --- | --- | --- | | [`SIGNALS_SEND_AUTO`](/signals/with-ovok/settings#signals_send_auto) | FHIR → Signals | Each Observation of a patient created through the FHIR API is sent to Signals, and enrols the patient on the first reading. | On | | [`SIGNALS_ANNOTATE_OBSERVATIONS`](/signals/with-ovok/settings#signals_annotate_observations) | Signals → FHIR | Each alert becomes a `DetectedIssue`, each episode a `Flag`, and the breaching reading gets an `interpretation`. | Follows `SIGNALS_SEND_AUTO` | Both need your project to have its own Signals tenant. ## How a reading flows [#how-a-reading-flows] 1. Your app creates an `Observation` for a patient through `POST /fhir/R4/Observation` (or in a bundle). 2. Ovok's Medplum notifies Ovok of the new Observation, and Ovok forwards it to Signals. A patient Signals does not know yet is enrolled by this first reading. 3. Signals judges the reading against the patient's triggers. A breach raises an alert, and, with episodes on, opens or extends an episode. 4. Signals tells Ovok, and Ovok writes the result into FHIR: a [`DetectedIssue`](/signals/with-ovok/fhir-annotations#the-alert-detectedissue) for the alert, a [`Flag`](/signals/with-ovok/fhir-annotations#the-episode-flag) for the episode, and an [`interpretation`](/signals/with-ovok/fhir-annotations#the-reading-observation) on the reading. 5. Your app reads them with ordinary FHIR searches, or shows them through the Slim [notification feeds](/slim-apis/notifications/list-medical-notifications). Not every new Observation is sent. Ovok skips one whose `subject` is not a `Patient`, one with `status` `entered-in-error` or `cancelled`, and one carrying an `ovok-event-id` or Signals identifier. Readings from connected devices that arrive through [Data Ingestion](/data-ingestion) carry `ovok-event-id`: the ingest path forwards them itself, whatever `SIGNALS_SEND_AUTO` says. ## How an episode behaves [#how-an-episode-behaves] An episode is one clinical event for one patient and one vital. It opens on the first breaching reading, takes in the readings that follow, and closes for one of the reasons below. Ovok shows it as a `Flag` with annotations on, and as a row of the Slim medical and out-of-bed notification feeds. - For banded vitals such as heart rate and breathing rate, a missing value, a value at or below 0, or a non-numeric value gets no verdict: it opens, extends or closes no episode. - One in-bed reading ends an out-of-bed absence and clears its acknowledgement silence. The next absent reading starts a new absence. | `closeReason` | Meaning | | --- | --- | | `RECOVERED` | A reading came back inside the limit (for out-of-bed, an in-bed reading). That reading is the episode's last value. | | `TIMEOUT` | No reading of this vital arrived within the disconnect window, so the episode closed at the last reading plus that window. | | `ACKNOWLEDGED` | Someone acknowledged it while it was open. The next breach opens a new episode. | | `CROSSED` | The value jumped from one side of the limit to the other. This episode closed and a new one opened for the other side. | | `THRESHOLD_CHANGED` | The limit that opened the episode was changed or removed. | | `AWAY` | The resident left the bed while a heart-rate or breathing-rate episode was open. | | `STALE` | An out-of-bed episode stayed open longer than 48 hours. No new out-of-bed alert follows until the resident is back in bed. | | `MANUAL` | Ovok closed it because the resident was taken off their sensor or discharged. | ## Before you start [#before-you-start] | Requirement | Details | | --- | --- | | Your own Signals tenant | Both settings work only for a project with a Signals tenant of its own. Turning one on otherwise answers `409` `SETTING_NOT_AVAILABLE`. | | FHIR access | Your app's access policy needs `Observation` create, and read on `DetectedIssue` and `Flag` to see the results. Project admins manage those policies. | | Who changes the settings | Project admins, with `PUT /v1/project/settings/:key`. | ## Rules and thresholds [#rules-and-thresholds] What makes a reading alert is set by triggers and bands in Signals. In an Ovok app, change them through the Slim [threshold routes](/slim-apis/threshold/get-patient-effective-threshold-v2), which save to Signals for you. Products that manage rules themselves can also use the [standalone API](/signals/standalone). ## Pages in this section [#pages-in-this-section] - [Settings](/signals/with-ovok/settings): the two switches, their defaults, and what saving them does. - [Alerts in FHIR](/signals/with-ovok/fhir-annotations): the `DetectedIssue`, `Flag` and `Observation` Ovok writes, and how to search them. - [Enable Signals for a Patient](/signals/enable-signals-patient): enrol an existing patient before its first reading. - [Gotchas](/signals/with-ovok/gotchas): what to know before you rely on it. ## Related [#related] - [Signals standalone](/signals/standalone) - [Signals route policies](/access-policies/signals) - [Data Ingestion](/data-ingestion) # Enable Signals for a Patient Canonical page: https://docs.ovok.com/signals/enable-signals-patient | Method | Path | | --- | --- | | `POST` | `/fhir/R4/Patient/:id/$enable-signals` | [Signals with Ovok](/signals/connected-ovok#before-you-start) lists what a project needs to use Signals through FHIR. Use this for a Patient that already exists in the project and was created without Signals. With [`SIGNALS_SEND_AUTO`](/signals/with-ovok/settings#signals_send_auto) on, a patient's first FHIR Observation enrols it anyway; call this only to enrol a patient before any reading. The unversioned and R5 aliases are also available: `/fhir/Patient/:id/$enable-signals` and `/fhir/R5/Patient/:id/$enable-signals`. | Requirement | Details | | --- | --- | | Access policy | `signals_config:update` and Patient `update` | | Request | No body; `:id` is the Ovok Patient ID | | Success | `200`; returns `patientId`, `signalsPatientId`, and `enabled: true` | | Retry behavior | Idempotent. If the Patient is already enrolled, Ovok returns the same Signals id and completes any missing enrollment setup. | | Failure | `403` for missing permission; `404` when the Patient cannot be found in the caller's project; `503 signals_mint_failed` ([`signals_mint_failed`](/errors/signals-mint-failed)) if provisioning does not complete. A failed operation leaves no partial enrollment, so retrying is safe. | ```bash curl --request POST \ --url 'https://api.sandbox.ovok.com/fhir/R4/Patient/3f1c2b7e-8d4a-4c1e-9b2f-6a7d5e4c3b21/$enable-signals' \ --header "Authorization: Bearer ${OVOK_TOKEN}" ``` This operation is also listed in the [Ovok primitives reference](/primitives/enable-signals-patient). # Signals Canonical page: https://docs.ovok.com/signals Actimi Signals is standalone, cloud-based medical-device software. It analyzes clinical data, evaluates patient-specific rules, and returns alert decisions to compatible software through an API. For Patients enrolled in Signals, Ovok stores connected-device data as FHIR resources and forwards eligible vital-sign readings according to the documented Signals forwarding behavior. Signals returns decisions through its API, and Ovok makes those decisions available to your application. Do not infer which measurements are forwarded; check [Data Ingestion](/data-ingestion) for the current forwarding behavior. **Signals is MDR Class IIa; Ovok is not a certified medical-device product.** ## Is Signals required? [#is-signals-required] No. If you are building a non-clinical product that does not need medical alert evaluation, you can opt out of Signals. You can still use Ovok's FHIR APIs without using Signals. ## Product details [#product-details] | Detail | Information | | --- | --- | | UDI-DI | `42700031203-API-XG` | | Security contact | [security@actimi.com](mailto:security@actimi.com) | ## What Signals does [#what-signals-does] Signals can analyze clinical data captured by compatible medical devices or supplied by other software through its API. Based on that data, it can: - generate patient-specific alerts; - create prioritized patient lists using preconfigured rules and validated algorithms informed by international clinical-society recommendations; and - support regular data collection, monitoring, and trend reporting, including rules configured for an individual patient by a medical practitioner. Signals is not intended to present results directly to end users. It returns results through an API to compatible software, which can process them and provide the interface clinicians use. In an Ovok-powered product, use Ovok APIs to bring the resulting decisions into your application's care workflow. ## How Signals fits with Ovok [#how-signals-fits-with-ovok] 1. Compatible devices or connected software provide clinical measurements. 2. For Patients enrolled in Signals, Ovok stores clinical data as FHIR resources and forwards eligible vital-sign readings according to the documented forwarding behavior. 3. Signals evaluates the data and returns its decisions through an API. 4. Ovok surfaces those decisions to your application, where your product implements the clinician-facing workflow. If you opt out of Signals, this alert-evaluation flow does not apply. Your application remains responsible for its own experience and workflow. Signals provides the analysis service; Ovok provides the FHIR data layer and API used by your application. ## Two ways to use Signals through Ovok [#two-ways-to-use-signals-through-ovok] | | [Standalone](/signals/standalone) | [With Ovok](/signals/connected-ovok) | | --- | --- | --- | | What you call | Signals' own API, at `/v1/signals/api/*` | Ovok's FHIR API and Slim APIs | | Where patients and readings live | In Signals, under your own ids (`refId`) | In FHIR (`Patient`, `Observation`); Ovok forwards readings to Signals | | Where alerts come back | Signals' alert and episode routes, and webhooks | FHIR `DetectedIssue`, `Flag` and `Observation.interpretation`, and the Slim notification feeds | | Credentials | A Manager or Submitter application, or any caller whose policy holds the `signals_*` capabilities | Any project credential with the FHIR access it needs | | Good for | A product with its own data store that only needs alert decisions | A product built on Ovok's FHIR data | Both need your project to have its own Signals tenant. You can use both at once: a patient created in FHIR and enrolled in Signals is also visible through the standalone API. ## What MDR Class IIa means [#what-mdr-class-iia-means] **Class IIa** is one of the medical-device risk classes defined by the EU Medical Device Regulation (MDR). The MDR's Annex VIII sets out classification rules based on a device's intended purpose and risk. Rule 11 addresses software that provides information used for diagnostic or therapeutic decisions and software intended to monitor physiological processes; it also sets out circumstances that can result in a higher class. See the [MDR, Annex VIII, Rule 11](https://eur-lex.europa.eu/eli/reg/2017/745/oj/eng) and the European Commission's [software qualification and classification guidance, MDCG 2019-11 rev.1](https://health.ec.europa.eu/document/download/b45335c5-1679-4c71-a91c-fc7a4d37f12b_en?filename=md_mdcg_2019_11_guidance_qualification_classification_software_en.pdf&prefLang=en). Actimi Signals' Class IIa status applies to Signals as a medical-device software product. It does not certify Ovok or automatically give the same status to an application that integrates with Signals. Ovok is a backend platform, not a certified medical device. ## What this means for your app [#what-this-means-for-your-app] **Showing a Signals alert does not, by itself, decide whether your app is a medical device.** The MDR assessment is based on the app's own intended purpose and what it is designed and presented to do. The intended purpose is informed by the manufacturer's statements in product materials, instructions for use, promotional or sales content, and clinical evaluation—not just by a disclaimer or the fact that the app uses a certified service. The boundary depends on the complete workflow. Software limited to storing, transferring, or simply displaying information may be treated differently from software intended to interpret or prioritize patient data, monitor a condition, recommend an intervention, or provide information used for diagnosis or treatment. A user interface can still be part of medical-device software when its intended purpose is to support clinical decisions. There is no blanket exemption for an app described as “display only.” For an Ovok-powered app, assess these points together: - **Purpose:** What medical purpose, if any, do you claim for the app, and who is it intended to help—clinicians, patients, or both? - **Role of the alert:** Does the app pass through the Signals result, or does it add interpretation, ranking, recommendations, escalation logic, or actions that influence care? - **Use in care:** Is the information intended to support diagnosis or treatment decisions, or to monitor a physiological process? What does the user understand they should do with an alert? - **Product claims:** Do the app's name, interface, documentation, instructions, and marketing describe a clinical function, even if the code only displays a result produced elsewhere? If your app has a medical intended purpose, assess it as its own software product under the MDR. Rule 11 may apply when software provides information used for diagnostic or therapeutic decisions, or is intended to monitor physiological processes. The resulting class depends on the intended purpose and the Rule 11 criteria; Signals' Class IIa classification does not set your app's class. The same assessment applies whether the software runs on a phone, server, or in the cloud. ### A practical review before release [#a-practical-review-before-release] 1. Write down the app's intended purpose, intended users, and the role of Signals results in the care workflow. 2. Compare that statement with the app's actual behavior and all user-facing claims, including alert labels, prioritization, notifications, and recommended next steps. 3. Document your qualification and, if applicable, classification rationale against MDR Annex VIII Rule 11 and the European Commission's software guidance. 4. Get a product-specific assessment from a qualified EU medical-device regulatory professional before placing the app on the market. Do not infer the answer from Ovok's status, Signals' class, or a UI disclaimer alone. This is a practical summary of public EU guidance, not a legal determination for your product. See the [MDR definition of intended purpose and medical device](https://eur-lex.europa.eu/eli/reg/2017/745/oj/eng) and the European Commission's [MDCG 2019-11 rev.1 software qualification and classification guidance](https://health.ec.europa.eu/document/download/b45335c5-1679-4c71-a91c-fc7a4d37f12b_en?filename=md_mdcg_2019_11_guidance_qualification_classification_software_en.pdf&prefLang=en). ## Official intended purpose [#official-intended-purpose] > Actimi Signals is a medical device stand alone cloud-based software intended to analyze clinical data captured by compatible medical devices or supplied by other software via the API. Based on the input, Actimi Signals generates patient-specific alerts and creates prioritized lists of patients based on pre-configured rules, using several validated algorithms, based on the recommendations of international societies, or based on a patient-specific rules set by an individual medical practitioner for a specific patient. Therefore, Actimi signals can bring to the clinician's attention those monitored patients potentially in need of clinical intervention or can be used for regular data collection, monitoring and trends reporting. Actimi Signals is not intended to directly present the output to the user, instead, it communicates the results via API and supplies them to a compatible software (i.e. software using adequate API), which can further process the data or provide a graphic user interface to a user. ## Related [#related] - [Signals standalone](/signals/standalone) - [Signals with Ovok](/signals/connected-ovok) - [Signals route policies](/access-policies/signals) # Acknowledge an alert, or an episode Canonical page: https://docs.ovok.com/signals/standalone/api/alerts/acknowledge-an-alert-or-an-episode {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Acknowledge an alert, or an episode [#acknowledge-an-alert-or-an-episode] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/alert/{id}/ack` | The path segment is an alert id, or an episode id with `episodes=true`. Acknowledging closes it: an alert resolves, an episode ends its alerting window, and the next breaching reading opens a new one. The patient's triggers decide what else closing does (their `onAck` hooks). Under the default pack, acknowledging an open out-of-bed alert (103214-3) also silences the absence under way. Idempotent: acknowledging again returns the original time and actor. Acknowledging one that already closed only stamps the acknowledgement. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_alerts:update`. Project admins have every capability; client applications get no admin bypass. - ovok sets `project` to your project, so you can leave it out. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the alert's patient must be one you can update: ovok reads the alert first. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | — | ### Query parameters [#query-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `episodes` | boolean | No | Read the id as an episode id rather than an alert id. | ### Body [#body] Optional. | Field | Type | Required | Description | | --- | --- | --- | --- | | `actor` | object | No | Who acknowledged, as your system identifies them, such as `Practitioner/`. Stored as given. | | `actor.reference` | string | Yes | — | | `actor.display` | string | No | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The alert, or the episode, now acknowledged. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 `project` names another project, or you can read the alert's patient but not update it. From Signals: `episodicAlerts` is off for this tenant, and an episode was asked for. | | `404` | The alert's patient is not one you can read. From Signals: No such alert or episode in this tenant and project. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `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 POST 'https://api.sandbox.ovok.com/v1/signals/api/alert/:id/ack' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Get one alert, or one episode with its readings Canonical page: https://docs.ovok.com/signals/standalone/api/alerts/get-one-alert-or-one-episode-with-its-readings {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Get one alert, or one episode with its readings [#get-one-alert-or-one-episode-with-its-readings] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/alert/{id}` | The path segment is an alert id, or an episode id with `episodes=true`. An alert reads whether or not the tenant has `episodicAlerts`. An episode comes with its summary, its acknowledgement and every value recorded for its code while it ran. The series starts at the first breaching reading. A long episode returns a capped series and sets `truncated`. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_alerts:read`. Project admins have every capability; client applications get no admin bypass. - ovok sets `project` to your project, so you can leave it out. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the alert's patient must be one you can read: ovok reads the alert first. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | — | ### Query parameters [#query-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `episodes` | boolean | No | Read the id as an episode id rather than an alert id. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The alert, or the episode and its value series. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 `project` names another project. From Signals: `episodicAlerts` is off for this tenant, and an episode was asked for. | | `404` | The alert's patient is not one you can read. From Signals: No such alert or episode in this tenant and project. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/alert/:id' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # List alerts, or the episodes they were folded into Canonical page: https://docs.ovok.com/signals/standalone/api/alerts/list-alerts-or-the-episodes-they-were-folded-into {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # List alerts, or the episodes they were folded into [#list-alerts-or-the-episodes-they-were-folded-into] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/alert` | The dashboard view. By default this is one row per breach, in v1's alert shape plus every nest alert field, inside v1's paginate envelope (`items`, `totalItems`, `page`, `totalPages`, …) with nest's `nextCursor` beside it. Page with v1's `page` and `limit` (a page may start at most 10000 rows in), or walk with `cursor`: pass `nextCursor` back verbatim. `sort` is v1's `time-desc` (the default) or `time-asc`; `ids` narrows to those patients. It works whether or not the tenant has `episodicAlerts`. Without `project` it is tenant-wide: a per-facility view must send `project`, which keeps only patients stamped with it. `?episodes=true` answers with episodes instead, as `{items, nextCursor}`: one row per clinical event, which opens on the first breaching reading, absorbs the rest, and closes on recovery, on going stale, or by hand. That grain REQUIRES `project`. It defaults to the tenant's `feedCodes` (`PATCH /api/tenant`), every code when it lists none; alerts have no code default. `codes`, `since` and `acknowledged` filter either grain. `until`, `page` and `ids` are alerts only: sending one with `episodes=true` is a 422, not a filter that silently did nothing. `status` reads ACTIVE/RESOLVED for alerts and OPEN/CLOSED for episodes. Episodes are newest first by `sort`: `openedAt`, the default, or `lastFiringAt`, the newest firing reading (the opening, for an episode that has none). `since` and the cursor use the same time. `openedAt` never changes, so walking every page lists each episode once. On `lastFiringAt` an episode that fires mid-walk moves above the cursor: it is never listed twice, but that walk misses it. A `sort` value from the other grain is a 422. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_alerts:read`. Project admins have every capability; client applications get no admin bypass. - ovok sets `project` to your project, so you can leave it out. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), name them with `patientId` or `ids`, each one you can read, at most 100. Signals then pages over just those patients, so pages and totals stay true. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Query parameters [#query-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `episodes` | boolean | No | Return episodes rather than the individual breaches they were folded from. An episode is one continuous clinical event for a (patient, code) pair: it opens on the first breaching reading, absorbs the rest, and closes on recovery, on going stale, or by hand. The default answers one row per breach, which is the duplication episodes exist to collapse. Requires `project`, and changes which of the filters below are accepted. | | `patientId` | string | No | — | | `ids` | array of string | No | v1's patient filter: only these patients' alerts, by Signals id. Repeat the parameter or separate with commas. Alerts only. | | `status` | `ACTIVE`, `RESOLVED`, `OPEN`, `CLOSED` | No | ACTIVE or RESOLVED for alerts; OPEN or CLOSED with `episodes=true`. | | `codes` | array of string | No | Restrict to these LOINC codes. On episodes it defaults to the tenant's `feedCodes`, every code when it lists none. Alerts have no default: absent, every alert, including those that carry no code. | | `since` | string | No | Alerts raised, or episodes whose `sort` time is, at or after this instant: opened by default, last fired with `sort=lastFiringAt`. | | `until` | string | No | Alerts raised before this instant. Alerts only. | | `acknowledged` | boolean | No | Filter on whether the episode, or the alert, has been acknowledged. | | `sort` | `time-desc`, `time-asc`, `openedAt`, `lastFiringAt` | No | On alerts, v1's order: `time-desc` (the default) or `time-asc`. On episodes, which time they are listed by, newest first; `since` and `cursor` use it too. `openedAt` (the default) never changes, so a walk of every page sees each episode once. `lastFiringAt` is the newest firing reading, or the opening for an episode that has none; an episode that fires mid-walk moves above the cursor. | | `page` | number | No | v1's 1-based page of `limit` alerts. A page may start at most 10000 rows in; walk further with `cursor`. Alerts only. | | `limit` | number | No | — | | `cursor` | string | No | — | | `tags[key]` | string | No | v1's tag filter: only patients whose `tags.key` equals one of the comma-separated values, or holds one in an array. Repeat with other keys to require them all. Keys are alphanumeric; `tags.key=` is accepted too. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | A page of alerts, or of episodes, plus the cursor for the next one. | | `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 `project` names another project, or your access covers only some patients and the call names none. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. Or: `episodicAlerts` is not enabled for this tenant, and episodes were requested. | | `404` | A patient the call names is not one you can read. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. More than 100 patients are named. From Signals: An alert filter was sent with `episodes=true`, `episodes=true` arrived without `project`, or the page starts too deep. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/alert' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Create a user Canonical page: https://docs.ovok.com/signals/standalone/api/clients/create-a-user {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Create a user [#create-a-user] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/user` | Mints an API client. `clientId` and `secret` are the Basic credential, chosen by the caller and never returned. `role` may be v1's lowercase. A SUBSCRIBER needs `webhookUrl` and at least one event. It is on `eventSchema` 2 unless the body says 1: on 2 its first Standard Webhooks signing secret is returned this once as `signingSecret`; on 1 it needs `webhookSecret` (v1 called it `secret`). `reach` is `attached` (default: the patients attached to it, as v1's) or `all` (every patient of the tenant, those enrolled later included). ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`, `signals_events:read`. Project admins have every capability; client applications get no admin bypass. - Only subscribers are created through ovok, on event schema 2. ovok generates their id and Signals login, which they never use, and Signals generates the webhook signing secret. - 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] ### Body [#body] Required. | Field | Type | Required | Description | | --- | --- | --- | --- | | `role` | `SUBSCRIBER` | Yes | Validated against the assignable roles rather than the full enum, so this MANAGER-gated route cannot mint a cross-tenant SUPER_ADMIN credential. | | `name` | string | No | — | | `webhookUrl` | string | No | — | | `events` | array of string | No | — | | `custom` | string | No | v1's `custom`: an opaque string every webhook carries back as `x-actimi-custom`. | | `eventSchema` | `2` | No | 1 keeps v1's event names and bodies; 2, the default, sends one name per state change. | | `reach` | `attached`, `all` | No | `attached`: the patients attached to it, as v1's; `all`: every patient of the tenant, later ones included. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `201` | The user, without its secret; `Location` names it. | | `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 `role` is not `SUBSCRIBER`, 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. Or: `FEATURE_DISABLED`: `events` names an episode event, and the tenant has `episodicAlerts` off, so it records none. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. From Signals: The `clientId` is taken. | | `415` | The body is not JSON. | | `422` | `role` is missing, `clientId`, `secret` or `webhookSecret` was sent, or `eventSchema` is not 2. From Signals: The payload failed validation. `EVENTS_NOT_IN_SCHEMA`: `events` names a type its `eventSchema` never sends, such as `alert.trigger` on schema 2. | | `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 POST 'https://api.sandbox.ovok.com/v1/signals/api/user' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Delete a user Canonical page: https://docs.ovok.com/signals/standalone/api/clients/delete-a-user {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Delete a user [#delete-a-user] | Method | Path | | --- | --- | | `DELETE` | `/v1/signals/api/user/{id}` | Revokes the credential at once and drops its undelivered webhook events. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:delete`. Project admins have every capability; client applications get no admin bypass. - Only subscribers are deleted through ovok. - 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] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | Deleted: the id of the user that is gone. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 user is not a subscriber, or your access covers only some patients. | | `404` | No such client in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `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 DELETE 'https://api.sandbox.ovok.com/v1/signals/api/user/:id' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Disable the webhook endpoint Canonical page: https://docs.ovok.com/signals/standalone/api/clients/disable-the-webhook-endpoint {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Disable the webhook endpoint [#disable-the-webhook-endpoint] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/subscriber/{id}/webhook/disable` | Stops deliveries. Queued events and new ones are held, not dropped, for a redeliver once it is enabled again. Disabling a disabled endpoint keeps its first reason. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The subscriber's Signals id or its `clientId`. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The endpoint as it now stands. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 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. Or: A SUBSCRIBER named another subscriber. | | `404` | No such subscriber in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `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 POST 'https://api.sandbox.ovok.com/v1/signals/api/subscriber/:id/webhook/disable' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Enable the webhook endpoint Canonical page: https://docs.ovok.com/signals/standalone/api/clients/enable-the-webhook-endpoint {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Enable the webhook endpoint [#enable-the-webhook-endpoint] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/subscriber/{id}/webhook/enable` | Resumes deliveries of new events. It re-queues nothing: events held while it was disabled go out only through `POST /api/events/redeliver?status=held`. Enabling an enabled endpoint changes nothing. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The subscriber's Signals id or its `clientId`. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The endpoint as it now stands. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 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. Or: A SUBSCRIBER named another subscriber. | | `404` | No such subscriber in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `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 POST 'https://api.sandbox.ovok.com/v1/signals/api/subscriber/:id/webhook/enable' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Get one user Canonical page: https://docs.ovok.com/signals/standalone/api/clients/get-one-user {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Get one user [#get-one-user] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/user/{id}` | Without its secret, which is not retrievable. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_clients:read`. Project admins have every capability; client applications get no admin bypass. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The client's Signals id. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The user. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | No such client in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/user/:id' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # List users Canonical page: https://docs.ovok.com/signals/standalone/api/clients/list-users {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # List users [#list-users] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/user` | The tenant's API clients, newest first, in v1's paginate envelope (`page`, `limit` defaulting to 10) with nest's `nextCursor`. `role` and `name` filter as in v1. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_clients:read`. Project admins have every capability; client applications get no admin bypass. ## Request [#request] ### Query parameters [#query-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `limit` | number | No | Page size. Defaults to 10, as in v1. | | `role` | `ADMIN`, `MANAGER`, `SUBMITTER`, `SUBSCRIBER`, `SUPER_ADMIN`, `TENANT_PROVISIONER` | No | Only this role: `manager`, `submitter`, `subscriber` (or `admin`), either case. | | `name` | string | No | Only clients with exactly this name. | | `page` | number | No | 1-based, as v1 paged. A page may start at most 10000 rows in; walk further with `cursor`. | | `cursor` | string | No | Opaque keyset cursor: a previous answer's `nextCursor`, passed back verbatim. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | One page of users. | | `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. 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. | | `422` | A query parameter failed validation, or the page starts too deep. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/user' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Read the webhook endpoint Canonical page: https://docs.ovok.com/signals/standalone/api/clients/read-the-webhook-endpoint {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Read the webhook endpoint [#read-the-webhook-endpoint] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/subscriber/{id}/webhook` | The URL, whether it is `enabled`, `failing` or `disabled` (and why), when its current run of failures began, and its newest delivered and failed attempts. Five days of failures with no delivery, or one 410, disable it. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:read`. Project admins have every capability; client applications get no admin bypass. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The subscriber's Signals id or its `clientId`. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The endpoint. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. Or: A SUBSCRIBER named another subscriber. | | `404` | No such subscriber in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/subscriber/:id/webhook' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Rotate the webhook signing secret Canonical page: https://docs.ovok.com/signals/standalone/api/clients/rotate-the-webhook-signing-secret {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Rotate the webhook signing secret [#rotate-the-webhook-signing-secret] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/subscriber/{id}/webhook/rotate-secret` | Mints a new Standard Webhooks signing secret (`whsec_` and 32 random bytes) and returns it this once. Every delivery carries `webhook-id` and `webhook-timestamp`; once the subscriber has a secret it also carries `webhook-signature`, so a receiver verifies with the Standard Webhooks library. The secret it replaces keeps signing until `previousSecretExpiresAt` (24 h), so `webhook-signature` holds both and the receiver switches with no gap. Each rotation keeps only the secret it replaces, so rotate again only once the receiver uses the new one. The first call mints the subscriber's first secret. A MANAGER rotates any subscriber of its tenant; a SUBSCRIBER only its own. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The subscriber's Signals id or its `clientId`. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The new secret; it cannot be read back later. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 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. Or: A SUBSCRIBER named another subscriber. | | `404` | No such subscriber in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `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 POST 'https://api.sandbox.ovok.com/v1/signals/api/subscriber/:id/webhook/rotate-secret' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Send a test event Canonical page: https://docs.ovok.com/signals/standalone/api/clients/send-a-test-event {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Send a test event [#send-a-test-event] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/subscriber/{id}/webhook/test` | Sends a signed `webhook.test` event (`{ event, subscriber, sentAt }`) now, with every header a real delivery carries, and answers what the receiver did. It is not queued, retried or listed, and it works on a disabled endpoint, so a receiver can be checked before it is enabled. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The subscriber's Signals id or its `clientId`. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The attempt: whether it was delivered, and the answer. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 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. Or: A SUBSCRIBER named another subscriber. | | `404` | No such subscriber in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `422` | The subscriber has no webhookUrl. | | `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 POST 'https://api.sandbox.ovok.com/v1/signals/api/subscriber/:id/webhook/test' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Update a user Canonical page: https://docs.ovok.com/signals/standalone/api/clients/update-a-user {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Update a user [#update-a-user] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/user/{id}` | Sets the name, webhook target, signing secret, events, event schema, reach or credential secret. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`, `signals_events:read`. Project admins have every capability; client applications get no admin bypass. - Only subscribers are changed through ovok. Their `role`, `eventSchema`, `clientId`, `secret` and `webhookSecret` can't be sent. - 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] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The client's Signals id. | ### Body [#body] Required. | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | No | — | | `webhookUrl` | string | No | — | | `events` | array of string | No | — | | `custom` | string | No | v1's `custom`: an opaque string every webhook carries back as `x-actimi-custom`. | | `reach` | `attached`, `all` | No | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The user as it now stands. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 user is not a subscriber, 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. Or: `FEATURE_DISABLED`: `events` names an episode event, and the tenant has `episodicAlerts` off, so it records none. | | `404` | No such client in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `422` | `role`, `eventSchema`, `clientId`, `secret` or `webhookSecret` was sent. From Signals: The payload failed validation. `EVENTS_NOT_IN_SCHEMA`: the `events` and `eventSchema` it would leave never match, such as `alert.trigger` on schema 2. Change both in one call. | | `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 POST 'https://api.sandbox.ovok.com/v1/signals/api/user/:id' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # List a delivery's attempts Canonical page: https://docs.ovok.com/signals/standalone/api/events/list-a-deliverys-attempts {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # List a delivery's attempts [#list-a-deliverys-attempts] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/events/{id}/attempts` | Each POST made for it, oldest first: when, how long, the status code or the error, and the first 2 KB of the answer. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_events:read`. Project admins have every capability; client applications get no admin bypass. - 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] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The delivery's id, an item's `id` in `GET /api/events`. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The attempts. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 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. Or: A SUBSCRIBER named another subscriber's delivery. | | `404` | No such delivery in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/events/:id/attempts' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # List webhook events Canonical page: https://docs.ovok.com/signals/standalone/api/events/list-webhook-events {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # List webhook events [#list-webhook-events] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/events` | Every event addressed to the caller, oldest first and keyset paged by `cursor`, each with its delivery status and payload: expired, failed and held ones too. An event is listed once it is two minutes old, so a page never moves past one a slower transaction has yet to commit. Filter by `types`, `status`, `patientId`, or (for a MANAGER) `subscriberId`. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_events:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), name them with `patientId`, each one you can read, at most 100. Signals then pages over just those patients, so pages and totals stay true. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Query parameters [#query-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `cursor` | string | No | Opaque keyset cursor: a previous answer's `nextCursor`, passed back verbatim. | | `limit` | number | No | Page size, 1 to 200. Defaults to 50. | | `types` | array of string | No | Only these event types, comma-separated: `alert.trigger,patient.inactive`. | | `status` | `failed`, `delivered`, `pending`, `expired`, `held` | No | Only deliveries in this state. | | `patientId` | string | No | Only events about this patient: its Signals id, as the payload's `patient`. | | `subscriberId` | string | No | Only this subscriber's deliveries, by Signals id or `clientId`. A subscriber may name only itself. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | One page of events. | | `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 your access covers only some patients and the call names none. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. Or: A SUBSCRIBER named another subscriber. | | `404` | A patient the call names is not one you can read. From Signals: `subscriberId` names no subscriber in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. More than 100 patients are named. From Signals: A query parameter 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 GET 'https://api.sandbox.ovok.com/v1/signals/api/events' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Redeliver events Canonical page: https://docs.ovok.com/signals/standalone/api/events/redeliver-events {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Redeliver events [#redeliver-events] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/events/redeliver` | Queues the oldest 1 000 deliveries in `status` (default `failed`) queued since `since` to be sent again, each with a fresh retry ladder: the same `webhook-id`, so receivers dedupe, and a new `webhook-timestamp`. An alert is sent whatever its age. Deliveries to a disabled endpoint, and ones being sent right now, are skipped. While it answers `queued: 1000`, call it again for the next ones. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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 | | --- | --- | --- | --- | | `status` | `failed`, `delivered`, `pending`, `expired`, `held` | No | The deliveries to send again: `failed` (the default), `expired`, `held` or `delivered`. | | `since` | string | Yes | Only events queued at or after this time. Required, so a replay is always bounded. | | `subscriberId` | string | No | Only this subscriber's deliveries, by Signals id or `clientId`. A subscriber may name only itself. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `202` | Queued: how many deliveries will be sent again. | | `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 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. Or: A SUBSCRIBER named another subscriber. | | `404` | `subscriberId` names no subscriber in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `422` | A query parameter failed validation, or `since` is missing. | | `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 POST 'https://api.sandbox.ovok.com/v1/signals/api/events/redeliver' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Redeliver one event Canonical page: https://docs.ovok.com/signals/standalone/api/events/redeliver-one-event {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Redeliver one event [#redeliver-one-event] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/events/{id}/redeliver` | Queues this delivery to be sent now, whatever its status, with a fresh retry ladder: the same `webhook-id` and a new `webhook-timestamp`. An alert is sent whatever its age. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The delivery's id, an item's `id` in `GET /api/events`. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `202` | Queued. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 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. Or: A SUBSCRIBER named another subscriber's delivery. | | `404` | No such delivery in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. From Signals: The endpoint is disabled, or the delivery is being sent right now. | | `415` | The body is not JSON. | | `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 POST 'https://api.sandbox.ovok.com/v1/signals/api/events/:id/redeliver' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Liveness Canonical page: https://docs.ovok.com/signals/standalone/api/health/liveness {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Liveness [#liveness] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/health` | Unauthenticated, always 200: the HTTP status reports that the process is serving, not that its dependencies are well, because this route gates container liveness. `healthy` is false while the database does not answer (`db.ok`); page on it. ### Through ovok [#through-ovok] - **Who can call it:** any caller with an ovok access token, or a client id and secret. It needs no capability. ## Request [#request] No parameters or body. ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The service is up; `db` reports database reachability. | | `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. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/health' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # List a patient's readings Canonical page: https://docs.ovok.com/signals/standalone/api/observations/list-a-patients-readings {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # List a patient's readings [#list-a-patients-readings] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/observation/{patientId}` | Newest first by clinical time, in v1's envelope `{items, total, page, pageSize, totalPages}` with nest's `nextCursor`. `from`, `to` and `code` (comma-separated) filter as in v1; `category` (comma-separated) keeps the readings carrying any of those FHIR category codes. With `from`, a reading whose clinical time is more than an hour ahead of when it was stored is not found: the read skips the storage older than that, so it never waits on it. `pageSize` defaults to 10; above 200 it needs both `from` and `to`, and then reaches 10000. A page may start at most 10000 rows in; walk further with `cursor`. Each item is a flat timeline entry (`code`, `valueNumber`, `observedAt`, `category`, `valueSampledData`, `components`, `effectiveStart`, `effectiveEnd`, `deviceId`, …) with v1's `_id`, `id`, `patient`, `valueQuantity` and `createdAt` beside it. `fields=code,valueNumber` returns exactly those keys instead. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_observations:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can read. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `patientId` | string | Yes | The Signals patient id. | ### Query parameters [#query-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `page` | number | No | 1-based, as v1 paged. A page may start at most 10000 rows in; walk further with `cursor`. | | `pageSize` | number | No | v1's page size; defaults to 10. Wins over `limit` when both are sent. | | `from` | string | No | Inclusive lower bound on clinical time; a reading timed over an hour after it was stored is missed. | | `to` | string | No | Inclusive upper bound on the reading's clinical time. | | `code` | string | No | One LOINC code, or several separated by commas. | | `category` | string | No | One FHIR category code, or several separated by commas; a reading carrying any of them. | | `limit` | number | No | — | | `cursor` | string | No | — | | `fields` | string | No | Only these keys of each item, separated by commas (`code,valueNumber,observedAt`). Every key when absent. A chart reading a day of readings needs a few of them. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | One page of readings. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: No such patient in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. From Signals: A query parameter failed validation, a large page lacked `from`/`to`, or the page starts too deep. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/observation/:patientId' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Submit a reading by patient refId Canonical page: https://docs.ovok.com/signals/standalone/api/observations/submit-a-reading-by-patient-refid {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Submit a reading by patient refId [#submit-a-reading-by-patient-refid] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/observation` | The patient is `patientRefId` in the body, else `subject.reference` (`Patient/`). The body is a FHIR R4 Observation: `code`, `value[x]` (`valueQuantity`, `valueInteger`, `valueString`, `valueBoolean`, `valueDateTime`, `valueCodeableConcept`) or `dataAbsentReason`, and a combined device sample's vitals as `component[]` (each `code`, `value[x]`, optional `dataAbsentReason`). The clinical time is `effectiveDateTime`, `effectiveInstant` or `effectivePeriod.start`, else `issued`, else the server's receipt; `device` is `{reference, display}`; the first `identifier`'s `value` is stored as v1's `refId`. Other FHIR elements (`meta`, `extension`, `performer`, `interpretation`, `referenceRange`, …) are accepted and ignored. v1's `observedAt` (it wins over `effective[x]`), `refId`, string `dataAbsentReason` and `device.id` still work. A node with `dataAbsentReason` and no value is judged as carrying no value. `valueSampledData` is judged by its latest sample and stored whole. A `valueDateTime`, on the reading or a component, is judged and aggregated as epoch ms (`valueNumber`) and listed as sent. **History is never judged.** A reading whose `category` has a coding the tenant names as history (its `historyCategories`; the default pack's: `batch-data`, `statistics`, `presence-batch`, `derived`) is stored and deduplicated like any other, answered with no alerts, and never judged nor read by the rules. The caller must be one of the patient's submitters, admins included: a known patient it is not attached to is a 403, an unknown one a 404 with type `PATIENT_NOT_FOUND`. **Idempotent.** A reading is named by its first `identifier` (`system|value`), else by its clinical time, code, device and `refId`. A resend of one stored within the last hour is a 409 `DUPLICATE_READING` whose `data.observationId` is the stored reading, and is neither stored nor evaluated again. A reading with neither an identifier nor a clinical time is not deduplicated. Concurrent requests are batched server-side. With `Prefer: respond-sync` evaluation finishes first and the reply adds `alertIds`, `alerts` (`[{id, code}]`), `resolvedAlertIds` and `ruleCoverage`; without it `mode` is `async` and alerts are delivered by webhook. ### Through ovok [#through-ovok] - **Who can call it:** Submitter apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_observations:create`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. - Each reading counts its patient as monitored for billing. ## Request [#request] ### Body [#body] Required. Schema `V1ObservationByRefDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `patientRefId` | string | No | — | | `resourceType` | string | No | — | | `identifier` | array of object | No | — | | `identifier[].system` | string | No | — | | `identifier[].value` | string | No | — | | `refId` | string | No | — | | `status` | string | No | — | | `category` | array of object | No | Its codings' codes are stored; a code the tenant names in `historyCategories` makes the reading history: stored, never judged. | | `note` | object | No | Accepted as a plain string or as FHIR's `[{text, time}]` Annotations, which the mapper flattens to newline-joined text. Deliberately untyped: typing it as a string would reject real readings ovok sends today. | | `code` | object | Yes | — | | `code.coding` | array of object | No | — | | `code.text` | string | No | — | | `subject` | object | No | — | | `subject.reference` | string | No | — | | `subject.display` | string | No | — | | `component` | array of object | No | — | | `component[].code` | object | Yes | — | | `component[].dataAbsentReason` | object | No | — | | `component[].valueQuantity` | object | No | — | | `component[].valueSampledData` | object | No | — | | `component[].valueString` | string | No | — | | `component[].valueInteger` | number | No | — | | `component[].valueBoolean` | boolean | No | — | | `component[].valueDateTime` | string | No | — | | `component[].valueCodeableConcept` | object | No | — | | `device` | object | No | `id` (v1) or `reference` (FHIR) names the device. | | `dataAbsentReason` | object | No | v1's string or FHIR's CodeableConcept; untyped so that neither is refused. | | `observedAt` | string | No | — | | `effectiveDateTime` | string | No | — | | `effectiveInstant` | string | No | — | | `effectivePeriod` | object | No | Only `.start` and `.end` are read, as in v1. | | `issued` | string | No | — | | `valueQuantity` | object | No | — | | `valueQuantity.value` | number | No | — | | `valueQuantity.unit` | string | No | — | | `valueQuantity.system` | string | No | — | | `valueQuantity.code` | string | No | — | | `valueSampledData` | object | No | — | | `valueSampledData.origin` | object | No | — | | `valueSampledData.period` | number | No | — | | `valueSampledData.factor` | number | No | — | | `valueSampledData.lowerLimit` | number | No | — | | `valueSampledData.upperLimit` | number | No | — | | `valueSampledData.dimensions` | number | No | — | | `valueSampledData.data` | string | No | Space-separated samples, oldest first; `E`, `L` and `U` are no sample. | | `valueString` | string | No | — | | `valueInteger` | number | No | — | | `valueBoolean` | boolean | No | — | | `valueDateTime` | string | No | — | | `valueCodeableConcept` | object | No | — | | `valueCodeableConcept.coding` | array of object | No | — | | `valueCodeableConcept.text` | string | No | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The reading as stored, plus the ingest outcome. | | `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 your access covers only some patients and the call names none, or you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: No patient with that refId in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. From Signals: A resend of a reading already stored (`DUPLICATE_READING`, `data.observationId`); nothing was stored or evaluated. | | `415` | The body is not JSON. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. More than 100 patients are named. A patient is named by something other than a string. From Signals: The payload failed validation, or named no patient. | | `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`. From Signals: The evaluation backlog is full, or the readings could not be stored and judged (no database connection free in time, a lock timeout, a stalled database). Nothing was stored; resend after `Retry-After` (2 s). | | `504` | Signals did not answer in time. | ## Example [#example] ```bash curl --request POST 'https://api.sandbox.ovok.com/v1/signals/api/observation' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Submit a reading for a patient id Canonical page: https://docs.ovok.com/signals/standalone/api/observations/submit-a-reading-for-a-patient-id {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Submit a reading for a patient id [#submit-a-reading-for-a-patient-id] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/observation/{patientId}` | `subject` is ignored: the path names the patient. The body is a FHIR R4 Observation: `code`, `value[x]` (`valueQuantity`, `valueInteger`, `valueString`, `valueBoolean`, `valueDateTime`, `valueCodeableConcept`) or `dataAbsentReason`, and a combined device sample's vitals as `component[]` (each `code`, `value[x]`, optional `dataAbsentReason`). The clinical time is `effectiveDateTime`, `effectiveInstant` or `effectivePeriod.start`, else `issued`, else the server's receipt; `device` is `{reference, display}`; the first `identifier`'s `value` is stored as v1's `refId`. Other FHIR elements (`meta`, `extension`, `performer`, `interpretation`, `referenceRange`, …) are accepted and ignored. v1's `observedAt` (it wins over `effective[x]`), `refId`, string `dataAbsentReason` and `device.id` still work. A node with `dataAbsentReason` and no value is judged as carrying no value. `valueSampledData` is judged by its latest sample and stored whole. A `valueDateTime`, on the reading or a component, is judged and aggregated as epoch ms (`valueNumber`) and listed as sent. **History is never judged.** A reading whose `category` has a coding the tenant names as history (its `historyCategories`; the default pack's: `batch-data`, `statistics`, `presence-batch`, `derived`) is stored and deduplicated like any other, answered with no alerts, and never judged nor read by the rules. The caller must be one of the patient's submitters, admins included: a known patient it is not attached to is a 403, an unknown one a 404 with type `PATIENT_NOT_FOUND`. **Idempotent.** A reading is named by its first `identifier` (`system|value`), else by its clinical time, code, device and `refId`. A resend of one stored within the last hour is a 409 `DUPLICATE_READING` whose `data.observationId` is the stored reading, and is neither stored nor evaluated again. A reading with neither an identifier nor a clinical time is not deduplicated. Concurrent requests are batched server-side. With `Prefer: respond-sync` evaluation finishes first and the reply adds `alertIds`, `alerts` (`[{id, code}]`), `resolvedAlertIds` and `ruleCoverage`; without it `mode` is `async` and alerts are delivered by webhook. ### Through ovok [#through-ovok] - **Who can call it:** Submitter apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_observations:create`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. - Each reading counts its patient as monitored for billing. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `patientId` | string | Yes | The Signals patient id. | ### Body [#body] Required. Schema `V1ObservationDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `resourceType` | string | No | — | | `identifier` | array of object | No | — | | `identifier[].system` | string | No | — | | `identifier[].value` | string | No | — | | `refId` | string | No | — | | `status` | string | No | — | | `category` | array of object | No | Its codings' codes are stored; a code the tenant names in `historyCategories` makes the reading history: stored, never judged. | | `note` | object | No | Accepted as a plain string or as FHIR's `[{text, time}]` Annotations, which the mapper flattens to newline-joined text. Deliberately untyped: typing it as a string would reject real readings ovok sends today. | | `code` | object | Yes | — | | `code.coding` | array of object | No | — | | `code.text` | string | No | — | | `subject` | object | No | — | | `subject.reference` | string | No | — | | `subject.display` | string | No | — | | `component` | array of object | No | — | | `component[].code` | object | Yes | — | | `component[].dataAbsentReason` | object | No | — | | `component[].valueQuantity` | object | No | — | | `component[].valueSampledData` | object | No | — | | `component[].valueString` | string | No | — | | `component[].valueInteger` | number | No | — | | `component[].valueBoolean` | boolean | No | — | | `component[].valueDateTime` | string | No | — | | `component[].valueCodeableConcept` | object | No | — | | `device` | object | No | `id` (v1) or `reference` (FHIR) names the device. | | `dataAbsentReason` | object | No | v1's string or FHIR's CodeableConcept; untyped so that neither is refused. | | `observedAt` | string | No | — | | `effectiveDateTime` | string | No | — | | `effectiveInstant` | string | No | — | | `effectivePeriod` | object | No | Only `.start` and `.end` are read, as in v1. | | `issued` | string | No | — | | `valueQuantity` | object | No | — | | `valueQuantity.value` | number | No | — | | `valueQuantity.unit` | string | No | — | | `valueQuantity.system` | string | No | — | | `valueQuantity.code` | string | No | — | | `valueSampledData` | object | No | — | | `valueSampledData.origin` | object | No | — | | `valueSampledData.period` | number | No | — | | `valueSampledData.factor` | number | No | — | | `valueSampledData.lowerLimit` | number | No | — | | `valueSampledData.upperLimit` | number | No | — | | `valueSampledData.dimensions` | number | No | — | | `valueSampledData.data` | string | No | Space-separated samples, oldest first; `E`, `L` and `U` are no sample. | | `valueString` | string | No | — | | `valueInteger` | number | No | — | | `valueBoolean` | boolean | No | — | | `valueDateTime` | string | No | — | | `valueCodeableConcept` | object | No | — | | `valueCodeableConcept.coding` | array of object | No | — | | `valueCodeableConcept.text` | string | No | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The reading as stored, plus the ingest outcome. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: No such patient in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. From Signals: A resend of a reading already stored (`DUPLICATE_READING`, `data.observationId`); nothing was stored or evaluated. | | `415` | The body is not JSON. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. 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`. From Signals: The evaluation backlog is full, or the readings could not be stored and judged (no database connection free in time, a lock timeout, a stalled database). Nothing was stored; resend after `Retry-After` (2 s). | | `504` | Signals did not answer in time. | ## Example [#example] ```bash curl --request POST 'https://api.sandbox.ovok.com/v1/signals/api/observation/:patientId' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Submit several readings for one patient Canonical page: https://docs.ovok.com/signals/standalone/api/observations/submit-several-readings-for-one-patient {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Submit several readings for one patient [#submit-several-readings-for-one-patient] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/observation/{patientId}/batch` | `{observations: []}`, each as `POST /api/observation/:patientId` takes it. In one transaction, evaluated in the order given. Answers v1's array, one entry per reading in request order: the reading as stored, or for a resend the 409 `DUPLICATE_READING` error body in its place. An array has nowhere to carry the ingest outcome, so a caller that needs `alertIds` posts them singly. The body is a FHIR R4 Observation: `code`, `value[x]` (`valueQuantity`, `valueInteger`, `valueString`, `valueBoolean`, `valueDateTime`, `valueCodeableConcept`) or `dataAbsentReason`, and a combined device sample's vitals as `component[]` (each `code`, `value[x]`, optional `dataAbsentReason`). The clinical time is `effectiveDateTime`, `effectiveInstant` or `effectivePeriod.start`, else `issued`, else the server's receipt; `device` is `{reference, display}`; the first `identifier`'s `value` is stored as v1's `refId`. Other FHIR elements (`meta`, `extension`, `performer`, `interpretation`, `referenceRange`, …) are accepted and ignored. v1's `observedAt` (it wins over `effective[x]`), `refId`, string `dataAbsentReason` and `device.id` still work. A node with `dataAbsentReason` and no value is judged as carrying no value. `valueSampledData` is judged by its latest sample and stored whole. A `valueDateTime`, on the reading or a component, is judged and aggregated as epoch ms (`valueNumber`) and listed as sent. **History is never judged.** A reading whose `category` has a coding the tenant names as history (its `historyCategories`; the default pack's: `batch-data`, `statistics`, `presence-batch`, `derived`) is stored and deduplicated like any other, answered with no alerts, and never judged nor read by the rules. The caller must be one of the patient's submitters, admins included: a known patient it is not attached to is a 403, an unknown one a 404 with type `PATIENT_NOT_FOUND`. **Idempotent.** A reading is named by its first `identifier` (`system|value`), else by its clinical time, code, device and `refId`. A resend of one stored within the last hour is a 409 `DUPLICATE_READING` whose `data.observationId` is the stored reading, and is neither stored nor evaluated again. A reading with neither an identifier nor a clinical time is not deduplicated. Concurrent requests are batched server-side. With `Prefer: respond-sync` evaluation finishes first and the reply adds `alertIds`, `alerts` (`[{id, code}]`), `resolvedAlertIds` and `ruleCoverage`; without it `mode` is `async` and alerts are delivered by webhook. ### Through ovok [#through-ovok] - **Who can call it:** Submitter apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_observations:create`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. - Each reading counts its patient as monitored for billing. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `patientId` | string | Yes | The Signals patient id. | ### Body [#body] Required. Schema `V1ObservationBatchDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `observations` | array of object | Yes | — | | `observations[].resourceType` | string | No | — | | `observations[].identifier` | array of object | No | — | | `observations[].refId` | string | No | — | | `observations[].status` | string | No | — | | `observations[].category` | array of object | No | Its codings' codes are stored; a code the tenant names in `historyCategories` makes the reading history: stored, never judged. | | `observations[].note` | object | No | Accepted as a plain string or as FHIR's `[{text, time}]` Annotations, which the mapper flattens to newline-joined text. Deliberately untyped: typing it as a string would reject real readings ovok sends today. | | `observations[].code` | object | Yes | — | | `observations[].subject` | object | No | — | | `observations[].component` | array of object | No | — | | `observations[].device` | object | No | `id` (v1) or `reference` (FHIR) names the device. | | `observations[].dataAbsentReason` | object | No | v1's string or FHIR's CodeableConcept; untyped so that neither is refused. | | `observations[].observedAt` | string | No | — | | `observations[].effectiveDateTime` | string | No | — | | `observations[].effectiveInstant` | string | No | — | | `observations[].effectivePeriod` | object | No | Only `.start` and `.end` are read, as in v1. | | `observations[].issued` | string | No | — | | `observations[].valueQuantity` | object | No | — | | `observations[].valueSampledData` | object | No | — | | `observations[].valueString` | string | No | — | | `observations[].valueInteger` | number | No | — | | `observations[].valueBoolean` | boolean | No | — | | `observations[].valueDateTime` | string | No | — | | `observations[].valueCodeableConcept` | object | No | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | Per reading, in request order: the reading as stored, or a resend's 409 body. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: No such patient in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. 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`. From Signals: The evaluation backlog is full, or the readings could not be stored and judged (no database connection free in time, a lock timeout, a stalled database). Nothing was stored; resend after `Retry-After` (2 s). | | `504` | Signals did not answer in time. | ## Example [#example] ```bash curl --request POST 'https://api.sandbox.ovok.com/v1/signals/api/observation/:patientId/batch' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Read the config status of many patients Canonical page: https://docs.ovok.com/signals/standalone/api/patient-config/read-the-config-status-of-many-patients {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Read the config status of many patients [#read-the-config-status-of-many-patients] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/patient/config/bulk-status` | Each patient's `configUpdatedAt` and trigger codes, so a caller can confirm a push landed without re-reading every trigger; `triggerFingerprints` adds what each rule says. Exactly one row per requested id, in the order asked. An id that resolves to nothing answers `refId: null` with no codes, as v1 did. A POST because the id list is the request; it writes nothing. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_config:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can read. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Body [#body] Required. Schema `V1BulkStatusDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `ids` | array of string | Yes | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | One status row per requested id, in request order. | | `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 your access covers only some patients and the call names none. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. More than 100 patients are named. A patient is named by something other than a string. 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 POST 'https://api.sandbox.ovok.com/v1/signals/api/patient/config/bulk-status' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Write a different config to each of many patients Canonical page: https://docs.ovok.com/signals/standalone/api/patient-config/write-a-different-config-to-each-of-many-patients {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Write a different config to each of many patients [#write-a-different-config-to-each-of-many-patients] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/patient/config/batch` | The per-patient form, each entry with its own triggers, flags, `metadata` and `resolvedAt`. `results[]` has v1's `{id, matched, modified}` per entry; `staleIgnored` and `misses` are additions. ### 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. - A patient stamped with another project is refused. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Body [#body] Required. Schema `V1BatchConfigDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `patients` | array of object | Yes | — | | `patients[].id` | string | Yes | Signals patient id, or the caller's refId. | | `patients[].triggers` | array of object | No | — | | `patients[].metadata` | object | No | Labels for this patient, merged not replaced. Whatever key the notification feed is queried by must appear here, or the patient is invisible to it. | | `patients[].resolvedAt` | string | No | ISO-8601 instant at which this entry's configuration was COMPUTED — not when it was sent. Per entry, because one batch can mix a fresh individual save with an older org fan-out slice. A push carrying one is ignored when the patient already holds a configuration resolved strictly later; omitting it applies the entry unconditionally. | | `patients[].alertIfEmpty` | boolean | No | — | | `patients[].alertIfNote` | boolean | No | — | | `patients[].alertInactiveDays` | number | No | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | Match and modify totals, per-patient results, and the ids that missed. | | `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 a patient is stamped with another project, or your access covers only some patients and the call names none, or you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. More than 100 patients are named. A patient is named by something other than a string. 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 POST 'https://api.sandbox.ovok.com/v1/signals/api/patient/config/batch' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Write one config to many patients Canonical page: https://docs.ovok.com/signals/standalone/api/patient-config/write-one-config-to-many-patients {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Write one config to many patients [#write-one-config-to-many-patients] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/patient/config` | Applies the same triggers, flags and metadata to every id named. An id may be the Signals id or the `refId`. Unknown ids are reported in `misses[]` rather than failing the batch. `modifiedCount` counts patients where a row actually changed; `status.triggerWrites` gives the row counts behind it. Trigger `metadata` is MERGED and left untouched when absent. Send `resolvedAt` (the instant the configuration was COMPUTED, not sent) to have this push refused rather than applied when the patient already carries a configuration resolved strictly later. Refusal is a silent no-op reported as `staleIgnoredCount`, never an error. Omitting it applies the push unconditionally. ### 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. - A patient stamped with another project is refused. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Body [#body] Required. Schema `V1ConfigDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `resolvedAt` | string | No | ISO-8601 instant at which this configuration was COMPUTED (not sent). A push carrying one is ignored if the patient already has a configuration resolved strictly later. Optional: a push without it is applied unconditionally, exactly as before. | | `triggers` | array of object | No | — | | `triggers[].code` | string | Yes | LOINC code. Unique per patient. | | `triggers[].system` | string | No | — | | `triggers[].display` | string | No | — | | `triggers[].valueKey` | string | No | Key the rule reads the reading under. | | `triggers[].constants` | object | No | Named values the rule compares against, e.g. `{ "low": 50, "high": 110 }`. | | `triggers[].logic` | object | No | json-logic. May return a boolean, a string used as the message, or an object `{alert, value, message}` — the shape the ECH rules use. | | `triggers[].delete` | boolean | No | Remove this trigger instead of writing it. The patient stops being alerted on the code. | | `triggers[].metadata` | object | No | Free-form routing labels, MERGED into whatever is already there and left untouched when absent — so a push that omits them cannot un-route a trigger. Signals does not interpret the keys. A caller managing thresholds at two levels records which level owns each trigger here, so a group-wide write matches one label and cannot clobber a per-patient exception. | | `ids` | array of string | Yes | — | | `metadata` | object | No | Stamped onto the Patient rows named by `ids`, merged not replaced. | | `alertIfEmpty` | boolean | No | — | | `alertIfNote` | boolean | No | — | | `alertInactiveDays` | number | No | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | v1's envelope: the ids echoed back and the match and modify counts. | | `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 a patient is stamped with another project, or your access covers only some patients and the call names none, or you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. More than 100 patients are named. A patient is named by something other than a string. 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 POST 'https://api.sandbox.ovok.com/v1/signals/api/patient/config' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Attach patients to a submitter Canonical page: https://docs.ovok.com/signals/standalone/api/patients/attach-patients-to-a-submitter {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Attach patients to a submitter [#attach-patients-to-a-submitter] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/submitter/{id}/patients` | Grants the client permission to post readings for those patients. Unknown patient ids are skipped, so a caller can re-post a superset of ids without a 404. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:update`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The client's `clientId`: the value a patient's `submitters`/`subscribers` hold. | ### Body [#body] Required. Schema `AssociatePatientsDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `patients` | array of string | Yes | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | `matched`: patients newly attached; `associated`: every requested patient now attached. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 your access covers only some patients and the call names none, or you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: `CLIENT_NOT_FOUND`: no SUBMITTER or ADMIN with that `clientId` in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. More than 100 patients are named. A patient is named by something other than a string. 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 POST 'https://api.sandbox.ovok.com/v1/signals/api/submitter/:id/patients' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Attach patients to a subscriber Canonical page: https://docs.ovok.com/signals/standalone/api/patients/attach-patients-to-a-subscriber {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Attach patients to a subscriber [#attach-patients-to-a-subscriber] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/subscriber/{id}/patients` | Grants the client permission to read those patients' records and receive their alert webhooks. Unknown patient ids are skipped, so a caller can re-post a superset of ids without a 404. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:update`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The client's `clientId`: the value a patient's `submitters`/`subscribers` hold. | ### Body [#body] Required. Schema `AssociatePatientsDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `patients` | array of string | Yes | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | `associated`: patients newly attached; `patients`: every requested patient now attached. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 your access covers only some patients and the call names none, or you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: `CLIENT_NOT_FOUND`: no SUBSCRIBER with that `clientId` in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. More than 100 patients are named. A patient is named by something other than a string. 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 POST 'https://api.sandbox.ovok.com/v1/signals/api/subscriber/:id/patients' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Create patients Canonical page: https://docs.ovok.com/signals/standalone/api/patients/create-patients {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Create patients [#create-patients] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/patient` | Upserts on `refId`: posting a patient that already exists updates it rather than duplicating it, so a replayed provisioning run is safe. Each entry's `config` — flags and triggers — is applied in the same call, and `metadata` is merged. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:update`. Project admins have every capability; client applications get no admin bypass. - ovok adds your project's submitter to each new patient and stamps `metadata.project` with your project. Sending `config` also needs `signals_config:update` and `signals_silence:update`. New patients count toward your plan's monitored-patient cap. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Body [#body] Required. Schema `V1CreatePatientsDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `patients` | array of object | Yes | — | | `patients[].config` | object | No | Initial config, applied in the same call: `alertIfEmpty`, `alertIfNote`, `alertInactiveDays`, and `triggers` in the same shape as V1ConfigTriggerSchema, including its `metadata` stamp. | | `patients[].id` | string | No | — | | `patients[].name` | string | No | — | | `patients[].refId` | string | Yes | — | | `patients[].submitters` | array of string | No | — | | `patients[].subscribers` | array of string | No | — | | `patients[].metadata` | object | No | — | | `patients[].email` | string | No | — | | `patients[].bsn` | string | No | — | | `patients[].umoId` | string | No | — | | `patients[].dateOfBirth` | string | No | — | | `patients[].tags` | object | No | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The patients as stored, in request order. | | `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. | | `402` | The new patients would go past your plan's monitored-patient cap. | | `403` | ovok refused the call: you lack a capability this route needs, or your session has no project, or a patient is stamped with another project, or your access covers only some patients and the call names none, or you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `415` | The body is not JSON. | | `422` | A number in the body is out of range. A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. More than 100 patients are named. A patient is named by something other than a string. 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 POST 'https://api.sandbox.ovok.com/v1/signals/api/patient' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Delete a patient Canonical page: https://docs.ovok.com/signals/standalone/api/patients/delete-a-patient {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Delete a patient [#delete-a-patient] | Method | Path | | --- | --- | | `DELETE` | `/v1/signals/api/patient/{id}` | Deletes the patient with its triggers, alerts, episodes and readings. This can't be undone through the API. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:delete`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can delete. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The Signals patient id. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | Deleted: the id of the patient that is gone. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 you can read a patient the call names but not delete it. | | `404` | A patient the call names is not one you can read. From Signals: No such patient in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. | | `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 DELETE 'https://api.sandbox.ovok.com/v1/signals/api/patient/:id' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Detach a patient from a submitter Canonical page: https://docs.ovok.com/signals/standalone/api/patients/detach-a-patient-from-a-submitter {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Detach a patient from a submitter [#detach-a-patient-from-a-submitter] | Method | Path | | --- | --- | | `DELETE` | `/v1/signals/api/submitter/{id}/patients/{patientId}` | The submitter may no longer post readings for the patient. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:update`. Project admins have every capability; client applications get no admin bypass. - Your project's own submitter stays attached to its patients. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The client's `clientId`: the value a patient's `submitters`/`subscribers` hold. | | `patientId` | string | Yes | The Signals patient id. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The pair that was detached. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 submitter is your project's own, or you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: The submitter was not attached to that patient. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. | | `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 DELETE 'https://api.sandbox.ovok.com/v1/signals/api/submitter/:id/patients/:patientId' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Detach a patient from a subscriber Canonical page: https://docs.ovok.com/signals/standalone/api/patients/detach-a-patient-from-a-subscriber {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Detach a patient from a subscriber [#detach-a-patient-from-a-subscriber] | Method | Path | | --- | --- | | `DELETE` | `/v1/signals/api/subscriber/{id}/patients/{patientId}` | The subscriber no longer reads the patient's records or receives its alerts. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:update`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The client's `clientId`: the value a patient's `submitters`/`subscribers` hold. | | `patientId` | string | Yes | The Signals patient id. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The pair that was detached. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: The subscriber was not attached to that patient. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. | | `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 DELETE 'https://api.sandbox.ovok.com/v1/signals/api/subscriber/:id/patients/:patientId' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Get one patient Canonical page: https://docs.ovok.com/signals/standalone/api/patients/get-one-patient {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Get one patient [#get-one-patient] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/patient/{id}` | The patient with its config, triggers keyed by code. A SUBMITTER or SUBSCRIBER reads only patients it is attached to. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps and Submitter apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can read. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The Signals patient id. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The patient. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: No such patient in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/patient/:id' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # List a submitter's patients Canonical page: https://docs.ovok.com/signals/standalone/api/patients/list-a-submitters-patients {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # List a submitter's patients [#list-a-submitters-patients] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/submitter/{id}/patients` | The ids of the patients in this tenant the submitter may post readings for. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:read`. Project admins have every capability; client applications get no admin bypass. - 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] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The client's `clientId`: the value a patient's `submitters`/`subscribers` hold. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | `{ patients: [id] }`. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 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. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/submitter/:id/patients' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # List a subscriber's patients Canonical page: https://docs.ovok.com/signals/standalone/api/patients/list-a-subscribers-patients {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # List a subscriber's patients [#list-a-subscribers-patients] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/subscriber/{id}/patients` | The ids of the patients in this tenant the subscriber reads and receives alerts for. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:read`. Project admins have every capability; client applications get no admin bypass. - 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] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The client's `clientId`: the value a patient's `submitters`/`subscribers` hold. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | `{ patients: [id] }`. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 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. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/subscriber/:id/patients' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # List patients Canonical page: https://docs.ovok.com/signals/standalone/api/patients/list-patients {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # List patients [#list-patients] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/patient` | Scoped to what the caller may see: a MANAGER gets the tenant, a SUBMITTER or SUBSCRIBER only the patients it is attached to. Newest first. v1's paginate envelope, driven by `page` and `limit` (default 10). A page may start at most 10000 rows in; past that, walk with the keyset `cursor`: pass `nextCursor` back verbatim, and `null` means the last page. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps and Submitter apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), name them with `ids`, each one you can read, at most 100. Signals then pages over just those patients, so pages and totals stay true. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Query parameters [#query-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `limit` | number | No | Page size. Defaults to 10, as in v1; at most 1000. | | `ids` | array of string | No | Only these patients, by Signals id. Repeat the parameter or separate with commas. | | `sort` | string | No | Accepted for v1 callers and ignored, as v1 ignored it. Newest first, always. | | `page` | number | No | 1-based, as v1 paged. A page may start at most 10000 rows in; walk further with `cursor`. | | `cursor` | string | No | Opaque keyset cursor: a previous answer's `nextCursor`, passed back verbatim. | | `tags[key]` | string | No | v1's tag filter: only patients whose `tags.key` equals one of the comma-separated values, or holds one in an array. Repeat with other keys to require them all. Keys are alphanumeric; `tags.key=` is accepted too. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | One page of patients, each with its config. | | `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 your access covers only some patients and the call names none. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. More than 100 patients are named. From Signals: A query parameter failed validation, or the page starts too deep. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/patient' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Resolve refIds to Signals ids Canonical page: https://docs.ovok.com/signals/standalone/api/patients/resolve-refids-to-signals-ids {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Resolve refIds to Signals ids [#resolve-refids-to-signals-ids] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/patient/ids` | An object from each `patientRefId` this tenant holds to its Signals id. A refId the tenant does not hold is left out rather than failing the request. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), name them with `patientRefId`, each one you can read, at most 100. Signals then pages over just those patients, so pages and totals stay true. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Query parameters [#query-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `patientRefId` | array of string | Yes | The caller's refIds to resolve. Repeat the parameter or separate with commas. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | An object mapping each found `refId` to its Signals id: `{ [refId]: id }`. | | `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 your access covers only some patients and the call names none. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. More than 100 patients are named. From Signals: `patientRefId` was absent or too long a list. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/patient/ids' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Update a patient Canonical page: https://docs.ovok.com/signals/standalone/api/patients/update-a-patient {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Update a patient [#update-a-patient] | Method | Path | | --- | --- | | `POST` | `/v1/signals/api/patient/{id}` | Only the fields present are changed; `metadata` is merged, not replaced. Answered with the v1 document. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:update`. Project admins have every capability; client applications get no admin bypass. - When you send `submitters` or `metadata`, ovok keeps your project's submitter and stamp in them. Sending `alertsPaused`, `alertIfEmpty`, `alertIfNote` or `alertInactiveDays` also needs `signals_config:update` and `signals_silence:update`. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient, and one a `refId` in the body names, must be ones you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The Signals patient id. | ### Body [#body] Required. Schema `UpdatePatientDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `refId` | string | No | v1 let an update move the patient to a new `refId`; one another patient holds is a 409. | | `name` | string | No | — | | `submitters` | array of string | No | — | | `subscribers` | array of string | No | — | | `alertIfEmpty` | boolean | No | — | | `alertIfNote` | boolean | No | — | | `alertInactiveDays` | number | No | — | | `alertsPaused` | boolean | No | — | | `metadata` | object | No | Merged into the existing metadata, not replaced — a write that omits `project` does not clear the stamp. | | `email` | string | No | — | | `bsn` | string | No | — | | `umoId` | string | No | — | | `dateOfBirth` | string | No | — | | `tags` | object | No | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The patient as it now stands. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 a patient is stamped with another project, or you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: No such patient in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. From Signals: Another patient in this tenant already has that `refId`. | | `415` | The body is not JSON. | | `422` | A number in the body is out of range. A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. 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 POST 'https://api.sandbox.ovok.com/v1/signals/api/patient/:id' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Get a patient's own rule settings Canonical page: https://docs.ovok.com/signals/standalone/api/settings/get-a-patients-own-rule-settings {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Get a patient's own rule settings [#get-a-patients-own-rule-settings] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/patient/{id}/settings` | `{}` when none were written. Signals stores `settings` as given and reads it only through the triggers it holds (`triggers`, the home's and the resident's own): what each other key means is theirs, so the object is checked for shape and size only. The default pack reads `bands` — per code `{ low?, high? }`, `{ mode: 'baseline', pct, low?, high? }` (outside either band fires; a patient's own baseline band with no sides of its own is judged alone) or `"NO_THRESHOLD"` — and `outOfBed`: `{ limitSeconds, enabled?, returnSeconds?, window?: { start: 'HH:MM', end: 'HH:MM', timeZone } }`. A patient's own key wins over the org's; extra keys are ignored. See tech/RULES-ENGINE.md. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_config:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can read. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The Signals patient id. | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The settings. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: No such patient in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. | | `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/patient/:id/settings' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Get an org's rule settings Canonical page: https://docs.ovok.com/signals/standalone/api/settings/get-an-orgs-rule-settings {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Get an org's rule settings [#get-an-orgs-rule-settings] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/settings/org` | This route is deprecated. The description below names its successor. Deprecated: a tenant's rule settings are `orgSettings` on `GET` and `PATCH /api/tenant`. This route still serves the per-project rows of a tenant several projects share. The settings for `project`, or the tenant-wide row without it. `{}` when none were written. Signals stores `settings` as given and reads it only through the triggers it holds (`triggers`, the home's and the resident's own): what each other key means is theirs, so the object is checked for shape and size only. The default pack reads `bands` — per code `{ low?, high? }`, `{ mode: 'baseline', pct, low?, high? }` (outside either band fires; a patient's own baseline band with no sides of its own is judged alone) or `"NO_THRESHOLD"` — and `outOfBed`: `{ limitSeconds, enabled?, returnSeconds?, window?: { start: 'HH:MM', end: 'HH:MM', timeZone } }`. A patient's own key wins over the org's; extra keys are ignored. See tech/RULES-ENGINE.md. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_config:read`. Project admins have every capability; client applications get no admin bypass. - Your tenant keeps one org row, the tenant-wide one, so `project` isn't taken. - Deprecated. Use `/v1/signals/api/tenant`. ## Request [#request] No parameters or body. ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The settings. | | `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. 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. | | `422` | `project` was sent, or `resolvedAt` is more than 5 minutes ahead of now. From Signals: `project` is empty or longer than 200 characters. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/settings/org' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # Replace a patient's own rule settings Canonical page: https://docs.ovok.com/signals/standalone/api/settings/replace-a-patients-own-rule-settings {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Replace a patient's own rule settings [#replace-a-patients-own-rule-settings] | Method | Path | | --- | --- | | `PUT` | `/v1/signals/api/patient/{id}/settings` | Replaced whole. The triggers read them beside the org's, as `settings.individual`. Audited as `UPDATE_PATIENT_SETTINGS`. A body whose `settings` has no `triggers` key keeps the stored `triggers` (the home defaults seeded by Signals, or triggers pushed through the config routes); a body that sends `triggers`, `{}` included, replaces them. The body may carry `resolvedAt` (ISO 8601), when the caller resolved this write: it lands only over a stored write resolved earlier, or stored without one, and is otherwise refused 409 `STALE_SETTINGS` with nothing written or audited. A write without `resolvedAt` always lands and keeps the stored stamp. Signals stores `settings` as given and reads it only through the triggers it holds (`triggers`, the home's and the resident's own): what each other key means is theirs, so the object is checked for shape and size only. The default pack reads `bands` — per code `{ low?, high? }`, `{ mode: 'baseline', pct, low?, high? }` (outside either band fires; a patient's own baseline band with no sides of its own is judged alone) or `"NO_THRESHOLD"` — and `outOfBed`: `{ limitSeconds, enabled?, returnSeconds?, window?: { start: 'HH:MM', end: 'HH:MM', timeZone } }`. A patient's own key wins over the org's; extra keys are ignored. See tech/RULES-ENGINE.md. ### 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. - `resolvedAt` may be at most 5 minutes ahead of now. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. ## Request [#request] ### Path parameters [#path-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The Signals patient id. | ### Body [#body] Required. Schema `WriteStampedSettingsDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `resolvedAt` | string | No | — | | `settings` | object | Yes | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The settings as stored. | | `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. 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 you can read a patient the call names but not update it. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. | | `404` | A patient the call names is not one you can read. From Signals: No such patient in this tenant. | | `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. From Signals: A write resolved no later than the stored one (`STALE_SETTINGS`); nothing was written. | | `415` | The body is not JSON. | | `422` | `resolvedAt` is more than 5 minutes ahead of now. A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. From Signals: `settings` is missing, is not a plain object or is over 64 KiB, or `resolvedAt` is invalid. | | `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 PUT 'https://api.sandbox.ovok.com/v1/signals/api/patient/:id/settings' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Replace an org's rule settings Canonical page: https://docs.ovok.com/signals/standalone/api/settings/replace-an-orgs-rule-settings {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Replace an org's rule settings [#replace-an-orgs-rule-settings] | Method | Path | | --- | --- | | `PUT` | `/v1/signals/api/settings/org` | This route is deprecated. The description below names its successor. Deprecated: a tenant's rule settings are `orgSettings` on `GET` and `PATCH /api/tenant`. This route still serves the per-project rows of a tenant several projects share. Replaces the settings for `project`, or the tenant-wide row without it, whole. A patient whose `metadata.project` has a row reads that row; any other patient reads the tenant-wide row. The two are not merged. A tenant-wide write first makes a tenant's only project row its tenant-wide row, as `PATCH /api/tenant` does. Audited as `UPDATE_ORG_SETTINGS`. With `ifAbsent=true` the row is created only when none exists and never replaced, so a default seeded at enrolment cannot overwrite a concurrent save; the answer adds `created` and carries the stored document either way, and only a creation is audited. A body whose `settings` has no `triggers` key keeps the stored `triggers` (the home defaults seeded by Signals, or triggers pushed through the config routes); a body that sends `triggers`, `{}` included, replaces them. The body may carry `resolvedAt` (ISO 8601), when the caller resolved this write: it lands only over a stored write resolved earlier, or stored without one, and is otherwise refused 409 `STALE_SETTINGS` with nothing written or audited. A write without `resolvedAt` always lands and keeps the stored stamp. Signals stores `settings` as given and reads it only through the triggers it holds (`triggers`, the home's and the resident's own): what each other key means is theirs, so the object is checked for shape and size only. The default pack reads `bands` — per code `{ low?, high? }`, `{ mode: 'baseline', pct, low?, high? }` (outside either band fires; a patient's own baseline band with no sides of its own is judged alone) or `"NO_THRESHOLD"` — and `outOfBed`: `{ limitSeconds, enabled?, returnSeconds?, window?: { start: 'HH:MM', end: 'HH:MM', timeZone } }`. A patient's own key wins over the org's; extra keys are ignored. See tech/RULES-ENGINE.md. ### 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. - Your tenant keeps one org row, the tenant-wide one, so `project` isn't taken. - 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. - Deprecated. Use `/v1/signals/api/tenant`. ## Request [#request] ### Query parameters [#query-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `ifAbsent` | boolean | No | Create the row only when none exists, never replace one: a default seeded at enrolment must not overwrite a concurrent save of the home. | ### Body [#body] Required. Schema `WriteStampedSettingsDto`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `resolvedAt` | string | No | — | | `settings` | object | Yes | — | ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The settings as stored, kept `triggers` included (with `created` under `ifAbsent`). | | `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 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 write resolved no later than the stored one (`STALE_SETTINGS`); nothing was written. | | `415` | The body is not JSON. | | `422` | `project` was sent, or `resolvedAt` is more than 5 minutes ahead of now. From Signals: `settings` is missing, is not a plain object or is over 64 KiB, or `project` or `resolvedAt` is invalid. | | `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 PUT 'https://api.sandbox.ovok.com/v1/signals/api/settings/org' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" \ --header 'Content-Type: application/json' \ --data @body.json ``` # Get the caller's tenant Canonical page: https://docs.ovok.com/signals/standalone/api/tenants/get-the-callers-tenant {/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */} # Get the caller's tenant [#get-the-callers-tenant] | Method | Path | | --- | --- | | `GET` | `/v1/signals/api/tenant` | The tenant is resolved from the credential; there is no id to pass. `orgSettings` is its tenant-wide rule settings, `{}` when none were written. ### Through ovok [#through-ovok] - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_config:read`. Project admins have every capability; client applications get no admin bypass. ## Request [#request] No parameters or body. ## Responses [#responses] | Status | Meaning | | --- | --- | | `200` | The tenant, its feature switches and its rule settings. | | `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. 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. | | `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 GET 'https://api.sandbox.ovok.com/v1/signals/api/tenant' \ --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}" ``` # 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` | `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 ``` # Signals standalone Canonical page: https://docs.ovok.com/signals/standalone Use Signals' own API through Ovok. You keep your patients and readings in your own system, send them to Signals under your own ids, and read back the alerts Signals raises. You need no FHIR data and no Signals credentials: Ovok holds them and scopes every call to your project. Every route is Signals' path under `/v1/signals/api`. For example, Signals' `GET /api/alert` is `GET /v1/signals/api/alert`. The [API reference](#api-reference) lists each route Ovok serves; any other path answers `404`. ## Before you start [#before-you-start] | Requirement | Details | | --- | --- | | Your own Signals tenant | Your project needs a Signals tenant of its own. A project on the shared tenant gets `409` `SIGNALS_TENANT_NOT_OWN`. | | Standalone only? | Switch [`SIGNALS_SEND_AUTO` and `SIGNALS_ANNOTATE_OBSERVATIONS`](/signals/with-ovok/settings) off. Both are on by default, and annotations would write a FHIR `DetectedIssue` for each of your alerts, pointing at a `Patient` that does not exist. | | Base URL | `https://api.sandbox.ovok.com/v1/signals/api` in the sandbox. | | Authentication | An Ovok access token as `Authorization: Bearer`, or a client application's id and secret as HTTP Basic. | | Capabilities | The caller's access policy needs the `signals_*` rows each route names. See [Signals route policies](/access-policies/signals). | ## App types [#app-types] Signals has three roles: a manager runs the tenant, a submitter posts readings, and a subscriber receives webhooks. In Ovok, create a **Manager** or **Submitter** application in the Console (Applications). Its access policy is made from the routes that role may call, so it holds exactly those capabilities. | App type | Signals role | What it can call | | --- | --- | --- | | Manager | `MANAGER` | Every route except submitting readings: patients, configs, alerts, settings, users, webhooks and events. | | Submitter | `SUBMITTER` | Submitting readings, and reading patients. | A manager application answers `403` when it posts a reading: use a submitter application for that. Subscribers are not Ovok applications. You create them through the API, and they never sign in; see [Webhooks](/signals/standalone/webhooks). Project admins pass every capability check. Client applications never get that bypass, even when marked as admins: they need the capabilities in their own policy. ## What Ovok adds to each call [#what-ovok-adds-to-each-call] Bodies and answers pass through as Signals sends them, with these exceptions. | Area | What Ovok does | | --- | --- | | Project scope | Alert reads and acknowledgements are pinned to your project: Ovok sets `project`, and naming another project answers `403`. | | New patients | Ovok adds your project's submitter to each new patient and stamps `metadata.project` with your project, so your submitter can post their readings and their alerts show in your project. | | Alerting changes | Writing a patient's `config`, or `alertsPaused`, `alertIfEmpty`, `alertIfNote` or `alertInactiveDays`, also needs `signals_config:update` and `signals_silence:update`. | | Tenant writes | `PATCH /tenant` takes only `orgSettings`, `resolvedAt` and `settings.episodicAlerts`. Any other field answers `403`. | | Users | Only subscribers are created, changed or deleted. Ovok generates their id and Signals login. | | Billing | Patients you create count toward your plan's monitored-patient cap; past it, the create answers `402`. Each accepted reading counts its patient as monitored. | | Bodies | Bodies must be JSON (`415` otherwise). On patient create, patient update and subscriber create, which Ovok rewrites, a number out of range answers `422`. | | Deprecations | `GET` and `PUT /settings/org` carry `Deprecation` and `Sunset` headers. Use `orgSettings` on `PATCH /tenant` instead. | ### Errors [#errors] Errors come in two shapes. Ovok's own refusals are [Problem Details](/errors) (`application/problem+json`): a missing token (`401`), a missing capability or another project (`403`), no tenant of your own (`409`), and the cap (`402`). Signals' own refusals, such as a validation failure or an unknown patient, keep Signals' JSON shape. When Signals cannot be reached, Ovok answers `502`, `503` with `Retry-After`, or `504` on a timeout. Signals' own answers, `5xx` included, come back as Signals sent them, with one exception: Signals never refuses your call with `401`. If it rejects Ovok's own credential, you get `502`. ## Quickstart [#quickstart] These calls give your tenant a heart-rate band, create a patient, post a reading above the band and read the alert it raises. Set `OVOK_MANAGER_ID`/`OVOK_MANAGER_SECRET` and `OVOK_SUBMITTER_ID`/`OVOK_SUBMITTER_SECRET` to your two applications. ### 1. Set a heart-rate band [#1-set-a-heart-rate-band] Signals' default rules judge heart rate (LOINC `8867-4`) against a band, and a new tenant has none, so a reading raises nothing yet. Set one for the whole tenant: ```bash curl --request PATCH 'https://api.sandbox.ovok.com/v1/signals/api/tenant' \ --user "${OVOK_MANAGER_ID}:${OVOK_MANAGER_SECRET}" \ --header 'Content-Type: application/json' \ --data '{"orgSettings":{"bands":{"8867-4":{"low":40,"high":110}}}}' ``` `orgSettings` is merged by key. A patient's own band, set with [`PUT /patient/:id/settings`](/signals/standalone/api/settings/replace-a-patients-own-rule-settings), wins over the tenant's. If a breaching reading still raises nothing, check the tenant's triggers with [`GET /tenant`](/signals/standalone/api/tenants/get-the-callers-tenant). ### 2. Create a patient [#2-create-a-patient] `refId` is your own id for the patient. ```bash curl --request POST 'https://api.sandbox.ovok.com/v1/signals/api/patient' \ --user "${OVOK_MANAGER_ID}:${OVOK_MANAGER_SECRET}" \ --header 'Content-Type: application/json' \ --data '{"patients":[{"refId":"resident-001","name":"Resident 001"}]}' ``` The answer lists the patients as stored, each with its Signals `id`. Creating the same `refId` again updates it rather than duplicating it. ### 3. Post a reading [#3-post-a-reading] The body is a FHIR R4 Observation. Name the patient with `patientRefId`. ```bash curl --request POST 'https://api.sandbox.ovok.com/v1/signals/api/observation' \ --user "${OVOK_SUBMITTER_ID}:${OVOK_SUBMITTER_SECRET}" \ --header 'Content-Type: application/json' \ --data '{ "patientRefId": "resident-001", "identifier": [{ "value": "reading-0001" }], "code": { "coding": [{ "system": "http://loinc.org", "code": "8867-4" }] }, "valueQuantity": { "value": 132, "unit": "/min" }, "effectiveDateTime": "2026-10-25T08:00:00Z" }' ``` Signals judges the reading before it answers. The answer lists the alerts it raised only if you send `Prefer: respond-sync`, and then no webhook is sent for them; otherwise read them with `GET /alert` or receive them by [webhook](/signals/standalone/webhooks). The first `identifier` is stored as the reading's `refId`; sending the same one again within an hour answers `409` `DUPLICATE_READING`. ### 4. Read the alerts [#4-read-the-alerts] ```bash curl --get 'https://api.sandbox.ovok.com/v1/signals/api/alert' \ --user "${OVOK_MANAGER_ID}:${OVOK_MANAGER_SECRET}" \ --data-urlencode 'status=ACTIVE' ``` For episodes, one row per clinical event rather than one per breach, add `episodes=true` and use `status=OPEN` or `CLOSED`. Episodes need `episodicAlerts` on for your tenant; see [Update tenant settings](/signals/standalone/api/tenants/update-tenant-settings). ### 5. Acknowledge one [#5-acknowledge-one] ```bash curl --request POST 'https://api.sandbox.ovok.com/v1/signals/api/alert/:id/ack' \ --user "${OVOK_MANAGER_ID}:${OVOK_MANAGER_SECRET}" \ --header 'Content-Type: application/json' \ --data '{"actor":{"reference":"Practitioner/123","display":"Dr. Max Mustermann"}}' ``` Acknowledging closes the alert. The next breaching reading opens a new one. ## API reference [#api-reference] The route pages are generated from the [API Explorer](/api-explorer) document, so they always match what Ovok serves. Each page lists the capabilities the route needs, what Ovok changes, and every answer. ## Related [#related] - [Webhooks](/signals/standalone/webhooks) - [Signals route policies](/access-policies/signals) - [Signals with Ovok](/signals/connected-ovok) # Signals webhooks Canonical page: https://docs.ovok.com/signals/standalone/webhooks Signals can push events to your system instead of you polling `GET /alert`. A **subscriber** is a Signals client with a webhook URL and a list of events. Signals manages the deliveries; Ovok exposes the routes to create and run subscribers, and holds their credentials. Every route on this page needs a [Manager application](/signals/standalone#app-types) or a user with the capabilities shown. | Task | Route | Capabilities | | --- | --- | --- | | Create a subscriber | [`POST /v1/signals/api/user`](/signals/standalone/api/clients/create-a-user) | `signals_webhooks:update`, `signals_events:read` | | Change its URL, events or reach | [`POST /v1/signals/api/user/:id`](/signals/standalone/api/clients/update-a-user) | `signals_webhooks:update`, `signals_events:read` | | Delete it | [`DELETE /v1/signals/api/user/:id`](/signals/standalone/api/clients/delete-a-user) | `signals_webhooks:delete` | | Check its endpoint | [`GET /v1/signals/api/subscriber/:id/webhook`](/signals/standalone/api/clients/read-the-webhook-endpoint) | `signals_webhooks:read` | | Send a test event | [`POST .../webhook/test`](/signals/standalone/api/clients/send-a-test-event) | `signals_webhooks:update` | | Turn it off or on | [`POST .../webhook/disable`](/signals/standalone/api/clients/disable-the-webhook-endpoint), [`.../enable`](/signals/standalone/api/clients/enable-the-webhook-endpoint) | `signals_webhooks:update` | | Rotate its signing secret | [`POST .../webhook/rotate-secret`](/signals/standalone/api/clients/rotate-the-webhook-signing-secret) | `signals_webhooks:update` | | See what was sent | [`GET /v1/signals/api/events`](/signals/standalone/api/events/list-webhook-events), [`.../events/:id/attempts`](/signals/standalone/api/events/list-a-deliverys-attempts) | `signals_events:read` | | Send events again | [`POST /v1/signals/api/events/redeliver`](/signals/standalone/api/events/redeliver-events), [`.../events/:id/redeliver`](/signals/standalone/api/events/redeliver-one-event) | `signals_webhooks:update` | ## Create a subscriber [#create-a-subscriber] ```bash curl --request POST 'https://api.sandbox.ovok.com/v1/signals/api/user' \ --user "${OVOK_MANAGER_ID}:${OVOK_MANAGER_SECRET}" \ --header 'Content-Type: application/json' \ --data '{ "role": "SUBSCRIBER", "name": "Ward alerts", "webhookUrl": "https://example.com/signals/webhook", "events": ["alert.*"], "reach": "all" }' ``` - Add `episode.*` only once your tenant has `episodicAlerts` on; until then it answers `403` `FEATURE_DISABLED` (see [Events](#events)). - Send `role: "SUBSCRIBER"`. Through Ovok, only subscribers are created; any other role answers `403`. - Don't send `clientId`, `secret` or `webhookSecret`. Ovok generates the subscriber's id and Signals login, which it never uses, and answers `422` if you send them. - Subscribers are on event schema 2. Sending another `eventSchema` answers `422`. - The answer carries `signingSecret` **once**. Store it: you need it to verify deliveries, and you get a new one only by rotating it. - `Location` names the new subscriber under `/v1/signals/api/user/:id`. A create retried after a timeout can make a second subscriber. List them with [`GET /v1/signals/api/user`](/signals/standalone/api/clients/list-users) and delete the extra one. ## Reach: which patients it hears about [#reach-which-patients-it-hears-about] | `reach` | Patients | | --- | --- | | `attached` (default) | Only the patients attached to it. Attach them with [`POST /v1/signals/api/subscriber/:id/patients`](/signals/standalone/api/patients/attach-patients-to-a-subscriber). | | `all` | Every patient of your tenant, including patients enrolled later. | ## Events [#events] Name exact events, or a whole family with a wildcard such as `alert.*`. | Event | When | | --- | --- | | `alert.triggered` | A reading breaches a trigger and opens an alert. | | `alert.refired` | Another breach refreshes an open alert. | | `alert.resolved` | A trigger resolves the alert. | | `alert.acknowledged` | Someone acknowledges the alert. | | `alert.empty`, `alert.note`, `alert.inactive` | An empty reading, a note, or a patient going quiet raises an alert. | | `episode.opened`, `episode.closed` | An episode starts or ends. | | `observation.created`, `observation.updated` | A reading is stored or changed. One delivery per reading: subscribe only if you need them. | | `patient.subscribed`, `patient.unsubscribed` | A patient is attached to or detached from the subscriber. | | `patient.config`, `patient.inactive` | A patient's config changes, or the patient goes inactive. | | `webhook.test` | You sent a test event. It is not queued, retried or listed. | | `webhook.disabled` | Signals turned another subscriber's endpoint off because it answered `410` or kept failing. You are never told about your own. | Readings posted with `Prefer: respond-sync` report their alerts in the answer, and send no webhook for them. **Episode events need episodes.** Signals records episodes only while your tenant has `episodicAlerts` on. Naming an episode event while it is off answers `403` `FEATURE_DISABLED`. Turn it on with [`PATCH /v1/signals/api/tenant`](/signals/standalone/api/tenants/update-tenant-settings) and `{"settings":{"episodicAlerts":true}}`. ## Verify each delivery [#verify-each-delivery] Deliveries follow [Standard Webhooks](https://www.standardwebhooks.com/). Each one carries `webhook-id`, `webhook-timestamp` and `webhook-signature`; verify them with a Standard Webhooks library and the subscriber's `signingSecret` (`whsec_…`). The body is one JSON event with its type, its data and when it happened. If you set `custom`, every delivery carries it back as `x-actimi-custom`. Answer `2xx` quickly and do the work afterwards. A delivery that fails is retried. **Rotating the secret.** [`rotate-secret`](/signals/standalone/api/clients/rotate-the-webhook-signing-secret) returns the new secret once. The old one keeps signing for 24 hours, so `webhook-signature` carries both and you can switch with no gap. Rotate again only after your receiver uses the new secret. ## When deliveries fail [#when-deliveries-fail] | Situation | What happens | | --- | --- | | Recent attempts failed | The endpoint is `failing`. Signals keeps retrying. | | Five days of failures with no delivery | Signals turns the endpoint off (`disabledReason: failing`). | | Your endpoint answers `410 Gone` | Signals turns it off at once (`disabledReason: gone`). | | You disabled it | Nothing is sent (`disabledReason: manual`). | While an endpoint is off, new events are **held**, not dropped. Ovok tells your project's admins when Signals turns one off. After you fix the receiver, [enable](/signals/standalone/api/clients/enable-the-webhook-endpoint) it, then send the held events with [`POST /v1/signals/api/events/redeliver`](/signals/standalone/api/events/redeliver-events)`?status=held&since=`. `since` is required; the call answers `202` with how many it queued, at most 1,000 at a time. Enabling alone re-queues nothing. [`GET /v1/signals/api/events`](/signals/standalone/api/events/list-webhook-events) lists every event with how its delivery went. It pages oldest first, and can lag a little behind the newest deliveries. ## Related [#related] - [Signals standalone](/signals/standalone) - [Signals route policies](/access-policies/signals) # Signals alerts in FHIR Canonical page: https://docs.ovok.com/signals/with-ovok/fhir-annotations With [`SIGNALS_ANNOTATE_OBSERVATIONS`](/signals/with-ovok/settings#signals_annotate_observations) on, Ovok writes each Signals alert and episode into your project as standard FHIR R4 resources. Your app reads them like any other FHIR data. | Signals | FHIR | Identified by | | --- | --- | --- | | An alert | [`DetectedIssue`](#the-alert-detectedissue) | `https://signals.actimi.com/alert` \| alert id | | An episode | [`Flag`](#the-episode-flag) | `https://signals.actimi.com/episode` \| episode id | | The reading that breached | `interpretation` and `referenceRange` on the [`Observation`](#the-reading-observation) | The Observation itself | Each write is keyed by these identifiers, so an event Signals sends twice changes nothing. ## The alert: DetectedIssue [#the-alert-detectedissue] | Element | Value | | --- | --- | | `identifier` | `https://signals.actimi.com/alert` \| alert id, and `https://signals.actimi.com/episode` \| episode id when the alert belongs to one. | | `status` | `final`. | | `code` | The alerted vital's code under system `http://loinc.org`, also for non-LOINC codes, with the alert's reason as `text`. | | `severity` | Always `moderate`. Signals' bands have no critical limits to grade by. | | `patient` | `Patient/`. | | `identifiedDateTime` | When Signals raised the alert. | | `implicated` | The breaching `Observation`. A refire adds its reading. | | `detail` | The alert's reason. | | `mitigation` | `Acknowledged` and `Resolved` as `action.text`, each with its `date`, once they happen. | | `extension` | `https://signals.actimi.com/StructureDefinition/alert-version`: Signals' version of the alert. | ## The episode: Flag [#the-episode-flag] | Element | Value | | --- | --- | | `identifier` | `https://signals.actimi.com/episode` \| episode id. | | `status` | `active` while the episode is open, `inactive` once it closes. A closed Flag never reopens. | | `category` | `http://terminology.hl7.org/CodeSystem/flag-category` \| `clinical`. | | `code` | The episode's vital, under system `http://loinc.org` unless Signals names another. | | `subject` | `Patient/`. | | `period` | `start` when it opened, `end` when it closed. | | `extension` | `https://signals.actimi.com/StructureDefinition/episode-close-reason`: why it closed. | Signals records episodes only while your tenant has `episodicAlerts` on. With it off, you get `DetectedIssue`s but no `Flag`s. ## The reading: Observation [#the-reading-observation] When a value breaches a trigger, Ovok updates the Observation once: | Element | Value | | --- | --- | | `interpretation` | `http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation`: `H` above the band, `L` below it, `A` otherwise. It is added beside any coding the device sent. There is no `HH` or `LL`. | | `referenceRange` | The band's `low` and `high` in the reading's unit, with `type` `normal`. Added only if the Observation has none. | - On a panel, such as a snapshot with `component[]`, both go on the component of the alerted vital. - Only value alerts annotate the reading. Note, empty-reading and inactivity alerts have no value to interpret, so they write only a `DetectedIssue`. - `status` is not changed, and the update does not send the reading to Signals again. ## Searching [#searching] | Question | Search | | --- | --- | | Is this reading in alert? | `GET /fhir/R4/DetectedIssue?implicated=Observation/` | | A patient's alerts | `GET /fhir/R4/DetectedIssue?patient=Patient/` | | The alerts of one episode | `GET /fhir/R4/DetectedIssue?identifier=https://signals.actimi.com/episode\|` | | A patient's open episodes | `GET /fhir/R4/Flag?patient=Patient/&status=active&identifier=https://signals.actimi.com/episode\|` | | One alert | `GET /fhir/R4/DetectedIssue?identifier=https://signals.actimi.com/alert\|` | ```bash curl --get 'https://api.sandbox.ovok.com/fhir/R4/Flag' \ --header "Authorization: Bearer ${OVOK_TOKEN}" \ --data-urlencode 'patient=Patient/3f1c2b7e-8d4a-4c1e-9b2f-6a7d5e4c3b21' \ --data-urlencode 'status=active' \ --data-urlencode 'identifier=https://signals.actimi.com/episode|' ``` Filter Flags by the episode identifier system, as above. Projects that used Ovok before 2026-10-15 can still hold Flags from an older Ovok marker, which are not episodes. ## Access [#access] `DetectedIssue` and `Flag` are in the Patient compartment. A role that should see alerts needs read on both in its access policy; project admins add them. Integration applications get read on both by default; Manager and Submitter applications hold Signals capabilities only. Patient sharing shares both read-only, and neither should be written through the FHIR API: a raw write never reaches Signals. ## Related [#related] - [Signals settings](/signals/with-ovok/settings) - [Gotchas](/signals/with-ovok/gotchas) - [FHIR API](/api/fhir) # Signals with Ovok gotchas Canonical page: https://docs.ovok.com/signals/with-ovok/gotchas ## Which readings reach Signals [#which-readings-reach-signals] - **Your project needs its own Signals tenant.** On the shared tenant, both [settings](/signals/with-ovok/settings) stay off and turning one on answers `409` `SETTING_NOT_AVAILABLE`. - **Only created Observations.** `SIGNALS_SEND_AUTO` sends an Observation when it is created through the FHIR API. Updating one sends nothing. To correct a reading, create a new Observation. - **Some are skipped.** An Observation whose `subject` is not a `Patient`, one with `status` `entered-in-error` or `cancelled`, and one carrying an `ovok-event-id` or Signals identifier are not sent. - **Ingest is separate.** Readings from [Data Ingestion](/data-ingestion) are sent by the ingest path, whatever `SIGNALS_SEND_AUTO` says. Turning the setting off does not stop them. - **The first reading enrols the patient.** You need [`$enable-signals`](/signals/enable-signals-patient) only to enrol a patient before any reading, for example to set their thresholds first. - **The same reading twice is judged once.** Signals ignores a reading it already has within an hour. ## Retries and gaps [#retries-and-gaps] - **About 34 minutes of retries.** If Ovok or Signals is down, the notification for a new Observation is retried for about 34 minutes. A longer outage loses that reading for Signals. The Observation stays in FHIR; it is not sent again later, and nothing replays it. - **Deleting the Subscription stops sending.** The Subscription tagged `signals-send-auto` is Ovok's. If it is deleted through the FHIR API, sending stops for the project; save `SIGNALS_SEND_AUTO` again to re-create it. - **No backfill.** `SIGNALS_ANNOTATE_OBSERVATIONS` writes alerts raised after it is turned on, not earlier ones. ## Alerts, episodes and annotations [#alerts-episodes-and-annotations] - **Episodes need `episodicAlerts`.** With it off for your tenant, Signals records no episodes: you get `DetectedIssue`s but no `Flag`s, and episode feeds stay empty. Turning it off empties them. - **Coarse grading.** `severity` is always `moderate`, and `interpretation` is only `H`, `L` or `A`. Signals' bands have no critical limits, so there is no `HH` or `LL`. - **Not every alert has a reading.** A reading Ovok did not keep in FHIR, such as a realtime tick from a device, gives a `DetectedIssue` with no `implicated`. Note, empty-reading and inactivity alerts never annotate an Observation. - **Events can arrive out of order.** Ovok merges them by Signals' alert version, so the stored `DetectedIssue` is always the newest. `implicated` and `mitigation` only grow, and a closed `Flag` never reopens. - **Old Flags.** Projects that used Ovok before 2026-10-15 can hold Flags from an older Ovok marker. Search episodes with `identifier=https://signals.actimi.com/episode|`. - **Patients created through the standalone API.** Annotations cover every alert of your tenant and name the patient as `Patient/`. For a patient you create through the [standalone API](/signals/standalone), use its FHIR Patient id as `refId`, or its `DetectedIssue` points at no Patient. A project that uses only the standalone API should switch both settings off. ## Writing and access [#writing-and-access] - **Don't write `DetectedIssue` or `Flag` yourself.** Ovok owns them, and a raw write never reaches Signals. Acknowledge an alert through the Slim [notification routes](/slim-apis/notifications/acknowledge-medical-notification) or the standalone [acknowledge route](/signals/standalone/api/alerts/acknowledge-an-alert-or-an-episode); the `DetectedIssue` then gains an `Acknowledged` mitigation. - **Thresholds live in Signals.** Change them through the Slim [threshold routes](/slim-apis/threshold/get-patient-effective-threshold-v2). Editing a `Goal` or `CarePlan` directly never reaches Signals. - **Grant read on `DetectedIssue` and `Flag`.** Roles that should see alerts need both in their access policy. Integration applications have them; Manager and Submitter applications hold Signals capabilities only. - **`$enable-signals` needs two grants.** The caller needs `signals_config:update` and Patient `update`. Project admins have both; a new Manager or integration application has only one. ## Related [#related] - [Signals settings](/signals/with-ovok/settings) - [Alerts in FHIR](/signals/with-ovok/fhir-annotations) - [Signals with Ovok](/signals/connected-ovok) # Signals settings Canonical page: https://docs.ovok.com/signals/with-ovok/settings Two project settings connect your FHIR data with Signals. Both are Boolean [project settings](/settings-and-features), changed by a project admin: ```bash curl --request PUT \ --url 'https://api.sandbox.ovok.com/v1/project/settings/SIGNALS_SEND_AUTO' \ --header "Authorization: Bearer ${OVOK_TOKEN}" \ --header 'Content-Type: application/json' \ --data '{"enabled":true}' ``` | Setting | Default when unset | Needs, or `effectiveSettings` is `false` | | --- | --- | --- | | `SIGNALS_SEND_AUTO` | On | A Signals tenant of the project's own. | | `SIGNALS_ANNOTATE_OBSERVATIONS` | Whatever `SIGNALS_SEND_AUTO` is | A Signals tenant of the project's own. | Read `effectiveSettings` in `GET /v1/project/settings` to see what Ovok applies. A project on the shared Signals tenant shows both as `false`, and turning either on answers `409` `SETTING_NOT_AVAILABLE`. ## Saving a setting sets it up [#saving-a-setting-sets-it-up] Saving a switch does the wiring in the same request, before the value is stored: - If the wiring works, the setting is saved and the response is the full settings record. - If it fails, the request answers `502` `SETTING_WIRING_FAILED`, nothing is saved, and any step already done is undone. Try again later. - While another change of the same switch is running, the request answers `409`. - Saving the same value again is safe, and repairs missing wiring. Use it after someone deleted the wiring, or after Signals turned a delivery off. A project that never saved `SIGNALS_SEND_AUTO` is set up on its first request to Ovok, so the default works without anyone saving it. ## SIGNALS_SEND_AUTO [#signals_send_auto] Sends each `Observation` created through the FHIR API to Signals. - **What saving it on sets up:** a FHIR `Subscription` in your project that notifies Ovok of every created Observation. It is tagged `https://api.ovok.com/identifier/system-resource|signals-send-auto`. Saving it off deletes it. - **Create only.** Updating an Observation sends nothing, so a reading is judged once. - **Enrols patients.** A patient Signals does not know yet is enrolled by its first forwarded reading. You don't need [`$enable-signals`](/signals/enable-signals-patient) first. - **Not for ingest.** Readings from [Data Ingestion](/data-ingestion) already go to Signals from the ingest path, and the Subscription skips them. - **Retries.** If Ovok or Signals is briefly down, the notification is retried for about 34 minutes. Signals ignores a reading it already has, so retries never alert twice. ## SIGNALS_ANNOTATE_OBSERVATIONS [#signals_annotate_observations] Writes Signals' alerts and episodes into FHIR. See [Alerts in FHIR](/signals/with-ovok/fhir-annotations) for the resources. - **What saving it on sets up:** a system subscriber in your Signals tenant that sends every alert and episode event to Ovok. Saving it off deletes it. - **Default:** it follows `SIGNALS_SEND_AUTO` until you save it yourself. Saving `SIGNALS_SEND_AUTO` switches it too, unless it has a saved value of its own. - **Why it follows send-auto.** It annotates readings that live in FHIR. Creating a Manager or Submitter application doesn't change it. - **Standalone-only projects: switch both off.** Both are on by default for every project with its own tenant. Annotations cover every alert of the tenant, so for patients you created through the [standalone API](/signals/standalone) they write `DetectedIssue`s that point at a `Patient/` that does not exist. - **Only new alerts.** Alerts raised before you turned it on are not written. ## Related [#related] - [Signals with Ovok](/signals/connected-ovok) - [Alerts in FHIR](/signals/with-ovok/fhir-annotations) - [Gotchas](/signals/with-ovok/gotchas) - [Project settings and features](/settings-and-features) # Fetch data of existing accounts Canonical page: https://docs.ovok.com/api/accounts/fetch-data-of-existing-accounts `GET /accounts` Lists the email addresses of every account in the caller's project. Use it to build a participant picker, for example for a video call. **Auth:** bearer token. The caller must be a Practitioner, a project admin or a super admin, or hold an access policy named "System Owner". Other callers get 403. **Scope:** the project of the token. ## Behaviour - Every project membership with a Patient or Practitioner profile and a User is included. Accounts whose User has no email are left out. - The handler returns only the `email` of each account. - The list is not paginated and has no defined sort order. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/accounts' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Change user password Canonical page: https://docs.ovok.com/api/authentication/change-user-password `PATCH /v2/auth/change-password` Changes the password of the signed-in user. Use it from an account settings screen where the user knows their current password. **Auth:** bearer token. **Scope:** the User of the token. ## Behaviour - `oldPassword` must match the current password. A wrong `oldPassword`, or an account with no password set, gives 401. - The new password may equal the old one. - The password must have at least 12 characters, not counting spaces at either end, and must not be on Ovok's list of common and breached passwords. Any character is allowed and none is required. A refused password answers 422 with the error on `newPassword`. - The route does not end existing sessions. - The email address is not marked as verified by this route. - The response is the updated `User` without its password hash. ## Example ```bash curl -X PATCH 'https://api.sandbox.ovok.com/v2/auth/change-password' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "oldPassword": "Ex4mple-Passw0rd", "newPassword": "a-new-password" }' ``` # Refresh access token Canonical page: https://docs.ovok.com/api/authentication/refresh-access-token `POST /auth/refresh-token` Exchanges a refresh token for a new access token and a new refresh token. Call it before the access token expires to keep a session alive. **Auth:** none. The refresh token in the body is the credential. ## Behaviour - Ovok forwards the token to Medplum's `oauth2/token` endpoint (`grant_type=refresh_token`, scope `openid offline_access`). - The request body takes the token as `refresh_token`. - The response holds `accessToken`, `refreshToken` and `expiresIn` (seconds), the same names the login routes use. Store the new `refreshToken`: use it for the next refresh. - The response also carries the same three values as `access_token`, `refresh_token` and `expires_in`. Those names are deprecated and will be removed in a later release: read the camelCase ones. - A refresh token Medplum refuses (spent, expired, revoked, or not a refresh token at all) gives a 401 with Medplum's error description. A refresh token is single-use, so retrying it after a successful refresh also gives a 401: sign in again. - A body without `refresh_token` gives a 400. - A session of a Patient whose project turned `PATIENT_LOGIN_ENABLED` off, or of a Practitioner whose project turned `PRACTITIONER_LOGIN_ENABLED` off, gives a 403 `Login is not enabled for this project.` That ends the session: the refresh token is used up, and signing in again is refused while login is off. A Practitioner who is a project admin is not refused, so an admin who is signed in can still turn login back on (they cannot sign in again while it is off). The access token already issued lasts until it expires (60 minutes). - `POST /oauth2/token` applies the same check to every token it grants (refresh and code exchange), answering `403 { "error": "access_denied", "error_description": "Login is not enabled for this project." }`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/refresh-token' \ -H 'Content-Type: application/json' \ -d '{ "refresh_token": "example.jwt.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk" }' ``` # Log out (server-side token revocation) Canonical page: https://docs.ovok.com/api/authentication/log-out-server-side-token-revocation `POST /v1/auth/logout` Signs the caller out on the server: the access token in the `Authorization` header stops working for every authenticated route, although it has not expired. **Auth:** bearer token. A missing or invalid token gives 401. ## Behaviour - Ovok adds the token to a denylist. The entry lasts for the rest of the token's lifetime (its `exp` claim), so the list never outgrows the set of live tokens. - Only this access token is revoked. The refresh token is not touched here; to end other sessions use `DELETE /auth/session/{option}`. - The call is idempotent: repeating it with the same token returns 204 with no further effect. A token without an `exp` claim, or one that has already expired, is ignored. - If the denylist store is unavailable the call still returns 204, and the token stays valid until it expires. Clear the local session as well. - The response has no body (204 No Content). - The route is available at both `/auth/logout` and `/v1/auth/logout`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/auth/logout' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Log out (server-side token revocation) Canonical page: https://docs.ovok.com/api/authentication/log-out-server-side-token-revocation-2 `POST /auth/logout` Signs the caller out on the server: the access token in the `Authorization` header stops working for every authenticated route, although it has not expired. **Auth:** bearer token. A missing or invalid token gives 401. ## Behaviour - Ovok adds the token to a denylist. The entry lasts for the rest of the token's lifetime (its `exp` claim), so the list never outgrows the set of live tokens. - Only this access token is revoked. The refresh token is not touched here; to end other sessions use `DELETE /auth/session/{option}`. - The call is idempotent: repeating it with the same token returns 204 with no further effect. A token without an `exp` claim, or one that has already expired, is ignored. - If the denylist store is unavailable the call still returns 204, and the token stays valid until it expires. Clear the local session as well. - The response has no body (204 No Content). - The route is available at both `/auth/logout` and `/v1/auth/logout`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/auth/logout' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Schedule user account deletion Canonical page: https://docs.ovok.com/api/authentication/schedule-user-account-deletion `DELETE /auth/delete` Schedules deletion of the caller's own account. The account is not deleted right away: it stays until the scheduled date, and signing in again before then cancels the deletion. **Auth:** bearer token of the user who deletes their own account. **Scope:** the caller's own User, in the project of the token. ## Behaviour - `days` (0 to 90, default 30) sets how many days from now the account is due. `wipe` (default `false`) is recorded on the request. - Ovok signs the user out of all sessions, then records the deletion date on the User. Calling the route again resets the date. - A job runs every day at midnight. For each User whose date has passed, it deletes the project membership, the profile (Patient or Practitioner) and the User. - The job does not purge medical data yet, so `wipe` has no effect on what is deleted. - Ovok sends a confirmation email (`PATIENT_ACCOUNT_DELETION` for a Patient, `ACCOUNT_DELETION` otherwise). A failed email does not fail the request. - A successful login on the account (`POST /v2/auth/login`, or the tenant login routes) removes the scheduled deletion. - The response holds `scheduled` (the due date, ISO 8601) and the updated `user`, without its password hash. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/auth/delete' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "days": 30, "wipe": false }' ``` # Login Canonical page: https://docs.ovok.com/api/authentication/login `POST /v2/auth/login` Signs a user in with email and password for the project that owns a client application, and returns an access token and a refresh token. New integrations should use the tenant login routes (`/auth/tenant/Patient/login/start` and `/auth/tenant/Practitioner/login/start`) instead. **Auth:** none. The email and password are the credential, and `clientId` names the project. **Scope:** the project that owns the `ClientApplication` with the given `clientId`. ## Behaviour - Ovok looks up the account by email in the client application's project. If a Patient and a Practitioner share the email in that project, one of them is picked and which one is not defined. - The account type's login switch must be on: the project setting `PATIENT_LOGIN_ENABLED` or `PRACTITIONER_LOGIN_ENABLED`. Both default to on. It is checked once the password is right, so its 403 never tells which emails have an account. - A wrong password and an unknown email give the same 401 `Invalid email or password.`, so the response does not tell you which one was wrong. An unknown `clientId` gives a 400. - After 5 failed sign-ins for one email within 15 minutes, that email's sign-ins answer 429 with `Retry-After` for 15 minutes, the right password included, whether or not the email has an account. A successful sign-in resets the count. - If Medplum's own login rate limit is hit, you get a 429 instead of a 401. Wait and retry. - Callers without a token may send at most 10 requests per minute from one IP address. - A successful login cancels a pending account deletion (`DELETE /auth/delete`). - This route has no MFA step. Use the tenant login routes for users with MFA enrolled. - The access token lasts one hour (`expiresIn` is in seconds). Use `POST /auth/refresh-token` to renew it. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v2/auth/login' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com", "password": "Ex4mple-Passw0rd", "clientId": "c3499c27-2973-0a7f-807e-fb8676a92dcb" }' ``` # Get account information Canonical page: https://docs.ovok.com/api/authentication/get-account-information `GET /auth/me` Returns the signed-in user's context: project, membership, profile, user configuration, access policy and security details such as MFA status and sessions. Call it after sign-in to learn who the token belongs to. **Auth:** bearer token. A missing, non-bearer or invalid token gives 401. **Scope:** the project of the token. ## Behaviour - The answer is Medplum's `auth/me` for the token's session. - The call always discards Ovok's cached copy of this session's profile and reads a fresh one, so changes to the profile or access policy show up in the response and in later requests with the same token. - Use the returned `profile.resourceType` to tell Patients from Practitioners. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/auth/me' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Send reset password email Canonical page: https://docs.ovok.com/api/reset-password/send-reset-password-email `POST /v2/auth/reset-password` Sends a password reset email to a Patient, a RelatedPerson (carer) or a Practitioner. The answer is the same whether or not an account exists, so the route cannot be used to find out which emails are registered. **Auth:** none. **Scope:** for a Patient or RelatedPerson, the project that owns `clientId`. For a Practitioner, the account is found by email across projects. ## Behaviour - `type` is `Patient`, `RelatedPerson` or `Practitioner`. `clientId` is required when `type` is `Patient` or `RelatedPerson` and is ignored for a Practitioner. - The response is always a FHIR `OperationOutcome` saying "If the user exists, a password reset email has been sent." It is returned for unknown emails, unknown client IDs and accounts that could not be mailed. - When the account exists, Ovok creates a reset request, which replaces any earlier open reset request for the user, and emails the user. Patients and RelatedPersons get the `PATIENT_RESET_PASSWORD` template and Practitioners the `RESET_PASSWORD` template. - The email carries a link `/setpassword//` plus the request `id` and `secret`. The app URL is the project's patient app URL for a Patient or RelatedPerson, and its practitioner app URL for a Practitioner; if none is set, the request's `Origin` is used when it is an allowed one. - A Practitioner who is a member of more than one project gets a link to the Ovok platform app instead of a project's app URL. - If no app URL can be found, the email still goes out, without a link. The `id` and `secret` in it can be sent to `POST /v2/auth/reset-password/process`. - If a Practitioner has several accounts, the first one found is used. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v2/auth/reset-password' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com", "clientId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "type": "Patient" }' ``` # Reset user password with the information from the email. Canonical page: https://docs.ovok.com/api/reset-password/reset-user-password-with-the-information-from-the-email `POST /v2/auth/reset-password/process` Sets a new password using the `id` and `secret` from a reset email. Use it when your app handles the reset itself instead of sending the user to the emailed link. **Auth:** none. The reset request `id` and `secret` are the credential. ## Behaviour - The `id` and `secret` come from the email sent by `POST /v2/auth/reset-password`. The `password` is the new password. - The password must have at least 12 characters, not counting spaces at either end, and must not be on Ovok's list of common and breached passwords. Any character is allowed and none is required. A refused password answers 422 with the error on `password`. - An invite link (from `POST /auth/invite` or a practitioner invite) sets a password for 7 days after it was sent. After that it answers 410 `This invite link has expired. Ask for a new invite.`, and inviting the user again sends a fresh link. Reset links are not limited this way. - A request can be used once. Ovok marks it used before it changes the password, so a request whose password change then fails cannot be retried and the user must ask for a new email. - Setting the password also marks the user's email as verified, because the secret came by email. - The response is a minimal `User` with `resourceType`, `id` and `email`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v2/auth/reset-password/process' \ -H 'Content-Type: application/json' \ -d '{ "id": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "secret": "k3J9xQ2mV7", "password": "Ex4mple-Passw0rd" }' ``` # Get all sessions Canonical page: https://docs.ovok.com/api/authentication---session-management/get-all-sessions `GET /auth/session` Lists the caller's live sessions (one per sign-in). Use it to build a "where you are signed in" screen. **Auth:** bearer token. **Scope:** the signed-in user's own sessions. ## Behaviour - A session is listed when its Login belongs to the user, has a project membership and is not revoked. Sessions that have been idle for a long time are listed as long as they are not revoked. - The list is ordered newest first. - `browser` and `os` are `null` for sessions that Medplum does not report them for. - The call only reads. It does not change any session. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/auth/session' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Revoke sessions Canonical page: https://docs.ovok.com/api/authentication---session-management/revoke-sessions `DELETE /auth/session/{option}` Signs the caller out of one or more sessions. Use it for "sign out everywhere" and "sign out other devices" actions. **Auth:** bearer token. **Scope:** the signed-in user's own sessions. A session ID that is not one of the caller's sessions revokes nothing. ## Behaviour - `option` in the path is one of: - `current`: the session of the token you call with. - `other`: every session except the current one. - `all`: every session, including the current one. - a session ID (UUID) from `GET /auth/session`: that one session. - Ovok rejects the access tokens of the revoked sessions on their next request, and marks each Login as revoked in Medplum so the session cannot be renewed. - Revoking `current` or `all` also ends the token you called with. - The response echoes the revoked sessions with `revoked: true`: one object for `current` or a session ID, a list for `other` and `all`. - To end only the token you hold, without the session, use `POST /v1/auth/logout`. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/auth/session/other' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Start practitioner login Canonical page: https://docs.ovok.com/api/tenant-authentication/start-practitioner-login `POST /auth/tenant/Practitioner/login/start` Starts a practitioner login: checks the email and password and returns either a session code plus the list of tenants the practitioner can enter, or, when the user has MFA enrolled, a login ID for the MFA step. **Auth:** none. **Scope:** no tenant yet. A practitioner's User is server-wide; the tenant is chosen in `login/token`. ## Behaviour - This is step 1 of a PKCE login. Generate a random `codeVerifier`, send its S256 hash as `codeChallenge` here, and send the `codeVerifier` itself to `POST /auth/tenant/Practitioner/login/token`. - Response `nextStep`: - `token`: no MFA. The response carries `sessionCode` and `profiles`, one entry per Practitioner membership of the user: its `tenantCode`, `project` (`id`, `resourceType`, `name`), `profile`, `admin` (true when the user is an admin of that project), `isMainProject` and `parentProjectId`. - `mfa`: the user has MFA enrolled. Pass `loginId` and the current TOTP code to `POST /auth/tenant/Practitioner/login/mfa`, which returns the same `profiles` list. - `isMainProject` is `true` when the project has no parent project, and `null` when the hierarchy could not be read. `parentProjectId` is set only when the caller is also a member of that parent; otherwise it is `null`. - `PRACTITIONER_LOGIN_ENABLED` is not checked here; it is checked in `login/token` against the chosen tenant. - A wrong email, an unknown account, an account without a password and a wrong password all give the same 401 `Invalid email or password.` - After 5 failed sign-ins for one email within 15 minutes, that email's sign-ins answer 429 with `Retry-After` for 15 minutes, the right password included, whether or not the email has an account. A successful sign-in resets the count. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Practitioner/login/start' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com", "password": "your-password", "codeChallenge": "" }' ``` # Exchange practitioner session code for tokens Canonical page: https://docs.ovok.com/api/tenant-authentication/exchange-practitioner-session-code-for-tokens `POST /auth/tenant/Practitioner/login/token` Finishes a practitioner login into one tenant: binds the session to the practitioner's membership in that tenant, then exchanges the session code and your PKCE `codeVerifier` for an access token and a refresh token. **Auth:** none. The session code and code verifier prove the earlier steps. **Scope:** the project that owns `tenantCode`. Pick it from the `profiles` returned by `login/start` or `login/mfa`. ## Behaviour - `PRACTITIONER_LOGIN_ENABLED` on the chosen project must not be `false` (it defaults to on). - The practitioner must have a membership in the chosen tenant. Ovok points the pending login at that membership before the code is redeemed, so the tokens are scoped to that project. - Ovok redeems the code with Medplum's `oauth2/token` endpoint (`grant_type=authorization_code`). - If the account was scheduled for deletion (`DELETE /auth/delete`), logging in cancels the deletion. - The response holds `accessToken`, `refreshToken`, `expiresIn` (seconds) and references to the `project` and `profile`. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Practitioner/login/token' \ -H 'Content-Type: application/json' \ -d '{ "sessionCode": "", "codeVerifier": "", "tenantCode": "my-medical-project" }' ``` # Verify practitioner MFA code Canonical page: https://docs.ovok.com/api/tenant-authentication/verify-practitioner-mfa-code `POST /auth/tenant/Practitioner/login/mfa` Verifies the TOTP code of a practitioner who has MFA enrolled, after `login/start` answered `nextStep: "mfa"`. Returns the session code for `login/token` and the list of tenants the practitioner can enter. **Auth:** none. The `loginId` from `login/start` identifies the login. ## Behaviour - `mfaToken` must equal the current TOTP code generated from the user's MFA secret. - On success the login is marked MFA-verified and the response is `{ "nextStep": "token", "sessionCode": ..., "profiles": [...] }`. `profiles` is the same list `login/start` returns without MFA. - Pass `sessionCode` and one `tenantCode` from `profiles` to `POST /auth/tenant/Practitioner/login/token`. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Practitioner/login/mfa' \ -H 'Content-Type: application/json' \ -d '{ "loginId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "mfaToken": "123456" }' ``` # Register a practitioner Canonical page: https://docs.ovok.com/api/tenant-authentication/register-a-practitioner `POST /auth/tenant/Practitioner/register` Registers a new practitioner account in a tenant and returns its tokens, so the user is signed in straight away. **Auth:** none. The tenant is named by `tenantCode`. **Scope:** the project that owns `tenantCode`. ## Behaviour - The project setting `PRACTITIONER_REGISTRATION_ENABLED` must be `true`. It is off unless set. - The new membership gets the project's default practitioner access policy: the text setting `DEFAULT_PRACTITIONER_ACCESS_POLICY`, else `CLINICIAN_INVITE_ACCESS_POLICY`. Without a valid one, nothing is created and the answer is a 409 with `error: "practitioner_registration_not_configured"`. - An email that already has a practitioner account (a server-wide User) joins this project when the request brings that account's own password: a new practitioner profile and membership, and the password is never changed. It is refused, with nothing written, for any other password, an account with MFA on, an account that is already a practitioner here, and an email that has a patient account in any project. - The password must have at least 12 characters, not counting spaces at either end, and must not be on Ovok's list of common and breached passwords. Any character is allowed and none is required. A refused password answers 422 with the error on `password`. - The User, the Practitioner profile and the membership are written in one atomic step. No email is sent. - Rate limit: 5 requests per minute per IP address. - Error responses are delayed to take at least one second. - A 409 with `practitioner_registration_not_configured` means the project has no practitioner registration setup. - A 429 means more than 5 requests in a minute from your IP address. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Practitioner/register' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com", "password": "your-password", "name": "Max", "surname": "Mustermann", "tenantCode": "my-medical-project" }' ``` # Start patient login Canonical page: https://docs.ovok.com/api/tenant-authentication/start-patient-login `POST /auth/tenant/Patient/login/start` Starts a patient login for one tenant: checks the email and password and returns either a session code to exchange for tokens or, when the user has MFA enrolled, a login ID for the MFA step. **Auth:** none. The tenant is named by `tenantCode`. **Scope:** the project that owns `tenantCode`. ## Behaviour - This is step 1 of a PKCE login. Generate a random `codeVerifier`, send its S256 hash as `codeChallenge` here, and send the `codeVerifier` itself to `POST /auth/tenant/Patient/login/token`. - The account must be a Patient of the tenant's project. A Practitioner with the same email cannot log in here. - `PATIENT_LOGIN_ENABLED` on the project must not be `false` (it defaults to on). - Response `nextStep`: - `token`: no MFA. Pass `sessionCode` to `login/token`. - `mfa`: the user has MFA enrolled. Pass `loginId` and the current TOTP code to `POST /auth/tenant/Patient/login/mfa`. - A wrong email, an unknown account, an account without a password and a wrong password all give the same 401 `Invalid email or password.` - After 5 failed sign-ins for one email within 15 minutes, that email's sign-ins answer 429 with `Retry-After` for 15 minutes, the right password included, whether or not the email has an account. A successful sign-in resets the count. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Patient/login/start' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com", "password": "your-password", "tenantCode": "my-medical-project", "codeChallenge": "" }' ``` # Exchange patient session code for tokens Canonical page: https://docs.ovok.com/api/tenant-authentication/exchange-patient-session-code-for-tokens `POST /auth/tenant/Patient/login/token` Finishes a patient login: exchanges the session code from `login/start` (or `login/mfa`) and your PKCE `codeVerifier` for an access token and a refresh token. **Auth:** none. The session code and code verifier prove the earlier steps. ## Behaviour - Ovok redeems the code with Medplum's `oauth2/token` endpoint (`grant_type=authorization_code`). - The signed-in profile must be a Patient. A code for any other profile type is refused. - If the account was scheduled for deletion (`DELETE /auth/delete`), logging in cancels the deletion. - The response holds `accessToken`, `refreshToken`, `expiresIn` (seconds) and references to the `project` and `profile`. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Patient/login/token' \ -H 'Content-Type: application/json' \ -d '{ "sessionCode": "", "codeVerifier": "" }' ``` # Verify patient MFA code Canonical page: https://docs.ovok.com/api/tenant-authentication/verify-patient-mfa-code `POST /auth/tenant/Patient/login/mfa` Verifies the TOTP code of a patient who has MFA enrolled, after `login/start` answered `nextStep: "mfa"`. Returns the session code for `login/token`. **Auth:** none. The `loginId` from `login/start` identifies the login. ## Behaviour - `mfaToken` must equal the current TOTP code generated from the user's MFA secret. - On success the login is marked MFA-verified and the response is `{ "nextStep": "token", "sessionCode": ... }`. Pass `sessionCode` to `POST /auth/tenant/Patient/login/token`. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Patient/login/mfa' \ -H 'Content-Type: application/json' \ -d '{ "loginId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "mfaToken": "123456" }' ``` # Register a patient Canonical page: https://docs.ovok.com/api/tenant-authentication/register-a-patient `POST /auth/tenant/Patient/register` Registers a new patient account in a tenant and returns its tokens, so the user is signed in straight away. On some projects a business email address gets a clinician invite instead. **Auth:** none. The tenant is named by `tenantCode`. **Scope:** the project that owns `tenantCode`. ## Behaviour - Registration needs a default patient access policy on the project, and `PATIENT_REGISTRATION_ENABLED` must not be `false` (it defaults to on). The new membership gets that access policy. - The password must have at least 12 characters, not counting spaces at either end, and must not be on Ovok's list of common and breached passwords. Any character is allowed and none is required. A refused password answers 422 with the error on `password`. - An email that already has a Patient account in this project is refused. - **Clinician invite.** When the project setting `CLINICIAN_INVITE_ON_BUSINESS_EMAIL` is on and the address is a business address (not free-mail or disposable), no patient is created. Ovok creates a practitioner account with the project's default practitioner access policy, emails a `CLINICIAN_SIGNUP_INVITE` with a set-password link, and answers `{ "nextStep": "clinician-invite" }` (no tokens). If the invite cannot go out (no default practitioner policy, no practitioner app URL, the email fails), a patient is registered as usual. - The invite email carries a "continue as patient" link with a `continueAsPatientToken`. Send that token here to register as a patient anyway. It is valid for 7 days and only for the same email and project. - On success a `PATIENT_WELCOME` email is sent in the background. The response does not wait for it. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Patient/register' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com", "password": "your-password", "name": "Max", "surname": "Mustermann", "tenantCode": "my-medical-project" }' ``` # Start related person login Canonical page: https://docs.ovok.com/api/tenant-authentication/start-related-person-login `POST /auth/tenant/RelatedPerson/login/start` Starts a related person (carer) login for one tenant: checks the email and password and returns either a session code to exchange for tokens or, when the user has MFA enrolled, a login ID for the MFA step. **Auth:** none. The tenant is named by `tenantCode`. **Scope:** the project that owns `tenantCode`. ## Behaviour - This is step 1 of a PKCE login. Generate a random `codeVerifier`, send its S256 hash as `codeChallenge` here, and send the `codeVerifier` itself to `POST /auth/tenant/RelatedPerson/login/token`. - The account must be a RelatedPerson of the tenant's project. A carer account is made only by accepting a record-share invite (`POST /v1/invites/record-share/accept`); there is no register route. A Patient or Practitioner with the same email cannot log in here. - `RELATED_PERSON_LOGIN_ENABLED` on the project must not be `false` (it defaults to on). It is the carers' own switch: `PATIENT_LOGIN_ENABLED` does not apply to them. - Response `nextStep`: - `token`: no MFA. Pass `sessionCode` to `login/token`. - `mfa`: the user has MFA enrolled. Pass `loginId` and the current TOTP code to `POST /auth/tenant/RelatedPerson/login/mfa`. - A wrong email, an unknown account, an account without a password and a wrong password all give the same 401 `Invalid email or password.` - After 5 failed sign-ins for one email within 15 minutes, that email's sign-ins answer 429 with `Retry-After` for 15 minutes, the right password included, whether or not the email has an account. A successful sign-in resets the count. - A forgotten password is reset through `POST /v2/auth/reset-password` with `"type": "RelatedPerson"` and the app's `clientId`. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/RelatedPerson/login/start' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com", "password": "your-password", "tenantCode": "my-medical-project", "codeChallenge": "" }' ``` # Exchange related person session code for tokens Canonical page: https://docs.ovok.com/api/tenant-authentication/exchange-related-person-session-code-for-tokens `POST /auth/tenant/RelatedPerson/login/token` Finishes a related person (carer) login: exchanges the session code from `login/start` (or `login/mfa`) and your PKCE `codeVerifier` for an access token and a refresh token. **Auth:** none. The session code and code verifier prove the earlier steps. ## Behaviour - Ovok redeems the code with Medplum's `oauth2/token` endpoint (`grant_type=authorization_code`). - The signed-in profile must be a RelatedPerson. A code for any other profile type is refused. - The token reads only what patients have shared with the carer: the shared Observation codes and each sharer's record with its contact fields hidden. Practitioner and patient-only routes refuse it with 403. - If the account was scheduled for deletion (`DELETE /auth/delete`), logging in cancels the deletion. - The response holds `accessToken`, `refreshToken`, `expiresIn` (seconds) and references to the `project` and `profile`. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/RelatedPerson/login/token' \ -H 'Content-Type: application/json' \ -d '{ "sessionCode": "", "codeVerifier": "" }' ``` # Verify related person MFA code Canonical page: https://docs.ovok.com/api/tenant-authentication/verify-related-person-mfa-code `POST /auth/tenant/RelatedPerson/login/mfa` Verifies the TOTP code of a related person (carer) who has MFA enrolled, after `login/start` answered `nextStep: "mfa"`. Returns the session code for `login/token`. **Auth:** none. The `loginId` from `login/start` identifies the login. ## Behaviour - `mfaToken` must equal the current TOTP code generated from the user's MFA secret. - On success the login is marked MFA-verified and the response is `{ "nextStep": "token", "sessionCode": ... }`. Pass `sessionCode` to `POST /auth/tenant/RelatedPerson/login/token`. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/RelatedPerson/login/mfa' \ -H 'Content-Type: application/json' \ -d '{ "loginId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "mfaToken": "123456" }' ``` # Get example email template params Canonical page: https://docs.ovok.com/api/email/get-example-email-template-params `GET /email/templates` Returns one example set of params for every email template, keyed by template name. Use it to preview what a template receives. For the types, nullability and audience of each param, use `GET /v1/email/templates` instead. **Auth:** bearer token. Any signed-in user can call it. The response is the same for every project. ## Behaviour - The response is an object with one key per template name. Each value is an example of the params that template receives when it is sent. - The values are fixed sample data, not data from your project. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/email/templates' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List email templates and their params Canonical page: https://docs.ovok.com/api/email/list-email-templates-and-their-params `GET /v1/email/templates` Lists every email template a project can map in its email ConceptMap, with the params each one receives. Use it when you write or review a template. **Auth:** bearer token. The caller must be a Practitioner, an admin or a super admin, or hold the "System Owner" access policy. **Scope:** none. The list is the same for every project. ## Behaviour - Each entry has the template `name`, the `audience` (`patient` or `practitioner`), the `params`, a full `example`, and the `syntax` each provider uses to reference a param. - `audience` tells you whose app the `baseUrl` param points at: the patient app or the practitioner dashboard. - Every listed param is always sent. A param marked `nullable` is `null` when there is no value. - A send whose params do not match its template is refused, so a template can rely on every param listed. - Resend accepts text and numbers only. A list param `x` reaches Resend as `xList`, with one item per line, and a null reaches it as an empty string. - Entries follow the order of the `TemplateNames` enum. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/email/templates' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List the project's email template mappings Canonical page: https://docs.ovok.com/api/email/list-the-project-s-email-template-mappings `GET /v1/projects/me/email-templates` Lists the email template mappings of your current project: for each Ovok template name, which template of your email provider it sends, in which language and for which domain. It also lists the template names the project has no mapping for. **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 - `mappings` holds the project's **own** mappings. Mappings of the parent project and of the platform are not listed. - `unmapped` holds the template names the project has no mapping for, in any language or domain. It does not say that nothing is sent: a parent project's or the platform's mapping may still apply, and an unmapped patient template (`PATIENT_RESET_PASSWORD`, `PATIENT_ACCOUNT_DELETION`, `PATIENT_ORGANIZATION_CODES`, `PATIENT_INVITE`) is sent as its shared template when the mapping maps that one. - A mapping applies to a mail in its `language` and for its `domain`. A `null` `language` or `domain` means the mapping names none. Sending tries the most specific context first: domain and language, domain and the project's default language, domain alone, language alone, the default language, then no context. Within one level it takes the project's mapping, then its parent's, then the platform's, so a parent's or the platform's mapping at a more specific level is used before the project's own at a less specific one. - `ready` is `false` when the project's secrets lack what the provider needs: its credential (`BREVO_API_KEY`, `SENDGRID_API_KEY`, `RESEND_API_KEY` or `SMTP_URL`), and `EMAIL_FROM` for SendGrid and SMTP. It only checks that they are there, not that they work. A mapping that is not ready cannot send; sending moves on to the next mapping that applies. - One language and domain use one provider. When a project has several ConceptMaps for the same language and domain, only the most recently updated one is read, as sending does. - Mappings are ordered as the template names are, then by language and domain. Their `html` is left out: `GET /v1/projects/me/email-templates/:name` returns it. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/projects/me/email-templates' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get an email template mapping Canonical page: https://docs.ovok.com/api/email/get-an-email-template-mapping `GET /v1/projects/me/email-templates/{name}` Returns one email template mapping of your current project, with its HTML when it is an SMTP one. **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 - `:name` must be one of the template names. An unknown one returns 400 `UNKNOWN_TEMPLATE` with the accepted names. - `language` and `domain` choose which mapping of the template. Both are matched exactly, and leaving one out asks for the mapping that has none. `language` is one of Ovok's locale codes, such as `en-US` or `de-DE`; a bare `en` is read as `en-US`, and any other value returns 422. `domain` is a host name such as `app.example.com`, lower-cased, without scheme or port. - Only the project's own mappings are found. A template that is mapped in the parent project or the platform, but not here, returns 404. - `subject` and `html` are set for SMTP only. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/projects/me/email-templates/INVITE_TO_PROJECT?language=en-US' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Remove an email template mapping Canonical page: https://docs.ovok.com/api/email/remove-an-email-template-mapping `DELETE /v1/projects/me/email-templates/{name}` Removes one email template mapping of your current project. **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 - `:name` must be one of the template names. An unknown one returns 400 `UNKNOWN_TEMPLATE` with the accepted names. - `language` and `domain` choose which mapping of the template. Both are matched exactly, and leaving one out removes the mapping that has none. A malformed `language` or `domain` returns 422. - Only the project's own mappings can be removed. A template that is not mapped there returns 404, even when the parent project or the platform maps it. - After it is removed, sending uses the next mapping that applies, in the order `GET /v1/projects/me/email-templates` describes. That can be a parent project's or the platform's mapping, including one for a more specific language or domain than the one you removed. With none, the mail is not sent, except that a patient template (`PATIENT_RESET_PASSWORD`, `PATIENT_ACCOUNT_DELETION`, `PATIENT_ORGANIZATION_CODES`, `PATIENT_INVITE`) is sent as its shared template when the same mapping maps that one. - When it was the last mapping of its language and domain, that ConceptMap is deleted with it. If the project has an older ConceptMap for the same language and domain, only the newest is read, so removing it brings the older one back. - A 409 means another write to the project's mappings is running, or they changed while the server wrote. Read them again and retry. - The answer is 204 with no body. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/projects/me/email-templates/INVITE_TO_PROJECT?language=en-US' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Map an email template Canonical page: https://docs.ovok.com/api/email/map-an-email-template `PUT /v1/projects/me/email-templates/{name}` Maps an Ovok email template to a template of your email provider, for one language and domain. It replaces what the template was mapped to there, or adds the mapping when there is none. **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 - `:name` must be one of the template names. An unknown one returns 400 `UNKNOWN_TEMPLATE` with the accepted names. - `language` and `domain` in the query say where the mapping applies; leave one out for none. `language` is one of Ovok's locale codes, such as `en-US` or `de-DE`, because that is what a mail's language is matched on; a bare `en` is stored as `en-US`, and any other value returns 422. `domain` is a host name, lower-cased, without scheme or port. See `GET /v1/projects/me/email-templates` for how sending picks between mappings. - `provider` is `brevo`, `sendgrid`, `resend` or `smtp`. `templateId` is up to 200 characters and must be valid for the provider: digits only for Brevo, `d-` followed by lower-case hex for SendGrid, and no whitespace for Resend and SMTP. Otherwise 422 `INVALID_TEMPLATE_ID`. - SMTP has no hosted templates: send the `subject` (up to 998 characters) and the `html` (up to 200,000 characters) with it, and nothing else may carry them. A missing or blank one for SMTP, or either for another provider, returns 422 `INVALID_TEMPLATE_CONTENT`. - An SMTP subject and html are test-rendered with the template's example params before they are stored, the way sending renders them: a param the template does not have, or a block that is not closed, returns 422 `INVALID_TEMPLATE_CONTENT`. `GET /v1/email/templates` lists every template's params and how each provider writes a param. - One language and domain use one provider. Mapping with another one than the one already there returns 409 `PROVIDER_MISMATCH`: remove that language and domain's mappings first. - This does not set up the provider. Its credential and `EMAIL_FROM` are project secrets; until they exist the mapping is stored with `ready: false` and nothing is sent through it. - Writes to a project's mappings are one at a time. A second write that arrives while another is running is refused with 409 and not queued: retry it. A 409 also means the mappings changed while the server wrote; read them again and retry. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/projects/me/email-templates/INVITE_TO_PROJECT?language=en-US' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "provider": "brevo", "templateId": "12" }' ``` # Get the project's email providers Canonical page: https://docs.ovok.com/api/email/get-the-project-s-email-providers `GET /v1/email/templates/provider` Returns which email providers your current project has set up, whether each can send, and the sender address. It never returns a secret. **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 - `providers` lists `brevo`, `sendgrid`, `resend` and `smtp`, each with `configured` and `ready`. - `configured` is `true` when the project holds a secret for the provider that this server can read: its API key, or the SMTP URL. A secret stored with another key reads as not configured; set it up again with `POST`. - `ready` is `true` when the provider can send: it is configured and, for SendGrid and SMTP, the project has a sender address. - `from` is the sender address (the `EMAIL_FROM` secret), or `null`. - These are the caller's project's own secrets. A mail sent through a parent project's or the platform's template mapping uses that project's secrets, not these. - The project's email template mappings (`GET /v1/projects/me/email-templates`) say which provider each mail is sent through. A mapping sends only when its provider is ready. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/email/templates/provider' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Set up an email provider Canonical page: https://docs.ovok.com/api/email/set-up-an-email-provider `POST /v1/email/templates/provider` Sets up an email provider for your current project: stores its secret and, optionally, the sender address. Each value is stored encrypted with a key of the project's own and is never returned. **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 - `provider` is `brevo`, `sendgrid`, `resend` or `smtp`. - `secret` is the provider's credential, up to 2,000 characters: - Brevo: an API key starting with `xkeysib-`. - SendGrid: an API key starting with `SG.`. - Resend: an API key starting with `re_`. - SMTP: a URL `smtp://user:password@host:port` or `smtps://…`, whose host resolves to a public address. Anything else returns 422 `INVALID_SECRET`. The key is not tried against the provider. - `from` is the sender address, one for the whole project. SendGrid and SMTP need it: setting one up when the project has none and `from` is not sent returns 422 `FROM_REQUIRED`. Brevo and Resend send from the template's own sender when there is none. Sending `from` sets it for the whole project, so Resend then sends from it too. - A provider whose secret this server cannot read (stored with another key) counts as not set up, so `POST` replaces it. - A provider that is already set up returns 409 `PROVIDER_CONFIGURED`: change it with `PATCH /v1/email/templates/provider`. - When the server has no encryption key, nothing is stored and the answer is 503 `ENCRYPTION_UNAVAILABLE`. - A 409 without a code means the project changed while the server wrote. Read it again and retry. - The answer is 201, with the project's providers as `GET /v1/email/templates/provider` returns them. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/email/templates/provider' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "provider": "brevo", "secret": "xkeysib-…", "from": "care@example.com" }' ``` # Change an email provider Canonical page: https://docs.ovok.com/api/email/change-an-email-provider `PATCH /v1/email/templates/provider` Changes an email provider your current project has set up: replaces its secret, the sender address, or both. Each value is stored encrypted and is never returned. **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 - `provider` names the provider to change. One that is not set up returns 404 `PROVIDER_NOT_CONFIGURED`: set it up with `POST /v1/email/templates/provider`. - Send `secret`, `from`, or both. The rules are those of `POST`; a secret the provider does not take returns 422 `INVALID_SECRET`. - `from` is one sender address for the whole project, so changing it changes it for every provider. It cannot be cleared, only replaced. - When the server has no encryption key, nothing is stored and the answer is 503 `ENCRYPTION_UNAVAILABLE`. - A 409 means the project changed while the server wrote. Read it again and retry. - The answer has the project's providers as `GET /v1/email/templates/provider` returns them. ## Example ```bash curl -X PATCH 'https://api.sandbox.ovok.com/v1/email/templates/provider' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "provider": "brevo", "secret": "xkeysib-…" }' ``` # Get project locales Canonical page: https://docs.ovok.com/api/localization/get-project-locales `GET /locales` Returns the languages enabled for your project and its default language. **Auth:** bearer token. You need `List:read` and `List:search` access, or be a project admin. **Scope:** the caller's project (from the token). ## Behaviour - The locale settings are stored as a FHIR `List` in your project. - If the project has no locale settings yet, the route returns 404. Create them with `PATCH /locales`. - Localization and content routes accept only the languages returned here. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/locales' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Set project locales Canonical page: https://docs.ovok.com/api/localization/set-project-locales `PATCH /locales` Sets the languages enabled for your project and its default language. Creates the locale settings if the project has none. **Auth:** bearer token. You need `List:create`, `List:read`, `List:update`, `List:delete` and `List:search` access, or be a project admin. **Scope:** the caller's project (from the token). ## Behaviour - The body replaces the whole setting. `languages` needs at least one language, and `defaultLanguage` must be one of them. - For each language that is new compared with the previous setting, background jobs create AI translations of all localization keys and content items from the previous default language. Existing translations are not changed. - Removing a language does not delete its localizations or content. - Changing `defaultLanguage` does not move or translate anything by itself. ## Example ```bash curl -X PATCH 'https://api.sandbox.ovok.com/locales' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "languages": ["en-US", "de-DE", "fr-FR"], "defaultLanguage": "en-US" }' ``` # List access policies Canonical page: https://docs.ovok.com/api/slim/policy/list-access-policies `GET /v1/slim/policy` Lists the access policies (roles) of a project, each with the practitioners who hold it. Use it to render a roles table. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `Practitioner:create`, the right to invite users (a project admin who holds no access policy skips this check). **Scope:** The caller's project (from the token), or `projectId` when given. `projectId` must be the caller's project or a direct child of it. ## Behaviour - Each row is `{ policy, members }`. `members` lists only `Practitioner` members, as `{ reference, display }`. - `profile` keeps only the policies held by that member, given as a reference such as `Practitioner/`. - `sortBy` is `_id` (default), `_lastUpdated` or `name`; `orderBy` is `ASC` (default) or `DESC`. Rows with an empty sort value go last in `ASC` and first in `DESC`. - Paging is in memory: `page` (default `0`) and `count` (default `20`, 1 to 100). `total` counts the rows after filtering, before paging. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/policy?sortBy=name&orderBy=ASC&page=0&count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create access policy Canonical page: https://docs.ovok.com/api/slim/policy/create-access-policy `POST /v1/slim/policy` Creates an access policy (role) in your project and assigns it to the listed practitioners. Use it to define a new role. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `AccessPolicy:create` and `ProjectMembership:update` (a project admin who holds no access policy skips this check). **Scope:** The policy is created in the caller's project (from the token). ## Behaviour - You cannot create a policy above your own rank. Ranks come from the policy name or its `basedOn` display: `System Owner` is the highest, then `Admin`, then every other policy. Project admins rank as System Owner. - Ovok adds interactions the apps rely on: - `Consent`: `read`, `search`, `create`, `update`, always; - `DeviceUseStatement` and `EpisodeOfCare`: `read`, `search`, `create`, `update`, when the policy may create or update `Patient`; - `Provenance` and `AuditEvent`: `read`, `search`, when the policy is named `Admin` or `System Owner`. - `members` are profile references such as `Practitioner/`. Each listed member's membership in your project now points to the new policy, replacing the policy it held before. A member with no membership in your project is skipped. - You cannot list a member whose current role ranks above yours. A member ranks as every policy their membership holds now (`accessPolicy` and any `access` entries), each ranked by its name. A project admin (`admin: true`) ranks as System Owner. - The policy and the membership changes commit together. Past 49 membership changes they are written in two steps. - The policy is then copied by name into each direct child project. A failed copy does not fail the request. - Returns the created policy with its members, as in `GET /v1/slim/policy/{id}`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/policy' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "policy": { "resourceType": "AccessPolicy", "name": "Night shift", "resource": [{ "resourceType": "Patient", "interaction": ["read", "search"] }] }, "members": [{ "reference": "Practitioner/c3499c27-2973-0a7f-807e-fb8676a92dcb", "display": "Max Mustermann" }] }' ``` # Get access policy Canonical page: https://docs.ovok.com/api/slim/policy/get-access-policy `GET /v1/slim/policy/{id}` Returns one access policy (role) with the practitioners who hold it. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `Practitioner:create`, the right to invite users (a project admin who holds no access policy skips this check). **Scope:** The policy must belong to the caller's project (from the token), its parent project or one of its direct child projects. ## Behaviour - Returns `{ policy, members }`. `policy` is the full `AccessPolicy`. `members` lists the `Practitioner` members whose membership points to it, as `{ reference, display }`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/policy/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Delete access policy Canonical page: https://docs.ovok.com/api/slim/policy/delete-access-policy `DELETE /v1/slim/policy/{id}` Deletes an access policy (role) of your project and detaches it from everyone who holds it. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `AccessPolicy:delete` and `ProjectMembership:update` (a project admin who holds no access policy skips this check). **Scope:** The policy must belong to the caller's project (from the token). ## Behaviour - A policy is not deleted while a holder would be left with no role (no `access` entry, not a project admin): the request answers 409 until they are moved to another role, because Medplum reads a membership with no policy as full access. Other holders are detached. - You cannot delete a policy you hold yourself. - You cannot delete a policy held by anyone whose role ranks above yours (a project admin ranks as System Owner), since that takes their role away. - Detaching the members and deleting the policy commit together. Past 49 membership changes they are written in two steps. - The policy's copies of the same name in direct child projects are then deleted. A failed copy delete does not fail the request. - Returns an empty body. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/slim/policy/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update access policy Canonical page: https://docs.ovok.com/api/slim/policy/update-access-policy `PUT /v1/slim/policy/{id}` Replaces an access policy (role) of your project and sets exactly which practitioners hold it. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `Practitioner:create`, the right to invite users (a project admin who holds no access policy skips this check). **Scope:** The policy must belong to the caller's project (from the token). Policies of parent or child projects can be read but not updated here. ## Behaviour - `policy.id` must equal the `id` in the path. - The policy body is replaced with `policy`. The same interactions as on create are added (`Consent`; `DeviceUseStatement` and `EpisodeOfCare` for policies that create or update `Patient`; `Provenance` and `AuditEvent` for `Admin` and `System Owner` policies). - You cannot update a policy that ranks above you, nor rename one to a rank above you. Ranks: `System Owner`, then `Admin`, then every other policy. - You cannot add or remove a member whose current role ranks above yours. A member ranks as every policy their membership holds now (`accessPolicy` and any `access` entries), each ranked by its name. A project admin (`admin: true`) ranks as System Owner. - `members` is the complete list of holders, as references such as `Practitioner/`: - a listed member's membership in your project now points to this policy, replacing the one it held; - a current holder not listed loses the policy. Medplum reads a membership with no policy as full access, so if that would leave them with none (no `access` entries, not a project admin), the request answers 409: move them to another role first; - you cannot remove yourself. - The policy and the membership changes commit together. Past 49 membership changes they are written in two steps. - The updated policy is then copied by name into each direct child project, also when it was renamed. A failed copy does not fail the request. - Returns the updated policy with its members. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/policy/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "policy": { "resourceType": "AccessPolicy", "id": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "name": "Night shift", "resource": [{ "resourceType": "Patient", "interaction": ["read", "search", "update"] }] }, "members": [{ "reference": "Practitioner/c3499c27-2973-0a7f-807e-fb8676a92dcb" }] }' ``` # Check child project access policy drift Canonical page: https://docs.ovok.com/api/sub-project/check-child-project-access-policy-drift `GET /sub-project/access-policy/drift` Compares the AccessPolicies of each direct child of your current project with your project's own, and reports the differences. Nothing is written. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token) and its direct children. Grandchildren are not compared. ## Behaviour - Policies are matched by `name`, and compared on `compartment`, `resource` and `ipAccessRule`. - Each difference is one `drift` entry with a `kind`: - `missing`: the child has no policy with that name. - `changed`: the child's policy differs from yours. - `orphan`: the child holds a policy whose name your project does not have. A child's own policies, such as its patient-sharing template, show up as orphans. - `copyOfDeletedPolicy` is true for an `orphan` that is a copy of one of your policies you have since deleted: every copy is tagged with the id of the policy it copies, and that policy is no longer in your project. It is false for every other entry, a child's own policies included, and always false for the two patient-sharing templates every project makes for itself, whatever their tag. - `count` is the number of entries. - `POST access-policy/reconcile` repairs the `missing` and `changed` entries and deletes the `copyOfDeletedPolicy` ones. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/internal/sub-project/access-policy/drift' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Check child project access policy drift Canonical page: https://docs.ovok.com/api/sub-project/check-child-project-access-policy-drift-2 `GET /internal/sub-project/access-policy/drift` Compares the AccessPolicies of each direct child of your current project with your project's own, and reports the differences. Nothing is written. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token) and its direct children. Grandchildren are not compared. ## Behaviour - Policies are matched by `name`, and compared on `compartment`, `resource` and `ipAccessRule`. - Each difference is one `drift` entry with a `kind`: - `missing`: the child has no policy with that name. - `changed`: the child's policy differs from yours. - `orphan`: the child holds a policy whose name your project does not have. A child's own policies, such as its patient-sharing template, show up as orphans. - `copyOfDeletedPolicy` is true for an `orphan` that is a copy of one of your policies you have since deleted: every copy is tagged with the id of the policy it copies, and that policy is no longer in your project. It is false for every other entry, a child's own policies included, and always false for the two patient-sharing templates every project makes for itself, whatever their tag. - `count` is the number of entries. - `POST access-policy/reconcile` repairs the `missing` and `changed` entries and deletes the `copyOfDeletedPolicy` ones. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/internal/sub-project/access-policy/drift' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Check child project access policy drift Canonical page: https://docs.ovok.com/api/sub-project/check-child-project-access-policy-drift-3 `GET /v1/sub-project/access-policy/drift` Compares the AccessPolicies of each direct child of your current project with your project's own, and reports the differences. Nothing is written. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token) and its direct children. Grandchildren are not compared. ## Behaviour - Policies are matched by `name`, and compared on `compartment`, `resource` and `ipAccessRule`. - Each difference is one `drift` entry with a `kind`: - `missing`: the child has no policy with that name. - `changed`: the child's policy differs from yours. - `orphan`: the child holds a policy whose name your project does not have. A child's own policies, such as its patient-sharing template, show up as orphans. - `copyOfDeletedPolicy` is true for an `orphan` that is a copy of one of your policies you have since deleted: every copy is tagged with the id of the policy it copies, and that policy is no longer in your project. It is false for every other entry, a child's own policies included, and always false for the two patient-sharing templates every project makes for itself, whatever their tag. - `count` is the number of entries. - `POST access-policy/reconcile` repairs the `missing` and `changed` entries and deletes the `copyOfDeletedPolicy` ones. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/internal/sub-project/access-policy/drift' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Check child project access policy drift Canonical page: https://docs.ovok.com/api/sub-project/check-child-project-access-policy-drift-4 `GET /v1/internal/sub-project/access-policy/drift` Compares the AccessPolicies of each direct child of your current project with your project's own, and reports the differences. Nothing is written. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token) and its direct children. Grandchildren are not compared. ## Behaviour - Policies are matched by `name`, and compared on `compartment`, `resource` and `ipAccessRule`. - Each difference is one `drift` entry with a `kind`: - `missing`: the child has no policy with that name. - `changed`: the child's policy differs from yours. - `orphan`: the child holds a policy whose name your project does not have. A child's own policies, such as its patient-sharing template, show up as orphans. - `copyOfDeletedPolicy` is true for an `orphan` that is a copy of one of your policies you have since deleted: every copy is tagged with the id of the policy it copies, and that policy is no longer in your project. It is false for every other entry, a child's own policies included, and always false for the two patient-sharing templates every project makes for itself, whatever their tag. - `count` is the number of entries. - `POST access-policy/reconcile` repairs the `missing` and `changed` entries and deletes the `copyOfDeletedPolicy` ones. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/internal/sub-project/access-policy/drift' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Repair child project access policy drift Canonical page: https://docs.ovok.com/api/sub-project/repair-child-project-access-policy-drift `POST /sub-project/access-policy/reconcile` Repairs AccessPolicy drift in the direct children of your current project: it creates each missing copy and overwrites each changed one from your project's policy. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token) and its direct children. Grandchildren are not touched. ## Behaviour - Uses the same comparison as `GET access-policy/drift` and returns what it found, in the same shape, before the repair. - A `missing` policy is created in the child; a `changed` one is overwritten with your `compartment`, `resource` and `ipAccessRule`. Either way the child's copy is tagged with the id of your policy. - An `orphan` with `copyOfDeletedPolicy: true` is deleted: it is a copy of a policy you have deleted. Members of the child who still hold it are locked out of the child until they are given another role. - Any other `orphan` is listed and never deleted. A child's own policies carry no copy tag, and its patient-sharing templates are never deleted, whatever their tag. - Idempotent: a second call finds nothing left to repair, apart from the orphans it keeps. - The writes are not atomic. If one fails, the request fails; policies already written stay written, and you can call the route again. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/internal/sub-project/access-policy/reconcile' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Repair child project access policy drift Canonical page: https://docs.ovok.com/api/sub-project/repair-child-project-access-policy-drift-2 `POST /internal/sub-project/access-policy/reconcile` Repairs AccessPolicy drift in the direct children of your current project: it creates each missing copy and overwrites each changed one from your project's policy. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token) and its direct children. Grandchildren are not touched. ## Behaviour - Uses the same comparison as `GET access-policy/drift` and returns what it found, in the same shape, before the repair. - A `missing` policy is created in the child; a `changed` one is overwritten with your `compartment`, `resource` and `ipAccessRule`. Either way the child's copy is tagged with the id of your policy. - An `orphan` with `copyOfDeletedPolicy: true` is deleted: it is a copy of a policy you have deleted. Members of the child who still hold it are locked out of the child until they are given another role. - Any other `orphan` is listed and never deleted. A child's own policies carry no copy tag, and its patient-sharing templates are never deleted, whatever their tag. - Idempotent: a second call finds nothing left to repair, apart from the orphans it keeps. - The writes are not atomic. If one fails, the request fails; policies already written stay written, and you can call the route again. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/internal/sub-project/access-policy/reconcile' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Repair child project access policy drift Canonical page: https://docs.ovok.com/api/sub-project/repair-child-project-access-policy-drift-3 `POST /v1/sub-project/access-policy/reconcile` Repairs AccessPolicy drift in the direct children of your current project: it creates each missing copy and overwrites each changed one from your project's policy. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token) and its direct children. Grandchildren are not touched. ## Behaviour - Uses the same comparison as `GET access-policy/drift` and returns what it found, in the same shape, before the repair. - A `missing` policy is created in the child; a `changed` one is overwritten with your `compartment`, `resource` and `ipAccessRule`. Either way the child's copy is tagged with the id of your policy. - An `orphan` with `copyOfDeletedPolicy: true` is deleted: it is a copy of a policy you have deleted. Members of the child who still hold it are locked out of the child until they are given another role. - Any other `orphan` is listed and never deleted. A child's own policies carry no copy tag, and its patient-sharing templates are never deleted, whatever their tag. - Idempotent: a second call finds nothing left to repair, apart from the orphans it keeps. - The writes are not atomic. If one fails, the request fails; policies already written stay written, and you can call the route again. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/internal/sub-project/access-policy/reconcile' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Repair child project access policy drift Canonical page: https://docs.ovok.com/api/sub-project/repair-child-project-access-policy-drift-4 `POST /v1/internal/sub-project/access-policy/reconcile` Repairs AccessPolicy drift in the direct children of your current project: it creates each missing copy and overwrites each changed one from your project's policy. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token) and its direct children. Grandchildren are not touched. ## Behaviour - Uses the same comparison as `GET access-policy/drift` and returns what it found, in the same shape, before the repair. - A `missing` policy is created in the child; a `changed` one is overwritten with your `compartment`, `resource` and `ipAccessRule`. Either way the child's copy is tagged with the id of your policy. - An `orphan` with `copyOfDeletedPolicy: true` is deleted: it is a copy of a policy you have deleted. Members of the child who still hold it are locked out of the child until they are given another role. - Any other `orphan` is listed and never deleted. A child's own policies carry no copy tag, and its patient-sharing templates are never deleted, whatever their tag. - Idempotent: a second call finds nothing left to repair, apart from the orphans it keeps. - The writes are not atomic. If one fails, the request fails; policies already written stay written, and you can call the route again. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/internal/sub-project/access-policy/reconcile' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List project relationships Canonical page: https://docs.ovok.com/api/sub-project/list-project-relationships `GET /sub-project` Returns where your current project sits in the project hierarchy: its parent and its direct children. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token). ## Behaviour - `parentProjectId` is `null` for a project with no parent. - `subProjectIds` lists direct children only. - The result is cached for up to 5 minutes. Creating or deleting a child through Ovok clears the cache; other changes can take that long to show. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/internal/sub-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create a sub tenant Canonical page: https://docs.ovok.com/api/sub-project/create-a-sub-tenant `POST /sub-project` Creates a child project (sub-tenant) of your current project. Use it from admin tooling and from headless integrations that hold an admin client token. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). Setting `parentProjectId` also requires a super admin. **Scope:** the parent is the caller's project (from the token), or `parentProjectId` for a super admin. ## Behaviour - Creates, all or nothing: the `Project` (with the standard Ovok project features, `extension` copied as given, and its own Signals tenant), its tenant code, the parent's link to it, a Practitioner and an admin membership in the new project, and the parent-child relationship. If a step fails, the steps already done are undone. - **User session:** the new project is owned by your user, the Practitioner copies your profile, and the membership is yours. The response is `{ "success": true }`. - **Client application session** (no user): the new project is owned by the parent project. The response is `{ "success": true, "projectId": "..." }`. - A concurrent create of the same name under the same parent is refused with 409 and writes nothing. A later create with the same name makes a second project. - Served at both `/v1/internal/sub-project` and `/sub-project`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/internal/sub-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "My Medical Project" }' ``` # List project relationships Canonical page: https://docs.ovok.com/api/sub-project/list-project-relationships-2 `GET /internal/sub-project` Returns where your current project sits in the project hierarchy: its parent and its direct children. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token). ## Behaviour - `parentProjectId` is `null` for a project with no parent. - `subProjectIds` lists direct children only. - The result is cached for up to 5 minutes. Creating or deleting a child through Ovok clears the cache; other changes can take that long to show. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/internal/sub-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create a sub tenant Canonical page: https://docs.ovok.com/api/sub-project/create-a-sub-tenant-2 `POST /internal/sub-project` Creates a child project (sub-tenant) of your current project. Use it from admin tooling and from headless integrations that hold an admin client token. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). Setting `parentProjectId` also requires a super admin. **Scope:** the parent is the caller's project (from the token), or `parentProjectId` for a super admin. ## Behaviour - Creates, all or nothing: the `Project` (with the standard Ovok project features, `extension` copied as given, and its own Signals tenant), its tenant code, the parent's link to it, a Practitioner and an admin membership in the new project, and the parent-child relationship. If a step fails, the steps already done are undone. - **User session:** the new project is owned by your user, the Practitioner copies your profile, and the membership is yours. The response is `{ "success": true }`. - **Client application session** (no user): the new project is owned by the parent project. The response is `{ "success": true, "projectId": "..." }`. - A concurrent create of the same name under the same parent is refused with 409 and writes nothing. A later create with the same name makes a second project. - Served at both `/v1/internal/sub-project` and `/sub-project`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/internal/sub-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "My Medical Project" }' ``` # List project relationships Canonical page: https://docs.ovok.com/api/sub-project/list-project-relationships-3 `GET /v1/sub-project` Returns where your current project sits in the project hierarchy: its parent and its direct children. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token). ## Behaviour - `parentProjectId` is `null` for a project with no parent. - `subProjectIds` lists direct children only. - The result is cached for up to 5 minutes. Creating or deleting a child through Ovok clears the cache; other changes can take that long to show. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/internal/sub-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create a sub tenant Canonical page: https://docs.ovok.com/api/sub-project/create-a-sub-tenant-3 `POST /v1/sub-project` Creates a child project (sub-tenant) of your current project. Use it from admin tooling and from headless integrations that hold an admin client token. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). Setting `parentProjectId` also requires a super admin. **Scope:** the parent is the caller's project (from the token), or `parentProjectId` for a super admin. ## Behaviour - Creates, all or nothing: the `Project` (with the standard Ovok project features, `extension` copied as given, and its own Signals tenant), its tenant code, the parent's link to it, a Practitioner and an admin membership in the new project, and the parent-child relationship. If a step fails, the steps already done are undone. - **User session:** the new project is owned by your user, the Practitioner copies your profile, and the membership is yours. The response is `{ "success": true }`. - **Client application session** (no user): the new project is owned by the parent project. The response is `{ "success": true, "projectId": "..." }`. - A concurrent create of the same name under the same parent is refused with 409 and writes nothing. A later create with the same name makes a second project. - Served at both `/v1/internal/sub-project` and `/sub-project`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/internal/sub-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "My Medical Project" }' ``` # List project relationships Canonical page: https://docs.ovok.com/api/sub-project/list-project-relationships-4 `GET /v1/internal/sub-project` Returns where your current project sits in the project hierarchy: its parent and its direct children. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token). ## Behaviour - `parentProjectId` is `null` for a project with no parent. - `subProjectIds` lists direct children only. - The result is cached for up to 5 minutes. Creating or deleting a child through Ovok clears the cache; other changes can take that long to show. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/internal/sub-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create a sub tenant Canonical page: https://docs.ovok.com/api/sub-project/create-a-sub-tenant-4 `POST /v1/internal/sub-project` Creates a child project (sub-tenant) of your current project. Use it from admin tooling and from headless integrations that hold an admin client token. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). Setting `parentProjectId` also requires a super admin. **Scope:** the parent is the caller's project (from the token), or `parentProjectId` for a super admin. ## Behaviour - Creates, all or nothing: the `Project` (with the standard Ovok project features, `extension` copied as given, and its own Signals tenant), its tenant code, the parent's link to it, a Practitioner and an admin membership in the new project, and the parent-child relationship. If a step fails, the steps already done are undone. - **User session:** the new project is owned by your user, the Practitioner copies your profile, and the membership is yours. The response is `{ "success": true }`. - **Client application session** (no user): the new project is owned by the parent project. The response is `{ "success": true, "projectId": "..." }`. - A concurrent create of the same name under the same parent is refused with 409 and writes nothing. A later create with the same name makes a second project. - Served at both `/v1/internal/sub-project` and `/sub-project`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/internal/sub-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "My Medical Project" }' ``` # Delete a sub tenant Canonical page: https://docs.ovok.com/api/sub-project/delete-a-sub-tenant `DELETE /sub-project/{subProjectId}` Deletes a child project of your current project, with the setup Ovok created for it. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** `:subProjectId` must be a direct child of the caller's project (from the token). ## Behaviour - A project that still holds a `Patient`, `Device` or `Location`, or is the parent of another project, is refused with 409 `project_not_empty`. The body names the count per type in `counts` and the child ids in `childProjectIds`. Move or delete those first. - Otherwise the route unlinks the project from its parent, deletes its memberships, Practitioners, AccessPolicies, PlanDefinitions, ClientApplications, Organizations and tenant code in one atomic write, deletes the `Project`, revokes its Signals tenant and finally deletes the parent-child relationship. Audit records (`Provenance`, `AuditEvent`) are kept. - Users are never deleted; they may belong to other projects. - Retry-safe: if the Signals revoke fails, the project is already deleted and the route answers 502 `signals_tenant_revoke_failed`. Call it again to finish. - A second delete of the same project while the first runs answers 409. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/internal/sub-project/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Delete a sub tenant Canonical page: https://docs.ovok.com/api/sub-project/delete-a-sub-tenant-2 `DELETE /internal/sub-project/{subProjectId}` Deletes a child project of your current project, with the setup Ovok created for it. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** `:subProjectId` must be a direct child of the caller's project (from the token). ## Behaviour - A project that still holds a `Patient`, `Device` or `Location`, or is the parent of another project, is refused with 409 `project_not_empty`. The body names the count per type in `counts` and the child ids in `childProjectIds`. Move or delete those first. - Otherwise the route unlinks the project from its parent, deletes its memberships, Practitioners, AccessPolicies, PlanDefinitions, ClientApplications, Organizations and tenant code in one atomic write, deletes the `Project`, revokes its Signals tenant and finally deletes the parent-child relationship. Audit records (`Provenance`, `AuditEvent`) are kept. - Users are never deleted; they may belong to other projects. - Retry-safe: if the Signals revoke fails, the project is already deleted and the route answers 502 `signals_tenant_revoke_failed`. Call it again to finish. - A second delete of the same project while the first runs answers 409. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/internal/sub-project/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Delete a sub tenant Canonical page: https://docs.ovok.com/api/sub-project/delete-a-sub-tenant-3 `DELETE /v1/sub-project/{subProjectId}` Deletes a child project of your current project, with the setup Ovok created for it. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** `:subProjectId` must be a direct child of the caller's project (from the token). ## Behaviour - A project that still holds a `Patient`, `Device` or `Location`, or is the parent of another project, is refused with 409 `project_not_empty`. The body names the count per type in `counts` and the child ids in `childProjectIds`. Move or delete those first. - Otherwise the route unlinks the project from its parent, deletes its memberships, Practitioners, AccessPolicies, PlanDefinitions, ClientApplications, Organizations and tenant code in one atomic write, deletes the `Project`, revokes its Signals tenant and finally deletes the parent-child relationship. Audit records (`Provenance`, `AuditEvent`) are kept. - Users are never deleted; they may belong to other projects. - Retry-safe: if the Signals revoke fails, the project is already deleted and the route answers 502 `signals_tenant_revoke_failed`. Call it again to finish. - A second delete of the same project while the first runs answers 409. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/internal/sub-project/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Delete a sub tenant Canonical page: https://docs.ovok.com/api/sub-project/delete-a-sub-tenant-4 `DELETE /v1/internal/sub-project/{subProjectId}` Deletes a child project of your current project, with the setup Ovok created for it. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** `:subProjectId` must be a direct child of the caller's project (from the token). ## Behaviour - A project that still holds a `Patient`, `Device` or `Location`, or is the parent of another project, is refused with 409 `project_not_empty`. The body names the count per type in `counts` and the child ids in `childProjectIds`. Move or delete those first. - Otherwise the route unlinks the project from its parent, deletes its memberships, Practitioners, AccessPolicies, PlanDefinitions, ClientApplications, Organizations and tenant code in one atomic write, deletes the `Project`, revokes its Signals tenant and finally deletes the parent-child relationship. Audit records (`Provenance`, `AuditEvent`) are kept. - Users are never deleted; they may belong to other projects. - Retry-safe: if the Signals revoke fails, the project is already deleted and the route answers 502 `signals_tenant_revoke_failed`. Call it again to finish. - A second delete of the same project while the first runs answers 409. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/internal/sub-project/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Email organization codes Canonical page: https://docs.ovok.com/api/organization-code-information/email-organization-codes `POST /organizations/code/email` Emails a user the tenant codes of every organization (project) they have an account in. Use it on a sign-in screen for users who forgot their organization code. **Auth:** none. ## Behaviour - The route always answers 202 with no body and does the work in the background, so the answer does not tell you whether the email has an account. - The background job finds every account with this email, then looks up the tenant code of each project. If there are no accounts or no codes, no email is sent. - The email lists each project's name and code. It uses the `PATIENT_ORGANIZATION_CODES` template when the first account found is a Patient, and `OVOK_ORGANIZATION_CODES` otherwise. Language and domain come from the request. - The email address is lowercased. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/organizations/code/email' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com" }' ``` # Get organization code Canonical page: https://docs.ovok.com/api/organization-code-information/get-organization-code `GET /organizations/code` Returns the tenant code of the caller's project. Users type the code on sign-in screens to choose their organization. **Auth:** bearer token. **Scope:** the caller's project (from the token). ## Behaviour - The response holds `code` and `projectId`. - If the project has no tenant code, the request fails with 400 (`Tenant code not found`). - If more than one code row exists for a project, the most recently updated one is returned. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/organizations/code' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get current project settings Canonical page: https://docs.ovok.com/api/projects/get-current-project-settings `GET /v1/project/settings` 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/`: 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//`. - 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//`. 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 setting Canonical page: https://docs.ovok.com/api/projects/update-a-project-setting `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 ```bash 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 }' ``` # Update a project text setting Canonical page: https://docs.ovok.com/api/projects/update-a-project-text-setting `PUT /v1/project/settings/values/{key}` 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/` 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//`. - 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//`. 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" }' ``` # List administered projects Canonical page: https://docs.ovok.com/api/projects/list-administered-projects `GET /v1/projects` Lists every project you administer, with the tenant code you need to switch to it. Every other `/v1/projects` route answers about the single project of your token; use this one to build a project picker. **Auth:** bearer token. The caller must be a Practitioner, a project admin, or hold the System Owner access policy. You do not need to be an admin of your current project. **Scope:** your own user's Practitioner memberships across all projects, kept only where the membership is an admin one. ## Behaviour - One row per project, in membership order, even when you hold two memberships on one project. - `page` (from 0, default 0) and `count` (1 to 100, default 20) page over the projects. `total` counts the projects you administer, not your memberships. - `tenantCode` is `null` for a project that has none. `name` is `null` when the project can no longer be read; the row is kept. - `isMainProject` is `true` for a project with no parent, `false` for a child, and `null` when the hierarchy could not be read. - `parentProjectId` is set only when the parent is also a project you administer; otherwise it is `null`. - To switch, pass `tenantCode` to `POST /v1/auth/tenant/Practitioner/login/token`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/projects?page=0&count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List current project members Canonical page: https://docs.ovok.com/api/projects/list-current-project-members `GET /v1/projects/me/members` Lists the Practitioner members of your current project, one page at a time. **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 - Only memberships with a Practitioner profile are returned; patient, bot and client memberships are left out. - Filters: `accessPolicyId` (the membership's access policy), `profileId` (a Practitioner id) and `userId`. - `page` (from 0, default 0) and `count` (1 to 100, default 20) page the results. `total` is the exact number of matches. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/projects/me/members?page=0&count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Invite a Practitioner to the project Canonical page: https://docs.ovok.com/api/projects/invite-a-practitioner-to-the-project `POST /v1/projects/me/members` Adds a Practitioner to your current project and emails them a link to set their password. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token). The project setting `PRACTITIONER_INVITATION_ENABLED` must be on. ## Behaviour - `email` is trimmed and lowercased. `firstName` and `lastName` default to `New` and `Member`; `admin` defaults to `false`. - Creates the User (when the address has no account yet), the Practitioner and the membership in one write. - The invitee is emailed a link to set a password, built on the project's practitioner app URL (the project's `PRACTITIONER_APP_URL`, then the parent project's, then the legacy `CLINICIAN_DASHBOARD_URL`, then your request's `Origin` when CORS allows it, then the deployment default). The response has `pending: true` and `existingAccount: false`. - An address that can already sign in (it has a password, or belongs to another project) gets the membership but no email, and the response has `existingAccount: true`. - If the email cannot be sent, the new account is removed again and the request fails. - `access` sets the membership's `access[]` entries. Each must name an AccessPolicy of this project. With `access`, the membership's base `accessPolicy` is the project's `DEFAULT_PRACTITIONER_ACCESS_POLICY` setting. - A member with this email already exists on the project: 409. Setting `access` on a project with no default practitioner access policy: 409 `invitation_not_configured`. No practitioner app URL resolves: 409 `app_url_not_configured`, and nothing is created. - Practitioner invitations disabled on the project: 403. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/projects/me/members' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com", "firstName": "Max", "lastName": "Mustermann", "admin": false }' ``` # Get a project member Canonical page: https://docs.ovok.com/api/projects/get-a-project-member `GET /v1/projects/me/members/{membershipId}` Reads one Practitioner member of your current project. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token). A membership of another project answers 404. ## Behaviour - `emailVerified` is `true` once the member has used an emailed set-password link, and `null` when the User cannot be read. - `pending` is always `false` on this route. - The route requires a Practitioner membership; any other membership type is refused with 400. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/projects/me/members/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update a project member Canonical page: https://docs.ovok.com/api/projects/update-a-project-member `PATCH /v1/projects/me/members/{membershipId}` Changes a Practitioner member of your current project: their admin flag, their `access[]` entries, or both. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token). A membership of another project answers 404. ## Behaviour - `admin`: `true` or `false` sets the flag; `null` leaves it as it is. - `access`: replaces the membership's `access[]` entries; an empty array removes them. Omit it to leave them as they are. Each entry must name an AccessPolicy of this project. A membership without a base `accessPolicy` cannot have its entries removed, because Medplum would then grant access to the whole project. - `versionId`: pass the `meta.versionId` you read. If the membership changed since, the request answers 409. A concurrent write that lands first also answers 409. - A request that changes nothing returns the member unchanged. - Demoting the last admin of the project is refused. - After the change, Ovok renews its cached session data for every session of the member. Medplum applies the change on the member's next request. ## Example ```bash curl -X PATCH 'https://api.sandbox.ovok.com/v1/projects/me/members/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "admin": true }' ``` # Remove a project member Canonical page: https://docs.ovok.com/api/projects/remove-a-project-member `DELETE /v1/projects/me/members/{membershipId}` Removes a Practitioner from your current project. **Auth:** bearer token of a project admin (`ProjectMembership.admin`). **Scope:** the caller's project (from the token). A membership of another project answers 404. ## Behaviour - Deletes the membership and its Practitioner profile. The User is deleted only when it has no other membership in any project. - All or nothing: if one delete fails, the others are undone and the request fails. - Removing the last admin of the project is refused. - The response is `{ "success": true }`. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/projects/me/members/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get current project features Canonical page: https://docs.ovok.com/api/projects/get-current-project-features `GET /v1/projects/me/features` Returns the Medplum features (`Project.features`) enabled on your current project, such as `bots` or `cron`. **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 - Values are returned as stored, without checking them against the list `PATCH` accepts. An empty array means no features are enabled. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/projects/me/features' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update current project features Canonical page: https://docs.ovok.com/api/projects/update-current-project-features `PATCH /v1/projects/me/features` Replaces the Medplum features (`Project.features`) of your current project with the list you send. **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 - The list replaces the stored one; it is not merged. Send every feature you want enabled. Sending the same list twice has the same result. - Each value must be one of the FHIR `Project.features` codes. - The write only succeeds if the project did not change since the server read it; otherwise it answers 409. ## Example ```bash curl -X PATCH 'https://api.sandbox.ovok.com/v1/projects/me/features' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "features": ["bots", "cron", "websocket-subscriptions"] }' ``` # Translate text Canonical page: https://docs.ovok.com/api/ai-translation/translate-text `POST /ai/translation` Translates a list of strings from one language to another with an LLM. Use it to draft translations for content and localization keys. **Auth:** bearer token. **Scope:** the caller's project (from the token). The project's settings can add instructions to the translation prompt. ## Behaviour - `sourceLanguage` and `targetLanguage` take a language code such as `en` or `de-DE`, or a language name. Each is 2 to 100 characters. - `text` holds 1 or more strings. Each string and all strings together are limited to 10,000 characters. - Strings can be plain text, HTML or Markdown, and can contain placeholders such as `{{name}}`. Markup and placeholders are meant to be kept as they are, but the output comes from an LLM, so check it before you publish it. - The response returns the translations in `text`, in the same order as the input. - If the project has a setting named `TRANSLATION_ADDITIONAL_PROMPT`, its value is added to the prompt for every translation in that project. - Nothing is stored. The route only returns the translation. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/ai/translation' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "sourceLanguage": "en", "targetLanguage": "de", "text": ["Hello {{name}}, how are you?", "

Your appointment is today.

"] }' ``` # List current project users Canonical page: https://docs.ovok.com/api/slim/project/list-current-project-users `GET /v1/slim/project/users` Lists the practitioner memberships of your current project, with each member's user, profile, access policy and invite status. Use it to render a project's team list. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `Practitioner:read` (a project admin who holds no access policy skips this check). The session must carry a project. **Scope:** The caller's project (from the token). ## Behaviour - Returns one row per `ProjectMembership` of `profileType` (`Practitioner`) that has both a user and a profile. Memberships whose user or profile cannot be resolved are left out. - `status` is `Pending` while the user has an unused invite or has never set a password, and `Active` otherwise. - `accessPolicyId`, `profileId` and `userId` narrow the memberships by exact id. - `search` is a fuzzy match over the profile name, the user name and the access policy name. - `sortBy` defaults to `profileName` and `orderBy` to `ASC`. Rows with an empty sort value go last in `ASC` and first in `DESC`. - Paging is in memory: `page` (default `0`) and `count` (default `20`, 1 to 100). `total` counts the rows after `search`, before paging. - Answers are cached for up to about a minute, so a member added or removed a moment ago can be missing or still listed. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/project/users?sortBy=userName&orderBy=ASC&page=0&count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List child project relationships Canonical page: https://docs.ovok.com/api/slim/project/list-child-project-relationships `GET /v1/slim/project/child` Returns your current project together with its parent project and its direct child projects. Use it to build a project switcher or hierarchy view. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `AccessPolicy:read` (a project admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - `currentProject` is the caller's project. - `parentProject` is the project your project is a child of, or `null` when it has none. - `childProjects` lists every direct child, with no cap. Grandchildren are not included. - A child whose project no longer exists is left out. - Each project carries `name` (the project id when it has none), `address`, `contact` and `settings`. `settings.timeZone` defaults to `Europe/Berlin`; `settings.trendsPeriod` defaults to `start: "09:00:00"` and `durationSeconds: 86400`. - `GET /v2/slim/project/child` returns the same lists with a device count per project. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/project/child' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create a child project Canonical page: https://docs.ovok.com/api/slim/project/create-a-child-project `POST /v1/slim/project/child` Creates a child project under your current project and makes you its admin. Use it to set up a new customer or site below your organisation. **Auth:** Bearer token for a project admin. No other role passes. **Scope:** The new project becomes a direct child of the caller's project (from the token). A project that is itself a child may create children of its own. ## Behaviour - Your project must already hold at least one access policy: the child gets a copy of every access policy of your project. Without one the request is refused with 424 and nothing is created. - A second child with exactly the same `name` under the same parent is refused with 422. - The whole create is all or nothing. A failure undoes what was written and answers the failure. - On success Ovok: - creates the project with practitioner invitations and practitioner login enabled, and practitioner registration plus all patient registration, invitation and login disabled; - gives it its own Signals tenant and its own tenant code; - links it to your project; - copies your practitioner profile into it and adds you as an admin member; - seeds its thresholds from the global defaults, with an out-of-bed window that ends at 09:00 and starts at a time picked once from 18:00 to 20:00 in 5-minute steps, so homes do not all start watching in the same minute. The start is stored and stays until someone saves another window; - gives its Signals tenant the derived readings: each resident's daily mean heart rate and breathing rate (local midnight to midnight) and last night's sleep period, scheduled in the project's time zone. - The organization stored inside the project is built from `name`, `address`, `contact` and `settings`. `settings.timeZone` must be an IANA time zone such as `Europe/Zurich` (any other value is refused with 422) and defaults to `Europe/Berlin`. `id` and `extension` in the body are ignored. - When Signals cannot take the derived readings, the create is undone and answers 502, 503 when Signals is overloaded, or 504 when it does not answer in time. - When the platform has it enabled, an Ovok support account is also added as a non-admin member holding the child's System Owner access policy. It is skipped when the child has no single policy of that name. This step never fails the create. - Child project lists are refreshed right away. - Returns `{ "projectId": "", "success": true }`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/project/child' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "My Medical Project", "contact": [{ "telecom": [{ "system": "email", "use": "work", "value": "max.mustermann@example.com" }] }], "settings": { "timeZone": "Europe/Berlin" } }' ``` ```json { "projectId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "success": true } ``` # List child projects with device counts Canonical page: https://docs.ovok.com/api/slim/project/list-child-projects-with-device-counts `GET /v2/slim/project/child` Returns your current project together with its parent project and its direct child projects, each with its device count. Use it for a project switcher or hierarchy view that shows fleet size. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `AccessPolicy:read` (a project admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - Same lists as `GET /v1/slim/project/child`: `currentProject`, `parentProject` (`null` when there is none) and every direct child in `childProjects`. Grandchildren and children whose project no longer exists are left out. - Every project also carries `deviceCount`: the number of `Device` resources in that project. - `settings.timeZone` defaults to `Europe/Berlin`; `settings.trendsPeriod` defaults to `start: "09:00:00"` and `durationSeconds: 86400`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v2/slim/project/child' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Delete a child project Canonical page: https://docs.ovok.com/api/slim/project/delete-a-child-project `DELETE /v1/slim/project/child/{subProjectId}` Deletes an empty direct child project of your current project, including the setup Ovok created with it. Use it to remove a child project that is no longer needed. **Auth:** Bearer token for a project admin. No other role passes. **Scope:** `subProjectId` must be a direct child of the caller's project (from the token). ## Behaviour - The child must be empty: no `Patient`, `Device` or `Location`, and no child projects of its own. Otherwise the request is refused with 409 and nothing is changed. The 409 body has `error: "project_not_empty"`, a `counts` object per resource type and the `childProjectIds`. - On success Ovok unlinks the child from your project, deletes its access policies, practitioners, memberships, threshold plan, client applications, top-level organizations and tenant code, deletes the project, then revokes its Signals tenant. - User accounts are never deleted: a user can belong to other projects. Audit records (`Provenance`, `AuditEvent`) are kept. - Two deletes of the same project cannot run at once: the second gets 409. - The delete is safe to retry. If the Signals revoke fails, the project is already deleted and the request answers 502. Send the same request again to finish it. - Returns `{ "success": true }`. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/slim/project/child/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List project users Canonical page: https://docs.ovok.com/api/slim/project/list-project-users `GET /v1/slim/project/{id}/users` Lists the practitioner memberships of a given project: your own project or one of its direct child projects. Use it to manage the team of a child project from its parent. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `Practitioner:read` (a project admin who holds no access policy skips this check). The session must carry a project. **Scope:** The project in the path. It must be the caller's project (from the token) or a direct child of it. Grandchildren are not reachable. ## Behaviour - The project is read first, so an unknown or out-of-scope `id` fails before any membership is searched. - Rows, filters, sorting, paging and `status` work exactly as in `GET /v1/slim/project/users`: one row per `Practitioner` membership with a user and a profile, `search` is fuzzy over profile, user and access policy names, `count` is 1 to 100 (default `20`). - Answers are cached for up to about a minute. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/project/c3499c27-2973-0a7f-807e-fb8676a92dcb/users?count=50' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get project device counts Canonical page: https://docs.ovok.com/api/slim/project/get-project-device-counts `GET /v1/slim/project/{id}/device-counts` Returns summary counts of the devices in a project: total, assigned to a resident, active and by manufacturer. Use it for project overview tiles. **Auth:** Bearer token. The caller's access policy must grant `Device:search` and `Device:read` (a project admin who holds no access policy skips this check). **Scope:** The project in the path. It must be the caller's project (from the token) or a direct child of it. ## Behaviour - Counts come from the project's live device list, the same rows that back the live device views. That list is cached, so a device change can take a moment to show. - A row is left out when its device, resident, location or organization belongs to another project. - `assignedResidentDeviceCount` counts devices with a resident; `unassignedDeviceCount` is the rest. - `activeDeviceCount` counts devices whose latest telemetry reports them active; `inactiveDeviceCount` is the rest. - `withingsDeviceCount` counts devices whose serial number resolves to Withings. Every other device is counted in `radarDeviceCount`. - If the device list fails to build, the last complete list is used. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/project/c3499c27-2973-0a7f-807e-fb8676a92dcb/device-counts' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get project patient counts Canonical page: https://docs.ovok.com/api/slim/project/get-project-patient-counts `GET /v1/slim/project/{id}/patient-counts` Returns summary counts of the residents in a project by state: active, recently discharged, discharged and archived. Use it for project overview tiles. **Auth:** Bearer token. The caller's access policy must grant `Patient:search` and `Patient:read` (a project admin who holds no access policy skips this check). **Scope:** The project in the path. It must be the caller's project (from the token) or a direct child of it. ## Behaviour - Counts come from the project's live device list, so only residents linked to a device row are counted. A resident without a device is not included. - Each resident is counted once, even when linked to several devices. - A row is left out when its device, resident, location or organization belongs to another project. - The device list is cached, so a change can take a moment to show. If the list fails to build, the last complete list is used. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/project/c3499c27-2973-0a7f-807e-fb8676a92dcb/patient-counts' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get a project Canonical page: https://docs.ovok.com/api/slim/project/get-a-project `GET /v1/slim/project/{id}` Returns a project's name, address, contact and settings. Use it to show or edit your project or one of its child projects. **Auth:** Bearer token. The caller's access policy must grant `AccessPolicy:read` and `AccessPolicy:update` (a project admin who holds no access policy skips this check). **Scope:** The project in the path. It must be the caller's project (from the token) or a direct child of it. ## Behaviour - `address` and `contact` come from the organization stored inside the project. - `name` falls back to the project id when the project has no name. - `settings.timeZone` defaults to `Europe/Berlin` when none is stored. - `settings.trendsPeriod` defaults to `start: "09:00:00"` and `durationSeconds: 86400` when none is stored. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/project/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update a project Canonical page: https://docs.ovok.com/api/slim/project/update-a-project `PUT /v1/slim/project/{id}` Updates a project's name, address, contact and settings, and returns the updated project. Use it to edit your project or one of its child projects. **Auth:** Bearer token of a project admin (`ProjectMembership.admin`). **Scope:** The project in the path. It must be the caller's project (from the token) or a direct child of it. ## Behaviour - Sets the project `name` and replaces the organization stored inside the project with one built from `name`, `address`, `contact` and `settings`. This is a full replace, not a merge: - an omitted `address` or `contact` clears it; - an omitted `settings.timeZone` resets the time zone to `Europe/Berlin`; - an omitted `settings.trendsPeriod` removes the stored trends period, so reads fall back to the default. - `id` and `extension` in the body are ignored. The project comes from the path. - `settings.trendsPeriod.start` must be `HH:MM:SS`. - The response has the shape of `GET /v1/slim/project/{id}`. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/project/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "My Medical Project", "address": [{ "line": ["Hauptstrasse 1"], "city": "Berlin", "postalCode": "10115", "country": "DE" }], "settings": { "timeZone": "Europe/Berlin", "trendsPeriod": { "start": "09:00:00", "durationSeconds": 86400 } } }' ``` # Get current threshold Canonical page: https://docs.ovok.com/api/slim/threshold/get-current-threshold `GET /v1/slim/threshold` Returns the home's threshold configuration: the alert limits every resident follows unless they have limits of their own. > **Deprecated.** Use `GET /v2/slim/threshold`. This v1 route stays available, unchanged, until every client has moved. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `PlanDefinition:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - Read-only. - A home that has never saved thresholds gets the default template, with no `id`: heart rate on at 40–110 and respiratory rate on at 8–25 (the limits a new home is seeded with), and every other metric disabled. - If the stored thresholds cannot be read, the route answers 502, never the default template. - Units: `durationOfOutOfBed` is in seconds, `sleepDuration` in hours. - The home's limit ranges and the optional vitals (SpO₂, pulse rate, perfusion index, body temperature) are only on the v2 route. - Heart-rate and respiratory-rate limits are evaluated by Signals. Ovok stores them and forwards them to Signals. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/threshold' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update threshold Canonical page: https://docs.ovok.com/api/slim/threshold/update-threshold `PUT /v1/slim/threshold` Replaces the home's threshold configuration: the alert limits every resident follows unless they have limits of their own. > **Deprecated.** Use `PUT /v2/slim/threshold`. This v1 route stays available until every client has moved. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `PlanDefinition:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - The body replaces the stored settings; fields you omit take their schema defaults, except the out-of-bed window: a body without `durationOfOutOfBed.period`, or without `durationOfOutOfBed`, keeps the home's stored window (19:00:00 to 09:00:00 when it has none). The home's limit ranges and optional vitals, which v1 cannot send, are kept as stored. - Units: `durationOfOutOfBed` is in seconds, `sleepDuration` in hours. - `enabled: false` switches a metric fully off: its `absolute` and `relative` bands are stored off too, whatever their own `enabled` says, and the residents following the home hold no Signals limit for it (a resident with limits of their own keeps them). Out of bed keeps its `relative` band, which only tightens its limit while it is on. - To switch a metric back on, send its band's `enabled: true` as well. A switch-off stores the band's flag `false`, so a body that sets only the metric's `enabled: true` reads back `enabled: true` but arms nothing: the residents following the home get no limit for it. - `meanHeartRate` and `meanRespiratoryRate` relative bands cannot be enabled for the home: a resident without a baseline of their own would get no alarm from them. Set baseline limits per resident. One sent under `enabled: false` is stored off. - Every limit is evaluated by Signals, so every save is all or nothing, as `PUT /v2/slim/threshold` describes: it answers once Signals holds the home's limits, which every resident following the home follows at once, or puts everything back and answers an error with `saved: false` (409 another save or a tenant move got in the way; 502 out of time, or Signals did not take them; 500 the undo failed too). Nothing is stored then; send the save again. A 504 from the gateway can come while a failed save is still being put back: read the limits before sending it again. - A change-history entry is written for a save that stands. - The response is the saved configuration. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/threshold' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "status": "active", "settings": { "heartRate": { "mode": "organization", "enabled": true, "absolute": { "enabled": true, "min": 40, "max": 120 } } } }' ``` # Get patient effective threshold Canonical page: https://docs.ovok.com/api/slim/threshold/patient/get-patient-effective-threshold `GET /v1/slim/threshold/patient/{patientId}` Returns the thresholds in effect for one resident: their own limits where they have them, and the home's limits everywhere else. > **Deprecated.** Use `GET /v2/slim/threshold/patient/{patientId}`. This v1 route stays available, unchanged, until every client has moved. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Goal:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - Read-only; nothing is created. - Each metric carries `mode`: `patient` (the resident's own limits) or `organization` (the home's limits, copied in). A few legacy records still read `patient-auto`; saves can no longer set it. - Medical limits are read from Signals, which evaluates them, where available. When Signals cannot answer, Ovok's stored copy is returned instead. - This route does not check that the resident exists; the v2 route does. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/threshold/patient/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update patient threshold Canonical page: https://docs.ovok.com/api/slim/threshold/patient/update-patient-threshold `PUT /v1/slim/threshold/patient/{patientId}` Saves one resident's own thresholds. > **Deprecated.** Use `PUT /v2/slim/threshold/patient/{patientId}`. This v1 route stays available, unchanged, until every client has moved. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Goal:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The resident must be in the caller's project (from the token) or one of its sub-projects. ## Behaviour - Each metric's `mode` decides what is stored: - `patient`: your `absolute` / `relative` limits. - `organization`: the home's limits. Sending `enabled: false` for a metric the home has enabled switches it to `patient` mode, disabled. - `patient-auto` is no longer accepted: a body that uses it is refused with 422. - `patientId` in the body is required but ignored; the path decides the resident. - `average` and `averageRange` are set by the server; values you send are ignored. - Enabling a relative heart-rate or respiratory-rate band for a resident with no baseline average answers 424, because the band would have nothing to be relative to. - Every limit is evaluated by Signals, so every save writes the resident's settings to Signals before it answers, all or nothing: Signals holds the saved limits once it answers, or it answers 502 with `saved: false` and nothing is changed (a 500 says putting the previous limits back failed too). Send the save again. - Change-history entries are written for each changed metric. - The response is the saved threshold. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/threshold/patient/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "patientId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "status": "active", "settings": { "heartRate": { "mode": "patient", "enabled": true, "absolute": { "enabled": true, "min": 45, "max": 110 } } } }' ``` # Get patient vital thresholds Canonical page: https://docs.ovok.com/api/slim/threshold/patient/get-patient-vital-thresholds `GET /v1/slim/threshold/patient/{patientId}/vitals` Lists the bands the resident's own Signals settings hold for vitals other than the ones Ovok's thresholds cover. Signals is the certified service that evaluates readings. Ovok reads the stored limits from it and does not evaluate readings. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Goal:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The resident must be in the caller's project (from the token) or one of its sub-projects. A resident outside that scope answers 404, the same as an unknown id. ## Behaviour - Read-only. - Codes that the threshold routes own (`GET /v2/slim/threshold/patient/{patientId}`, for example SpO₂ and pulse rate) are left out of the list. - Each entry has `code`, `min` and `max` (each `null` for no bound on that side). `version` and `updatedAt` are always `null`: Signals keeps the band in the resident's settings, unversioned. - A resident with no Signals record, or with no such thresholds, gets `{ "vitals": [] }`. - A resident whose Signals record was left half-created by an interrupted create is completed by this read. - If Signals cannot be reached the route answers 502, never an empty list. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/threshold/patient/c3499c27-2973-0a7f-807e-fb8676a92dcb/vitals' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Remove a patient vital threshold Canonical page: https://docs.ovok.com/api/slim/threshold/patient/remove-a-patient-vital-threshold `DELETE /v1/slim/threshold/patient/{patientId}/vitals/{code}` Removes one resident's threshold for a single vital code in Signals, so that code no longer alerts for the resident. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Goal:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The resident must be in the caller's project (from the token) or one of its sub-projects; otherwise 404. ## Behaviour - Answers 204 with no body once Signals confirms the removal. A 502 means Signals did not confirm; the call is safe to repeat. - Codes the threshold routes own (for example SpO₂ and pulse rate) are refused with 400. - `code` must be 1 to 64 characters from letters, digits, `.`, `_` and `-`. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/slim/threshold/patient/c3499c27-2973-0a7f-807e-fb8676a92dcb/vitals/59408-5' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Set a patient vital threshold Canonical page: https://docs.ovok.com/api/slim/threshold/patient/set-a-patient-vital-threshold `PUT /v1/slim/threshold/patient/{patientId}/vitals/{code}` Sets one resident's threshold for a single vital code, replacing any threshold already held for that code. The threshold is written to Signals, which evaluates it. Ovok stores and forwards the limits and never evaluates readings. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Goal:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The resident must be in the caller's project (from the token) or one of its sub-projects; otherwise 404. The threshold is filed under the resident's own project. ## Behaviour - The body needs `min`, `max`, or both; a missing bound is `null`. When both are set, `min` must be less than `max`. To remove a threshold, use the DELETE route. - `code` must be 1 to 64 characters from letters, digits, `.`, `_` and `-`. - Codes the threshold routes own (for example SpO₂ and pulse rate) are refused with 400. Set those on `PUT /v2/slim/threshold/patient/{patientId}`. - The write waits for Signals to confirm. A 2xx means Signals holds the threshold; a 502 means it does not, so nothing changed and the call is safe to repeat. - The response is the saved `code`, `min` and `max`. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/threshold/patient/c3499c27-2973-0a7f-807e-fb8676a92dcb/vitals/59408-5' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "min": 90, "max": null }' ``` # Get current org threshold (v2) Canonical page: https://docs.ovok.com/api/slim/threshold/v2/get-current-org-threshold-v2 `GET /v2/slim/threshold` Returns the home's threshold configuration in the v2 shape: the alert limits every resident follows unless they have limits of their own. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `PlanDefinition:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - Heart-rate and respiratory-rate limits (and the optional vitals below) are evaluated by Signals. Ovok stores them and forwards them to Signals. - `settings.heartRate` and `settings.respiratoryRate` carry `mode: 'organization'` with absolute `min` and `max`. A home stored on a baseline band before baseline bands became per-resident still reads back as `mode: 'baseline'` with `deviationPercent`. A PUT no longer accepts that, so such a home must send an absolute band. - `settings.outOfBed.maxDurationSeconds` is a non-negative multiple of 60. `deviationPercent` is the home's relative out-of-bed band, or `null`. `baselineAverage` and `effectiveMaxDurationSeconds` are per resident, so they are `null` here; see `GET /v2/slim/threshold/patient/{patientId}`. - `settings.bedTimePeriod` is a top-level field, separate from `outOfBed`. `timezone` is resolved by the server: the home's time zone (Europe/Berlin unless the home set one), in which `start` and `end` are wall-clock times. A window nobody stored reads as 19:00 to 09:00, and that is the window the out-of-bed check applies. A home created through `POST /v1/slim/project/child` stores its own start, picked once from 18:00 to 20:00, so it reads the same on every call. - `ranges` is the range each vital's limits may take in this home. It is always present: what the home set, else the default (heart rate 40–120, respiratory rate 4–60). - `settings.oxygenSaturation`, `pulseRate`, `perfusionIndex` and `bodyTemperature` are `null` until the home watches the vital, else `{ mode: 'organization', enabled, min, max }`, where `min` or `max` is `null` for a one-sided limit. - Not in v2: `sleepDuration`, `numberOfTimesGettingOutOfBed`, standalone `meanHeartRate` / `meanRespiratoryRate`, `status`, `date`, the `patient-auto` mode, and the deprecated `durationSeconds`. - A home with no thresholds yet gets the default template, with `id: null`: heart rate on at 40–110 and respiratory rate on at 8–25 (the limits a new home is seeded with), and out of bed off. Heart or respiratory rate is off only once someone saves it off. If the stored thresholds cannot be read, the route answers 502, never the default template. - The v1 route `GET /v1/slim/threshold` is deprecated in favour of this one. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v2/slim/threshold' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update org threshold (v2) Canonical page: https://docs.ovok.com/api/slim/threshold/v2/update-org-threshold-v2 `PUT /v2/slim/threshold` Saves the home's threshold configuration in the v2 shape. `mode` is required on every settings field; `patient` is not a valid mode here. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `PlanDefinition:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - `settings.heartRate` and `settings.respiratoryRate`: `mode: 'organization'` with `enabled`, `min` and `max`. The home's band is absolute; `mode: 'baseline'` answers 422, because a resident without a baseline of their own would get no alarm from it. Set baseline limits per resident with `PUT /v2/slim/threshold/patient/{patientId}`. - `settings.outOfBed`: `mode: 'organization'` with `enabled` and `maxDurationSeconds` (a multiple of 60, from 0 to 86400), plus an optional `deviationPercent` (an integer from 5 to 300, or `null` to switch it off). With it, every resident on the home's out-of-bed setting alerts once an exit runs that far past their own usual exit, if that is sooner than `maxDurationSeconds`. Omit it to keep the stored value. - `settings.bedTimePeriod`: `mode: 'organization'` with `start` and `end` (`HH:MM:SS`). `end` equal to `start` means 24 hours; `end` before `start` crosses midnight. - `settings.oxygenSaturation`, `pulseRate`, `perfusionIndex`, `bodyTemperature` (each optional): `{ mode: 'organization', enabled, min, max }`, the home's default for every resident. Either bound may be `null` for a one-sided limit. An enabled vital needs at least one bound, and `min` must be below `max`. Omitting one, or sending `null`, keeps what is stored. Disabling one removes its rules in Signals. - `ranges` (optional): the range each vital's limits may take, for the home and every resident. Per vital, `{ min, max }` with `min < max`, inside heart rate 20–300, respiratory rate 4–150, SpO₂ 50–100, pulse 20–300, perfusion index 0–20 and body temperature 30–45. A vital left out keeps its stored range, or the default: heart rate 40–120, respiratory rate 4–60, SpO₂ 70–100, pulse 40–120, perfusion index 0–20, body temperature 34–42. A range for SpO₂, pulse, perfusion index or temperature is kept with that vital's setting, so the home must have set the vital (it may be disabled); otherwise the PUT answers 422 on `ranges.`. - Every enabled limit must sit inside its range, counting `ranges` in the same request. One outside answers 422 naming the field (for example `settings.heartRate.max`) and nothing is saved. A disabled band is not checked. - Narrowing a range does not rewrite residents whose limits fall outside it. A resident's next change to such a limit must fit; their other edits still save. - Medical limits (heart rate, respiratory rate, the optional vitals, the out-of-bed limit and the bed-time window) are evaluated by Signals. Every save is all or nothing, one that changes nothing included: it writes the home's settings to Signals and answers only once Signals holds them, and nothing writes them later. Residents following the home follow it at once, the out-of-bed band included (Signals applies it to each resident's usual exit); a resident with limits of their own keeps them. - Homes with many residents take longer: the save gives up after about 25 seconds and puts back what it wrote. Putting back can take longer than the gateway allows, so the caller may get a 504 while it finishes. Read the limits (`GET /v2/slim/threshold`) before sending the save again: until the undo is done, another save answers 409. - If any of that fails, everything the save changed is put back and it answers an error with `saved: false`. Nothing is stored; send the save again: - 409: another save of this home's limits is running, the home is moving to another Signals tenant, or the home's limits were saved while this one ran. - 502: the save ran out of time, or Signals did not take the limits. - 500: putting the previous limits back failed too. The message says which side kept the new limits; save the home's limits again. - If the stored thresholds cannot be read, the PUT answers 502 and nothing is saved. - Unknown keys are stripped, so a GET response can be sent back as a PUT body, with two exceptions: a heart-rate or respiratory-rate field still stored on baseline (see above), and a range the GET reports for an optional vital the home has never set. - A change-history entry is written for a save that stands. The response is the saved configuration, with `signalsSync: { status: 'ok' }`. - The v1 route `PUT /v1/slim/threshold` is deprecated in favour of this one. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v2/slim/threshold' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "settings": { "heartRate": { "mode": "organization", "enabled": true, "min": 40, "max": 120 }, "respiratoryRate": { "mode": "organization", "enabled": true, "min": 8, "max": 25 }, "outOfBed": { "mode": "organization", "enabled": true, "maxDurationSeconds": 900 }, "bedTimePeriod": { "mode": "organization", "start": "19:00:00", "end": "09:00:00" } } }' ``` # Get patient effective threshold (v2) Canonical page: https://docs.ovok.com/api/slim/threshold/patient/v2/get-patient-effective-threshold-v2 `GET /v2/slim/threshold/patient/{patientId}` Retrieves the effective patient threshold for a resident in the v2 contract. Every settings field carries a `mode` that tells the client whether the value is individualised (`'patient'`) or inherited from the org (`'organization'`); `'baseline'` on HR/RR indicates baseline-driven alerting. - `settings.heartRate` / `respiratoryRate`: discriminated on `mode` (`'organization' | 'patient' | 'baseline'`). Absolute branches carry `min` + `max`; baseline carries `deviationPercent`. Organization-mode fields carry the concrete effective org values so clients never compute the fallback themselves. - `settings.outOfBed` and `settings.bedTimePeriod` individualise independently — a resident can have a per-resident bed-time window on the org duration, or vice-versa (the #859 case). - `settings.outOfBed.deviationPercent` (or `null`) is the relative band: alert once an exit runs p % past the resident's usual one. `baselineAverage` is that usual exit length in seconds: the median exit inside the resident's bed-time period over the last 14 nights of Sleepiz presence batches, `null` with the band off or fewer than 7 nights in bed and 5 exits. `effectiveMaxDurationSeconds` is that limit as Ovok computes it for display: `maxDurationSeconds`, or the usual exit + p % when that is shorter, floored to the minute; `null` when out-of-bed alerting is off. Signals derives the limit it applies itself, from the raw `maxDurationSeconds` and band Ovok writes. - `timezone` inside `bedTimePeriod` is server-resolved: the zone the out-of-bed check reads the window in, which is the home's (Europe/Berlin unless the home set one). `start` and `end` are wall-clock times in it. - A window nobody stored reads as 19:00→09:00, and that is also the window the out-of-bed check applies. A stored `end === start` is a deliberate 24 h window. - `settings.oxygenSaturation`, `pulseRate`, `perfusionIndex`, `bodyTemperature`: `null` when neither the home nor the resident watches the vital, else `{ mode, enabled, min, max }` (`mode` is `'organization'` when it follows the home, `'patient'` for the resident's own limit), read from Ovok's store, which Signals' settings are written from. - `ranges`: the home's range for each vital's limits, the same as on `GET /v2/slim/threshold`, so an editor can bound a resident's inputs. - `signalsSync` is `pending` with `never-pushed` for a resident Signals holds no patient for (never enrolled), and `null` otherwise. Nothing is read back from Signals: every save writes Signals or fails, so what Ovok shows is what Signals holds. # Update patient threshold (v2) Canonical page: https://docs.ovok.com/api/slim/threshold/patient/v2/update-patient-threshold-v2 `PUT /v2/slim/threshold/patient/{patientId}` Updates the patient threshold in the v2 contract. `mode` is required on every settings field, and dictates which values the branch requires: - `mode: 'organization'` — follow the org default; send no other values. - `mode: 'patient'` (HR/RR/OOB) — individual absolute bounds. HR/RR: `enabled` + `min` + `max`. OOB: `enabled` + `maxDurationSeconds`, plus an optional `deviationPercent` (integer 5–300, or `null` to switch it off) that alerts sooner when an exit runs that far past the resident's usual one. It only ever brings the limit forward: `maxDurationSeconds` stays the limit when there is no baseline yet. Leaving `deviationPercent` out keeps what is stored. - `mode: 'baseline'` (HR/RR only) — individual baseline-driven alerting. `enabled` + `deviationPercent`. - `settings.bedTimePeriod`: `mode: 'organization'` (follow org window) or `mode: 'patient'` + `start` + `end`. Semantics: - Save = applied, all or nothing. Every save writes the resident's settings to Signals before it answers: `signalsSync: { status: 'ok' }` once Signals holds them, or 502 with `saved: false` and nothing changed (a 500 says putting the previous limits back failed too). Send the save again. - A second save of the same resident while one is still running answers 409 with `saved: false` and changes nothing. Send it again. - `enabled: false` preserves stored values (bounds or deviationPercent) — Disable round-trips untouched. - `timezone` never travels up on PUT bodies. - `settings.oxygenSaturation`, `pulseRate`, `perfusionIndex`, `bodyTemperature` (each optional): `{ mode: 'organization' }` follows the home; `{ mode: 'patient', enabled, min, max }` is the resident's own limit, either bound `null` for a one-sided one. Leaving one out, or sending `null`, keeps what is stored. Following a home that does not watch the vital removes the resident's rule in Signals. - A resident's own enabled limits, the four vitals' included, must sit inside the home's `ranges` (see GET). One outside answers 422 naming the field, and nothing is saved. A limit sent back unchanged is not re-checked, so a home that narrows its range does not block a resident's other edits. Ranges are the home's: set them on `PUT /v2/slim/threshold`; a `ranges` key here is ignored. # List change history Canonical page: https://docs.ovok.com/api/slim/change-history/list-change-history `GET /v1/slim/change-history` Lists the recorded changes to thresholds, locations, zones, devices, residents, and users and their roles in your project, newest first. Use it for the resident and administration change-history screens. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Provenance:read`. Only the Admin and System Owner access policies carry it, so other users get no change history. **Scope:** the caller's project (from the token). The rows are read with your token, so you only see changes recorded in your project. ## Behaviour - Each row is one recorded change. `details.key` names the change and `details.values` holds the values to put into its message. - Rows are sorted by recording time, newest first. `sort=asc` returns the same rows oldest first. Rows recorded in the same millisecond keep one fixed order, so paging never skips or repeats a row. - Without `startDate`, the list starts 30 days before now. `endDate` is optional. Both bounds are inclusive. - `types` limits the rows to the given change types. Omit it to get every type. Repeat the parameter to pass several types. - `scope=global` keeps only project-wide changes: organization threshold edits, device, location and zone lifecycle changes, and user and role changes. `scope=all` (the default) returns every row. - `types=Access` lists the user and role changes: a user invited (`userInvited`), renamed (`userRenamed`), moved to another role (`userRoleChanged`) or removed (`userRemoved`), and a role created (`roleCreated`), given other permissions (`rolePermissionsChanged`) or deleted (`roleDeleted`). They name users and roles by name and concern no resident. - `userId`, `residentId`, `deviceId`, `locationId` and `zoneId` are ids, not references. Each takes several ids, repeated or comma-separated, and matches a row concerning any of them. Different filters combine with AND. `userId` matches the practitioner who made the change. A value that is not an id answers 422. - `relatedTo` takes typed references (`Patient/`, `Device/`, `Location/`, `Organization/`), repeated or comma-separated, and returns every row concerning any of them, once each. - `actions` keeps the kinds of change you name: `created`, `deleted`, `renamed`, `moved`, `assigned`, `unassigned`, `discharged`, `reactivated`, `thresholdChanged`. Rows recorded before this filter shipped carry no kind, so they never match it. - `resident` on a row is the resident it concerns, `{patientId, residentId}`, or null when it concerns none. `residentId` inside it is their Resident ID, or null when they have none: show a placeholder, never a name. The flat `residentId` carries the same Resident ID, or is empty. Neither is ever a name or an internal id. - Threshold and Signals settings changes made through the Signals API are listed as Threshold changes, with the reason given. - Changes a device makes itself, such as a baseline re-push after a new 7-day mean, are never listed, and never counted in `total`. - Unknown query parameters are ignored. - `page` is zero-based and `count` defaults to 50, maximum 100. `total` counts only rows the list can return, and never exceeds 10,000. Pages from offset 10,000 on come back empty, so narrow the filters or the date range to reach older rows. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/change-history?types=Threshold&types=Resident&page=0&count=50' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List devices with telemetry (compatibility) Canonical page: https://docs.ovok.com/api/slim/query/list-devices-with-telemetry-compatibility `GET /v1/slim/query` Compatibility route for older query clients. Returns device rows joined with their resident, location, zone and telemetry. For new integrations, use `GET /v1/slim/device/live` or the `/v1/slim/patient` routes. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `search` and `read` on `Patient`, `Device`, `Location`, `Observation` and `Organization`. **Scope:** the caller's project (from the token). The `project` parameter is ignored. ## Behaviour - `mustInclude` lists the resources a row must have to be returned. `shouldInclude` lists the resources added to each row when present. Both are comma-separated lists of `organization`, `device`, `location`, `patient` and `telemetry`. - Every entry in `mustInclude` must also be in `shouldInclude`. `telemetry` in either list needs `device` in the same list. - When `mustInclude` contains `patient`, the query runs on the older resident-oriented path, which reads telemetry from the device database and Redis. Otherwise it runs on the same path as `GET /v1/slim/device/live`. - Without `includeUnassigned=true`, rows without a resident are left out when `patient` is required. - `organization` takes `Organization/`, `assigned` or `unassigned`. - `page` is zero-based. `count` defaults to 20, maximum 100. - The route returns 503 when the server is at capacity for live reads or the device list cannot be built. Retry shortly. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/query?mustInclude=device,telemetry&shouldInclude=organization,device,location,patient,telemetry&page=0&count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List telemetry and alerts (compatibility) Canonical page: https://docs.ovok.com/api/slim/query/list-telemetry-and-alerts-compatibility `GET /v1/slim/query/telemetry` Compatibility route for older live polling clients. Returns telemetry and alerts maps keyed by device identifier. For new integrations, use `GET /v1/slim/device/live/telemetry`. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `search` and `read` on `Patient`, `Device`, `Location`, `Observation` and `Organization`. **Scope:** the caller's project (from the token). The `project` parameter is ignored. ## Behaviour - Takes the same query parameters as `GET /v1/slim/query`, with the same validation rules. - Returns `total`, plus `telemetry` and `alerts` for the requested page only. - `alerts` has an entry for every device on the page. `telemetry` has an entry only for devices with telemetry. - The route returns 503 when the server is at capacity for live reads or the device list cannot be built. Retry shortly. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/query/telemetry?mustInclude=device,telemetry&shouldInclude=device,telemetry' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get resident devices with telemetry (compatibility) Canonical page: https://docs.ovok.com/api/slim/query/get-resident-devices-with-telemetry-compatibility `GET /v1/slim/query/patient/{id}` Compatibility route for older resident vitals clients. Returns the devices assigned to one resident, each with its telemetry. For new integrations, use `GET /v1/slim/patient/{id}/current-vitals`. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `search` and `read` on `Patient`, `Device`, `Location`, `Observation` and `Organization`. **Scope:** the caller's project (from the token). The `project` parameter is ignored. ## Behaviour - Returns up to 100 device rows for the resident, with zone, device and telemetry. - Results are cached for up to 60 seconds. Writes made through the Slim routes refresh the cache sooner. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/query/patient/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Count devices per zone (compatibility) Canonical page: https://docs.ovok.com/api/slim/query/count-devices-per-zone-compatibility `GET /v1/slim/query/organization/device/count` Compatibility route for older zone count clients. Returns device counts per zone. For new integrations, use `GET /v1/slim/zones/device-counts`. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Organization:search` and `Device:search`. **Scope:** the caller's project (from the token). For admins, the counts also cover the project's sub-projects. ## Behaviour - Each entry has the zone (`organization`) and its `deviceCount`, `assignedResidentDeviceCount`, `activeDeviceCount` and `inactiveDeviceCount`. - Devices without a zone are counted in an entry without `organization`. - Only zones with at least one device are listed, sorted by `deviceCount`, highest first. - A device counts as active when its telemetry reports it active. - The top-level `total*` fields sum the counts over all entries. `total` is the number of entries. - Results are cached for up to 60 seconds. Writes made through the Slim routes refresh the cache sooner. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/query/organization/device/count' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List users (compatibility) Canonical page: https://docs.ovok.com/api/slim/query/list-users-compatibility `GET /v1/slim/query/user` Compatibility route for older user list clients. Lists the practitioner users of a project with their profile, membership and access policy. For new integrations, use `GET /v1/slim/project/users`. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Practitioner:read`. **Scope:** the caller's project (from the token). When you pass `project=Project/`, that project is used instead. It must be your project or one of its sub-projects. ## Behaviour - `profileType` is required and must be `Practitioner`. - Each row has `user`, `profile`, `membership` and, when set, `accessPolicy`, reduced to the fields a list needs. - A user's status is `Pending` when they have an unused invite or no password yet, otherwise `Active`. - `accessPolicy`, `profile` and `user` filter on exact references, for example `AccessPolicy/`. - `search` matches profile name, user name and access policy name, with fuzzy matching. - `page` is zero-based. `count` defaults to 20, maximum 100. - Results are cached for up to 60 seconds. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/query/user?profileType=Practitioner&page=0&count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List users across projects (compatibility) Canonical page: https://docs.ovok.com/api/slim/query/list-users-across-projects-compatibility `GET /v1/slim/query/admin/user` Compatibility route for older cross-project user list clients. Behaves exactly like `GET /v1/slim/query/user`. For new integrations, use `GET /v1/slim/project/{id}/users`. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Practitioner:read`. No extra admin check is applied. **Scope:** the caller's project (from the token), or the project in `project=Project/` when it is your project or one of its sub-projects. ## Behaviour - Same parameters, filters, sorting, paging and caching as `GET /v1/slim/query/user`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/query/admin/user?profileType=Practitioner&project=Project/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get terms and conditions consent Canonical page: https://docs.ovok.com/api/slim/user/get-terms-and-conditions-consent `GET /v1/slim/user/terms-and-conditions-consent` Returns whether the signed-in practitioner has accepted the current terms and conditions. Use it to decide whether to show the terms prompt. **Auth:** Bearer token for a practitioner session (the profile must be a `Practitioner`). The caller's access policy must grant `Consent:read` and `Consent:search` (a project admin who holds no access policy skips this check). **Scope:** The caller's practitioner profile in the caller's project (from the token). ## Behaviour - `termsAndConditionsConsent` is `true` only when an acceptance is on file and either matches the currently published terms version or no version has been published yet. - Publishing new terms turns it `false` for everyone until they accept again. - The published version is the one of the root project of your project tree: a child project follows its parent's terms. Without one, the platform-wide version applies. - `GET /v1/me/consent/legal` returns the same acceptance with its dates and terms link. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/user/terms-and-conditions-consent' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update terms and conditions consent Canonical page: https://docs.ovok.com/api/slim/user/update-terms-and-conditions-consent `POST /v1/slim/user/terms-and-conditions-consent` Accepts or withdraws the terms and conditions for the signed-in practitioner. Other consents are not changed. **Auth:** Bearer token for a practitioner session (the profile must be a `Practitioner`). The caller's access policy must grant `Consent:read`, `Consent:search`, `Consent:create` and `Consent:update` (a project admin who holds no access policy skips this check). **Scope:** The caller's practitioner profile in the caller's project (from the token). ## Behaviour - `true` records acceptance of the currently published terms version. `false` withdraws it. - The acceptance is also kept as a legal `Consent` in your project: accepting creates or re-activates it with a link to the terms page of your project's practitioner app; withdrawing revokes it with reason `withdrawn`. - Repeating the same value writes nothing. The call is idempotent. - The consent answers of `/v1/me/consent/*` are refreshed right away. - Returns the resulting `termsAndConditionsConsent`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/user/terms-and-conditions-consent' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "termsAndConditionsConsent": true }' ``` # Get all user consents Canonical page: https://docs.ovok.com/api/slim/user/get-all-user-consents `GET /v1/slim/user/consents` Returns every consent of the signed-in practitioner in one response. Use it at sign-in to decide which consent prompts to show. **Auth:** Bearer token for a practitioner session (the profile must be a `Practitioner`). The caller's access policy must grant `Consent:read` and `Consent:search` (a project admin who holds no access policy skips this check). **Scope:** The caller's practitioner profile in the caller's project (from the token). ## Behaviour - Both `medicalSettingsNotificationsConsent` and `termsAndConditionsConsent` are versioned. Each is `true` only when an acceptance is on file and either matches the currently published version of that consent or no version has been published yet. - Publishing a new version of a consent turns it `false` for everyone until they accept again. - The published version is the one of the root project of your project tree. Without one, the platform-wide version applies. - A consent with no record reads `false`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/user/consents' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` ```json { "medicalSettingsNotificationsConsent": true, "termsAndConditionsConsent": false } ``` # Update user consents Canonical page: https://docs.ovok.com/api/slim/user/update-user-consents `POST /v1/slim/user/consents` Updates one or more consents of the signed-in practitioner. Use it to save the answers of a combined consent prompt. **Auth:** Bearer token for a practitioner session (the profile must be a `Practitioner`). The caller's access policy must grant `Consent:read`, `Consent:search`, `Consent:create` and `Consent:update` (a project admin who holds no access policy skips this check). **Scope:** The caller's practitioner profile in the caller's project (from the token). ## Behaviour - Send at least one of `medicalSettingsNotificationsConsent` and `termsAndConditionsConsent`. Only the fields you send change. - `true` records acceptance of the currently published version of that consent. `false` withdraws it. - A `termsAndConditionsConsent` change also creates, re-activates or revokes the legal `Consent` read by `GET /v1/me/consent/legal`. - All changes commit together or not at all. Repeating the same values writes nothing. - The consent answers of `/v1/me/consent/*` are refreshed right away. - The response always carries the resulting state of every consent. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/user/consents' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "medicalSettingsNotificationsConsent": true, "termsAndConditionsConsent": true }' ``` # Send support message Canonical page: https://docs.ovok.com/api/slim/user/send-support-message `POST /v1/slim/user/support` Sends a support email on behalf of the signed-in user to the support address configured for this Ovok environment. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `Patient:read`, `Patient:search`, `Device:read`, `Device:search`, `Observation:read` and `Observation:search` (a project admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - Sends one email built from the `message`, `version` and `environment` you send. - The email also carries details taken from your session, not from the body: your name, email, project name, profile type, access policy name and tenant code. - Nothing else is written. - Returns `true` once the email is sent. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/user/support' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "message": "The live view does not load.", "version": "1.8.0", "environment": "production" }' ``` # Delete user Canonical page: https://docs.ovok.com/api/slim/user/delete-user `DELETE /v1/slim/user/{profileType}/{profileId}` Removes a practitioner from a project: deletes their membership and practitioner profile, and their user account when this was their last membership. Use it to offboard a team member. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `Practitioner:delete` (a project admin who holds no access policy skips this check). **Scope:** The practitioner's project must be the caller's project (from the token) or a direct child of it. ## Behaviour - `profileType` must be `Practitioner` and `profileId` a UUID. - The membership, the practitioner and, when it has no other membership, the user are deleted together or not at all. - The owner of the caller's own project cannot be deleted. The owner of a child project can. - After the delete, an account-deletion email is sent to the user's email address, if they have one. A failed email does not fail the request. - Returns `{ "success": true }`. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/slim/user/Practitioner/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get legal consent Canonical page: https://docs.ovok.com/api/me/consent/get-legal-consent `GET /v1/me/consent/legal` Returns the signed-in practitioner's legal consent: which terms they accepted, when, and whether the acceptance is still active. Use it on app load to decide whether to ask for the terms again. **Auth:** Bearer token for a practitioner session (the profile must be a `Practitioner`). The caller's access policy must grant `Consent:read` and `Consent:search` (a project admin who holds no access policy skips this check). **Scope:** The caller's practitioner profile in the caller's project (from the token). ## Behaviour - `legal` is `null` when the practitioner has never accepted the terms in this project. - `status` is `active` or `revoked`. Publishing new terms revokes every acceptance on an older version with `revokedReason: "tos-updated"`; withdrawing revokes it with `revokedReason: "withdrawn"`. Both reasons are `null` while the consent is active. - `revokedAt` is when the revoke happened, or for `tos-updated` when the new terms were published. - `termsUrl` is the terms page the practitioner accepted. It is `null` unless it is an `http(s)` URL or an app-relative path. - `termsUpdatedAt` is when the accepted terms were last updated, `null` when that is not known. - The published terms version is the one of the root project of your project tree: a child project follows its parent's terms. - Answers are cached for a rolling day. Any consent write by the practitioner and any publish of new terms refreshes them right away. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/me/consent/legal' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` ```json { "legal": { "consentId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "status": "revoked", "termsUrl": "https://app.example.com/legal/terms-and-conditions", "termsUpdatedAt": "2026-09-01T08:00:00.000Z", "acceptedAt": "2026-09-02T07:30:00.000Z", "revokedAt": "2026-10-01T09:00:00.000Z", "revokedReason": "tos-updated" } } ``` # Accept or withdraw the terms Canonical page: https://docs.ovok.com/api/me/consent/accept-or-withdraw-the-terms `POST /v1/me/consent/legal` Accepts or withdraws the terms for the signed-in practitioner and returns the resulting legal consent. **Auth:** Bearer token for a practitioner session (the profile must be a `Practitioner`). The caller's access policy must grant `Consent:read`, `Consent:search`, `Consent:create` and `Consent:update` (a project admin who holds no access policy skips this check). **Scope:** The caller's practitioner profile in the caller's project (from the token). ## Behaviour - `termsAndConditionsConsent: true` records acceptance of the currently published terms. It creates the legal consent, or re-activates a revoked one, with a link to the terms page of your project's practitioner app and the time of acceptance. - `termsAndConditionsConsent: false` revokes an active legal consent with `revokedReason: "withdrawn"`. With no active consent it changes nothing. - Accepting again on the same terms version writes nothing. - The terms value read by `GET /v1/slim/user/consents` changes in the same commit. Other consents are not changed. - The response has the shape of `GET /v1/me/consent/legal`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/me/consent/legal' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "termsAndConditionsConsent": true }' ``` # Get medical consent Canonical page: https://docs.ovok.com/api/me/consent/get-medical-consent `GET /v1/me/consent/medical` Returns the signed-in practitioner's medical settings notifications consent, or `null` when it is not given. Use it on app load to decide whether to show the medical notifications prompt. **Auth:** Bearer token for a practitioner session (the profile must be a `Practitioner`). The caller's access policy must grant `Consent:read` and `Consent:search` (a project admin who holds no access policy skips this check). **Scope:** The caller's practitioner profile in the caller's project (from the token). ## Behaviour - `medical` is `null` when the practitioner never gave the consent or withdrew it. - Only withdrawing ends it. Unlike `GET /v1/slim/user/consents`, a newly published version does not turn it off here. - `acceptedAt` is when it was given, `null` when that is not recorded. - Answers are cached for a rolling day. Any consent write by the practitioner refreshes them right away. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/me/consent/medical' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` ```json { "medical": { "consentId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "acceptedAt": "2026-09-02T07:30:00.000Z" } } ``` # Give or withdraw the medical consent Canonical page: https://docs.ovok.com/api/me/consent/give-or-withdraw-the-medical-consent `POST /v1/me/consent/medical` Gives or withdraws the medical settings notifications consent for the signed-in practitioner and returns the resulting medical consent. Other consents are not changed. **Auth:** Bearer token for a practitioner session (the profile must be a `Practitioner`). The caller's access policy must grant `Consent:read`, `Consent:search`, `Consent:create` and `Consent:update` (a project admin who holds no access policy skips this check). **Scope:** The caller's practitioner profile in the caller's project (from the token). ## Behaviour - `medicalSettingsNotificationsConsent: true` records the consent on the currently published version. `false` withdraws it. - Sending the current value again writes nothing. - The value read by `GET /v1/slim/user/consents` changes in the same commit. - The response has the shape of `GET /v1/me/consent/medical`: `medical` is `null` after a withdrawal. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/me/consent/medical' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "medicalSettingsNotificationsConsent": true }' ``` # Get a public resource Canonical page: https://docs.ovok.com/api/public-resource-access/get-a-public-resource `GET /public/{token}` Reads a FHIR resource through its public token, without a bearer token. Use it to share one resource, such as a form or a document, with people who have no Ovok account. **Auth:** none. The public token in the path is the credential: anyone with it can read the resource. ## Behaviour - A resource becomes public when it gets a token in `meta.extension`, with the URL `https://api.ovok.com/fhir/StructureDefinition/public-resource-token`. Use `PATCH /public/{resourceType}/{id}` to give a resource a token. - The token names exactly one resource. The response is that resource as stored, including its `meta.extension`. - A token stops working when the resource's token is replaced or deleted, or when the resource is deleted. ## Example ```bash curl 'https://api.sandbox.ovok.com/public/example.jwt.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Change public resource token Canonical page: https://docs.ovok.com/api/public-resource-access/change-public-resource-token `PATCH /public/{resourceType}/{id}` Gives a resource a new public token, so it can be read with `GET /public/{token}`. If the resource already has a token, the old one is replaced and stops working. **Auth:** bearer token of a project admin. ## Behaviour - The resource must be in the caller's project or one of its sub-projects. A resource of any other project, the parent project included, answers `403` and is left unchanged; an unknown id answers `404`. - The token is written to the resource's `meta.extension` with the URL `https://api.ovok.com/fhir/StructureDefinition/public-resource-token`. Other extensions are kept. - The response is `{ token, resource }`: the new token and the updated resource. ## Example ```bash curl -X PATCH 'https://api.sandbox.ovok.com/public/DocumentReference/87ea5dfc-8b8e-384d-8489-79496e706390' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` ```json { "token": "...", "resource": { "resourceType": "DocumentReference", "id": "87ea5dfc-8b8e-384d-8489-79496e706390", "meta": { "extension": [ { "url": "https://api.ovok.com/fhir/StructureDefinition/public-resource-token", "valueString": "..." } ] }, ... } } ``` # Delete public resource token Canonical page: https://docs.ovok.com/api/public-resource-access/delete-public-resource-token `DELETE /public/{resourceType}/{id}` Removes the public token from a resource, so it can no longer be read with `GET /public/{token}`. The resource itself is kept. **Auth:** bearer token of a project admin. ## Behaviour - The resource must be in the caller's project or one of its sub-projects. A resource of any other project, the parent project included, answers `403` and is left unchanged; an unknown id answers `404`. - Removes the `meta.extension` entry with the URL `https://api.ovok.com/fhir/StructureDefinition/public-resource-token`. Other extensions are kept. - Calling it on a resource without a token succeeds. - The response is `{ token: null, resource }` with the updated resource. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/public/DocumentReference/87ea5dfc-8b8e-384d-8489-79496e706390' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Search documents Canonical page: https://docs.ovok.com/api/document/search-documents `GET /document` Lists the documents you can read, newest first by default. Use it to build a file list. **Auth:** bearer token. The search runs with your token, so Medplum returns only DocumentReferences you can read. ## Behaviour - `_count` sets the page size (default `100`), `_offset` the number of documents to skip (default `0`), and `_sort` the order (default `-_lastUpdated`). - `total` is an estimate from Medplum, not an exact count. Use it for a page counter, not for logic that needs the exact number. - Each entry has `id`, `meta.lastUpdated`, `author`, `fileName`, `contentType`, and `publicToken` when the document is public. Entries never include `uploadOptions`. ## Example ```bash curl -G 'https://api.sandbox.ovok.com/document' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -d '_count=20' \ -d '_offset=0' ``` # Create document upload credentials Canonical page: https://docs.ovok.com/api/document/create-document-upload-credentials `POST /document` Creates a document and returns a signed form that you use to upload its file straight to storage. Use it for every new file: Ovok never receives the file bytes itself. **Auth:** bearer token. The document is created with your token, so you need create access to Binary and DocumentReference. **Scope:** the caller's project (from the token). ## Behaviour - Creates an empty Binary and a DocumentReference with `status: current`, the given `fileName` as title and `contentType`, and you as `author`. - `contentType` must be one of the allowed types: `image/jpeg`, `image/jpg`, `image/png`, `image/gif`, `image/webp`, `application/pdf`, `application/json`, `application/xml`, `text/plain`, `text/csv`, `video/mp4`, `video/webm`, `audio/mpeg`, `audio/wav`. - With `isPublic: "true"`, the document also gets a public token (`publicToken`) that anyone can use with `GET /document/public/{token}`. - `uploadOptions` holds a URL and form fields. Send a `multipart/form-data` POST to `uploadOptions.url` with every entry of `uploadOptions.fields` as a form field, then the file as the field `file`. The form expires 10 minutes after it is issued and accepts files up to 5 GB. - The document exists as soon as this call returns, even if you never upload the file. - This route is rate limited: 20 requests a minute for admins, 10 a minute for other users. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/document' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "fileName": "cat.png", "contentType": "image/png", "isPublic": "false" }' ``` ```json { "id": "87ea5dfc-8b8e-384d-8489-79496e706390", "meta": { "lastUpdated": "2026-01-01T12:00:00.000Z" }, "author": { "reference": "Practitioner/...", "display": "Max Mustermann" }, "fileName": "cat.png", "contentType": "image/png", "uploadOptions": { "url": "https://...", "fields": { "key": "...", "Policy": "...", "X-Amz-Signature": "...", ... } } } ``` Then upload the file with the returned form: ```bash curl -X POST '' \ -F 'key=...' \ -F 'Policy=...' \ -F 'X-Amz-Signature=...' \ -F 'file=@cat.png' ``` # Download a public document Canonical page: https://docs.ovok.com/api/document/download-a-public-document `GET /document/public/{token}` Downloads the file of a public document, without a bearer token. Use it to embed a file in a web page or an email, for example in an `` tag. **Auth:** none. The public token in the path is the credential: anyone with the URL can get the file. ## Behaviour - The token is the document's `publicToken`. A document gets one when it is created or updated with `isPublic` set to true. - The response is `307 Temporary Redirect` to a signed file URL, as in `GET /document/{id}`, including the same resizing options (`width`, `height`, `fit`). - A token stops working when the document is made private again, or when its public token is replaced. ## Example ```bash curl -L 'https://api.sandbox.ovok.com/document/public/example.jwt.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' -o file.png ``` # Download a document Canonical page: https://docs.ovok.com/api/document/download-a-document `GET /document/{id}` Downloads the file of a document by answering with a redirect to a short-lived signed URL. Use it to show or download a file you have access to. **Auth:** bearer token. The DocumentReference is read with your token, so you need read access to it. ## Behaviour - The response is `307 Temporary Redirect`. The `Location` header holds the file URL. Follow the redirect to get the file. - For files Ovok stored, the signed URL is valid for one hour. Images (`image/jpeg`, `image/jpg`, `image/png`, `image/gif`, `image/webp`) are served inline; every other type is served as an attachment with the document's file name. - Pass `width` and `height` together to get a resized copy of an image. Both must be positive integers up to 16384. `fit` sets how the image fits the box (`cover` by default; also `contain`, `fill`, `inside`, `outside`). The resized copy is cached, so later requests for the same size are fast. Files that are not resizable images, and images larger than 40 MB, are returned unchanged. - If the image cannot be resized, the original file is returned. ## Example ```bash curl -L 'https://api.sandbox.ovok.com/document/c3499c27-2973-0a7f-807e-fb8676a92dcb?width=200&height=200&fit=cover' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -o cat.png ``` # Create document replacement credentials Canonical page: https://docs.ovok.com/api/document/create-document-replacement-credentials `POST /document/{id}` Replaces the file of an existing document. It updates the document's metadata and returns a signed upload form, as `POST /document` does. **Auth:** bearer token. The document is read and updated with your token, so you need update access to the DocumentReference. ## Behaviour - `fileName` and `contentType` are required and set on the document. `isPublic` is optional and works as in `PATCH /document/{id}`. - The current file is deleted before the upload form is returned. Until you upload the new file, the document has no file to download. - The document keeps its id, so existing references to it stay valid. - Upload with `uploadOptions` as described for `POST /document`. The form expires after 10 minutes. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/document/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "fileName": "new-cat.png", "contentType": "image/png" }' ``` # Update document metadata Canonical page: https://docs.ovok.com/api/document/update-document-metadata `PATCH /document/{id}` Changes a document's file name, content type or public status, without uploading a new file. **Auth:** bearer token. The document is read and updated with your token, so you need update access to the DocumentReference. ## Behaviour - Every field is optional. Fields you leave out keep their value. - `contentType` must be one of the allowed types listed under `POST /document`. It changes both the DocumentReference and the stored file's content type. - `isPublic: true` gives a private document a public token. `isPublic: false` removes the public token, so existing public links stop working. Setting the status it already has changes nothing. - The response has the same shape as a search entry, without `uploadOptions`. ## Example ```bash curl -X PATCH 'https://api.sandbox.ovok.com/document/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "fileName": "updated-image.png", "isPublic": false }' ``` # Delete a document Canonical page: https://docs.ovok.com/api/document/delete-a-document `DELETE /document/{id}` Deletes a document and its stored file. This cannot be undone. **Auth:** bearer token. The document is read and deleted with your token, so you need read and delete access to the DocumentReference. ## Behaviour - The stored file is deleted first, then the DocumentReference. - If deleting the stored file fails, the DocumentReference is still deleted. - Public links to the document stop working. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/document/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` ```json { "message": "Document deleted successfully" } ``` # Execute a bot Canonical page: https://docs.ovok.com/api/bots---execute-a-custom-script/execute-a-bot `POST /bots` Runs a Medplum Bot of your project, found by its identifier, and returns its output. Use it to call custom server-side logic without knowing the Bot's id. **Auth:** bearer token. The Bot is searched and run with your token, so you need read access to the Bot and permission to execute it. ## Behaviour - `identifier` uses FHIR token search syntax: `system|value`, `system|`, or just `value`. Exactly one Bot must match. - The JSON request body is passed to the Bot as its input, unchanged. The body is optional. - The response is whatever the Bot returns. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/bots?identifier=https://example.com|get-users' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "parameter1": "value1" }' ``` # List patients Canonical page: https://docs.ovok.com/api/slim/patient/list-patients `GET /v1/slim/patient` Lists the residents (patients) of your project with their zone, room, device and settings tags. Use it for the residents table in the Slim dashboard. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:search`, `Patient:read`, `Device:read`, `Location:read` and `Organization:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). A token without a project is refused. ## Behaviour - Read-only. - One row per resident. When a resident is on several devices, the row shows one of them, so a resident is never listed twice. - `residentState` defaults to `active`, so discharged residents are hidden unless you ask for them. `discharged-recent` means discharged within the last 30 days; `discharged` means longer ago. `all` turns the filter off. - `includeDischargedRecent=true` widens `residentState=active` or `residentState=discharged` to also include `discharged-recent` residents. - `organizationId` keeps residents in that zone. `hasDevice=true` keeps residents with a device; `hasDevice=false` keeps residents without one. - `medicalSettings` and `bedActivitySettings` keep residents with that settings tag. These tags are `null` when Ovok could not read the project's threshold settings; such rows match no settings filter. - `search` is a case-insensitive substring match on the resident's name, nickname, room name and zone name. - Sort with `sortBy` (default `patientName`) and `orderBy` (`ASC` or `DESC`, any case, default `ASC`). - Pagination is zero-based: `page` (default `0`) and `count` (default `20`, max `100`). `total` counts all matching rows. - Fields with no value are `null`. - Results are cached for up to 60 seconds per user. A change to a resident, device, room or zone made through Ovok clears the cache. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/patient?residentState=active&sortBy=patientNickname&orderBy=asc&page=0&count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create patient Canonical page: https://docs.ovok.com/api/slim/patient/create-patient `POST /v1/slim/patient` Creates a resident (patient), optionally placed on devices, in a room and in a zone, and registers them with Signals. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:create`, plus `Device:update` when `deviceId` is set (an admin or super admin who holds no access policy skips this check). **Scope:** The resident is created in the caller's project (from the token). A super-admin caller can pass `?projectId=` to create it in that project instead. Any other caller who passes `projectId` gets a 403. Devices, rooms and zones you reference must be in your project, its parent project, or one of its sub-projects. ## Behaviour - `name` must contain an entry with `use: "nickname"` and a non-blank first `given` value. This is the Resident ID. - The Resident ID must be unique in the project, compared as in `POST /v1/slim/patient/check-name-exists`. - `admissionDate` defaults to now. It cannot be later than the start of the current day. - The resident is created as `active`, and an `EpisodeOfCare` is opened for the admission. - Placement: - `deviceId` (one id or a list): the resident is assigned to those devices. A device that already has a resident is reassigned to the new one, and the resident who had it loses it, with its room, as on `PUT /v1/slim/patient/{id}`. - `locationId` with `deviceId`: those devices are also moved to the room. - `locationId` without `deviceId`: the resident is assigned to the room's device. The room must have exactly one device. - `organizationId` without `locationId` or `deviceId` is refused with 422: a resident's zone is read from their device, so a zone alone would not show. - `organizationId`: the resident is placed in the zone. When `deviceId` is set, those devices and their rooms move to the zone too. - Without `organizationId`, the resident's zone is their device's: the room's zone, else the device's own. Devices in more than one zone are refused with 422. - The resident is registered with Signals in the same request. If that fails, everything this request wrote is rolled back and you get a 503 with `error: "signals_mint_failed"`. You can retry. - The write is atomic and locks the Resident ID and the devices, so two concurrent creates of the same Resident ID leave one resident. - Change-history entries are added for each assignment, including the zone the resident gets from their device, and for a resident who lost a device to the new one. - The response is the created resident, in the same shape as `GET /v1/slim/patient/{id}`. - If the resident cannot be registered with Signals, the create is rolled back and the request fails with 503. Retry it. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/patient' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": [ { "use": "nickname", "given": ["Maxi"] }, { "use": "official", "given": ["Max"], "family": "Mustermann" } ], "gender": "male", "birthDate": "1940-05-01", "deviceId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "locationId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "organizationId": "87ea5dfc-8b8e-384d-8489-79496e706390" }' ``` # Get patient current vitals Canonical page: https://docs.ovok.com/api/slim/patient/get-patient-current-vitals `GET /v1/slim/patient/{id}/current-vitals` Returns the latest live telemetry for a resident: one entry per device assigned to them, with the device, resident and zone. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `search` and `read` on `Patient`, `Device`, `Location`, `Observation` and `Organization` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). A resident outside that project returns `total: 0` and no entries. ## Behaviour - Read-only. - Returns one entry per device assigned to the resident, up to 100. A resident with no device returns `total: 0`. - The response is cached for up to 60 seconds, so `telemetry` can lag the latest reading by up to a minute. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/patient/c3499c27-2973-0a7f-807e-fb8676a92dcb/current-vitals' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get patient $everything Canonical page: https://docs.ovok.com/api/slim/patient/get-patient-everything `GET /v1/slim/patient/{id}/$everything` Returns a FHIR `Bundle` with the resident and every resource that references them, using the FHIR `Patient/$everything` operation. Use it to export or inspect a resident's full record. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The resident must belong to the caller's project (from the token) or one of its sub-projects. A resident in the parent project is refused. ## Behaviour - Read-only. - The bundle is produced by Medplum and read with the caller's own token, so it contains only resources that token can read. - The response is a raw FHIR `Bundle`, not a Slim DTO. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/patient/c3499c27-2973-0a7f-807e-fb8676a92dcb/$everything' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get patient Canonical page: https://docs.ovok.com/api/slim/patient/get-patient `GET /v1/slim/patient/{id}` Returns one resident (patient) by id, with their names, resident state and current placement. The response is the shape `PUT /v1/slim/patient/{id}` accepts back. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The resident is read with the caller's own token, so you get any patient your Medplum access lets you read. There is no extra project check on this route. ## Behaviour - Read-only. - `deviceId` is one device id, or `null` when the resident has no device. If the resident is on several devices, it is the most recently updated one. `locationId`, `floor`, `room`, `bed` and `organizationId` describe that same device's placement. - `residentState` is `active`, `discharged-recent` (discharged within the last 30 days), `discharged` or `archived`. - `admissionDate` and `dischargeDate` are returned as stored. - A `name` entry without a `use` is returned as `official`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/patient/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Delete patient Canonical page: https://docs.ovok.com/api/slim/patient/delete-patient `DELETE /v1/slim/patient/{id}` Deletes a resident (patient) who has no device. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:delete` and `Device:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The resident must belong to the caller's project (from the token). ## Behaviour - A resident who still has a device is refused with 409 `Resident still has device . Unassign it first.`, and nothing is changed. Take the device off the resident first (`PUT /v1/slim/patient/{id}` without `locationId`), then delete. - Only the Patient resource is deleted. This route does not delete the resident's other records. - Archived residents cannot be deleted. - A change-history entry records the delete. - The response has no body. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/slim/patient/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update patient Canonical page: https://docs.ovok.com/api/slim/patient/update-patient `PUT /v1/slim/patient/{id}` Updates a resident (patient): names, gender, birth date, placement on devices, room and zone, and resident state (discharge or reactivation). **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:update`, plus `Device:update` when the request changes which devices the resident is on (an admin or super admin who holds no access policy skips this check). **Scope:** The resident must belong to the caller's project (from the token). Devices, rooms and zones you reference must be in your project, its parent project, or one of its sub-projects. ## Behaviour The body is a full replacement of the editable fields, designed so that the result of `GET /v1/slim/patient/{id}` can be sent back unchanged. Fields the update does not declare, such as `id`, `floor` or `admissionDate`, are ignored. - `name` replaces all of the resident's names, each trimmed of leading and trailing spaces. It must contain a `nickname` entry with a non-blank first `given` value. If the nickname changes, it must be unique in the project. - `gender` and `birthDate` are replaced. Omitting them, or sending `""`, clears them. - **Placement depends on `locationId`:** - **`locationId` omitted or `""`: the resident is removed from all of their devices**, and `deviceId` and `organizationId` are ignored. Send the current `locationId` to keep the placement. - `locationId` with `deviceId`: the resident is placed on those devices, and the devices move to the room. The resident leaves any other device. A resident already on one of those devices is replaced. - `locationId` without `deviceId`: the resident is placed on the room's device. The room must have exactly one device. - `locationId` with `deviceId` `null`, `[]` or `""` is refused with 422 and changes nothing: a room is not a placement without a device. - A resident in a room is in the room's zone. An `organizationId` that differs from the zone of the room the resident stays in answers 422 with `path: ["organizationId"]` and changes nothing: move the room to that zone with `PUT /v1/slim/location/{id}`, or the resident to a room in it. A resident moving to another room takes that room's zone. When the room has no zone, `organizationId` re-zones the resident's devices. - A save that puts the resident on devices in more than one zone, when they were not in exactly those zones before, is refused with 422. - A discharged resident (`discharged` or `discharged-recent`) placed on a device they are not on is refused with 422 and nothing changes, with or without `deviceId`. Send `residentState: "active"` in the same save to reactivate and place them. - `residentState`: - `discharged` on an active resident: the resident is tagged discharged, `dischargeDate` is stored (default: now), the `EpisodeOfCare` is finished, and the resident is removed from all devices. `locationId` must be omitted or `""`. - `discharged` on a resident already discharged: only a different `dischargeDate` has an effect; it corrects the stored date. - `active` on a discharged resident: the resident is reactivated, the latest `EpisodeOfCare` is reopened and `dischargeDate` is removed. - Other values, or the current state, change nothing. - Any resident who loses a device in this request has their active out-of-bed notification revoked in the same write, and the device's live telemetry state is cleared afterwards. - Archived residents cannot be updated. - The write is atomic and takes a short write lock on the resident, the devices and, on a rename, the new Resident ID. - Change-history entries are added for each changed field and assignment. A resident replaced on a device gets one naming the device, and the room and zone they leave with it. - The response is the resident after the update, in the same shape as `GET /v1/slim/patient/{id}`. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/patient/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": [{ "use": "nickname", "given": ["Maxi"] }], "gender": "male", "birthDate": "1940-05-01", "deviceId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "locationId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "organizationId": "87ea5dfc-8b8e-384d-8489-79496e706390", "residentState": "active" }' ``` # Check patient name exists Canonical page: https://docs.ovok.com/api/slim/patient/check-patient-name-exists `POST /v1/slim/patient/check-name-exists` Checks whether a Resident ID (the resident's nickname) is already used in your project. Use it to validate the Resident ID field before you create or rename a resident. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read` (an admin or super admin who holds no access policy skips this check). **Scope:** Residents in the caller's project (from the token). ## Behaviour - Read-only. - Only the `name` entry with `use: "nickname"` is compared. Official and maiden names are ignored. Without a nickname entry the answer is `exists: false`. - A match needs the same `given` tokens in the same order and the same `family` (or no `family` on both sides). Tokens are trimmed and compared case-insensitively. - When you edit an existing resident, pass their id as `excludePatientId` so their own record does not count as a match. - The create and update routes run the same check, so a `true` here means those requests would be refused with a 422. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/patient/check-name-exists' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": [{ "use": "nickname", "given": ["Maxi"] }], "excludePatientId": "c3499c27-2973-0a7f-807e-fb8676a92dcb" }' ``` ```json { "exists": false } ``` # List projects for device assignment Canonical page: https://docs.ovok.com/api/slim/device/list-projects-for-device-assignment `GET /v1/slim/device/assign/project` Lists the projects you can move a device into: your own project, its parent project and its sub-projects. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:update`. **Scope:** the caller's project (from the token) and its parent and sub-projects. ## Behaviour - Each entry is `{ project: { id, name } }`. `name` is an empty string when the project has none. - `total` is the number of projects returned. - Read-only. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/device/assign/project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Move device to another project Canonical page: https://docs.ovok.com/api/slim/device/move-device-to-another-project `PUT /v1/slim/device/assign/project` Moves a device into another project in your project tree, and optionally places it in a location there. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:update`. **Scope:** the device must be in the caller's project or one of its sub-projects. The target `projectId` must be your project, its parent or one of its sub-projects. ## Behaviour - The device's resident, location and zone are removed before the move, because those references belong to the old project. - If a resident was assigned, their active out-of-bed episode is closed and their open device use record is ended, in the same write. - When you send `locationId`, the device is placed in that location. The location must be in the target project. - The move is written in one transaction. If it fails, nothing is written. - Moving a device to the project it is already in writes nothing and still succeeds. - The response is `{ success, deviceId, projectId, locationId }`. `locationId` is `null` when you sent none. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/device/assign/project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{"deviceId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "projectId": "87ea5dfc-8b8e-384d-8489-79496e706390"}' ``` # List devices Canonical page: https://docs.ovok.com/api/slim/device/list-devices `GET /v1/slim/device` Lists the devices in your project with their zone, location and resident names. Use it for device directory and administration screens. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:search` and `Device:read`. **Scope:** the caller's project (from the token). ## Behaviour - Every device in the project is listed, whether or not it has a location or resident. - `id` is the Device resource id. `thingsboardId` is the device identifier that telemetry is keyed by. - `status` is `active` when the device's live telemetry reports it active, otherwise `inactive`. - `lastActivityTime` is the latest telemetry activity time, or the device's last-seen time when telemetry has none. - `search` matches device, location and zone names. `patientSearch` matches resident names. Both are case-insensitive substring matches. - `organizationId`, `locationId`, `patientId` and `active` filter on exact values. - `orderBy` is `ASC` or `DESC` in any case, default `ASC`. Rows with an empty sort value sort last in `ASC` order and first in `DESC` order. - `page` is zero-based. `count` defaults to 20, maximum 100. `total` is the number of rows after filtering. - The device structure is cached for up to 5 minutes. Writes made through the Slim routes refresh it sooner. - If the device list cannot be built and no earlier complete list exists, the route returns 503. Retry shortly. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/device?page=0&count=20&sortBy=deviceName&orderBy=ASC' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create device Canonical page: https://docs.ovok.com/api/slim/device/create-device `POST /v1/slim/device` Creates a device in your project and, optionally, assigns it to a zone, a location and a resident in the same write. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:create`. **Scope:** the device is created in the caller's project (from the token). ## Behaviour - `name` is stored, trimmed, as the device's user-friendly name and as its official device identifier. - A `name` whose serial a device of your project already holds is refused with 422, in any spelling: spaces around it or its `/`, other case, with or without the manufacturer prefix ingest gives the serial (`Sleepiz/30QD24001`, `sleepiz/30qd24001` and `30QD24001` hold one serial). Ingest finds a device by its serial, so one serial belongs to one device. - A `name` whose serial a device of another customer already holds is refused with 409, in the same spellings. Ingest routes readings by serial, and cannot tell two customers' devices with one serial apart. - `thingsboardId` is stored as a second identifier. When you omit it, Ovok generates a random UUID for it. - `organizationId`, `locationId` and `patientId` are optional. Each one you send is assigned in the same transaction as the create. If any part fails, nothing is written. - A device in a room is in the room's zone. An `organizationId` that differs from the zone of the device's room (the room you send, or the one it is in) answers 422 with `path: ["organizationId"]` and changes nothing: move the room to that zone, or the device to a room in it. A device with no room, or in a room with no zone, takes any zone. A zone change re-zones only the device, never its room, the room's other devices or a resident. - Assigning a resident moves them: the resident is removed from every other device they hold, and their active out-of-bed episode is closed. - Assigning a resident who is not active (`discharged`, `discharged-recent` or `archived`) is refused with 422 and nothing is created: reactivate them first. - The device starts with status `active`. - The create is recorded in the change history. - The response is the same as `GET /v1/slim/device/{id}` for the new device. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/device' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{"name": "Sleepiz/3001000", "locationId": "c3499c27-2973-0a7f-807e-fb8676a92dcb"}' ``` # List live device rows Canonical page: https://docs.ovok.com/api/slim/device/list-live-device-rows `GET /v1/slim/device/live` Lists live device rows for the dashboard's monitoring views: each device with its resident, location, zone, current telemetry and alerts. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `search` and `read` on `Patient`, `Device`, `Location`, `Observation` and `Organization`. **Scope:** the caller's project (from the token). ## Behaviour - By default only devices with a resident assigned are returned. Set `includeUnassigned=true` to include devices without a resident. - `organizationId` takes a zone id, `assigned` or `unassigned`. A zone id also matches devices in its child zones. - `deviceId` restricts the result to one device, matched against the device identifier. - `effectiveSleepStatus` filters on the device's current sleep status. - `search` matches resident nickname and name, location name, zone name, and device name, identifier and serial. The resident, location and zone names match fuzzily; the device fields match only as a case-insensitive substring, so a full device name finds that device alone. - `orderBy` is `ASC` or `DESC` in any case, default `ASC`. - `residentState` is accepted but ignored. - A row's `patient` carries the resident's `id`, `name`, `meta` and `extension` only, not the whole FHIR Patient. - Telemetry is read fresh on every request. The device structure is cached and refreshed when you write through the Slim routes. - `page` is zero-based. `count` defaults to 20, maximum 100. - For polling only the telemetry and alerts, use `GET /v1/slim/device/live/telemetry` with the same query. - The route returns 503 when the server is at capacity for live reads or the device list cannot be built. Retry shortly. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/device/live?page=0&count=20&sortBy=locationName&orderBy=ASC' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List live telemetry and alerts by device Canonical page: https://docs.ovok.com/api/slim/device/list-live-telemetry-and-alerts-by-device `GET /v1/slim/device/live/telemetry` Returns the telemetry and alerts for one page of live devices, keyed by device. Use it to poll the values on a page you already loaded with `GET /v1/slim/device/live`. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `search` and `read` on `Patient`, `Device`, `Location`, `Observation` and `Organization`. **Scope:** the caller's project (from the token). ## Behaviour - Takes the same query parameters as `GET /v1/slim/device/live` and selects the same page of devices in the same order. - `telemetry` and `alerts` are keyed by the device identifier (for example `Sleepiz/3001000`), not by the Device resource id. - `alerts` has an entry for every device on the page. `telemetry` has an entry only for devices with telemetry. - Each telemetry entry carries the room readings `roomTemperature` (°C), `humidity` (%), `soundLevel` (dB), `infrared`, `illuminance` (lux), `airQualityIndex`, `tvoc` (ppb) and `eco2` (ppm) as `{ value, ts }`. They are `null` until the device reports one, and again when it has sent none for 30 minutes. They do not depend on whether the resident is in bed. - `total`, `page` and `count` describe the page, as on `/live`. - Telemetry is read fresh on every request. - The route returns 503 when the server is at capacity for live reads or the device list cannot be built. Retry shortly. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/device/live/telemetry?page=0&count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List live device rows (lean) Canonical page: https://docs.ovok.com/api/slim/device/list-live-device-rows-lean `GET /v2/slim/device/live` Lists live device rows for the dashboard's monitoring views, with only the fields the dashboard renders: each device with its resident, room, zone, current readings and alert colours. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `search` and `read` on `Patient`, `Device`, `Location`, `Observation` and `Organization`. **Scope:** the caller's project (from the token) and its sub-projects. ## Behaviour - The same query, filters, search, sort and paging as `GET /v1/slim/device/live`. The difference is where the rows come from: only the Devices are read, with the resident, room and zone context every Slim write stores on them, instead of a sweep of every Patient, Location and Organization of the project. - Every field is present; an absent value is `null`. - The resident, room and zone values are the copies stored on the Device, so what a row shows follows the Device's project and access, not a fresh read of the Patient. Each backend fills in devices no Slim write has touched once per build, after it boots; until then such a device answers `residentState: null` and no zone. - `id` is the Medplum Device id. `GET /v2/slim/device/live/telemetry` keys its readings by it. - The device structure is cached and refreshed when you write through the Slim routes. Readings and alerts are read fresh on every request. - `page` is zero-based. `count` defaults to 20, maximum 100. - The route returns 503 when the server is at capacity for live reads or the device list cannot be built. Retry shortly. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v2/slim/device/live?page=0&count=20&sortBy=locationName&orderBy=ASC' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List live telemetry and alerts by device (lean) Canonical page: https://docs.ovok.com/api/slim/device/list-live-telemetry-and-alerts-by-device-lean `GET /v2/slim/device/live/telemetry` Lists the current readings and alert colours of one page of live devices, keyed by Medplum Device id. Poll it with the query you sent to `GET /v2/slim/device/live` to refresh the vitals without reloading the rows. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `search` and `read` on `Patient`, `Device`, `Location`, `Observation` and `Organization`. **Scope:** the caller's project (from the token) and its sub-projects. ## Behaviour - Takes the same query as `GET /v2/slim/device/live` and answers for the same page of devices. - `resources` maps each Device id to its `telemetry` (`null` when the device has sent nothing recent) and `alerts`. - Readings and alerts are read fresh on every request. - The route returns 503 when the server is at capacity for live reads. Retry shortly. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v2/slim/device/live/telemetry?page=0&count=20&sortBy=locationName&orderBy=ASC' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Resolve how ingest routes device serials Canonical page: https://docs.ovok.com/api/slim/device/resolve-how-ingest-routes-device-serials `POST /v1/slim/device/routing` For each serial you send, returns the manufacturer and model that ingest files it under, and whether ingest accepts the serial at all. Use it to check serials before you create devices or send data. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:read`. ## Behaviour - Send 1 to 500 serials, each at most 64 characters. - Rows come back in the order you sent them. - `routable: false` means ingest rejects the serial with `400`. `manufacturer` and `model` are then `null`. - The serial alone decides the result. A manufacturer that ingest only accepts when named explicitly, such as Masimo, is never inferred from a serial. - Nothing is read or written. The result is computed from the serial only. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/device/routing' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{"serials": ["3001000", "12,34"]}' ``` ```json { "resources": [ { "serial": "3001000", "manufacturer": "Sleepiz", "model": "OnePlus", "routable": true }, { "serial": "12,34", "manufacturer": null, "model": null, "routable": false } ] } ``` # Get device Canonical page: https://docs.ovok.com/api/slim/device/get-device `GET /v1/slim/device/{id}` Returns one device with its zone, location and resident assignments and its current connection status. Use it to show or edit a single device. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:read`. **Scope:** the device is read with your token, so Medplum's access policy limits which devices you can read. ## Behaviour - `organizationId` is the zone of the device's location. When the device has no location, it falls back to the device's own owner organization. - `organizationName`, `locationName` and `patientName` are display names. Each is `null` when the resource has no name that can be shown. - `status` is `active` only when the device was last seen recently enough. A device whose last-seen time is stale reads `inactive`, even if it was never marked offline. A device without an identifier reports its stored FHIR status. - `statusReason` explains an `inactive` status when the platform recorded why. - `floor`, `room` and `bed` come from the address of the device's location. - Read-only. Nothing is written. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/device/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Delete device Canonical page: https://docs.ovok.com/api/slim/device/delete-device `DELETE /v1/slim/device/{id}` Deletes a device from your project. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:delete`. System Owners cannot delete devices. **Scope:** the device must belong to the caller's project (from the token). ## Behaviour - The Device resource is deleted. This cannot be undone. - If a resident is assigned, they are unassigned and their active out-of-bed episode is closed in the same transaction. - The device's use history is updated in the same transaction. - The delete is recorded in the change history. - The response has no body. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/slim/device/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update device Canonical page: https://docs.ovok.com/api/slim/device/update-device `PUT /v1/slim/device/{id}` Updates a device's name and identifier, and assigns or unassigns its zone, location and resident. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:update`. **Scope:** the device must belong to the caller's project (from the token). ## Behaviour - `name` is required and replaces the device's user-friendly name, trimmed. Renaming the device to a serial that a device of another customer already holds is refused with 409, in any spelling. - Renaming the device to a serial another device of your project holds is refused with 422, in any spelling: spaces around it or its `/`, other case, with or without the manufacturer prefix ingest gives the serial. A device may take another spelling of its own serial. - For `organizationId`, `locationId` and `patientId`: omit the field to leave it unchanged, send `null` to unassign, or send a UUID to assign. - A device in a room is in the room's zone. An `organizationId` that differs from the zone of the device's room (the room you send, or the one it is in) answers 422 with `path: ["organizationId"]` and changes nothing: move the room to that zone, or the device to a room in it. A device with no room, or in a room with no zone, takes any zone. A zone change re-zones only the device, never its room, the room's other devices or a resident. - Assigning a resident moves them: the resident is removed from every other device they hold. The resident who was on this device before loses it. Each resident who loses a device has their active out-of-bed episode closed in the same transaction. - Assigning a resident who is not active (`discharged`, `discharged-recent` or `archived`) is refused with 422 and changes nothing: reactivate them first. Unassigning one (`patientId: null`) is allowed. - All changes are written in one transaction. If any part fails, nothing is written. - Sending values the device already has is not an error, and writes nothing. - Resident assignment changes, renames, identifier changes and zone changes are recorded in the change history. - The response is the same as `GET /v1/slim/device/{id}` after the update. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/device/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{"name": "Sleepiz/3001000", "patientId": null}' ``` # Create night report PDF Canonical page: https://docs.ovok.com/api/slim/export/create-night-report-pdf `POST /v1/slim/export/pdf` Creates a night report PDF for one resident and stores it. Optionally emails the PDF. Use it for the report download and email feature on the dashboard. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `search` and `read` on `Patient`, `Device` and `Observation`. **Scope:** the caller's project (from the token). The resident is read with your token, so Medplum's access policy limits which residents you can export. ## Behaviour - `code` must be `TRENDS_PDF_EXPORT`. Any other value is rejected with `400`. - The report layout comes from the export template content for `code` and `language`. A template in your project wins over one in its parent project. The route returns `400` when no template exists. - The report period is `(period.start, period.end]` in the project's time zone: for a range of more than one day the first day is left out, because its night belongs to the day before. A single-day range reports that day. A night counts for the day its sleep ends. - The report covers sleep statistics, heart rate and respiratory rate for each night. It holds only what ends inside one of the resident's use periods of its device, as `GET /v1/slim/sleep/statistics` does: the sleep table's recordings, and the readings behind the heart and respiratory rate rows and charts. A reading with no end time is then left out. So a previous resident's night that ended before the device was handed over, but reached Ovok after it, is not reported. A resident with no device use history has everything reported. - When a night has several sleep recordings left, the sleep table uses the one written last (latest `meta.lastUpdated`), the rule `GET /v1/slim/sleep/statistics` uses. - Once a resident has any use period, the report also leaves out what a device with no period of theirs recorded, and what a device recorded before its earliest period. A device assigned before use periods were recorded gets its first one on its next edit in Ovok, starting at the Device's last write before that edit, so what it recorded before then is not reported. Each device whose readings in a report all drop is counted in the `sleep.device_use_device_dropped` metric and logged at most once a minute. - Report times use the project's time zone. The `timeZone` field in the body is not used. - The PDF is stored as a Binary, and a `DocumentReference` links it to the resident. Both are written in one transaction, so a failed store leaves neither. The response is that `DocumentReference`. Its `content[0].attachment.url` points to the Binary. - When `mailTo` has addresses, the PDF is emailed to them as an attachment after the store succeeds. The email is sent in the language you set. With no addresses, nothing is emailed. - If the email cannot be sent, the route returns `500`, but the report has already been stored. - Every call creates a new report. Nothing is deduplicated. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/export/pdf' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "code": "TRENDS_PDF_EXPORT", "patientId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "language": "en", "period": { "start": "2026-09-21T00:00:00Z", "end": "2026-09-28T00:00:00Z" }, "mailTo": ["max.mustermann@example.com"] }' ``` # List content with translations Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/list-content-with-translations `GET /cms/{type}/map/{language}` Lists content items as pairs of the default-language item and its translation in the requested language. Use it for translation screens that show the original next to the translation. **Auth:** bearer token. **Scope:** the caller's project (from the token). Only items in that project are listed. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` is the target language and must be one of the languages in your project's locale settings. - Each result has `source` (the item in the project's default language) and `target` (the item in `language`) for the same key. Either one is missing when that language has no item for the key. - Pairs are sorted by the target's `date`, newest first, falling back to the source's `date`. - `search` is a fuzzy match over the title, author name, category, section titles and text, and key of both items. - `code` keeps only items with that content code. - `_count` defaults to `10` and `_offset` to `0`. `total` is the number of matching pairs before paging. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/cms/blog/map/de-DE?search=sleep&_count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List content with translations Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/list-content-with-translations-2 `GET /internal/cms/{type}/map/{language}` Lists content items as pairs of the default-language item and its translation in the requested language. Use it for translation screens that show the original next to the translation. **Auth:** bearer token. **Scope:** the caller's project (from the token). Only items in that project are listed. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` is the target language and must be one of the languages in your project's locale settings. - Each result has `source` (the item in the project's default language) and `target` (the item in `language`) for the same key. Either one is missing when that language has no item for the key. - Pairs are sorted by the target's `date`, newest first, falling back to the source's `date`. - `search` is a fuzzy match over the title, author name, category, section titles and text, and key of both items. - `code` keeps only items with that content code. - `_count` defaults to `10` and `_offset` to `0`. `total` is the number of matching pairs before paging. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/cms/blog/map/de-DE?search=sleep&_count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Copy all content from the parent project Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/copy-all-content-from-the-parent-project `POST /cms/{type}/{language}/copy-from-parent-project` Copies all content items of one type from the parent project, giving each copy a new key. Use it in a sub-project to start from the parent's content. **Auth:** bearer token. You must be a project admin. **Scope:** the caller's project (from the token) and its parent project. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` must be one of the languages in your project's locale settings. - If `language` is your project's default language, items in every language are copied. Otherwise only items in `language` are copied. - Each copy is a new item with a new key: the original key plus a random suffix. Translations of the same original key share the same new key. `date` is set to now and `author` to your profile. - Running the route again creates another set of copies. It does not update earlier copies. - If the parent has no matching items, nothing is copied and the response is still `{ "success": true }`. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/cms/blog/en-US/copy-from-parent-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Copy all content from the parent project Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/copy-all-content-from-the-parent-project-2 `POST /internal/cms/{type}/{language}/copy-from-parent-project` Copies all content items of one type from the parent project, giving each copy a new key. Use it in a sub-project to start from the parent's content. **Auth:** bearer token. You must be a project admin. **Scope:** the caller's project (from the token) and its parent project. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` must be one of the languages in your project's locale settings. - If `language` is your project's default language, items in every language are copied. Otherwise only items in `language` are copied. - Each copy is a new item with a new key: the original key plus a random suffix. Translations of the same original key share the same new key. `date` is set to now and `author` to your profile. - Running the route again creates another set of copies. It does not update earlier copies. - If the parent has no matching items, nothing is copied and the response is still `{ "success": true }`. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/cms/blog/en-US/copy-from-parent-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Copy one content item from the parent project Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/copy-one-content-item-from-the-parent-project `POST /cms/{type}/{language}/{key}/copy-from-parent-project` Copies one content item, by key, from the parent project, giving the copy a new key. **Auth:** bearer token. You must be a project admin. **Scope:** the caller's project (from the token) and its parent project. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `key` is the key of the item in the parent project. - If `language` is your project's default language, the item is copied in every language it exists in. Otherwise only the item in `language` is copied. - The copy gets a new key: the original key plus a random suffix. All copied languages share that new key. `date` is set to now and `author` to your profile. - Running the route again creates another copy. It does not update an earlier copy. - The response is `{ "success": true }`. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/cms/blog/en-US/blog-sleeping-well-a1b2c3d4/copy-from-parent-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Copy one content item from the parent project Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/copy-one-content-item-from-the-parent-project-2 `POST /internal/cms/{type}/{language}/{key}/copy-from-parent-project` Copies one content item, by key, from the parent project, giving the copy a new key. **Auth:** bearer token. You must be a project admin. **Scope:** the caller's project (from the token) and its parent project. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `key` is the key of the item in the parent project. - If `language` is your project's default language, the item is copied in every language it exists in. Otherwise only the item in `language` is copied. - The copy gets a new key: the original key plus a random suffix. All copied languages share that new key. `date` is set to now and `author` to your profile. - Running the route again creates another copy. It does not update an earlier copy. - The response is `{ "success": true }`. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/cms/blog/en-US/blog-sleeping-well-a1b2c3d4/copy-from-parent-project' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List content Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/list-content `GET /cms/{type}/{language}` Lists content items of one type in one language, with optional fuzzy search and paging. **Auth:** bearer token. **Scope:** the caller's project (from the token). Only items in that project are listed. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` must be one of the languages in your project's locale settings. - Items are sorted by `date`, newest first. - `search` is a fuzzy match over title, author name, category, section titles and text, and key. - `code` keeps only items with that content code. - `_count` defaults to `10` and `_offset` to `0`. `total` is the number of matching items before paging. - At most 10,000 items per type and language are considered. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/cms/blog/en-US?search=sleep&_count=20&_offset=0' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create content Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/create-content `POST /cms/{type}/{language}` Creates a content item of one type in one language. Use it to add a blog post, video, audio item or template to your project's content. **Auth:** bearer token. **Scope:** the caller's project (from the token). The item is stored in that project. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` must be one of the languages in your project's locale settings. - The item is stored as a FHIR `Composition`. Ovok sets `key`, `date` (now), `author` (your profile), `type`, `language` and the project. You cannot set them yourself. - `key` is built from the type and the title plus a random suffix. Use it to address the item in other routes and to link its translations across languages. - When you create an item in the project's default language, a background job creates an AI translation of it for every other project language. The translations appear later, not in this response. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/cms/blog/en-US' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "title": "Sleeping well", "category": "health", "section": [ { "title": "Introduction", "text": "Why sleep matters.", "code": ["main-content"] } ] }' ``` # List content Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/list-content-2 `GET /internal/cms/{type}/{language}` Lists content items of one type in one language, with optional fuzzy search and paging. **Auth:** bearer token. **Scope:** the caller's project (from the token). Only items in that project are listed. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` must be one of the languages in your project's locale settings. - Items are sorted by `date`, newest first. - `search` is a fuzzy match over title, author name, category, section titles and text, and key. - `code` keeps only items with that content code. - `_count` defaults to `10` and `_offset` to `0`. `total` is the number of matching items before paging. - At most 10,000 items per type and language are considered. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/cms/blog/en-US?search=sleep&_count=20&_offset=0' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create content Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/create-content-2 `POST /internal/cms/{type}/{language}` Creates a content item of one type in one language. Use it to add a blog post, video, audio item or template to your project's content. **Auth:** bearer token. **Scope:** the caller's project (from the token). The item is stored in that project. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` must be one of the languages in your project's locale settings. - The item is stored as a FHIR `Composition`. Ovok sets `key`, `date` (now), `author` (your profile), `type`, `language` and the project. You cannot set them yourself. - `key` is built from the type and the title plus a random suffix. Use it to address the item in other routes and to link its translations across languages. - When you create an item in the project's default language, a background job creates an AI translation of it for every other project language. The translations appear later, not in this response. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/cms/blog/en-US' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "title": "Sleeping well", "category": "health", "section": [ { "title": "Introduction", "text": "Why sleep matters.", "code": ["main-content"] } ] }' ``` # Get content by key and language Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/get-content-by-key-and-language `GET /cms/{type}/{language}/{key}` Returns one content item by type, language and key. **Auth:** bearer token. **Scope:** the caller's project (from the token). Only items in that project are found. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` must be one of the languages in your project's locale settings. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/cms/blog/en-US/blog-sleeping-well-a1b2c3d4' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Delete content Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/delete-content `DELETE /cms/{type}/{language}/{key}` Deletes a content item, or all its translations when you name the default language. **Auth:** bearer token. **Scope:** the caller's project (from the token). Only items in that project are deleted. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - If `language` is the project's default language, the item is deleted in every project language. Otherwise only that language's item is deleted. - Deleting a key that does not exist succeeds and changes nothing. - The response has no body. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/cms/blog/en-US/blog-sleeping-well-a1b2c3d4' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update content Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/update-content `PUT /cms/{type}/{language}/{key}` Replaces the content item with the given key in one language. Use it to edit an item you created with `POST /cms/{type}/{language}`. **Auth:** bearer token. **Scope:** the caller's project (from the token). Only items in that project are found. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` must be one of the languages in your project's locale settings. - The body replaces `title`, `category`, `section` and `code`. Ovok sets `date` to now and `author` to your profile. - If more than one item exists for this type, key and language, Ovok keeps the first and deletes the others. - When you update an item, a background job runs for every project language. It only creates translations that do not exist yet; existing translations are not changed. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/cms/blog/en-US/blog-sleeping-well-a1b2c3d4' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "title": "Sleeping well", "category": "health", "section": [ { "title": "Introduction", "text": "Why good sleep matters.", "code": ["main-content"] } ] }' ``` # Get content by key and language Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/get-content-by-key-and-language-2 `GET /internal/cms/{type}/{language}/{key}` Returns one content item by type, language and key. **Auth:** bearer token. **Scope:** the caller's project (from the token). Only items in that project are found. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` must be one of the languages in your project's locale settings. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/cms/blog/en-US/blog-sleeping-well-a1b2c3d4' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Delete content Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/delete-content-2 `DELETE /internal/cms/{type}/{language}/{key}` Deletes a content item, or all its translations when you name the default language. **Auth:** bearer token. **Scope:** the caller's project (from the token). Only items in that project are deleted. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - If `language` is the project's default language, the item is deleted in every project language. Otherwise only that language's item is deleted. - Deleting a key that does not exist succeeds and changes nothing. - The response has no body. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/cms/blog/en-US/blog-sleeping-well-a1b2c3d4' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update content Canonical page: https://docs.ovok.com/api/cms-(fhir-legacy)/update-content-2 `PUT /internal/cms/{type}/{language}/{key}` Replaces the content item with the given key in one language. Use it to edit an item you created with `POST /cms/{type}/{language}`. **Auth:** bearer token. **Scope:** the caller's project (from the token). Only items in that project are found. ## Behaviour - `type` is one of `blog`, `video`, `audio`, `template` or `export-template`. - `language` must be one of the languages in your project's locale settings. - The body replaces `title`, `category`, `section` and `code`. Ovok sets `date` to now and `author` to your profile. - If more than one item exists for this type, key and language, Ovok keeps the first and deletes the others. - When you update an item, a background job runs for every project language. It only creates translations that do not exist yet; existing translations are not changed. - The route is also served under `/internal/cms/{type}`. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/cms/blog/en-US/blog-sleeping-well-a1b2c3d4' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "title": "Sleeping well", "category": "health", "section": [ { "title": "Introduction", "text": "Why good sleep matters.", "code": ["main-content"] } ] }' ``` # List location assignment candidates Canonical page: https://docs.ovok.com/api/slim/location/list-location-assignment-candidates `GET /v1/slim/location/assignment-candidates` Lists locations a resident can be placed in, flagged as occupied or vacant. Use it to fill the location picker when you assign a resident. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Location:search`, `Location:read`, `Device:read`, `Patient:read` and `Organization:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). A non-admin token without a project is refused. ## Behaviour - Read-only. - Built from the same data as `GET /v1/slim/location`: **one row per device** at a location, and one row for a location with no device. `total` counts rows. - `occupied` is `true` when the row's device has a resident assigned. Such rows carry `warningCode: "location_has_existing_resident"`. Otherwise `warningCode` is `null`. - `assignable` is always `true`. - Fields with no value are `null`. - `search` and `organizationId` filter as on `GET /v1/slim/location`. `occupied` takes `occupied`, `vacant` or `all` (default `all`). - Rows are sorted as on `GET /v1/slim/location`. - Pagination is zero-based: `page` (default `0`) and `count` (default `50`, max `50`). ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/location/assignment-candidates?occupied=vacant&count=50' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` ```json { "total": 1, "page": 0, "count": 50, "resources": [ { "locationId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "locationName": "Room 201 Bed 1", "organizationId": null, "organizationName": null, "deviceId": null, "deviceName": null, "patientId": null, "patientName": null, "occupied": false, "assignable": true, "warningCode": null } ] } ``` # List locations Canonical page: https://docs.ovok.com/api/slim/location/list-locations `GET /v1/slim/location` Lists the locations (rooms and beds) in your project, with the device, resident and zone at each one. Use it for the location table in the Slim dashboard. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Location:search` and `Location:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). Only locations, devices and residents in that project are returned. ## Behaviour - Read-only. - **One row per device.** A location with several devices appears once per device. A location with no device appears once, without device and resident fields. `total` counts rows, not locations. - `patientId` and `patientName` are the resident assigned to that row's device. `organizationId` and `organizationName` are the location's zone. - `search` matches, as a case-insensitive substring, the location name, the name of a device at the location, the name of a resident on such a device, or the zone name. - `floor`, `room` and `bed` match the location's codes exactly. `organizationId` keeps locations in that zone. `deviceId` keeps only the row for that device. - Rows are sorted by floor, room, bed, device name, then location name. The sort is case-insensitive and numeric-aware ("2" before "10"). Rows with a missing value sort after rows that have one. - Pagination is zero-based: `page` (default `0`) and `count` (default `20`, max `100`). - Unknown query parameters are rejected. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/location?search=Room%20201&page=0&count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create location Canonical page: https://docs.ovok.com/api/slim/location/create-location `POST /v1/slim/location` Creates a location (room or bed), optionally in a zone. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Location:create` and `Device:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The location is created in the caller's project (from the token). A super-admin caller can pass `?projectId=` to create it in that project instead. Any other caller who passes `projectId` gets a 403. ## Behaviour - `name` must be unique. The check is an exact name match against the locations your token can search. With `?projectId`, the check runs in that project only. - When any of `floor`, `room` or `bed` is set, the combination of zone, floor, room and bed must also be unique. The comparison ignores case and extra whitespace. A location with only a name has no such check. - `floor`, `room` and `bed` are stored as type codes on the location. `organizationId` sets the zone. The zone must be in your project, one of its sub-projects, or its parent project. - The create is guarded against a concurrent create of the same floor, room and bed. If another request creates it first, you get a 409 that names the existing location. - No devices or residents are attached. Use `PUT /v1/slim/location/{id}` for that. - A location-created entry is added to the change history. A failure to write that entry does not fail the request. - The response is the created location, in the same shape as `GET /v1/slim/location/{id}`. - If a location with the same zone, floor, room and bed exists, the request is refused with 409 and the body carries `existingLocationId` and `existingLocationName`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/location' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "Room 201", "floor": "2", "room": "201", "bed": "A", "organizationId": "87ea5dfc-8b8e-384d-8489-79496e706390" }' ``` # List locations in a project (admin) Canonical page: https://docs.ovok.com/api/slim/location/list-locations-in-a-project-admin `GET /v1/slim/location/admin/list` Lists the locations of a given project. The admin dashboard uses it to fill the location picker after you choose a project. **Auth:** Bearer token. The caller must be a Medplum project admin. Super admins without the admin role, practitioners and System Owner callers are refused. The access-policy check (`Location:search`, `Location:read`) is skipped only for an admin who holds no access policy. **Scope:** The project named by the required `projectId` query parameter. The search runs with Ovok's admin client, not the caller's token. ## Behaviour - Read-only. - Locations are sorted by name. - Pagination is zero-based: `page` (default `0`) and `count` (default `50`, max `100`). - `total` is an estimate: when a page is full it is one more than the rows seen so far, so a full page means more may follow. - Unlike `GET /v1/slim/location`, rows carry no device or resident fields: one row per location. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/location/admin/list?projectId=c3499c27-2973-0a7f-807e-fb8676a92dcb&page=0&count=50' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create location in a project (admin) Canonical page: https://docs.ovok.com/api/slim/location/create-location-in-a-project-admin `POST /v1/slim/location/admin` Creates a location in a given project. The admin dashboard uses it during device assignment, when the right room does not exist yet. **Auth:** Bearer token. The caller must be a Medplum project admin. Super admins without the admin role, practitioners and System Owner callers are refused. The access-policy check (`Location:create`) is skipped only for an admin who holds no access policy. **Scope:** The project named by `projectId` in the body. The location is created with Ovok's admin client and stamped with that project. ## Behaviour - `floor`, `room` and `bed` are stored as type codes. `organizationId` sets the zone (`managingOrganization`). - The location is created with `status: active`. - Unlike `POST /v1/slim/location`, this route does not check for a duplicate name or a duplicate floor, room and bed, and adds no change-history entry. - The response is `{ id, name, projectId }` of the created location. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/location/admin' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "projectId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "name": "Room 18", "floor": "2", "room": "18", "organizationId": "87ea5dfc-8b8e-384d-8489-79496e706390" }' ``` # Get location Canonical page: https://docs.ovok.com/api/slim/location/get-location `GET /v1/slim/location/{id}` Returns one location (room or bed) by id, with its zone, devices and resident. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Location:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The location is read with the caller's own token, so you get any location your Medplum access lets you read. There is no extra project check on this route. ## Behaviour - Read-only. - `floor`, `room` and `bed` come from the location's type codes. - `organizationId` and `organizationName` are the location's zone (`Location.managingOrganization`). - `deviceId` lists every device at the location. `deviceName` is the alphabetically first of their names. - `patientId` and `patientName` are the resident on the first device at the location that has one. - Fields with no value are omitted. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/location/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` ```json { "id": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "name": "Room 201", "floor": "2", "room": "201", "bed": "A", "organizationId": "87ea5dfc-8b8e-384d-8489-79496e706390", "organizationName": "Ward A", "deviceId": ["..."], "deviceName": "...", "patientId": "...", "patientName": "Maxi" } ``` # Delete location Canonical page: https://docs.ovok.com/api/slim/location/delete-location `DELETE /v1/slim/location/{id}` Deletes a location that has no devices attached. **Auth:** Bearer token. The caller must be a Medplum project admin or super admin. The access policy must grant `Location:delete` and `Device:update` (an admin or super admin who holds no access policy skips the access-policy check). **Scope:** The location must belong to the caller's project (from the token). ## Behaviour - Detach every device first (`PUT /v1/slim/location/{id}` with `"deviceId": []`). A location with a device attached is refused. - The Location resource is deleted. - The write is atomic and takes a short write lock. A concurrent write to the same location gets a 409. - A location-deleted entry is added to the change history. A failure to write that entry does not fail the request. - The response has no body. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/slim/location/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update location Canonical page: https://docs.ovok.com/api/slim/location/update-location `PUT /v1/slim/location/{id}` Updates a location: its name, floor, room, bed and zone, the devices at it, and the resident on those devices. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Location:update` and `Device:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The location must belong to the caller's project (from the token). Devices and residents you attach must be in your project or one of its sub-projects. The zone must be in your project, a sub-project, or the parent project. ## Behaviour - `name` is required and must be unique among the locations your token can search, not counting this one. - `floor`, `room`, `bed`: an omitted field keeps its current value. If the zone, floor, room or bed changes, the new combination must not match another location's. - `organizationId`: - omitted: the zone is unchanged. - `null`: the zone is removed from the location and from every device at it. - an id: the location and every device at it move to that zone. Residents on those devices move too. - `deviceId` (one id or a list): - omitted: the devices at the location are unchanged. - a list: it becomes the full set of devices at the location. Devices not in the list are detached; new ones are attached. `null` or `[]` detaches all devices. - Devices that hold a discharged resident cannot be attached. - `patientId`: - an id: that resident is assigned to the devices in `deviceId`, or, when `deviceId` is omitted or empty, to the single device at the location. The resident is first removed from any other device. A resident already on a target device is replaced. A discharged resident is refused. - **omitted: every resident is removed from every device at the location and every device in `deviceId`.** To keep the current resident, send their `patientId`. - A resident who loses a device has their active out-of-bed notification revoked in the same write, and the device's live telemetry state is cleared afterwards. - Device use history is updated for every device whose resident changes. - The write is atomic and takes a short write lock. A concurrent write to the same resources, or a device reassigned by someone else while this request ran, gets a 409. - Every save adds a location-updated entry to the change history. Residents who move into a new zone, or lose a device, also get an entry in their own change history. - The response is the location after the update, in the same shape as `GET /v1/slim/location/{id}`. - If another location has the same zone, floor, room and bed, the request is refused with 409 and the body carries `existingLocationId` and `existingLocationName`. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/location/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "Room 201", "floor": "2", "room": "201", "bed": "A", "organizationId": "87ea5dfc-8b8e-384d-8489-79496e706390", "deviceId": ["c3499c27-2973-0a7f-807e-fb8676a92dcb"], "patientId": "c3499c27-2973-0a7f-807e-fb8676a92dcb" }' ``` # Get organization Canonical page: https://docs.ovok.com/api/slim/organization/get-organization `GET /v1/slim/organization/{id}` Returns one organization (a zone in the Slim dashboard) by id. Use it to show or edit a zone. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Organization:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The organization is read with the caller's own token, so you get any organization your Medplum access lets you read. There is no extra project check on this route. ## Behaviour - Read-only. - `description` is the organization's narrative text with the XHTML `
` wrapper removed. It is absent when the organization has no narrative. - `parentOrganizationId` is the id from `Organization.partOf`. It is absent for a top-level zone. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/organization/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` ```json { "id": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "name": "Ward A", "parentOrganizationId": "87ea5dfc-8b8e-384d-8489-79496e706390", "description": "Ground floor" } ``` # Delete organization Canonical page: https://docs.ovok.com/api/slim/organization/delete-organization `DELETE /v1/slim/organization/{id}` Deletes an organization (zone) and moves its residents, rooms and devices out of it. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Organization:delete` and `Device:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The organization must belong to the caller's project (from the token). ## Behaviour - The Organization resource is deleted. - Every patient, location and device that references the zone is re-pointed: - If the zone has a parent zone in your project, they move to the parent zone. - Otherwise their zone reference is removed. - Device use history is updated for any device whose assignment changes. - The writes run in one bundle. Because a large zone can exceed the size limit of an atomic write, this route does not take the atomic write lock. A very large zone is written as a checked batch, so a partial failure is reported as an error rather than rolled back. - A zone-deleted entry is added to the change history. A failure to write that entry does not fail the request. - The response has no body. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/slim/organization/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update organization Canonical page: https://docs.ovok.com/api/slim/organization/update-organization `PUT /v1/slim/organization/{id}` Updates an organization's (zone's) name, description and parent zone. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Organization:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The organization must belong to the caller's project (from the token). Organizations in a parent project or a sub-project are refused. ## Behaviour - `name` is required and must be unique among the organizations your token can search, not counting this one. - `parentOrganizationId` sets the parent zone. It must name an organization in your own project. **Omitting it removes the current parent**, which makes the zone top-level. - `description`, when non-empty, replaces the narrative text. Omitting it, or sending `null` or an empty string, leaves the existing description unchanged. - The write is atomic and takes a short write lock. A concurrent write to the same resources gets a 409. - A zone-updated entry is added to the change history. A failure to write that entry does not fail the request. - The response is the organization after the update, in the same shape as `GET /v1/slim/organization/{id}`. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/organization/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "Ward A", "parentOrganizationId": "87ea5dfc-8b8e-384d-8489-79496e706390", "description": "Ground floor" }' ``` # Create organization Canonical page: https://docs.ovok.com/api/slim/organization/create-organization `POST /v1/slim/organization` Creates an organization (a zone in the Slim dashboard), optionally as a child of another zone. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Organization:create` (an admin or super admin who holds no access policy skips this check). **Scope:** The organization is created in the caller's project (from the token). A super-admin caller can pass `?projectId=` to create it in that project instead. Any other caller who passes `projectId` gets a 403. ## Behaviour - `name` must be unique. The check is an exact name match against the organizations your token can search. With `?projectId`, the check runs in that project only. - `parentOrganizationId`, when set, must name an organization in your own project. A sub-project's or parent project's organization is refused. The new zone's `partOf` points at it. - `description`, when non-empty, is stored as the organization's narrative text. `null` or an empty string stores nothing. - The write is atomic and takes a short write lock. A concurrent write to the same resources gets a 409. - A zone-created entry is added to the change history. A failure to write that entry does not fail the request. - The response is the created organization, in the same shape as `GET /v1/slim/organization/{id}`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/organization' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "Ward A", "parentOrganizationId": "87ea5dfc-8b8e-384d-8489-79496e706390", "description": "Ground floor" }' ``` # List zones Canonical page: https://docs.ovok.com/api/slim/zones/list-zones `GET /v1/slim/zones` Lists the zones of your project with their device counts. A zone is a FHIR `Organization`. Use it for a zone overview; use `GET /v1/slim/zones/{zoneId}` for one zone's locations. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Organization:search`, `Organization:read` and `Device:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - Counts are taken from the same rows as `GET /v1/slim/device/live`: only devices assigned to a resident are counted. `deviceCount` is the number of such devices in the zone; `activeDeviceCount` and `inactiveDeviceCount` split them by whether the device is currently active, as on the live view. - Only zones with at least one counted device are listed. A zone with no assigned devices does not appear; `GET /v1/slim/zones/device-counts?includeEmpty=true` lists it. - `search` keeps zones whose name contains the text, ignoring case. - `sortBy`: `name` (default), `deviceCount`, `activeDeviceCount` or `inactiveDeviceCount`. `orderBy`: `ASC` (default) or `DESC`. - Paging: `page` from 0, `count` from 1 to 100 (default 20). `total` is the number of zones after the search filter. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/zones?sortBy=deviceCount&orderBy=DESC&page=0&count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get zone device counts Canonical page: https://docs.ovok.com/api/slim/zones/get-zone-device-counts `GET /v1/slim/zones/device-counts` Returns device counts per zone for your project, with project-wide totals. A zone is a FHIR `Organization`. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Organization:search`, `Organization:read`, `Device:search` and `Device:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - By default, `deviceCount` matches the rows `GET /v1/slim/device/live` returns for each zone: devices assigned to a resident. - `all=true` counts every device in each zone, assigned or not, and ignores `effectiveSleepStatus`. - `effectiveSleepStatus` (`disconnected`, `connected`, `awake`, `away`, `asleep`) counts only devices in that state. A device that is not active counts as `disconnected`. - `includeUnassigned=true` also counts devices with no resident (unless `all=true` already does) and adds a bucket, with `organization` unset, for devices in no zone. - `includeEmpty=true` keeps project zones that have no matching devices, with zero counts. - For each zone, `assignedResidentDeviceCount` counts devices with a resident, and `activeDeviceCount` / `inactiveDeviceCount` split devices by whether they are currently active. - Zones are sorted by `deviceCount`, highest first. `total` is the number of entries; the `total…Count` fields sum the per-zone counts. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/zones/device-counts?includeEmpty=true&includeUnassigned=true' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get zone detail Canonical page: https://docs.ovok.com/api/slim/zones/get-zone-detail `GET /v1/slim/zones/{zoneId}` Returns one zone with all of its locations and the devices and residents assigned to each location. A zone is a FHIR `Organization`. Use it for a zone drill-down view. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Organization:read` and `Location:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The zone must belong to the caller's project (from the token), its parent project, or one of its sub-projects. ## Behaviour - Returns every location whose managing organization is the zone; there is no paging. - Each location carries `floor`, `room` and `bed` when set, and its `devices` and `residents`. Devices and residents are sorted by name in natural order (so "Bed 2" sorts before "Bed 10"). - A location with no devices has empty `devices` and `residents` lists. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/zones/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create location in zone Canonical page: https://docs.ovok.com/api/slim/zones/create-location-in-zone `POST /v1/slim/zones/{zoneId}/locations` Creates a location (a FHIR `Location`) inside a zone. The new location's managing organization is the zone. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Location:create` and `Device:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The location is created in the caller's project (from the token). A super-admin caller may pass `?projectId=` to create it in that project instead; the project must exist. The zone must belong to the project in use, its parent project, or one of its sub-projects. ## Behaviour - `name` is required and must be unique among the locations your token can search. - `floor`, `room` and `bed` are optional. When at least one is set, no other location in the zone may have the same floor, room and bed. A location with none of them is checked by name only. - The location is created with no devices or residents. Assign them with `PUT /v1/slim/zones/{zoneId}/locations/{locationId}`. - A location-created entry is added to the change history. A failure to write that entry does not fail the request. - The response is the new location, in the same shape as `GET /v1/slim/location/{id}`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/zones/c3499c27-2973-0a7f-807e-fb8676a92dcb/locations' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "Room 101 Bed 1", "floor": "1", "room": "101", "bed": "1" }' ``` # Delete location in zone Canonical page: https://docs.ovok.com/api/slim/zones/delete-location-in-zone `DELETE /v1/slim/zones/{zoneId}/locations/{locationId}` Deletes an empty location from a zone, or, with `dryRun=true`, previews which devices and residents are at it without changing anything. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Location:update` and `Device:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The zone must belong to the caller's project (from the token), its parent project, or one of its sub-projects. The location must belong to the zone and to your project or a sub-project; a parent project's location is refused. ## Behaviour - `dryRun=true` returns `200` with `affected_devices` and `affected_residents` at the location, and a `warning` when either list is not empty. Nothing is written. - Without `dryRun` (any other value counts as false), the location is deleted only when no device is assigned to it. The call answers `204` with no body. - Reassign the location's devices before deleting it; the delete never unassigns devices for you. - A location-deleted entry is added to the change history. A failure to write that entry does not fail the request. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/slim/zones/c3499c27-2973-0a7f-807e-fb8676a92dcb/locations/87ea5dfc-8b8e-384d-8489-79496e706390?dryRun=true' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update location in zone Canonical page: https://docs.ovok.com/api/slim/zones/update-location-in-zone `PUT /v1/slim/zones/{zoneId}/locations/{locationId}` Updates a location in a zone: its name, floor, room and bed, the devices assigned to it, and the resident on those devices. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Location:update` and `Device:update` (an admin or super admin who holds no access policy skips this check). **Scope:** The zone must belong to the caller's project (from the token), its parent project, or one of its sub-projects. The location must be in the caller's project, and its managing organization must be the zone. Devices and residents named in the body must be in your project or a sub-project. ## Behaviour - `name` is required and must be unique among the locations your token can search, not counting this one. - `floor`, `room` and `bed` replace only the values you send; omitted ones keep their stored value. The resulting floor, room and bed must not match another location in the zone. - `deviceId` (one UUID or a list) sets the devices at the location to exactly that set: devices not listed are removed from it, new ones are added. `null` removes every device. Omit `deviceId` to leave the devices unchanged. - `patientId` assigns that resident to the devices named in `deviceId`, or, without `deviceId`, to the location's single device. A resident assigned there before is unassigned from those devices. - **Omitting `patientId` unassigns the current resident from every device at the location** (and from the devices in `deviceId`). Send the current `patientId` to keep the resident. - A discharged resident cannot be assigned. - The write is atomic and takes a short write lock on the devices and locations it touches. - The response is the updated location, in the same shape as `GET /v1/slim/location/{id}`. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/zones/c3499c27-2973-0a7f-807e-fb8676a92dcb/locations/87ea5dfc-8b8e-384d-8489-79496e706390' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "Room 101 Bed 1", "room": "101", "bed": "1", "deviceId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "patientId": "87ea5dfc-8b8e-384d-8489-79496e706390" }' ``` # Invite practitioner Canonical page: https://docs.ovok.com/api/slim/invite/invite-practitioner `POST /v1/slim/invite/practitioner` Invites a practitioner to your project, or to one of its direct child projects, and emails them a link to set their password. **Auth:** Bearer token for a practitioner, project admin or System Owner session. The caller's access policy must grant `Practitioner:create` (a project admin who holds no access policy skips this check). **Scope:** The caller's project (from the token), or `projectId` when given. `projectId` must be the caller's project or a direct child of it. ## Behaviour - Practitioner invitations must be enabled on the target project. They are enabled unless the project turns them off. - `accessPolicyId` must name a policy of your project, its parent or a direct child, at or below your own rank. It is checked before anything is written. - An existing practitioner account with this `email` in the target project is refused: an invite never changes a member's role or admin flag (use `PUT /v1/slim/policy/{id}`). An existing practitioner account elsewhere, your own project included, is reused: only the membership and practitioner profile are new. A patient account of another project is not: it is that project's own, and the invitee gets a practitioner account of their own. - Ovok creates the membership with the access policy and the practitioner profile, then emails an invitation with a password-setup link. The link points to the app the request came from, and sets a password for 7 days after it was sent. If the email fails, the account is undone and the request answers 400. - `admin` in the body is ignored. The invitee becomes an admin member, and the project owner, only when the target project has no owner yet. - The invitee shows as `Pending` in user lists until they set a password. - Returns the new membership, the practitioner profile and `status: "Pending"`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/invite/practitioner' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com", "name": "Max", "surname": "Mustermann", "accessPolicyId": "c3499c27-2973-0a7f-807e-fb8676a92dcb" }' ``` # Get sleep statistics Canonical page: https://docs.ovok.com/api/slim/sleep/get-sleep-statistics `GET /v1/slim/sleep/statistics` Returns a resident's sleep statistics for one night, grouped by device, with each metric compared against the average of the preceding nights. Use it for the sleep detail view. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Observation:read` and `Observation:search`. **Scope:** the caller's project (from the token). Sleep data is read with your token, so Medplum's access policy limits what you see. ## Behaviour - The "night" is the calendar day, in the project's time zone, of `endDate`. A sleep recording belongs to the day its `effectivePeriod.end` falls on. - `lastDayCount` is how many earlier days feed `average`. It defaults to `7` and must be between 1 and 30. - Each device entry holds, per metric, `current` (the night of `endDate`), `average` (over the earlier nights that have a recording) and `diff`. A device with no recording for the night of `endDate` is left out. - When one night has several recordings, the one written last is used: the latest `meta.lastUpdated`. Its period and completeness do not count, so a shorter recording written later wins, and so can a same-day nap ending after the night. A metric it does not carry is `null`, never taken from another recording. The PDF export's sleep table uses the same rule, and so do the `GET /v1/slim/trends/graphs` charts where they can match a night's readings to its recordings. - `average` and `diff` use each earlier night's latest-written recording the same way. - Only recordings that end inside one of the resident's use periods of their device are counted, before a night's recording is picked. So a previous resident's night that ended before the device was handed over, but reached Ovok after it and was stored under this resident, is not shown. A resident with no device use history has all recordings counted. The PDF export and the `GET /v1/slim/trends/graphs` charts apply the same filter. - Once a resident has any use period, recordings of a device with no period of theirs, and those from before a device's earliest period, are not counted. A device assigned before use periods were recorded gets its first one on its next edit in Ovok, starting at the Device's last write before that edit. Each device whose recordings in a request all drop is counted in the `sleep.device_use_device_dropped` metric and logged at most once a minute. - Ovok reads the `sleep-stats` observations first and falls back to the LOINC pair `93832-4` (sleep duration) and `103216-8` (out-of-bed count) when there are none. - The response is `{}` when no qualifying recording exists. - Results are cached for up to 60 seconds per project, resident, `endDate` and `lastDayCount`. A write to the resident's data invalidates the cache sooner. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/sleep/statistics?patientId=c3499c27-2973-0a7f-807e-fb8676a92dcb&endDate=2026-09-28T00:00:00Z&lastDayCount=7' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List effective observation ids by device Canonical page: https://docs.ovok.com/api/slim/telemetry/list-effective-observation-ids-by-device `GET /v1/slim/telemetry/effectiveIds` Returns the effective Observation ids for every device in your project, keyed by device identifier. These are the readings that produced each device's current heart rate, respiratory rate, sleep status and presence values. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:read` and `Device:search`. **Scope:** the caller's project (from the token). ## Behaviour - Covers the devices that have telemetry, up to the first 1000 devices of the project, including devices without a resident. - Each value has the same shape as `GET /v1/slim/telemetry/{deviceId}/effectiveIds`. Fields are `null` when no reading has set them. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/telemetry/effectiveIds' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List last-received observation ids by device Canonical page: https://docs.ovok.com/api/slim/telemetry/list-last-received-observation-ids-by-device `GET /v1/slim/telemetry/lastIds` Returns the last-received Observation ids for every device in your project, keyed by device identifier. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:read` and `Device:search`. **Scope:** the caller's project (from the token). ## Behaviour - Covers the devices that have telemetry, up to the first 1000 devices of the project, including devices without a resident. - Each value has the same shape as `GET /v1/slim/telemetry/{deviceId}/lastIds`. Fields are `null` when nothing has been received for them. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/telemetry/lastIds' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get effective observation ids for a device Canonical page: https://docs.ovok.com/api/slim/telemetry/get-effective-observation-ids-for-a-device `GET /v1/slim/telemetry/{deviceId}/effectiveIds` Returns, for one device, the ids of the Observations that produced its current heart rate, respiratory rate, sleep status and presence values. Use it to trace a displayed value back to its source reading. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:read`. **Scope:** a device identifier only resolves when the device is visible to your token and in the caller's project. ## Behaviour - `deviceId` is either the device identifier or the Device resource id (a UUID). - Each field is an Observation id, or `null` when no reading has set that value yet. - Only devices whose readings carry their own Observation id fill these fields. For other devices every field is `null`. - A device that is not found returns every field `null`, not an error. - Lookups of a device are cached for up to 10 minutes, and misses for 30 seconds. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/telemetry/c3499c27-2973-0a7f-807e-fb8676a92dcb/effectiveIds' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get last-received observation ids for a device Canonical page: https://docs.ovok.com/api/slim/telemetry/get-last-received-observation-ids-for-a-device `GET /v1/slim/telemetry/{deviceId}/lastIds` Returns, for one device, the ids of the most recent Observations received for heart rate, respiratory rate, sleep status and presence, plus the latest batch. Unlike `effectiveIds`, these change on every reading, whether or not the displayed value changed. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:read`. **Scope:** a device identifier only resolves when the device is visible to your token and in the caller's project. ## Behaviour - `deviceId` is either the device identifier or the Device resource id (a UUID). - Each field is an Observation id, or `null` when nothing has been received for it yet. - Only devices whose readings carry their own Observation id fill these fields. For other devices every field is `null`. - A device that is not found returns every field `null`, not an error. - Lookups of a device are cached for up to 10 minutes, and misses for 30 seconds. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/telemetry/c3499c27-2973-0a7f-807e-fb8676a92dcb/lastIds' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get device telemetry and alerts Canonical page: https://docs.ovok.com/api/slim/telemetry/get-device-telemetry-and-alerts `GET /v1/slim/telemetry/{deviceId}` Returns the current telemetry and alerts for one device. Use it to poll the resident detail view. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Device:read`. **Scope:** the caller's project (from the token). Only devices in that project are found. ## Behaviour - `deviceId` is either the device identifier (for example `Sleepiz/3001000`) or the Device resource id (a UUID). A UUID is resolved to the identifier. - The response `deviceId` is the identifier the telemetry is keyed by. - `telemetry` and `alerts` have the same shape as one entry of `GET /v1/slim/device/live/telemetry`. - The device is looked up among the first 1000 devices of your project, including devices without a resident. - Telemetry is read fresh on every request. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/telemetry/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get practitioner Canonical page: https://docs.ovok.com/api/slim/practitioner/get-practitioner `GET /v1/slim/practitioner/{id}` Returns a practitioner profile by id. Use it to show your own profile or, with the extra permission, another practitioner's. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Practitioner:read`. Reading another practitioner's profile also needs `Practitioner:update`. An admin or super admin who holds no access policy skips the access-policy check. **Scope:** Your own profile is always readable. Another practitioner must belong to your project, one of its sub-projects, or its parent project. ## Behaviour - Read-only. - Your own profile is read with your token. Another practitioner's profile is read with Ovok's admin client after the project check above passes. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/practitioner/87ea5dfc-8b8e-384d-8489-79496e706390' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update practitioner Canonical page: https://docs.ovok.com/api/slim/practitioner/update-practitioner `PUT /v1/slim/practitioner/{id}` Updates a practitioner profile: name, surname, email, phone, address and photo. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Practitioner:read`. Updating another practitioner's profile also needs `Practitioner:update`. An admin or super admin who holds no access policy skips the access-policy check. **Scope:** You can always update your own profile. Another practitioner must belong to your project, one of its sub-projects, or its parent project. ## Behaviour - The Practitioner resource is **replaced** with one built from the body. A field you omit is cleared, and FHIR fields that the body cannot carry are not kept. Send the full profile, for example the result of `GET /v1/slim/practitioner/{id}` with your changes applied. - `id` in the body is optional. When present it must equal the `id` in the path. - `meta` in the body is ignored. Ovok sets `meta.author` to the caller. - `email` is stored in lower case. - This route does not change roles or access policies. - Your own profile is written with your token. Another practitioner's profile is written with Ovok's admin client after the project check above passes. - The response is the updated profile. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/practitioner/87ea5dfc-8b8e-384d-8489-79496e706390' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "Max", "surname": "Mustermann", "email": "max.mustermann@example.com", "phone": "+491234567890" }' ``` # List recent notifications Canonical page: https://docs.ovok.com/api/slim/notifications/list-recent-notifications `GET /v1/slim/notifications/recent` Lists the newest active notifications stored as CommunicationRequests for your project, of every type (such as out-of-bed, device alarms and attention presses). Use it for a notification bell. For filtered or paged history, use the out-of-bed and alarm feeds. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `CommunicationRequest:read` and `CommunicationRequest:search` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - Returns at most `count` rows (1 to 50, default 20), newest first by event time. - Rows come from a Redis copy of the active notifications when that copy is enabled and loaded, and from a FHIR store search otherwise. `warm` is `true` and `source` is `redis` for the first case; `warm` is `false` and `source` is `fhirStore` for the second. A cold read also starts loading the Redis copy in the background, so a later call can be warm. - The Medplum search returns `active` notifications updated within the last year. - `total` counts the active notifications the source knows about, capped at the list result cap (1,000 by default). From Medplum it is an estimate. - `locationName` is the room's current name, read from the Location as on the notification lists, so a renamed room shows its new name on every row, old alerts and new. When rows come from Redis, that lookup is cached per caller for up to a minute and dropped when a room is renamed through this API. If the caller cannot read the Location, or the lookup takes more than 2 seconds, a row keeps the name it was raised with. - Rows whose notification type cannot be resolved are left out. - Medical notifications (heart rate, respiratory rate and other vitals) are decided by Signals and served by `GET /v1/slim/notifications/recent/medical`. To show one type only, use `GET /v1/slim/notifications/recent/oob` or `GET /v1/slim/notifications/recent/alarms`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/recent?count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List recent medical notifications Canonical page: https://docs.ovok.com/api/slim/notifications/list-recent-medical-notifications `GET /v1/slim/notifications/recent/medical` Lists the newest open, unacknowledged medical notifications for your project. Use it for a medical notification bell. Medical episodes are decided by Signals; Ovok reads them from Signals and adds the resident context. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read`, `Device:read` and `Location:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token), applied on both sides: Signals filters on the resident's project stamp, and Ovok checks each resolved resident against your project. ## Behaviour - The filter is fixed by the server: open, unacknowledged episodes, newest last notification first (`episode.lastFiringAt`, or `episode.openedAt` when that is null), at most `count` (1 to 50, default 20). Every row's `episode.status` is `OPEN`. An episode leaves the bell when it closes, whether or not anyone acknowledged it. Closed episodes stay in `GET /v1/slim/notifications/medical`, where they can still be acknowledged with `POST /v1/slim/notifications/medical/{episodeId}/ack`. - An open episode is listed however many closed episodes fired after it. - Rows have the same shape as `GET /v1/slim/notifications/medical`, including `episode.firedBand`. - `nextCursor` is set when the page is full, so more open, unacknowledged episodes may exist. A bell can ignore it. - A resident who cannot be resolved into your project is left out, so a page can hold fewer than `count` rows. - A resident with no Signals project stamp matches no project and does not appear. - When the project's Signals tenant has episodic alerts switched off, the list is empty. - A 503 with `signals_unavailable` means Signals could not be reached, not that there are no notifications; retry after `retryAfterSec`. - Out-of-bed is not here; read `GET /v1/slim/notifications/recent/oob`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/recent/medical?count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List recent out-of-bed notifications Canonical page: https://docs.ovok.com/api/slim/notifications/list-recent-out-of-bed-notifications `GET /v1/slim/notifications/recent/oob` Lists the newest active out-of-bed notifications for your project. Use it for an out-of-bed notification bell. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `CommunicationRequest:read` and `CommunicationRequest:search` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - Out-of-bed alerts are episodes Signals decides (code `103214-3`); Ovok reads them from Signals and adds the resident context. Medical notifications are not here: read `GET /v1/slim/notifications/recent/medical` for those, so one event is never counted by both bells. - Returns at most `count` rows (1 to 50, default 20): the newest unacknowledged episodes not closed by hand, by last firing, from the first 200 Signals holds for the last year. - `deviceName` and `locationName` name the device the alert was raised on and its room's current name, also after the resident moved to another device or was unassigned. - `total` counts every active row in those 200, capped at the list result cap (1,000 by default). `warm` is `true` and `source` is `signals`. - An episode that has ended but has not been acknowledged stays active, and so stays in this bell, until someone acknowledges it with `PATCH /v1/slim/notifications/{id}/ack`. - While Signals is unavailable, the bell answers the last page Signals gave it for your project, up to 10 minutes old and cut to `count`. An acknowledgement drops that page, so an acknowledged row never comes back. With no page kept, it answers 503 with `signals_unavailable`; retry after `retryAfterSec`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/recent/oob?count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List recent alarm notifications Canonical page: https://docs.ovok.com/api/slim/notifications/list-recent-alarm-notifications `GET /v1/slim/notifications/recent/alarms` Lists the newest active device alarms and attention presses for your project. Use it for an alarm bell. It has the same response shape as `GET /v1/slim/notifications/recent/oob`. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `CommunicationRequest:read` and `CommunicationRequest:search` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). ## Behaviour - Device alarms and attention presses are decided by the sending system. Ovok stores and forwards them. - Returns at most `count` rows (1 to 50, default 20), newest first by event time. - Always read from the FHIR store, limited to the `deviceAlarm` and `attention` types, so `warm` is `false` and `source` is `fhirStore`. - `total` counts alarm rows only. It is an estimate, capped at the list result cap (1,000 by default). - Acknowledge a row with `PATCH /v1/slim/notifications/{id}/ack`; it then leaves this bell. - Out-of-bed is on `GET /v1/slim/notifications/recent/oob`, medical notifications on `GET /v1/slim/notifications/recent/medical`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/recent/alarms?count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List out-of-bed notifications Canonical page: https://docs.ovok.com/api/slim/notifications/list-out-of-bed-notifications `GET /v1/slim/notifications/oob` Lists your project's out-of-bed notifications, filtered and paged. Out-of-bed is evaluated and recorded by Ovok as CommunicationRequests, and this is its feed. Medical notifications are not here; read `GET /v1/slim/notifications/medical` for those. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `CommunicationRequest:read`, `CommunicationRequest:search` and `Observation:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). The `project` query parameter is accepted but ignored. ## Behaviour - The notification type is fixed to out-of-bed; there is no `type` parameter. Prefer this route over the deprecated `GET /v1/slim/notifications?type=outOfBed`. - `status=active` lists the new notifications and `status=completed` the reviewed ones. Leave `status` out to list new and reviewed together; each row keeps its own `status`. An episode closed by hand without an acknowledgement is `revoked`, so it is in none of these lists; ask `status=revoked` for it. An episode that has ended but has not been acknowledged stays `active`, with an end-of-episode marker, so one resident can have more than one active row. - One row per out-of-bed episode, not per reading: the resident's open episode is updated in place. - Sort order: newest first by event time (`occurrenceDateTime`, then `authoredOn`, then id). - `patient` takes a Patient id or `Patient/{id}`. `device` takes a Device id, `Device/{id}`, or the device's identifier value. A Device id that does not exist returns an empty page rather than an unfiltered one. `device` matches the device that raised each alert, and each row's device and room are that device's, also after the resident moved to another device or was unassigned. - `startDate` and `endDate` are inclusive ISO 8601 UTC instants, used exactly as sent. They bind to the episode's last firing time (`occurrenceDateTime`), whatever the status. Either may be omitted. A missing `startDate` defaults to one year back for `status=active` and 30 days back otherwise. Without `status`, the new rows keep the one-year default and the reviewed rows the 30-day one, so the list holds exactly the rows of `status=active` and `status=completed` together. - Paging: `page` from 0, `count` from 1 to 100 (default 25). `total` is an exact count for the filter, the same on every page, cached for 15 seconds. It counts matching CommunicationRequests, so it is an upper bound on the rows you can page through. It reads `0` if the count lookup fails; the rows are unaffected. - The list pages through at most the first 1,000 results (server-configurable). `total` is clamped to that cap. When the cap or the per-request scan limit stops a page short, `truncated` says why: `{ reason: 'result-cap', limit }` or `{ reason: 'scan-budget', limit }`. `truncated` is `null` when the page is complete. - Acknowledge a row with `PATCH /v1/slim/notifications/{id}/ack`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/oob?status=active&page=0&count=25' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List alarm notifications Canonical page: https://docs.ovok.com/api/slim/notifications/list-alarm-notifications `GET /v1/slim/notifications/alarms` Lists your project's device alarms and attention presses, filtered and paged. These are decided by the sending system; Ovok stores them as CommunicationRequests and forwards them. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `CommunicationRequest:read`, `CommunicationRequest:search` and `Observation:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). The `project` query parameter is accepted but ignored. ## Behaviour - One row per alarm episode. Each row's `alarm` carries the sender's own alarm id (`episodeId`), its severity, type and text, so the sender can match an acknowledgement to its own record. - `type`: `deviceAlarm`, `attention`, or both comma separated. Both when omitted. - `severity`: `RED`, `YELLOW`, `ATTENTION`, comma separated, as the sender coded the alarm. Every severity when omitted. - `status` defaults to `active`; an acknowledged alarm is `completed`. - `sort`: `newest` (default) or `oldest`, by event time (`occurrenceDateTime`, then `authoredOn`, then id). - `patient`, `device`, `startDate`, `endDate`, `page`, `count`, `total` and `truncated` work as on `GET /v1/slim/notifications/oob`: `count` is 1 to 100 (default 25), dates are inclusive UTC instants, and the list pages through at most the first 1,000 results (server-configurable). - Acknowledge a row with `PATCH /v1/slim/notifications/{id}/ack`. - Out-of-bed is on `GET /v1/slim/notifications/oob`; vital-sign alerts, decided by Signals, are on `GET /v1/slim/notifications/medical`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/alarms?type=deviceAlarm&severity=RED&sort=newest' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List medical notifications Canonical page: https://docs.ovok.com/api/slim/notifications/list-medical-notifications `GET /v1/slim/notifications/medical` Lists your project's medical notifications (heart rate, respiratory rate and other vital-sign alerts), newest last notification first, one page at a time. Medical episodes are decided by Signals; Ovok reads them from Signals, adds the resident context, and never re-derives a clinical value. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read`, `Device:read` and `Location:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token), applied on both sides: Signals filters on the resident's project stamp, and Ovok checks each resolved resident against your project. ## Behaviour - Order: newest last notification first. That is `episode.lastFiringAt`, the newest reading outside the band, or `episode.openedAt` for an episode stored without one (before 2026-09-28). An open episode that fires again moves up, so while you read page 2 it can move to page 1. It is never listed twice, and the next read of page 1 shows it. - One row per episode, not per reading: a run of readings outside the band is one episode, which closes on recovery or acknowledgement. - Each row has three blocks. `episode` is the Signals episode with its aggregates. `carehub` is the resident context Signals does not hold: resident, room and bed, device, zone. `patientName` is the resident's Resident ID, also after a discharge, an unassign or a device move. The room, bed, device and zone are those of the device the episode was raised on, also after the resident moved to another device or was unassigned. They are `null` when that device is not known or is no longer in your project. `acknowledgement` is `null` until someone acknowledges the episode. - Use `episode.id` with `GET /v1/slim/notifications/medical/{episodeId}` to get the full value history. - `episode.firedBand` is the band the episode was judged under: the band Signals recorded when it fired, or else the band rebuilt from Signals' configuration history at the episode's trigger version. It is not the resident's current band, so editing a threshold does not change past rows. `min` and `max` are each nullable (a band can be one-sided). `firedBand` is `null` when the band cannot be established; that never fails the read. - Filters: `status` (`OPEN` or `CLOSED`, both when omitted), `since` (episodes whose last notification, as in the order above, is at or after this ISO 8601 instant), `acknowledged` (`true`, `1` or `yes` for acknowledged only; any other value for unacknowledged only; both when omitted). - `patient` narrows the feed to one resident, by Medplum `Patient.id` (the `carehub.patientId` a row returns). It does not change the project scope. A resident who cannot be resolved, or who is in another project, answers 404 rather than an unfiltered page. - `codes` narrows the feed to these LOINC codes, comma separated, at most 32 (for example `8867-4,9279-1`). Perfusion index is `PI`. Signals applies the filter. Out-of-bed is never in this feed. - Paging: `limit` is 1 to 200 (default 50). Pass the previous page's `nextCursor` as `cursor`. Page until `nextCursor` is `null`, not until a short page arrives: rows whose resident cannot be resolved into your project are dropped after Signals counted them. - A resident with no Signals project stamp matches no project and does not appear. - When the project's Signals tenant has episodic alerts switched off, the page is empty. - Out-of-bed is served by `GET /v1/slim/notifications/oob`. - A 503 with `signals_unavailable` means Signals could not be reached; retry after `retryAfterSec`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/medical?status=OPEN&codes=8867-4,9279-1&limit=50' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get medical notification Canonical page: https://docs.ovok.com/api/slim/notifications/get-medical-notification `GET /v1/slim/notifications/medical/{episodeId}` Returns one medical notification with its full value history, addressed by the `episode.id` a feed row carries. The episode is read from Signals, which decides medical alerts. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read`, `Device:read` and `Location:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token), applied on both sides: Signals matches it against the resident's project stamp, and Ovok checks the resolved resident against your project. ## Behaviour - `episode` is the Signals episode as Signals returned it: status, open and close times, close reason, aggregates, and every reading recorded while it ran (`values`). Check `episode.truncated`: a very long episode returns a capped series and says so. - `carehub` adds the resident context: resident, room and bed, device and zone. `patientName` is the resident's Resident ID, also after a discharge, an unassign or a device move. The room, bed, device and zone are those of the device the episode was raised on, also after the resident moved to another device or was unassigned. They are `null` when that device is not known or is no longer in your project. - `acknowledgement` is `null` until someone acknowledges the episode. - `episode.firedBand` is the band the episode was judged under, as described on `GET /v1/slim/notifications/medical`. It is `null` when it cannot be established. - An episode in another project, or an out-of-bed episode (code `103214-3`), answers 404, the same as one that does not exist. A 404 is never caused by Signals being down. - A 503 with `signals_unavailable` means Signals could not be reached; retry after `retryAfterSec`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/medical/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Acknowledge medical notification Canonical page: https://docs.ovok.com/api/slim/notifications/acknowledge-medical-notification `POST /v1/slim/notifications/medical/{episodeId}/ack` Acknowledges one medical notification, so it leaves the medical bell. The acknowledgement is written to Signals, which owns medical episodes. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). Ovok reads the episode with your project and checks its resident against your project before it writes anything. ## Behaviour - No CommunicationRequest is created or changed. Signals closes the episode with reason `ACKNOWLEDGED`. A resident still outside the band opens a new episode on their next reading. - Repeating the call is safe. - Answers 200 with the acknowledged row, in the feed's row shape, already carrying the new `acknowledgement` and closed status. Replace the list entry with it; no refetch is needed. - `acknowledgement.acknowledgedBy` is Ovok's client id at Signals, not a person; do not show it as a name. `acknowledgement.acknowledgedActor` is the caller's profile reference and display name, or `null` when the session has no profile. - Ovok clears its cached index of the project's open episodes, so other reads see the episode as closed straight away rather than after a cache expiry. - An episode in another project, an out-of-bed episode (code `103214-3`) or one that does not exist answers the same 404, and nothing is acknowledged. Acknowledge an out-of-bed alert with `PATCH /v1/slim/notifications/{id}/ack`. - A 409 means the project's Signals tenant has episodic alerts switched off. - While Signals does not answer, Ovok keeps trying for up to 12 seconds before it answers. A 503 (`signals_unavailable`) means Ovok could not confirm the acknowledgement; repeat the call after `retryAfterSec` (also sent as `Retry-After`). ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/notifications/medical/c3499c27-2973-0a7f-807e-fb8676a92dcb/ack' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Leave a note on a notification Canonical page: https://docs.ovok.com/api/slim/notifications/leave-a-note-on-a-notification `POST /v1/slim/notifications/notes` Leaves a note on a notification. A note is a practitioner's comment on a notification, stored as a FHIR `Communication` whose `basedOn` points at the alert. The alert itself is never changed. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read` (an admin or super admin who holds no access policy skips this check). Only a practitioner can write notes. **Scope:** The caller's project (from the token). An alert or note from another project, of another kind, or that does not exist answers the same 404. ## Behaviour - `kind` names the feed the notification comes from: `oob` or `alarm` with the row's `commId` as `id`, `medical` with the row's `episode.id`, or `alert` with a raw Signals alert's `id`. - A note on a raw alert is also listed and counted on that alert's episode. Which episode is decided once, when the note is written. - `text` is trimmed and must be 1 to 2000 characters. - The author is the calling practitioner, never a body field. - Notes can be left on acknowledged notifications too. - `medical` and `alert` notes are read from Signals first, so they answer 503 `signals_unavailable` while Signals is down. Retry once Signals is back. - Answers 201 with the note as stored. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/slim/notifications/notes' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "kind": "oob", "id": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "text": "Resident was in the bathroom." }' ``` # An out-of-bed notification's notes Canonical page: https://docs.ovok.com/api/slim/notifications/an-out-of-bed-notification-s-notes `GET /v1/slim/notifications/oob/{id}/notes` Lists the notes on an out-of-bed notification. A note is a practitioner's comment on a notification, stored as a FHIR `Communication` whose `basedOn` points at the alert. The alert itself is never changed. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `CommunicationRequest:read` and `CommunicationRequest:search` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). An alert or note from another project, of another kind, or that does not exist answers the same 404. ## Behaviour - `id` is the notification row's `commId`. - Newest first. Deleted notes are not listed. - Read-only. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/oob/c3499c27-2973-0a7f-807e-fb8676a92dcb/notes' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # An alarm notification's notes Canonical page: https://docs.ovok.com/api/slim/notifications/an-alarm-notification-s-notes `GET /v1/slim/notifications/alarms/{id}/notes` Lists the notes on an alarm notification. A note is a practitioner's comment on a notification, stored as a FHIR `Communication` whose `basedOn` points at the alert. The alert itself is never changed. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `CommunicationRequest:read` and `CommunicationRequest:search` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). An alert or note from another project, of another kind, or that does not exist answers the same 404. ## Behaviour - `id` is the notification row's `commId`. - Newest first. Deleted notes are not listed. - Read-only. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/alarms/c3499c27-2973-0a7f-807e-fb8676a92dcb/notes' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # A medical notification's notes Canonical page: https://docs.ovok.com/api/slim/notifications/a-medical-notification-s-notes `GET /v1/slim/notifications/medical/{episodeId}/notes` Lists the notes on a medical notification. A note is a practitioner's comment on a notification, stored as a FHIR `Communication` whose `basedOn` points at the alert. The alert itself is never changed. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read`, `Device:read` and `Location:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The caller's project (from the token). An alert or note from another project, of another kind, or that does not exist answers the same 404. ## Behaviour - `episodeId` is the feed row's `episode.id`. - Newest first. Deleted notes are not listed. - The episode is read from Signals first, as the detail and the acknowledgement read it, so this answers 503 `signals_unavailable` while Signals is down. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/medical/c3499c27-2973-0a7f-807e-fb8676a92dcb/notes' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # A raw Signals alert's notes Canonical page: https://docs.ovok.com/api/slim/notifications/a-raw-signals-alert-s-notes `GET /v1/slim/notifications/raw-alerts/{alertId}/notes` Lists the notes on a raw Signals alert. A note is a practitioner's comment on a notification, stored as a FHIR `Communication` whose `basedOn` points at the alert. The alert itself is never changed. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read` (an admin or super admin who holds no access policy skips this check). **Scope:** The alert is read from Signals first: 404 when it isn't in the caller's project or the caller can't read its resident. ## Behaviour - Newest first. Deleted notes are not listed. - Answers 503 `signals_unavailable` while Signals is down. Retry once Signals is back. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/notifications/raw-alerts/c3499c27-2973-0a7f-807e-fb8676a92dcb/notes' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Edit a note's text Canonical page: https://docs.ovok.com/api/slim/notifications/edit-a-note-s-text `PATCH /v1/slim/notifications/notes/{noteId}` Changes a note's text. A note is a practitioner's comment on a notification, stored as a FHIR `Communication` whose `basedOn` points at the alert. The alert itself is never changed. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read` (an admin or super admin who holds no access policy skips this check). Only the note's author can change it. **Scope:** The caller's project (from the token). An alert or note from another project, of another kind, or that does not exist answers the same 404. ## Behaviour - Same effect as `PUT`: a note's text is the only field a caller can change. - `text` is trimmed and must be 1 to 2000 characters. - If the note changed while your edit was in flight, the route answers 409. Reload the note and try again. ## Example ```bash curl -X PATCH 'https://api.sandbox.ovok.com/v1/slim/notifications/notes/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "text": "Resident was in the bathroom; back in bed 02:14." }' ``` # Delete a note Canonical page: https://docs.ovok.com/api/slim/notifications/delete-a-note `DELETE /v1/slim/notifications/notes/{noteId}` Deletes a note. A note is a practitioner's comment on a notification, stored as a FHIR `Communication` whose `basedOn` points at the alert. The alert itself is never changed. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read` (an admin or super admin who holds no access policy skips this check). Only the note's author can delete it. **Scope:** The caller's project (from the token). An alert or note from another project, of another kind, or that does not exist answers the same 404. ## Behaviour - The note is marked `entered-in-error`, not erased, so the clinical record and its history survive. - A deleted note leaves every list and every `noteCount`. - Answers 204 with no body. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/slim/notifications/notes/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Replace a note's text Canonical page: https://docs.ovok.com/api/slim/notifications/replace-a-note-s-text `PUT /v1/slim/notifications/notes/{noteId}` Changes a note's text. A note is a practitioner's comment on a notification, stored as a FHIR `Communication` whose `basedOn` points at the alert. The alert itself is never changed. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read` (an admin or super admin who holds no access policy skips this check). Only the note's author can change it. **Scope:** The caller's project (from the token). An alert or note from another project, of another kind, or that does not exist answers the same 404. ## Behaviour - Same effect as `PATCH`: a note's text is the only field a caller can change. - `text` is trimmed and must be 1 to 2000 characters. - If the note changed while your edit was in flight, the route answers 409. Reload the note and try again. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/slim/notifications/notes/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "text": "Resident was in the bathroom; back in bed 02:14." }' ``` # Acknowledge notification Canonical page: https://docs.ovok.com/api/slim/notifications/acknowledge-notification `PATCH /v1/slim/notifications/{id}/ack` Acknowledges one notification stored as a CommunicationRequest (out-of-bed, device alarm, attention press) by setting its status to `completed`. For a medical notification, use `POST /v1/slim/notifications/medical/{episodeId}/ack` instead. **Auth:** Bearer token. The caller must be a practitioner, an admin, a super admin, or hold the "System Owner" access policy. The access policy must grant `Patient:read` (an admin or super admin who holds no access policy skips this check). No `CommunicationRequest:update` grant is needed. **Scope:** The CommunicationRequest is read with your own credentials and must belong to your project (from the token). Sub-projects are not included. ## Behaviour - After those checks pass, Ovok writes the status change with its own credentials. - Acknowledging an already completed notification succeeds and changes nothing. - If the notification is updated at the same moment (for example by a new reading on the same episode), Ovok re-reads it and retries, keeping the newer content, up to three times. - The notification leaves the active lists and bells. The device's alert state in the live views is cleared. - Acknowledging a running out-of-bed episode stops that episode from raising the alert again. A new bed exit raises a new alert. - Answers 200 with the updated row, in the same shape as the list rows. - A 409 means the notification kept changing and all three attempts lost the race. Re-read it and call again. ## Example ```bash curl -X PATCH 'https://api.sandbox.ovok.com/v1/slim/notifications/c3499c27-2973-0a7f-807e-fb8676a92dcb/ack' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get trends graphs Canonical page: https://docs.ovok.com/api/slim/trends/get-trends-graphs `GET /v1/slim/trends/graphs` Returns a resident's heart rate and respiratory rate over a date range, grouped by graph type and device, with threshold and baseline values and summary statistics. Use it to draw the trend charts. For live readings from the last day, use `GET /v1/slim/trends/realtime`. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Organization:read`, `Device:read`, `Patient:read` and `DocumentReference:read`. **Scope:** the caller's project (from the token). Observations are read with your token, so Medplum's access policy limits what you see. ## Behaviour - `graphType` is a comma-separated list of `heartRate` and `respiratoryRate`. Repeated entries are ignored. `startDate` must not be after `endDate`. - Days are cut at the project's time zone (default `Europe/Berlin`). The chart for a day starts at 09:00 local time, so a night stays in one day. - A range of two or more days is an over-day chart: one point per day, at 09:00 local time, starting the day after `startDate`. Each point is the day's mean from the pre-computed statistics, with batch readings filling nights that have none. - A range of one day or less is an in-day chart: 30-second points across the 24 hours that start at 09:00 local time on `startDate`. `endDate` only decides which kind of chart you get. In-day points come from batch readings only. - Before a night's recording is picked, both charts drop the readings and sleep statistics that end outside the resident's use periods of their device, as `GET /v1/slim/sleep/statistics` does. So a previous resident's night that ended before the device was handed over, but reached Ovok after it and was stored under this resident, is not charted. A resident with no device use history keeps all of them. - Once a resident has any use period, this also drops the readings of a device with no period of theirs, and those from before a device's earliest period. A device assigned before use periods were recorded gets its first one on its next edit in Ovok, starting at the Device's last write before that edit, so its readings from before then are not charted. Each device whose readings in a request all drop is counted in the `sleep.device_use_device_dropped` metric and logged at most once a minute. - The use periods are read on every uncached call. When Medplum answers that read with an error, the route answers `502` rather than chart a night it cannot check; when the request itself fails, the route fails with Medplum's status, or `500`. - When a night (the calendar day its recordings end on, in the project's time zone) has several sleep recordings left, both charts show only the readings of the one whose sleep statistics were written last (latest `meta.lastUpdated`): its heart and respiratory rate statistics, matched by the recording's exact period, and its batch readings, matched by their start (below). That is the rule `GET /v1/slim/sleep/statistics` uses. A night with no sleep statistics goes by its heart and respiratory rate statistics' write times. A night with one recording left, a night with batch readings only, and a night none of whose readings belongs to the chosen recording are charted with all the readings left. Readings with no end time cannot be put on a night, so neither rule applies to them: they are always charted. - Sleep statistics are read over the chart's range, which ends at 09:00 local time on its last day, so a recording that starts later that day is not weighed. - A batch block is matched by its start, because Sleepiz ends one up to about ten minutes before its recording: it belongs to the recording that starts at the same instant and ends at or after it, at most 15 minutes later, the earliest such end when two recordings share the start. A batch block that starts at any other time belongs to no recording, so on a night with several recordings it is dropped: a chosen recording whose only heart rate reading is a batch block that starts after the recording shows no heart rate for that night, while its respiratory rate still shows. - Every bucket is returned. A bucket without a reading has `data: null`. `pointTimestamp` and `pointTimestampRange` show which readings filled it. - `maxThreshold`, `minThreshold`, `maxBaseLine` and `minBaseLine` are the values that applied at that time. They are left out when none apply, and when the threshold lookup fails the chart still returns without them. - When a heart or breathing rate limit changed inside the range (a nurse's edit or a home-wide save), each point carries the limit in force at its own time, as Signals recorded it, so the lines step where the limit changed. Points after the last change carry the limits the limits screen shows. If Signals' change history cannot be read, every point carries the current limits. - Devices are keyed `-`. A resident who changed device has one entry per device. - A graph type with no data in the range comes back as `{}`. When nothing at all can be charted, both `heartRate` and `respiratoryRate` are `{}`. - Results are cached for up to 60 seconds. A write to the resident's data invalidates the cache sooner. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/trends/graphs?patientId=c3499c27-2973-0a7f-807e-fb8676a92dcb&startDate=2026-09-01T00:00:00Z&endDate=2026-09-30T00:00:00Z&graphType=heartRate,respiratoryRate' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` ```json { "heartRate": { "Sleepiz-5f0c...": { "dataPoints": [ { "timestamp": "2026-09-02T07:00:00.000Z", "timestampMs": 1788332400000, "data": 72, "maxThreshold": 100, "minThreshold": 60, "pointTimestamp": "2026-09-02T05:41:00.000Z" } ], "stats": { "average": 72, "max": 72, "min": 72, "total": 1 } } }, "respiratoryRate": {} } ``` # Get realtime trends graphs Canonical page: https://docs.ovok.com/api/slim/trends/get-realtime-trends-graphs `GET /v1/slim/trends/realtime` Returns the resident's readings from Signals, one data point per reading, in the same shape as `GET /v1/slim/trends/graphs`. Use it for the live part of a chart, or to look at any day of the last 14. **Auth:** bearer token. The caller must be a practitioner, an admin or a System Owner, and needs `Organization:read`, `Device:read`, `Patient:read` and `DocumentReference:read`. **Scope:** the resident must be in the caller's project or one of its sub-projects (not its parent). A resident outside that scope answers `404`, the same as one that does not exist. ## Behaviour - The chart covers exactly `[startTime, endTime]`. Unlike `/graphs`, it does not snap to monitoring days. - Every reading in the window comes back as Signals recorded it, oldest first: one data point per reading, at the reading's own time, with its own value. Nothing is bucketed or averaged, and no empty points are added between readings, so a silent device shows as a stretch with no points. A reading with no numeric value comes back with `data: null`. - The response grows with the device's cadence: a day of readings every 30 seconds is about 2,900 points per graph type. - The readings are the resident's, whatever device they wear now: a resident whose device was unassigned or moved to someone else, or who was discharged, still gets every reading Signals holds for them in the window. A resident who takes over a device gets only the readings sent after they took it. - Readings are charted under one key: the resident's most recently assigned device, keyed as on `/graphs`. A resident with no device now is charted under the device they wore last, so the key does not change when the device is taken away, and a resident who never wore one under `Patient/`. Signals readings carry no device, so a resident whose device changed inside the window shows one key here where `/graphs` shows one per device. - Threshold and baseline values are the same as `/graphs`. `stats` are computed over every reading in the window. - Every graph type in the table below can be charted. Only `heartRate` and `respiratoryRate` carry threshold and baseline values. Each point carries the limit in force at its own time, as on `/graphs`, so the lines step where a limit changed inside the window. - `startTime` must not be after `endTime`, the window may span at most 24 hours, and `startTime` must not be more than 14 days ago. A request that breaks one of these fails validation. - Readings are charted by when they were observed, or by when Signals stored them when no observed time exists. Late-arriving readings are included. - A graph type with no readings in the window is `{}`. - If Signals cannot be reached, does not answer within 12 seconds, or holds more readings than one request can page through, the route returns `503` with `error: "signals_unavailable"` and a `retryAfterSec` value, rather than a partial or empty chart. - Results are cached for up to 15 seconds. Both request times are rounded down to that interval, and the readings returned are those of the rounded window, so a repeated poll can show a window up to 15 seconds old. A result over 128 KB (most full days) is not cached. - A chart reads this once per page load. Each caller may make 20 requests a minute; past that the route returns `429` with `Retry-After`. When too many realtime reads are already running on the server, it returns `503` with `error: "signals_unavailable"` and `retryAfterSec` at once, before reading anything. ## Graph types Each type charts every Signals reading recorded under one of its codes. The names are the dashboard telemetry's, so pulse rate by pulse oximetry is `pulseRate` and never part of `heartRate`. | `graphType` | Codes | | ------------------------ | ---------------------------------------------------------------- | | `heartRate` | `8867-4`, `43149-4` | | `respiratoryRate` | `9279-1` | | `oxygenSaturation` | `59408-5`, `2708-6` | | `pulseRate` | `8889-8` (heart rate by pulse oximetry) | | `perfusionIndex` | `61006-3`, `PI` (Kinderspitex's own vital code, not LOINC) | | `bodyTemperature` | `8310-5` | | `systolicBloodPressure` | `8480-6` | | `diastolicBloodPressure` | `8462-4` | | `heartRateVariability` | `80404-7` | ## Example cURL request ```bash curl -X GET \ 'https://api.sandbox.ovok.com/v1/slim/trends/realtime?patientId=c3499c27-2973-0a7f-807e-fb8676a92dcb&startTime=2026-01-01T12:00:00Z&endTime=2026-01-02T12:00:00Z&graphType=heartRate,respiratoryRate' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get health status Canonical page: https://docs.ovok.com/api/slim/health/get-health-status `GET /v1/slim/health` Returns the health of the Slim API and the systems it depends on. Use it for uptime checks and status screens. **Auth:** none. ## Behaviour - `status` is `healthy` when both the FHIR store and Redis are up, `degraded` when one is down, and `unhealthy` when both are down. The route still answers `200` in every case, so read `status`, not the HTTP code. - `externalSystems.fhirStore` and `externalSystems.redis` hold each system's own status and, when available, its version, memory and connection figures. `responseTimeMs` is the time the FHIR store took to answer its health check. - `cache` holds hit, miss and error counts of the application cache since the process started. - `ovok`, `system` and the FHIR store `serverMetrics` come from the monitoring system, from the last 5 minutes. They are left out when monitoring is not configured or does not answer. - `uptimeSeconds` is the time since this process started. `version` is `null` when the deployment does not set one. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/slim/health' ``` # Request consent signature Canonical page: https://docs.ovok.com/api/consent-signature/request-consent-signature `POST /consent/signature/{consentId}` Requests an e-signature for a FHIR `Consent`: Ovok renders the consent text as a PDF, uploads it to the e-signature service (Documenso) with the verifier as the signer, and returns the document metadata. **Auth:** bearer token. Every FHIR read runs with your token, so you must be able to read the Consent and the resources it points to. ## Behaviour - The Consent must have: - `patient` referencing a `Patient`; - a `provision.data` reference to a `Composition` that holds the consent text; - a `verification` entry whose `verifiedWith` references a `Patient` or `RelatedPerson`, with `verified` not `true`. - The text comes from the Composition section coded `main-content`. It is a Handlebars template filled with `patient`, `signer` and `organization` (the display names of the patient, the verifier and the project). - The signer's email is the first `email` entry in the verifier's `telecom`. - The document language comes from the Composition's CMS language coding when it is one of `en`, `de`, `fr`, `es`, `it`, `pl`; otherwise `de`. - On success an identifier with system `https://app.documenso.com` and the new document ID is added to the Consent. Each call creates a new signature document and adds another identifier. - The response holds `numberOfPages`, `title`, `author`, `subject`, `documentId` and `email` (the signer's address). ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/consent/signature/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List published documents of a public collection Canonical page: https://docs.ovok.com/api/payload-cms-public-delivery/list-published-documents-of-a-public-collection `GET /v1/public/cms/collections/{collectionSlug}/items` Lists the published documents of a CMS collection for one tenant, in one language, one page at a time. Use it to show content such as release notes or articles in an app or website. **Auth:** one of the following, checked in this order: - The CMS public API key, in the `x-api-key` header, as `Authorization: Bearer `, or as the `apiKey` query parameter. - No key, for collections configured as keyless (by default `legal-pages` and `translations`). - A signed-in Ovok session (bearer token), which may only read its own tenant. **Scope:** the tenant you name, by tenant code (`x-ovok-tenant-code` header or `tenant` query parameter) or by project id (`x-ovok-medplum-project-id` header or `projectId` query parameter). Headers win over query parameters, and a tenant code wins over a project id. If you name neither, a signed-in session reads its own tenant. Each Ovok deployment has one set of content; there is no environment to choose. ## Behaviour - Any collection except the `users` and `tenants` system collections can be read. - Only documents with status `published` are returned. The response is the CMS list envelope (`docs`, `totalDocs`, `page`, `limit`, and so on). - `locale` is a language tag such as `de` or `en-US`. Without it, the CMS default locale is used. Missing translations fall back as configured in the CMS. - `page` defaults to `1` and is limited to 1 to 100. `limit` defaults to `20` and is limited to 1 to 50. Values outside those ranges are clamped; values that are not whole numbers fall back to the default. - `sort` is a top-level field name, optionally prefixed with `-` for descending order, for example `-publishedAt`. Without it, the CMS default order is used. - Ovok also has a shared tenant whose published documents are added to every tenant's list. Where both have a document with the same `slug`, the tenant's own document wins. If either tenant has more than 200 published documents in the collection, only the tenant's own documents are returned. - Responses are cached by Ovok for up to 60 seconds. A request that names a tenant gets `Cache-Control: public, s-maxage=60, stale-while-revalidate=300` and a `Vary` on the tenant and API key headers. A request that names no tenant gets `Cache-Control: no-store`. Error responses carry neither. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/public/cms/collections/release-notes/items?tenant=my-medical-project&locale=de&sort=-publishedAt&limit=10' \ -H 'x-api-key: ' ``` # Get a published document by slug Canonical page: https://docs.ovok.com/api/payload-cms-public-delivery/get-a-published-document-by-slug `GET /v1/public/cms/collections/{collectionSlug}/items/{slug}` Returns one published document of a CMS collection by its slug. Use it for stable public pages and deep links, such as terms and conditions or a privacy policy. **Auth:** one of the following, checked in this order: - The CMS public API key, in the `x-api-key` header, as `Authorization: Bearer `, or as the `apiKey` query parameter. - No key, for collections configured as keyless (by default `legal-pages` and `translations`). - A signed-in Ovok session (bearer token), which may only read its own tenant. **Scope:** the tenant you name, by tenant code (`x-ovok-tenant-code` header or `tenant` query parameter) or by project id (`x-ovok-medplum-project-id` header or `projectId` query parameter). Headers win over query parameters, and a tenant code wins over a project id. If you name neither, a signed-in session reads its own tenant. Each Ovok deployment has one set of content; there is no environment to choose. ## Behaviour - Any collection except the `users` and `tenants` system collections can be read. - Only a document with status `published` is returned. The response is the document itself, with the fields its collection defines. - `slug` must start with a lowercase letter or digit and contain only lowercase letters, digits, `-`, `_` and `.`, up to 128 characters. - `locale` is a language tag such as `de` or `en-US`. Without it, the CMS default locale is used. Missing translations fall back as configured in the CMS. - If the tenant has no published document with this slug, Ovok returns the shared tenant's document with that slug, when one exists. - Responses are cached by Ovok for up to 60 seconds. A request that names a tenant gets `Cache-Control: public, s-maxage=60, stale-while-revalidate=300` and a `Vary` on the tenant and API key headers. A request that names no tenant gets `Cache-Control: no-store`. Error responses carry neither. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/public/cms/collections/legal-pages/items/terms-and-conditions?tenant=my-medical-project&locale=en-US' ``` # List published items of a content type Canonical page: https://docs.ovok.com/api/payload-cms-public-delivery/list-published-items-of-a-content-type `GET /v1/public/cms/{contentTypeSlug}/items` Lists the published items of a user-defined content type for one tenant. First-class collections are read with `GET /v1/public/cms/collections/{collectionSlug}/items` instead. **Auth:** one of the following: - The CMS public API key, in the `x-api-key` header, as `Authorization: Bearer `, or as the `apiKey` query parameter. - A signed-in Ovok session (bearer token), which may only read its own tenant. **Scope:** the tenant you name, by tenant code (`x-ovok-tenant-code` header or `tenant` query parameter) or by project id (`x-ovok-medplum-project-id` header or `projectId` query parameter). Headers win over query parameters, and a tenant code wins over a project id. If you name neither, a signed-in session reads its own tenant. Each Ovok deployment has one set of content; there is no environment to choose. ## Behaviour - Returns the CMS `content-items` whose content type has the slug `contentTypeSlug` and whose status is `published`, in the CMS list envelope. - At most 100 items are returned. There is no paging, sorting or locale selection on this route. - Responses are cached by Ovok for up to 60 seconds. A request that names a tenant gets `Cache-Control: public, s-maxage=60, stale-while-revalidate=300` and a `Vary` on the tenant and API key headers. A request that names no tenant gets `Cache-Control: no-store`. Error responses carry neither. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/public/cms/faq/items?tenant=my-medical-project' \ -H 'x-api-key: ' ``` # List the project's CMS API keys Canonical page: https://docs.ovok.com/api/payload-cms-api-keys/list-the-project-s-cms-api-keys `GET /v1/cms/api-keys` Lists the API keys of your current project's CMS content. A key unlocks public CMS delivery (`/v1/public/cms/...`) of this project's tenant only. The keys themselves are never returned. **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 - `keys` is newest first. Each has `id`, `name`, `prefix` (the key's first 12 characters, to tell keys apart), `createdAt` and `isDefault`. - Every project starts with one key, `isDefault: true` with `id` `default` and `createdAt: null`: the key public delivery took before keys were per project. It works until you revoke it. Its `prefix` is only its first 4 characters: the same key serves every project that has not revoked it. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/cms/api-keys' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create a CMS API key Canonical page: https://docs.ovok.com/api/payload-cms-api-keys/create-a-cms-api-key `POST /v1/cms/api-keys` Creates an API key for public CMS delivery (`/v1/public/cms/...`) of your current project's tenant. The answer carries the key itself, once: it is stored only as a hash and cannot be shown again. **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 - `name` is 1 to 64 characters, trimmed. - The key starts with `ovok_cms_`. Send it as `x-api-key`, `Authorization: Bearer` or `?apiKey=`, with the tenant it belongs to (`x-ovok-tenant-code`, `?tenant=`, `x-ovok-medplum-project-id` or `?projectId=`). Naming another project's tenant answers 401. - A project holds at most 20 keys, the default key included: one more returns 409 `CMS_API_KEY_LIMIT`. - A 409 without a code means the project changed while the server wrote. Retry. - The answer is 201. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/cms/api-keys' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "name": "Marketing site" }' ``` # Revoke a CMS API key Canonical page: https://docs.ovok.com/api/payload-cms-api-keys/revoke-a-cms-api-key `DELETE /v1/cms/api-keys/{id}` Revokes one of your current project's CMS API keys. Public delivery stops taking it at once. **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 - `id` is a key's `id` from `GET /v1/cms/api-keys`; `default` revokes the default key. - A key the project does not hold returns 404 `CMS_API_KEY_NOT_FOUND`. - A 409 means the project changed while the server wrote. Retry. - Public responses a CDN already cached may still be served for up to a minute. - The answer is 204. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/cms/api-keys/default' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get i18next resources for a language Canonical page: https://docs.ovok.com/api/localization-keys/get-i18next-resources-for-a-language `GET /localization/i18next/{language}` Returns all localizations of one language as a nested i18next resource object. Apps load it to initialise i18next. **Auth:** bearer token. **Scope:** the caller's project (from the token). Localizations are read and written with your token. ## Behaviour - `language` must be one of the languages in your project's locale settings (`GET /locales`). - Dot-separated keys are turned into nested objects: `home.screen.title` becomes `{ "home": { "screen": { "title": "..." } } }`. - If a key is both a value and the parent of other keys, for example `home` and `home.title`, the nested object wins and the value of `home` is left out. - At most 10,000 entries are included. - The result per project and language is cached. A `PATCH` to this language becomes visible only after its background job has finished. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/localization/i18next/en-US' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Write i18next resources for a language Canonical page: https://docs.ovok.com/api/localization-keys/write-i18next-resources-for-a-language `PATCH /localization/i18next/{language}` Writes many localizations of one language at once from a nested i18next resource object. The write runs in the background. **Auth:** bearer token. **Scope:** the caller's project (from the token). Localizations are read and written with your token. ## Behaviour - `language` must be one of the languages in your project's locale settings (`GET /locales`). - The body is a nested object. Keys may contain only letters, digits, `_` and `-`; nesting builds dot-separated keys. Each value is either a string of 1 to 4,096 characters or another nested object. - Keys in the body are created or overwritten. Keys that are not in the body are not changed. Nothing is deleted. - The route answers `202 Accepted` with no body as soon as the job is queued. The values are written by a background job, and the cache for the language is cleared when it finishes. - A second background job per project language creates AI translations of the default-language values for keys that have no translation in that language yet. Existing translations are not changed. ## Example ```bash curl -X PATCH 'https://api.sandbox.ovok.com/localization/i18next/en-US' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "home": { "title": "Home", "subtitle": "Welcome back" } }' ``` # List localizations with translations Canonical page: https://docs.ovok.com/api/localization-keys/list-localizations-with-translations `GET /localization/map/{target}` Lists localization keys as pairs of the default-language value and its translation in a target language. Use it for translation screens that show the original next to the translation. **Auth:** bearer token. **Scope:** the caller's project (from the token). Localizations are read and written with your token. ## Behaviour - `target` must be one of the languages in your project's locale settings, and must not be the default language. - Each result has `source` (the entry in the default language) and `target` (the entry in the target language) for the same key. `target` is missing when the key has no translation yet. - Pairs are sorted by the target's `date`, newest first, falling back to the source's `date`. `_sort` is accepted but has no effect. - `search` is a fuzzy match over both values, both keys and the target's author name. - `_count` defaults to `10` and must be greater than 0. `_offset` defaults to `0`. `total` is the number of matching pairs before paging. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/localization/map/de-DE?search=home' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List localizations for a language Canonical page: https://docs.ovok.com/api/localization-keys/list-localizations-for-a-language `GET /localization/{language}` Lists the localization keys and values of one language, with optional fuzzy search and paging. **Auth:** bearer token. **Scope:** the caller's project (from the token). Localizations are read and written with your token. ## Behaviour - `language` must be one of the languages in your project's locale settings (`GET /locales`). - Results are sorted by `date`, newest first. `_sort` is accepted but has no effect. - `search` is a fuzzy match over the value, the key and the author name. - `_count` defaults to `10` and must be greater than 0. `_offset` defaults to `0`. `total` is the number of matching entries before paging. - At most 10,000 entries per language are considered. - The list per project and language is cached. Writes through these routes clear the cache for the language they change. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/localization/en-US?search=home&_count=20' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Get a localization Canonical page: https://docs.ovok.com/api/localization-keys/get-a-localization `GET /localization/{language}/{key}` Returns the localization for one key in one language. **Auth:** bearer token. **Scope:** the caller's project (from the token). Localizations are read and written with your token. ## Behaviour - `language` must be one of the languages in your project's locale settings (`GET /locales`). - `key` is a dot-separated path such as `home.screen.title`. It may contain letters, digits, `_`, `-` and `.`, and must not start with `.`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/localization/en-US/home.screen.title' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Delete a localization Canonical page: https://docs.ovok.com/api/localization-keys/delete-a-localization `DELETE /localization/{language}/{key}` Deletes one key in one language, or in every language when you name the default language. **Auth:** bearer token. **Scope:** the caller's project (from the token). Localizations are read and written with your token. ## Behaviour - `language` must be one of the languages in your project's locale settings (`GET /locales`). - If `language` is the project's default language, the key is deleted in every project language. Otherwise only that language's entry is deleted. - Deleting a key that does not exist succeeds and changes nothing. - The response has no body. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/localization/en-US/home.screen.title' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create or update a localization Canonical page: https://docs.ovok.com/api/localization-keys/create-or-update-a-localization `PUT /localization/{language}/{key}` Sets the value of one key in one language. Creates the localization if it does not exist yet. **Auth:** bearer token. **Scope:** the caller's project (from the token). Localizations are read and written with your token. ## Behaviour - `language` must be one of the languages in your project's locale settings (`GET /locales`). - `key` is a dot-separated path such as `home.screen.title`. It may contain letters, digits, `_`, `-` and `.`, and must not start with `.`. - Ovok sets `author` to your profile. If more than one entry exists for this key and language, the first is kept and the others are deleted. - After the write, a background job runs for every project language. It creates an AI translation of the default-language value for each language that has no entry for this key yet. Existing translations are not changed. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/localization/en-US/home.screen.title' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "value": "Home" }' ``` # MCP endpoint (POST only) Canonical page: https://docs.ovok.com/api/mcp/mcp-endpoint-post-only `GET /mcp` This MCP server is stateless: use POST. # MCP endpoint Canonical page: https://docs.ovok.com/api/mcp/mcp-endpoint `POST /mcp` Ovok's MCP server, for Claude or any MCP client: it sets up the project it is connected to, as one of the project's admins. **Auth:** an access token from Ovok's MCP OAuth server, never a Medplum token. Clients find it the standard way: 1. A `GET`, `POST` or `DELETE` without a token answers 401 with `WWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource/mcp"`. 2. That document names the authorization server, `/mcp`. Its metadata is at `/.well-known/oauth-authorization-server/mcp`. 3. The client registers itself at `/mcp/register`, sends the user to `/mcp/authorize` (PKCE S256), and exchanges the code at `/mcp/token`. The answer to the client carries `iss`, this authorization server's issuer (RFC 9207), on allow and on deny. Sign-in and consent happen on the Ovok console. Only an admin of the project can connect a client, and never to the Super Admin project. ## Behaviour - Streamable HTTP, stateless: send every JSON-RPC message with `POST`, one per request. A batch answers 400. There are no sessions: `GET` and `DELETE` answer 405 to a caller with a valid token, and 401 without one. - `server/discover` (MCP 2026-07-28) answers the protocol versions this server speaks, its `tools` capability and its name. None of those versions is 2026-07-28 yet: start with `initialize`. - `/mcp`, its OAuth routes and both MCP metadata documents answer with `Strict-Transport-Security: max-age=31536000; includeSubDomains`. - Every request checks the token, then that its account is still an admin of the project. An account that is no longer an admin gets 403 at once, whatever the token's expiry. When that can't be read, the answer is 503: try again. - Tools act on the project the connection was granted for: - `get_project`; - `get_settings`, `set_setting`, `set_setting_value`; - `list_members`, `invite_member`; - `list_apps` (without the apps' secrets), `create_app`; - `get_signals`. - Each tool runs the same service as the matching API route, with the same rules. A refused call answers a tool error carrying the route's status and error body. - Limits: - Each admin may send 300 messages a minute. Over that, the answer is 429 with `Retry-After`. - Each tool allows 60 calls a minute per admin; `create_app` and `invite_member` allow 10. Over that, the tool error has status 429 and `retryAfterSec`. - Tool errors carry the route's status and body for a refusal (4xx). A failure (5xx) is logged and answered without its detail. - MCP calls are not API usage: like the console's own calls, they are left out of statistics and the plan's monthly request cap. - Access tokens last an hour. Refresh tokens last 30 days, and each one works once: a refresh answers a new pair. A repeat within 30 seconds, such as parallel refreshes, gets a pair of its own. A refresh token used again later ends the connection, and so does revoking either token. A connection ends 90 days after its consent, however often it refreshes: connect again. ## Example Add it to Claude Code, which signs in through the browser on first use: ```bash claude mcp add --transport http ovok https://api.sandbox.ovok.com/mcp ``` # MCP endpoint (POST only) Canonical page: https://docs.ovok.com/api/mcp/mcp-endpoint-post-only-2 `DELETE /mcp` This MCP server is stateless: use POST. # Get patient sharing settings Canonical page: https://docs.ovok.com/api/patient-sharing/get-patient-sharing-settings `GET /v1/patient-sharing/settings` Returns the caller's project settings for data sharing: whether patients may share their data with each other, and whether the patient and practitioner invites (`/v1/invites`) are on. **Auth:** bearer token of a project admin. **Scope:** the caller's project (from the token). ## Behaviour - `enabled`: patient-to-patient sharing is on. Off unless an admin turned it on. - `accessPolicyId`: the ID of the read-only template AccessPolicy every patient-to-patient share points at, or `null` while none has been created. - `practitionerSharingEnabled`: the `/v1/invites` routes are on. Off unless an admin turned it on. - `practitionerAlertDigest`: whether the clinician alert digest is on and how many hours apart it goes out. Off, every 6 hours, unless an admin set it. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/patient-sharing/settings' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Update patient sharing settings Canonical page: https://docs.ovok.com/api/patient-sharing/update-patient-sharing-settings `PUT /v1/patient-sharing/settings` Turns patient-to-patient sharing, and the patient and practitioner invites (`/v1/invites`), on or off for the caller's project. **Auth:** bearer token of a project admin. **Scope:** the caller's project (from the token). ## Behaviour - `enabled` is required. Turning it on creates the read-only sharing template AccessPolicy, or brings an existing one up to date, in the same atomic write as the setting. The template lets a recipient read and search the sharer's Observations with the shared codes, and read the sharer's Patient resource with contact details, identifiers and most other fields hidden. - Turning `enabled` off stops new invites and redemptions. Existing shares stay until they are ended. - `enabled` also lets a signed-in patient share Observation codes with a related person by email (`POST /v1/invites/record-share` with `"recipient": "related-person"`). A new address gets a related-person account when it accepts, with a built-in base policy that reads only its own RelatedPerson; it is created the first time it is needed. Map `RELATED_PERSON_INVITED` and `RELATED_PERSON_RECORD_SHARED`, or the `PATIENT_INVITE` and `PATIENT_ASSIGNMENT_REQUEST` templates they fall back to: an invite whose email cannot be sent is undone. - `practitionerSharingEnabled` does the same for the patient and practitioner invites, with the practitioner share's template. Leave it out or send `null` to keep its current value. - Both are off by default. The response is the settings after the write, as `GET /v1/patient-sharing/settings` returns them. - With `practitionerSharingEnabled` on, a signed-in patient can create a practitioner account (with the project's default practitioner access policy) for a new address, and a practitioner can create a patient account, each holding the share. Make sure that policy gives a new practitioner nothing a patient should not hand out. Map the `PATIENT_INVITE`, `PATIENT_ASSIGNMENT_REQUEST`, `PRACTITIONER_INVITED_BY_PATIENT` and `PRACTITIONER_PATIENT_SHARED` email templates first: an invite whose email cannot be sent is undone. - Do not turn on `practitionerSharingEnabled` in projects whose practitioners use the carehub dashboard: its route guard checks resource types only, so a practitioner who only holds shared patients could see project-wide data there. - `practitionerAlertDigest` turns the clinician alert digest on or off: `{ "enabled": true, "everyHours": 6 }`, where `everyHours` is 1, 6, 12 or 24. Leave `everyHours` out to keep the saved hours (6 until set). Leave the whole field out, or send `null`, to keep the digest as it is. - Switching it on needs Signals annotations (`SIGNALS_ANNOTATE_OBSERVATIONS`), `enabled` and `practitionerSharingEnabled` all on; otherwise the write is refused with 409 `SETTING_NOT_AVAILABLE`. A write that only keeps it on is not checked, so sharing can still be turned off. While any of the three is off, no digest goes out. - Every `everyHours`, each practitioner on an active practitioner share gets one email listing their patients with new Signals alerts: the patient's name, how many new alerts, and a link to the patient's alerts in the dashboard. It carries no reading or value, and nothing goes out when there are no new alerts. - It counts alerts from the moment it was switched on, never the backlog before. Switching it off, or one of its prerequisites going off, forgets where it was, so switching it on again starts afresh. - Each digest covers alerts up to an hour before it goes out: alerts reach FHIR through a flush that can lag, and an alert that arrives more than an hour late is not counted. - Map the `PRACTITIONER_ALERT_DIGEST` email template first. - A 409 without a code means the project's settings changed during the write. Read the settings again and retry. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/v1/patient-sharing/settings' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "enabled": true, "practitionerSharingEnabled": null, "practitionerAlertDigest": { "enabled": true, "everyHours": 6 } }' ``` # Create a share invite Canonical page: https://docs.ovok.com/api/patient-sharing/create-a-share-invite `POST /v1/patient-sharing/invites` The signed-in patient creates a one-time invite to share Observations with the given codes with another patient. Set `includeMedications` to `true` to also share patient-scoped MedicationStatements and MedicationAdministrations. Hand the `inviteId` and `code` to the other patient, who accepts with `POST /v1/patient-sharing/invites/redeem`. **Auth:** bearer token of a Patient. **Scope:** the caller's project (from the token). ## Behaviour - Patient sharing must be on for the project (`PUT /v1/patient-sharing/settings`). - `codes`: 1 to 100 Observation codes, each 1 to 64 letters, digits, `.` or `-`. Duplicates are removed. - `includeMedications`: optional, defaults to `false`. When true, the recipient can read the sharer's MedicationStatements and MedicationAdministrations until the share ends. - `endsAt` must be `null`: a share lasts until it is ended. A date is refused for now. - The invite is stored as a draft `Consent`. Only a SHA-256 hash of `code` is stored, so `code` is returned once, in this response. - The invite expires 15 minutes after it is created (`expiresAt`). - A patient can hold at most 10 unexpired invites at once. - A 429 means the patient already holds 10 unexpired invites. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/patient-sharing/invites' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "codes": ["8480-6", "8462-4"], "endsAt": null, "includeMedications": true }' ``` # Accept a share invite Canonical page: https://docs.ovok.com/api/patient-sharing/accept-a-share-invite `POST /v1/patient-sharing/invites/redeem` The signed-in patient accepts another patient's share invite, and from then on can read what it shares. **Auth:** bearer token of a Patient. **Scope:** the caller's project (from the token). ## Behaviour - Patient sharing must be on for the project. - The invite is single use, expires 15 minutes after it was created, and cannot be accepted by the patient who made it. - On success the invite's `Consent` becomes `active` and names the caller as recipient, and a grant is added to the caller's membership, in one atomic write. The caller's cached sessions are refreshed, so the new access applies on the next request. - The grant lets the caller read and search the sharer's Observations with the shared codes, and read the sharer's Patient resource with contact details, identifiers and most other fields hidden. - A share also grants a multi-value reading's group Observation when it covers every value the group repeats (systolic and diastolic for blood pressure, the waveform for an ECG, any part of an SpO2 or urine-strip reading), so the whole reading can be read and nothing more. The share's `codes` stay as the sharer chose them. - A 409 that says your account changed meanwhile can be retried as is. - A 503 means sharing is on but its template AccessPolicy is missing. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/patient-sharing/invites/redeem' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "inviteId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "code": "" }' ``` # List shares Canonical page: https://docs.ovok.com/api/patient-sharing/list-shares `GET /v1/patient-sharing/shares` Lists the signed-in patient's active shares in both directions, the practitioners their whole record is shared with, and the related persons they share codes with. For a signed-in related person (a carer), lists the shares patients gave them. **Auth:** bearer token of a Patient or a RelatedPerson. **Scope:** the caller's project (from the token). ## Behaviour - `outgoing`: the caller's active patient-to-patient shares (Consents where the caller is the sharer), including the `includeMedications` choice. - `incoming`: what is shared with the caller, read from the grants on the caller's own membership, since those decide what the caller can see. Each share includes its `includeMedications` choice. A grant whose Consent cannot be read is still listed, so it can be ended. - `practitioners`: the caller's active record shares with practitioners. - `relatedPersons`: the caller's active shares with related persons (carers), each with its `codes` and `includeMedications` choice. - `received`: for a related person, the active shares patients gave them: the sharing patient (`sharer`), the shared `codes`, `includeMedications` and `startedAt`. Only their own: another carer's shares never show. Empty for a patient. - A related person gets only `received`; the other lists are empty. - Names are the display names of the Patient, Practitioner and RelatedPerson profiles in the project. - A practitioner gets 403. - Each Consent search returns at most 100 entries; there is no paging. - Pending invites (drafts) are not listed. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/patient-sharing/shares' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # End a share Canonical page: https://docs.ovok.com/api/patient-sharing/end-a-share `DELETE /v1/patient-sharing/shares/{consentId}` Ends a share, cancels a pending invite, or declines a practitioner's invite. A related person (a carer) leaves a share they received. Access stops at once. **Auth:** bearer token of a Patient or a RelatedPerson. **Scope:** the caller's project (from the token). ## Behaviour - Who may call it, by `consentId`: - a patient-to-patient share: the sharer or the recipient; - a pending patient-to-patient invite: the sharer (this cancels it); - a share of the caller's record with a practitioner, or a practitioner's pending invite to the caller: the patient. - a share of the caller's codes with a related person, or its pending invite: the patient; - a share a patient gave the caller as their related person: the related person (see below). - A practitioner gets 403. - Every grant bound to the Consent is removed from the members who hold it, and the Consent is set to `inactive`, in one atomic write. The holders' cached sessions are refreshed. - Calling it again on an ended share only sweeps any grants left behind, so retrying is safe. - If the records keep changing during the write, it retries up to three times, then answers 409. Retry the call. - Returns `204 No Content`. ## A related person leaving a share - The Consent is set to `inactive`, as when the patient ends it, and its grant leaves the caller's own membership, in one atomic write. The caller's cached sessions are refreshed. - The membership keeps its base policy. One that had lost it gets it back, so it never reads as full project access. - `404` when the share is not one the caller received, for example another carer's or a patient-to-patient share. It never says whose it is. - `409` when the share already ended, or a record changed during the write. Read the list again and retry. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/patient-sharing/shares/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Share my record Canonical page: https://docs.ovok.com/api/invites/share-my-record `POST /v1/invites/record-share` The signed-in patient shares their record by email, with a practitioner or a related person (a carer): - `"recipient": "practitioner"` shares the whole record. A new address gets a practitioner account that already holds the share; a practitioner of the project gets an offer to accept. - `"recipient": "related-person"` shares only the Observation `codes` named in the body, and optionally the patient's MedicationStatements and MedicationAdministrations when `includeMedications` is `true`. The patient record's contact fields stay hidden. Either way the address gets an invite to accept; a new address makes its related-person account when it accepts. Any other `recipient` is a 422 naming `recipient`. **Auth:** bearer token of a Patient. **Scope:** the caller's project (from the token). ## Behaviour ### Practitioner - **Gates**, checked before the address is looked up, in this order: - practitioner sharing (`practitionerSharingEnabled` on `PUT /v1/patient-sharing/settings`) is on; it is off by default; - `PRACTITIONER_INVITATION_ENABLED` is not `false`; - the project has a practitioner app URL; - the project has a default practitioner access policy (`DEFAULT_PRACTITIONER_ACCESS_POLICY`, else `CLINICIAN_INVITE_ACCESS_POLICY`); - the patient has fewer than 20 pending offers. - **What happens, by address:** - No User has the address: a practitioner account of the project is created with the default practitioner access policy and the patient's share on its membership, in one atomic write. The address gets a `PRACTITIONER_INVITED_BY_PATIENT` email with a set-password link on the practitioner app. - The address belongs to exactly one active practitioner of the project: a pending offer is created and the address gets a `PRACTITIONER_PATIENT_SHARED` email with an accept link, `/accept-invite?invite=&code=`, valid for 7 days. The share starts only when that practitioner, signed in, posts both values to `POST /v1/invites/record-share/accept`. - The record is already shared with that practitioner: nothing is sent, unless their account has no password yet, in which case the set-password email goes out again. - Anything else (a User that is not a practitioner of this project, or a practitioner with full project access): nothing is written or sent. - Each email is sent as the last step of the write. Map the email templates named above in the project's email configuration first. - Do not enable practitioner sharing in projects whose practitioners use the carehub dashboard: its route guard checks resource types only, so a practitioner who only holds shared patients could see project-wide data there. - A 409 with `invitation_not_configured` means the project has no default practitioner access policy. It needs project configuration, not a retry. - A 429 means the patient already has 20 pending offers. ### Related person - **Body:** `email`, `firstName`, `lastName`, `codes` (1 to 100 Observation codes, each letters, digits, `.` and `-` only), and optional `includeMedications` (defaults to `false`). - **Gates**, checked before the address is looked up, in this order: - patient sharing (`enabled` on `PUT /v1/patient-sharing/settings`) is on; it is off by default; - `RELATED_PERSON_INVITATION_ENABLED` is not `false` (403 `Invitation is not enabled for this project.`, as for a practitioner); - the project has a patient app URL; - the patient has fewer than 20 pending related-person invites. - **What happens, by address:** - No User has the address: a pending share is created and the address gets a `RELATED_PERSON_INVITED` email with an accept link, `/accept-invite?invite=&code=`, valid for 7 days. Nothing else is created yet: the account is made when the link is accepted (`POST /v1/invites/record-share/accept` with a `password`). - The address belongs to exactly one active related person of the project: a pending share is created and the address gets a `RELATED_PERSON_RECORD_SHARED` email with the same kind of link. The share starts when that related person, signed in, accepts it. - Anything else (a patient, a practitioner, or a User that is not a related person of this project): nothing is written or sent. - The pending share is a `draft` Consent holding only a hash of the one-time code. It grants nothing until it is accepted. - `RELATED_PERSON_INVITED` and `RELATED_PERSON_RECORD_SHARED` carry `firstName`, `lastName`, `sharerName` (the patient's name), `invitationUrl` (the accept link) and `baseUrl`. A project whose email configuration maps neither sends `PATIENT_INVITE` and `PATIENT_ASSIGNMENT_REQUEST` instead, with `inviterName` set to the patient's name. - A 429 means the patient already has 20 pending related-person invites. ### Both - The answer is always `202 { "status": "sent" }`, whichever case applied, so it does not reveal whether the address has an account. If the email cannot be sent, everything the invite wrote is undone, and the answer is still 202. - A 409 with `app_url_not_configured` means the project has no app URL for the recipient: the practitioner app, or the patient app for a related person. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/invites/record-share' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "recipient": "practitioner", "email": "max.mustermann@example.com", "firstName": "Max", "lastName": "Mustermann" }' ``` ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/invites/record-share' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "recipient": "related-person", "email": "max.mustermann@example.com", "firstName": "Max", "lastName": "Mustermann", "codes": ["8480-6", "8462-4"], "includeMedications": true }' ``` # Accept a patient's record share Canonical page: https://docs.ovok.com/api/invites/accept-a-patient-s-record-share `POST /v1/invites/record-share/accept` Accepts a patient's record share from its email: a practitioner's `PRACTITIONER_PATIENT_SHARED` offer, or a related person's `RELATED_PERSON_INVITED` or `RELATED_PERSON_RECORD_SHARED` invite. From then on the share is in place. The invite decides how it is accepted. **Auth:** bearer token of the Practitioner or RelatedPerson the invite names; none for an invite to a new address. **Scope:** the caller's project (from the token); for a new address, the invite's project. ## Behaviour - Send the `invite` and `code` values from the email's accept link as `inviteId` and `code`. `password` is only for a new related person; send `null` (or leave it out) otherwise. - Every invite is single use and expires 7 days after it was sent. A used one answers 409, an expired one 410, and an unknown one or a wrong `code` 404, whoever calls. - On success the invite's Consent becomes `active` and its grant is added to the recipient's membership, in one atomic write. The recipient's cached sessions are refreshed, so the new access applies on the next request. - The share lasts until the patient ends it (`DELETE /v1/patient-sharing/shares/{consentId}`). ### A practitioner's offer - Signed in as the practitioner the offer names; without a token the answer is 401. - Gates: practitioner sharing must be on for the project, and `PRACTITIONER_INVITATION_ENABLED` must not be `false`. - The share covers the patient's whole compartment. Observations, Communications, DocumentReferences, QuestionnaireResponses, ServiceRequests, Tasks and Appointments can be read, searched, created and updated; CommunicationRequests, Goals, CarePlans, Flags, EpisodeOfCare and DeviceUseStatements are read-only; the Patient can be read, searched and updated. Nothing can be deleted. - A 409 with `practitioner_without_access_policy` means the caller has full project access, which a share would narrow. - The answer is the practitioner share: `consentId`, `sharer`, `practitioner`, `startedAt`, `endsAt`. ### A related person's invite - Gate: patient sharing must be on for the invite's project. - The share covers the sharer's Observations with the invite's codes (read and search), and the sharer's Patient resource with contact details, identifiers and most other fields hidden. - A share also covers a multi-value reading's group Observation when it covers every value the group repeats (systolic and diastolic for blood pressure, the waveform for an ECG, any part of an SpO2 or urine-strip reading), so the whole reading can be read and nothing more. The share's `codes` stay as the sharer chose them. - **A new address** (`RELATED_PERSON_INVITED`): no token. Send a `password` that meets the password policy; without one the answer is a 422 with `password_required`. In one atomic write under the address's account lock, the account is made: a User scoped to the project, a RelatedPerson of the sharer, and a membership holding the built-in related-person base policy (read and search of its own RelatedPerson only, created the first time it is needed) and the share's grant. If the address has any account by now, nothing is written and the answer is a 409 with `address_has_account`. Sign in afterwards with the address and that password. - **A related person of the project** (`RELATED_PERSON_RECORD_SHARED`): signed in as the related person the invite names; without a token the answer is 401, as another related person or in another project 404. The grant is added to their membership, keeping its base policy. - The answer is the related-person share: `consentId`, `sharer`, `relatedPerson`, `codes`, `startedAt`, `endsAt`. - A 409 with `sharing_not_configured` means the project lost its patient-sharing template; turn patient sharing on again. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/invites/record-share/accept' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "inviteId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "code": "", "password": null }' ``` A new related person, without a token: ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/invites/record-share/accept' \ -H 'Content-Type: application/json' \ -d '{ "inviteId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "code": "", "password": "Ex4mple-Passw0rd" }' ``` # Invite a patient into my care Canonical page: https://docs.ovok.com/api/invites/invite-a-patient-into-my-care `POST /v1/invites/care` A signed-in practitioner invites a patient into their care, by email. A new address gets a patient account whose record is already shared with the inviter; a patient of the project gets an invite to accept. **Auth:** bearer token of a Practitioner. **Scope:** the caller's project (from the token). ## Behaviour - **Gates**, checked before the address is looked up, in this order: - practitioner sharing (`practitionerSharingEnabled` on `PUT /v1/patient-sharing/settings`) is on; it is off by default; - `PATIENT_INVITATION_ENABLED` is not `false`; - the project has a patient app URL; - the project has a default patient access policy; - the inviter's membership has an access policy (a membership with full project access is refused, because a share would narrow it); - the inviter has fewer than 20 pending invites. - **What happens, by address:** - No User has the address: a patient account of the project is created with the default patient access policy, and its record is shared with the inviter, in one atomic write. The address gets a `PATIENT_INVITE` email with a set-password link on the patient app. - The address belongs to exactly one active patient of the project: a pending invite is created and the address gets a `PATIENT_ASSIGNMENT_REQUEST` email with an accept link, `/accept-invite?invite=&code=`, valid for 7 days. The share starts only when that patient, signed in, posts both values to `POST /v1/invites/care/accept`. - The patient already shares their record with the inviter: nothing is sent, unless their account has no password yet, in which case the set-password email goes out again. - Anything else (a User that is not a patient of this project): nothing is written or sent. - The answer is always `202 { "status": "sent" }`, whichever case applied, so it does not reveal whether the address has an account. If the email cannot be sent, everything the invite wrote is undone, and the answer is still 202. - Each email is sent as the last step of the write. Map the email templates named above in the project's email configuration first. - Do not enable practitioner sharing in projects whose practitioners use the carehub dashboard: its route guard checks resource types only, so a practitioner who only holds shared patients could see project-wide data there. - A 409 with `app_url_not_configured` means the project has no patient app URL; `invitation_not_configured` means it has no default patient access policy; `practitioner_without_access_policy` means the inviter has full project access. None of these is fixed by retrying. - A 429 means the practitioner already has 20 pending invites. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/invites/care' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com", "firstName": "Max", "lastName": "Mustermann" }' ``` # Accept a practitioner's care invite Canonical page: https://docs.ovok.com/api/invites/accept-a-practitioner-s-care-invite `POST /v1/invites/care/accept` The signed-in patient accepts a practitioner's invite into their care from a `PATIENT_ASSIGNMENT_REQUEST` email. From then on their whole record is shared with the inviting practitioner. **Auth:** bearer token of a Patient. **Scope:** the caller's project (from the token). ## Behaviour - Send the `invite` and `code` values from the email's accept link as `inviteId` and `code`. - Gates: practitioner sharing must be on for the project, and `PATIENT_INVITATION_ENABLED` must not be `false`. - Only the patient the invite names can accept it. The invite is single use and expires 7 days after it was sent. - On success the invite's Consent becomes `active` and a grant for the caller's record is added to the practitioner's membership, in one atomic write. The practitioner's cached sessions are refreshed. - The practitioner gets the access described on `POST /v1/invites/record-share/accept`: the patient's whole compartment, with no delete. - The share lasts until the patient ends it (`DELETE /v1/patient-sharing/shares/{consentId}`). - A 409 with `practitioner_without_access_policy` means the practitioner has full project access, which a share would narrow. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/invites/care/accept' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "inviteId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "code": "" }' ``` # Backfill missed Sleepiz nights Canonical page: https://docs.ovok.com/api/sleepiz/backfill-missed-sleepiz-nights `POST /sleepiz/backfill` Refills Sleepiz nights that the live push never delivered. Ovok pulls each night from the Sleepiz public API for one device and sends it through the same ingest path as live data. **Auth:** Bearer token. The caller must be a project admin. **Scope:** The caller's project (from the token) and its sub-projects. The device must belong to one of them. The route takes no project parameter. ## Behaviour - The body is strict: `serialNumber` (6 to 10 digits), `from` and `to` (`YYYY-MM-DD`). Unknown fields are rejected. - `from` to `to` is inclusive, `from` must not be after `to`, `to` must be yesterday (UTC) or earlier, and the range is at most 7 nights. Longer gaps need several calls. - The device is looked up by its serial. It must be a Sleepiz serial, must belong to your project or one of its sub-projects (403 otherwise), and must have an assigned resident (409 otherwise). Assign the resident and call again. A serial held by devices in more than one project is refused with 409 too: ingest routes its readings to none of them. - Nights are matched to the device's patient deployments in Sleepiz. Each night in the response has an `outcome`: `posted`, `no_recording`, `no_deployment` or `error`. One night failing does not stop the others. - **`posted` means queued, not stored.** Ovok queues the night's Observations through the live ingest router and nothing is written to Medplum during the request. `jobIds` lists the queued jobs and `missingBlocks` names data Sleepiz had no samples for. - Re-running the same device and range is safe. The queue job ids are deterministic and the Observation write is conditional on its event id, so no duplicates appear. - The route answers 503 when the Sleepiz credentials are not configured on the server, and 502 when the Sleepiz API cannot be reached. - **Last night needs no call.** Every day at 11:00 UTC ovok runs the same refill for yesterday's night on every device that has a resident and no recording of that night yet, except the stakeholder beds. Use this route for older nights. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/sleepiz/backfill' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "serialNumber": "", "from": "2026-01-01", "to": "2026-01-03" }' ``` # Get Pulsene MQTT settings Canonical page: https://docs.ovok.com/api/iotdevice/get-pulsene-mqtt-settings `POST /v1/iot-device/pulsene/setup` Returns the MQTT connection settings for a Pulsene MC01 device. The device calls this route on startup to learn which broker to connect to. **Auth:** None at the HTTP level (no bearer token). The body must carry an `apiKey` that matches the key the device firmware ships with. A wrong or missing key is rejected with 401. ## Behaviour - The body must contain `serialNumber` (non-empty string) and `apiKey` (non-empty string). - Ovok does not look the device up. Any serial that passes the key check receives the same response shape: `mqtt.clientId` is the serial you sent, `username` and `password` are the fixed MC01 broker credentials, and `url` is the broker URL configured for the environment. - `wifi` and `pairing` are not returned for this device family. - The route answers `200`. It does not write anything. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/iot-device/pulsene/setup' \ -H 'Content-Type: application/json' \ -d '{ "serialNumber": "", "apiKey": "" }' ``` # Fetch user's video call access permission Canonical page: https://docs.ovok.com/api/video-call/fetch-user-s-video-call-access-permission `GET /video-call/livekit/access-permission/{appointmentId}` Returns the video call access permission of the signed-in user for one Appointment. Use it to check whether the user has been invited before you request a join link. **Auth:** bearer token. **Scope:** the caller's project (from the token). ## Behaviour - The permission is the `CommunicationRequest` that links the Appointment to the user's profile as recipient. The route returns it without its `meta`. - If there is no such grant for the caller's profile, the route returns 403. - The lookup uses the caller's own profile reference (for example `Patient/`), so a user only ever sees their own permission. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/video-call/livekit/access-permission/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create video call guest access Canonical page: https://docs.ovok.com/api/video-call/create-video-call-guest-access `POST /video-call/livekit/guest-access/{appointmentId}` Creates a join link for a video call Appointment for someone who has no Ovok account. A Practitioner calls it, then shares the returned `videoCallUrl` with the guest. **Auth:** bearer token. The caller must be a Practitioner. **Scope:** the caller's project (from the token). The Appointment is read in that project. ## Behaviour - The guest has no room admin rights. The guest's display name in the call is `guestEmail`. - The link is valid from 1 hour before the Appointment `start` until 1 hour after its `end`. - The route does not send an email. To email the link, use the video call mail routes. - Every call returns a new token. Earlier tokens stay valid until they expire. - The response holds `videoCallUrl` (the full join link), `livekitJwt` and `passphrase`. The passphrase is the one stored on the Appointment and is also the fragment of `videoCallUrl`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/video-call/livekit/guest-access/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "guestEmail": "max.mustermann@example.com" }' ``` # Create video call Ovok-user access Canonical page: https://docs.ovok.com/api/video-call/create-video-call-ovok-user-access `POST /video-call/livekit/user-access/{appointmentId}` Creates a join link for a video call Appointment for the signed-in Ovok user. Use it when a Practitioner or Patient joins a call from an Ovok app. **Auth:** bearer token. The caller's profile must be a Practitioner or a Patient. A RelatedPerson is refused. **Scope:** the caller's project (from the token). ## Behaviour - A Practitioner can always join and joins as room admin. - A Patient can join only after a Practitioner has granted access to the Appointment. The grant is a `CommunicationRequest` that names the Patient as recipient. `POST /video-call/livekit/notification/active-call/{appointmentId}` creates it. Without it the route returns 401. - The display name in the call is the Practitioner's name, or for a Patient the user's email, or `user-` when there is no email. - The token is valid from 1 hour before the request until 24 hours after it. Unlike guest access, it does not follow the Appointment times. - The response holds `videoCallUrl` (the full join link), `livekitJwt` and `passphrase`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/video-call/livekit/user-access/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Fetch user's video call Appointments Canonical page: https://docs.ovok.com/api/video-call/fetch-user-s-video-call-appointments `GET /video-call/livekit/appointment` Lists the video call Appointments in which the signed-in user is a participant, ordered by date. **Auth:** bearer token. Any signed-in user can call it. **Scope:** the caller's project (from the token). Only Appointments that name the caller's own profile as a participant are returned. ## Behaviour - Only Appointments created through the video call routes are returned. - `startDate` and `endDate` are optional. Each is a UTC date-time such as `2025-01-01T14:00:00Z`, with an optional FHIR search prefix (`eq`, `ne`, `lt`, `gt`, `ge`, `le`, `sa`, `eb`, `ap`), for example `ge2025-01-01T00:00:00Z`. Each becomes a FHIR `date` search on the Appointment start. - The route has no paging. It returns every match in one response. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/video-call/livekit/appointment?startDate=ge2026-01-01T12:00:00Z&endDate=le2026-01-02T12:00:00Z' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Create video call Appointment Canonical page: https://docs.ovok.com/api/video-call/create-video-call-appointment `POST /video-call/livekit/appointment` Creates a video call Appointment with its participants. Use it before you invite participants or create join links. **Auth:** bearer token. The caller must be a Practitioner, an admin or a super admin, or hold the "System Owner" access policy. **Scope:** the caller's project (from the token). Participant accounts are looked up and created in that project. ## Behaviour - `start` and `end` are UTC date-times. `end` must be later than `start`. - Participants are identified by email. Duplicate emails are dropped. - For each email, a Practitioner account in the project is used if one exists. Otherwise a Patient account is used, and one is created if the email has none yet. - The Appointment must have at least one Practitioner participant. - Each participant gets a TAN (a one-time access code), valid from one hour before the request until one day after `end`. Invitation and update emails include it. - The Appointment gets a random passphrase. Join links include it, and you cannot set or change it. - Participants are stored with status `tentative`. The route sends no emails and creates no access permission. Use `POST /video-call/livekit/mail/invite` to email participants and `POST /video-call/livekit/notification/active-call/{appointmentId}` to let them join. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/video-call/livekit/appointment' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "start": "2026-01-01T12:00:00Z", "end": "2026-01-02T12:00:00Z", "comment": "Check-up call", "description": "Follow-up appointment", "videoCallParticipants": [{ "email": "max.mustermann@example.com" }] }' ``` # Update video call Appointment Canonical page: https://docs.ovok.com/api/video-call/update-video-call-appointment `PUT /video-call/livekit/appointment/{appointmentId}` Replaces the time, title, description and participants of an existing video call Appointment. Use it to reschedule a call or change who is invited. **Auth:** bearer token. The caller must be a Practitioner, an admin or a super admin, or hold the "System Owner" access policy. **Scope:** the caller's project (from the token). ## Behaviour - The Appointment is identified by the `appointmentId` path parameter. Any `id` in the body is ignored. - The body works like the create route: `end` must be later than `start`, participants are identified by email and deduplicated, and at least one must be a Practitioner. Unknown emails become Patient accounts. - The participant list is replaced by the one you send. Send everyone who should stay. - The passphrase of the Appointment does not change, so existing join links keep working. - New TANs are created for all participants on every update. - If the Appointment already has an access permission, its recipients are replaced by the new participant list. A Patient you add can therefore join without a second call to the active-call notification route. - The route sends no emails. Use `POST /video-call/livekit/mail/update` to tell participants about the change. ## Example ```bash curl -X PUT 'https://api.sandbox.ovok.com/video-call/livekit/appointment/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "start": "2026-01-01T12:00:00Z", "end": "2026-01-02T12:00:00Z", "comment": "Check-up call", "videoCallParticipants": [{ "email": "max.mustermann@example.com" }] }' ``` # Send emails: video call invitation Canonical page: https://docs.ovok.com/api/video-call/send-emails-video-call-invitation `POST /video-call/livekit/mail/invite` Sends invitation emails for a video call Appointment to the recipients you list. The route does not change the Appointment. **Auth:** bearer token. The caller must be a Practitioner, an admin or a super admin, or hold the "System Owner" access policy. **Scope:** the caller's project (from the token). ## Behaviour - `emailRecipients` takes 1 to 20 entries. Each has an `email` and a `profileRef` (`Practitioner/` or `Patient/`). Duplicate emails are dropped. - The caller is never emailed, even when listed. If no recipient is left, the route returns an empty `emailRecipientsResult`. - The email contains the recipient's TAN (a one-time access code) and its expiry. A recipient with no TAN gets no email and `isEmailSent` is `false`. - The email includes the Appointment title, the practitioner's name, start and end in CET. The `Origin` header of your request sets the app domain used in the email, and the request language sets its language. - Emails are sent one by one. A failed send does not fail the request. Check `isEmailSent` for each recipient. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/video-call/livekit/mail/invite' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "appointmentId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "emailRecipients": [{ "email": "max.mustermann@example.com", "profileRef": "Patient/c3499c27-2973-0a7f-807e-fb8676a92dcb" }] }' ``` # Send emails: video call update Canonical page: https://docs.ovok.com/api/video-call/send-emails-video-call-update `POST /video-call/livekit/mail/update` Sends update emails for a video call Appointment to the recipients you list. The route does not change the Appointment. **Auth:** bearer token. The caller must be a Practitioner, an admin or a super admin, or hold the "System Owner" access policy. **Scope:** the caller's project (from the token). ## Behaviour - `emailRecipients` takes 1 to 20 entries. Each has an `email` and a `profileRef` (`Practitioner/` or `Patient/`). Duplicate emails are dropped. - The caller is never emailed, even when listed. If no recipient is left, the route returns an empty `emailRecipientsResult`. - The email contains the recipient's TAN (a one-time access code) and its expiry. A recipient with no TAN gets no email and `isEmailSent` is `false`. - The email includes the Appointment title, the practitioner's name, start and end in CET. The `Origin` header of your request sets the app domain used in the email, and the request language sets its language. - Emails are sent one by one. A failed send does not fail the request. Check `isEmailSent` for each recipient. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/video-call/livekit/mail/update' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "appointmentId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "emailRecipients": [{ "email": "max.mustermann@example.com", "profileRef": "Patient/c3499c27-2973-0a7f-807e-fb8676a92dcb" }] }' ``` # Send emails: video call cancellation Canonical page: https://docs.ovok.com/api/video-call/send-emails-video-call-cancellation `POST /video-call/livekit/mail/cancel` Sends cancellation emails for a video call Appointment to the recipients you list. The route does not change the Appointment. **Auth:** bearer token. The caller must be a Practitioner, an admin or a super admin, or hold the "System Owner" access policy. **Scope:** the caller's project (from the token). ## Behaviour - `emailRecipients` takes 1 to 20 entries. Each has an `email` and a `profileRef` (`Practitioner/` or `Patient/`). Duplicate emails are dropped. - The caller is never emailed, even when listed. If no recipient is left, the route returns an empty `emailRecipientsResult`. - Cancellation emails need no TAN. - The email includes the Appointment title, the practitioner's name, start and end in CET. The `Origin` header of your request sets the app domain used in the email, and the request language sets its language. - Emails are sent one by one. A failed send does not fail the request. Check `isEmailSent` for each recipient. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/video-call/livekit/mail/cancel' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "appointmentId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "emailRecipients": [{ "email": "max.mustermann@example.com", "profileRef": "Patient/c3499c27-2973-0a7f-807e-fb8676a92dcb" }] }' ``` # Send notifications to video call participants Canonical page: https://docs.ovok.com/api/video-call/send-notifications-to-video-call-participants `POST /video-call/livekit/notification/active-call/{appointmentId}` Tells the participants of a video call Appointment that the call is active, and lets them join on their own. A Practitioner calls it when they start the call. **Auth:** bearer token. The caller must be a Practitioner, an admin or a super admin, or hold the "System Owner" access policy. **Scope:** the caller's project (from the token). ## Behaviour - Creates the access permission for the Appointment: a `CommunicationRequest` with the caller as sender and every Appointment participant as recipient. If one already exists for the Appointment, it is replaced. - Patients need this permission to get a join link from `POST /video-call/livekit/user-access/{appointmentId}`. - Queues a real-time event, `/video-call/livekit/notification/active-call`, for each participant who is not already in the LiveKit room. The event carries the sender's name, the Appointment id, description, start and end. Connect to the Ovok events socket to receive it. - The route returns once the event is queued, not when it is delivered. The response is an `OperationOutcome` with severity `information`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/video-call/livekit/notification/active-call/c3499c27-2973-0a7f-807e-fb8676a92dcb' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List the project's wearable providers Canonical page: https://docs.ovok.com/api/wearables/list-the-project-s-wearable-providers `GET /v1/wearables/providers` Returns every cloud wearable provider ovok supports, and whether your current project has set each one up. It never returns a secret. **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 - `providers` lists `oura`, `whoop`, `strava`, `withings`, `polar`, `suunto`, `garmin` and `ultrahuman`. - `configured` is `true` when the project holds OAuth credentials for the provider that this server can read. Credentials stored with another key read as not configured; set them up again with `POST`. - `enabled` is `true` when the provider is configured and switched on. Only then can the project's patients connect it. - `clientId` is the OAuth client ID, or `null`. - `redirectUri` is the callback URL to register in the provider's developer portal, the same for every project. It is `null` when this server has no public base URL. - `webhookUrl` is where the provider sends notifications of new data, unique to the project. For Withings it ends in a per-project token that proves a notification's origin, so only admins see it; keep it private. Paste it where the provider's portal asks for one (Suunto). For Withings and Polar it is for information only: ovok registers it itself. It is `null` when the provider sends no notifications (Oura, Whoop, Strava, Garmin and Ultrahuman for now), is not set up, or this server has no public base URL. See `POST /v1/wearables/webhooks//`. - `webhookReady` is `true` when ovok holds the secret that checks the provider's notifications: Polar's signing key from its webhook setup, the secret ovok makes for Withings, or Suunto's `webhookSecret`. It is `false` until then, so a Polar webhook setup that failed shows here; save Polar again to retry. It is `null` when the provider sends no notifications. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/wearables/providers' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Set up a wearable provider Canonical page: https://docs.ovok.com/api/wearables/set-up-a-wearable-provider `POST /v1/wearables/providers` Stores your project's OAuth app at a wearable provider, so the project's patients can connect their accounts. **Auth:** bearer token of a project admin. **Scope:** the caller's project (from the token). ## Before you call it 1. Register an app in the provider's developer program. Garmin, Suunto and Polar approve apps before they work. For Suunto, subscribe the app to the Cloud API product to get its subscription key, both shown on your Suunto profile page. 2. Set its redirect URL to the provider's `redirectUri` from `GET /v1/wearables/providers`. ## Behaviour - `clientId` and `secret` are the app's OAuth client ID and secret. `secret` is never returned. - `subscriptionKey` is required for Suunto (its API-management subscription key) and refused for every other provider. - `webhookSecret` is Suunto's notification secret, the one set beside its notification URL in the Suunto developer portal. It is optional, never returned, and refused for every other provider with `422 WEBHOOK_SECRET_NOT_USED`. Without it, ovok refuses Suunto's notifications and syncs Suunto only daily and on demand. - `enabled` defaults to `true`. - The credentials are encrypted before they are stored. A server that cannot encrypt answers `501` and stores nothing. - For Polar, when `enabled` is `true`, ovok then creates the client's webhook at Polar for the `SLEEP` and `ACTIVITY_SUMMARY` events, pointing at `webhookUrl`. Polar first sends it a `PING`, which ovok answers. ovok keeps the webhook's signing key with the credentials, encrypted and never returned. Should this fail, the credentials stay stored, `webhookReady` answers `false`, and saving them again retries. - A Polar client has one webhook. If it has one already for this project, ovok points it at `webhookUrl` and switches it back on. When ovok does not hold that webhook's signing key, which Polar shows only once, ovok replaces the webhook to get a new key. A webhook pointing at another project, or anywhere else, is left alone: `webhookReady` stays `false`; give each project its own Polar client. - Withings with the client ID of ovok's own Withings device integration answers `422 CLIENT_ID_RESERVED`: register an app of your own. - A provider already set up answers `409 PROVIDER_CONFIGURED`; change it with `PATCH`. A project changed by someone else while this request wrote also answers `409`; read it again and retry. - The answer is `201` with a `Location` header naming the provider. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/wearables/providers' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "provider": "oura", "clientId": "your-client-id", "secret": "your-client-secret" }' ``` # Get a wearable provider Canonical page: https://docs.ovok.com/api/wearables/get-a-wearable-provider `GET /v1/wearables/providers/{provider}` Returns one wearable provider of your current project, set up or not, in the shape of `GET /v1/wearables/providers`. It never returns a secret. **Auth:** bearer token of a project admin. **Scope:** the caller's project (from the token). ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/wearables/providers/oura' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Change a wearable provider Canonical page: https://docs.ovok.com/api/wearables/change-a-wearable-provider `PATCH /v1/wearables/providers/{provider}` Changes a wearable provider your project has already set up: its client ID, its secret, Suunto's subscription key or notification secret, or whether patients may connect it. **Auth:** bearer token of a project admin. **Scope:** the caller's project (from the token). ## Behaviour - Send at least one of `clientId`, `secret`, `subscriptionKey`, `webhookSecret` and `enabled`. Fields you leave out keep their value. - `webhookSecret` is Suunto's notification secret; change it here when you change it in the Suunto portal. Other providers answer `422 WEBHOOK_SECRET_NOT_USED`. - Changing Suunto's `clientId` keeps its `webhookSecret`. Send a new one in the same request if the new app signs with another secret. A secret the provider issued, like Polar's, belongs to its client and is replaced on a client change. - `enabled: false` stops new connections. Patients already connected stay connected and can still disconnect. - A provider not set up answers `404 PROVIDER_NOT_CONFIGURED`; set it up with `POST`. - Changing Withings' `clientId` to the one of ovok's own Withings device integration answers `422 CLIENT_ID_RESERVED`. - Changing Withings' `secret` keeps its `webhookUrl`: the URL's token comes from a secret ovok makes for the project, not from the client secret. Changing its `clientId` makes a new token, and so a new URL; patients connect again to the new app anyway. - For Polar, every change with `enabled: true` sets the webhook up again as `POST` does. `enabled: false` leaves the webhook in place; its notifications answer `404` until you switch Polar back on. ## Example ```bash curl -X PATCH 'https://api.sandbox.ovok.com/v1/wearables/providers/oura' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \ -H 'Content-Type: application/json' \ -d '{ "enabled": false }' ``` # Remove a wearable provider Canonical page: https://docs.ovok.com/api/wearables/remove-a-wearable-provider `DELETE /v1/wearables/providers/{provider}` Removes your project's credentials for a wearable provider. **Auth:** bearer token of a project admin. **Scope:** the caller's project (from the token). ## Behaviour - Patients can no longer connect the provider. - Patients already connected keep their connection until they disconnect it. - For Polar, ovok also deletes the client's webhook at Polar when it points at this project's `webhookUrl`; a webhook pointing anywhere else is left alone. Should that fail, the credentials are removed all the same. - A provider not set up answers `404 PROVIDER_NOT_CONFIGURED`. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/wearables/providers/oura' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # List the patient's wearable connections Canonical page: https://docs.ovok.com/api/wearables/list-the-patient-s-wearable-connections `GET /v1/wearables/connections` Returns the wearable providers the signed-in patient can connect, and when they connected each one. **Auth:** bearer token of a patient. **Scope:** the caller's project and Patient profile (from the token). ## Behaviour - `connections` holds one entry per provider the project has enabled, plus any provider the patient is still connected to after the project switched it off. - `connection` is `null` when the patient has not connected the provider. Otherwise: - `connectedAt`: when the patient last connected it; - `syncedThrough`: up to when its data has been synced, `null` before the first sync; - `reconnectRequired`: `true` when the provider no longer accepts the connection. Connect it again to clear it. - A session that is not a patient's answers `403 PATIENT_PROFILE_REQUIRED`. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/wearables/connections' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Start connecting a wearable provider Canonical page: https://docs.ovok.com/api/wearables/start-connecting-a-wearable-provider `POST /v1/wearables/connections/{provider}/authorize` Starts connecting the signed-in patient's account at a wearable provider. Open the returned `authorizationUrl` in a browser or an auth session (`ASWebAuthenticationSession`, Custom Tabs) whose callback scheme is your patient app's. **Auth:** bearer token of a patient. **Scope:** the caller's project and Patient profile (from the token). ## Flow 1. The patient consents on the provider's page. 2. The provider sends the browser to `GET /v1/wearables/oauth//callback`. 3. ovok exchanges the code for tokens, stores them encrypted, and redirects the browser (`302`) to the project's patient app at `/wearables/?result=connected|denied|failed`. ## Behaviour - The URL is valid for 10 minutes and for one use. - Polar shares data only for users registered to the app, so ovok registers the patient with Polar right after the code exchange. A patient who has not accepted Polar's mandatory consents is refused, and the callback ends with `result=failed`. - Connecting a provider the patient is already connected to replaces the stored tokens. - A provider the project has not set up or has switched off answers `404 PROVIDER_NOT_AVAILABLE`. - A project with no usable patient app URL (`PATIENT_APP_URL`) answers `409 APP_URL_NOT_CONFIGURED`: the flow would have nowhere to return to. - When the authorization cannot be stored, the answer is `503 STATE_STORE_UNAVAILABLE` with `Retry-After`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/wearables/connections/oura/authorize' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Sync a connected wearable provider now Canonical page: https://docs.ovok.com/api/wearables/sync-a-connected-wearable-provider-now `POST /v1/wearables/connections/{provider}/sync` Pulls the signed-in patient's latest data from a connected wearable provider now, instead of waiting for the daily sync, and writes it as Observations. **Auth:** bearer token of a patient. **Scope:** the caller's project and Patient profile (from the token). ## Behaviour - Oura, WHOOP, Strava, Withings, Polar, Ultrahuman and Suunto can be synced. Other providers answer `501 SYNC_NOT_SUPPORTED` for now; they can still be connected. - The first sync reads the last 30 days. Each later sync reads from 2 days before `syncedThrough`, because providers revise recent records. - Each reading becomes one Observation about the patient, created once. A reading already held is updated in place, so a value the provider revised within the re-read window replaces the earlier one, and `created` counts only new ones. - What is synced: - heart rate, resting heart rate, heart-rate variability (RMSSD), SpO2, respiratory rate; - daily steps; - sleep duration and its light, deep, REM and awake parts. - What each provider gives: - Oura: per sleep period, heart rate, resting heart rate, HRV, respiratory rate and the sleep stages; daily SpO2 and steps. - WHOOP: resting heart rate, HRV and SpO2 from each recovery; respiratory rate and the sleep stages; each day's average heart rate. - Strava records workouts only, so it gives each workout's average heart rate. - Withings gives heart-rate and SpO2 measurements, daily steps, and per night its sleep summary: the night's average heart rate, average respiratory rate and RMSSD, and the sleep durations. - Polar gives each night's sleep stages, and from its nightly recharge the night's average heart rate, heart-rate variability (RMSSD) and breathing rate, dated by the night. Its daily steps are dated by the watch's local day. - Ultrahuman: SpO2 (when given as one value), resting heart rate during sleep, daily steps and the sleep stages. Its per-sample heart rate and HRV are not synced. It is asked one day at a time, so a first sync makes 31 requests. It gives no respiratory rate. - Suunto: daily steps only, for now. - `heart_rate` is not the same kind of value everywhere: for Oura, Withings and Polar it is a sleep or nightly average (Withings adds its heart-rate measurements), for WHOOP the day's average, and for Strava the average of one workout. - Codes are LOINC, except heart-rate variability: LOINC has no RMSSD code, so it is `https://api.ovok.com/fhir/CodeSystem/wearables|hrv-rmssd`. - Every Observation carries the provider in `meta.tag` (`https://api.ovok.com/fhir/CodeSystem/wearables-source`) and in `device.display`. - Wearable Observations are not forwarded to Signals. - A daily sync runs for every connection at 08:00 UTC; this route only brings it forward, at most once every 15 minutes. - Withings also tells ovok when a patient has new data, and a sync of that connection follows about 30 seconds later. ovok subscribes each patient when they connect; nothing needs setting up in the Withings portal beyond the redirect URL. - Withings Sleep Analyzer mats on ovok's own Withings device integration are separate: their bed presence and sleep series do not come through this connection, and this connection does not change them. - A sync never reads further back than 30 days: when the provider or the connection is out of reach for longer, the oldest days are lost. - Polar lists sleep and nightly recharge for its last 28 days only, so a first Polar sync holds 28 days of those and 30 of steps. - Polar's access is long-lived and cannot be refreshed: once Polar stops accepting it, the sync answers `409 RECONNECT_REQUIRED`. ## Errors - `404 CONNECTION_NOT_FOUND`: the patient has not connected this provider, or disconnected it during the sync. - `404 PROVIDER_NOT_AVAILABLE`: the project removed or switched off the provider. - `409 SYNC_IN_PROGRESS`: a sync of this connection is already running. - `409 CONNECTION_CHANGED`: the patient reconnected the provider while it was syncing; nothing was written over the new connection. Sync again. - `409 RECONNECT_REQUIRED`: the provider no longer accepts the connection, for example after the patient removed the app's access. Connect it again with `POST /v1/wearables/connections//authorize`. `GET /v1/wearables/connections` shows `reconnectRequired: true` meanwhile. - `429 SYNC_TOO_SOON`: the last sync was under 15 minutes ago. Retry after the seconds in `Retry-After`; the provider was not asked. - `500 SYNC_FAILED`: the sync failed on our side; nothing moved, so try again later. - `502 PROVIDER_UNAVAILABLE`: the provider failed, could not be reached, or answered something unreadable; nothing moved, so try again later. - `503 PROVIDER_RATE_LIMITED`: the provider is limiting requests. Retry after the seconds in `Retry-After`. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/v1/wearables/connections/oura/sync' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Disconnect a wearable provider Canonical page: https://docs.ovok.com/api/wearables/disconnect-a-wearable-provider `DELETE /v1/wearables/connections/{provider}` Disconnects the signed-in patient from a wearable provider: the connection is deleted and its tokens are no longer readable through the API. **Auth:** bearer token of a patient. **Scope:** the caller's project and Patient profile (from the token). ## Behaviour - Before the connection is deleted, ovok undoes what it set up at the provider where the provider allows it: Withings stops notifying ovok about the patient, and Polar deregisters the patient, which also revokes the app's access. Other providers keep the app's access until the patient removes it in the provider's own settings. - A failure at the provider never stops the disconnect; the connection is deleted all the same. - The resource history keeps the earlier versions, with the tokens still encrypted. - A provider the patient has not connected answers `404 CONNECTION_NOT_FOUND`. ## Example ```bash curl -X DELETE 'https://api.sandbox.ovok.com/v1/wearables/connections/oura' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ``` # Wearable provider OAuth callback Canonical page: https://docs.ovok.com/api/wearables/wearable-provider-oauth-callback `GET /v1/wearables/oauth/{provider}/callback` Where a wearable provider sends the patient's browser after consent. Register it as the redirect URL of your app at the provider; you never call it yourself. **Auth:** none. The one-time `state` from `POST /v1/wearables/connections//authorize` identifies the patient and project. ## Behaviour - `state` is taken once. An expired, reused or unknown `state`, or one started for another provider, answers `422 INVALID_STATE`. - With a valid `state`, the answer is always `302` to the project's patient app at `/wearables/?result=…`: - `connected`: the tokens are stored; - `denied`: the patient refused, or the provider sent an `error`; - `failed`: the code exchange or the save failed, the project switched the provider off meanwhile, or the provider refused to register the patient (Polar, when the patient has not accepted its consents). Nothing stays connected. - `result` is for display only: the app should read `GET /v1/wearables/connections` for the state of record. - When the pending authorization cannot be read, the answer is `503 STATE_STORE_UNAVAILABLE` with `Retry-After`; the `state` is kept, so the same callback can be retried. # Receive a signed wearable provider notification Canonical page: https://docs.ovok.com/api/wearables/receive-a-signed-wearable-provider-notification `POST /v1/wearables/webhooks/{projectId}/{provider}` Where a wearable provider tells ovok that one of its users has new data. Register it in the provider's developer portal where the provider asks for one; you never call it yourself. **Auth:** none. The provider's signature over the body, or the secret token at the end of the URL, is the proof. **Scope:** the project in the path. ## Behaviour - The URL is the provider's `webhookUrl` from `GET /v1/wearables/providers`: `/v1/wearables/webhooks//`, followed by `/` for a provider that does not sign its notifications. - The body is the provider's own, as JSON or as form fields, at most 64 KB. ovok reads only the provider's user ids from it. - A call without the provider's signature header, or without a URL token of the right shape, is refused before anything is looked up. - ovok writes no data here. For each patient connected to a named account, it queues one sync, which runs about 30 seconds later. Notifications about the same connection within one 30-second window join one sync; one arriving while that sync runs queues the next window's, so no notification is lost. - A sync that finds another sync of the same connection running is queued once more, 30 seconds later. - A notification about an account nobody in the project has connected is accepted too, with `outcome` `no_connection`: providers stop calling URLs that keep failing. ## Answers | Status | When | |---|---| | `202` | The notification is accepted; `outcome` is `queued`, or `no_connection` when no patient here is connected to the named accounts (nothing is queued). | | `200` | A setup call, such as Polar's `PING` when the webhook is created; `outcome` is `handshake`, nothing is queued. | | `400 MALFORMED_NOTIFICATION` | The body is neither a JSON object nor form fields, or does not parse. | | `401 INVALID_SIGNATURE` | The signature or the URL token is missing or does not match. `WWW-Authenticate` is sent. | | `404 PROJECT_NOT_FOUND` | There is no such project. | | `404 PROVIDER_NOT_AVAILABLE` | The project has not set up the provider, or has switched it off. | | `404 WEBHOOK_NOT_SUPPORTED` | ovok takes no notifications from this provider. | | `413` | The body is larger than 64 KB. | | `422` | The project id is not a UUID, or the provider is not one ovok supports. | | `429` | More than 300 calls a minute from one address. Retry after `Retry-After`. | | `503 SYNC_QUEUE_UNAVAILABLE` | The sync could not be queued. Retry after `Retry-After`. | ## Per provider - **Withings:** does not sign its notifications, so its URL ends with a token derived from a random secret ovok makes when the project saves its Withings credentials, keeps encrypted with them and never returns. ovok subscribes each patient at connect time with this URL, for measurements such as heart rate and SpO2 (`appli` 4), activity (16) and sleep (44); there is nothing to paste. Disconnecting revokes those three only. Changing the client secret keeps the URL; changing the client ID makes a new one. Until the secret exists, Withings has no `webhookUrl` and every call answers `401`. The body is form fields `userid`, `appli`, `startdate` and `enddate`; ovok reads `userid`. - **Polar:** ovok creates the webhook when the project saves its Polar credentials switched on, and deletes it when the project removes them; `webhookUrl` is for information only. Polar signs each notification with `Polar-Webhook-Signature`, an HMAC-SHA256 of the body under the webhook's signing key, which ovok keeps encrypted with the credentials. Notifications for `SLEEP` and `ACTIVITY_SUMMARY` queue a sync. - **Suunto:** in the Suunto developer portal, open your app's settings, paste `webhookUrl` as its notification URL and set a notification secret. Give ovok the same secret as `webhookSecret` with `POST` or `PATCH /v1/wearables/providers`. Suunto signs each notification with `X-HMAC-SHA256-Signature`, the HMAC-SHA256 of the body under that secret, and names the account in `username`. Until the secret is stored, every Suunto notification answers `401`. - **Ultrahuman:** sends no notifications; its data is synced daily and on demand. # Check a wearable webhook URL Canonical page: https://docs.ovok.com/api/wearables/check-a-wearable-webhook-url `HEAD /v1/wearables/webhooks/{projectId}/{provider}` Answers whether a webhook URL is live, for a provider that checks it before it sends notifications (Withings does). You never call it yourself. **Auth:** none. A token at the end of the URL is not checked here. **Scope:** the project in the path. ## Answers - `200` with no body when the project has set up and switched on the provider, and ovok takes notifications from it. - Otherwise the same `404` and `422` answers as `POST` on the same URL. # Receive a wearable provider notification by URL token Canonical page: https://docs.ovok.com/api/wearables/receive-a-wearable-provider-notification-by-url-token `POST /v1/wearables/webhooks/{projectId}/{provider}/{token}` Where a wearable provider tells ovok that one of its users has new data. Register it in the provider's developer portal where the provider asks for one; you never call it yourself. **Auth:** none. The provider's signature over the body, or the secret token at the end of the URL, is the proof. **Scope:** the project in the path. ## Behaviour - The URL is the provider's `webhookUrl` from `GET /v1/wearables/providers`: `/v1/wearables/webhooks//`, followed by `/` for a provider that does not sign its notifications. - The body is the provider's own, as JSON or as form fields, at most 64 KB. ovok reads only the provider's user ids from it. - A call without the provider's signature header, or without a URL token of the right shape, is refused before anything is looked up. - ovok writes no data here. For each patient connected to a named account, it queues one sync, which runs about 30 seconds later. Notifications about the same connection within one 30-second window join one sync; one arriving while that sync runs queues the next window's, so no notification is lost. - A sync that finds another sync of the same connection running is queued once more, 30 seconds later. - A notification about an account nobody in the project has connected is accepted too, with `outcome` `no_connection`: providers stop calling URLs that keep failing. ## Answers | Status | When | |---|---| | `202` | The notification is accepted; `outcome` is `queued`, or `no_connection` when no patient here is connected to the named accounts (nothing is queued). | | `200` | A setup call, such as Polar's `PING` when the webhook is created; `outcome` is `handshake`, nothing is queued. | | `400 MALFORMED_NOTIFICATION` | The body is neither a JSON object nor form fields, or does not parse. | | `401 INVALID_SIGNATURE` | The signature or the URL token is missing or does not match. `WWW-Authenticate` is sent. | | `404 PROJECT_NOT_FOUND` | There is no such project. | | `404 PROVIDER_NOT_AVAILABLE` | The project has not set up the provider, or has switched it off. | | `404 WEBHOOK_NOT_SUPPORTED` | ovok takes no notifications from this provider. | | `413` | The body is larger than 64 KB. | | `422` | The project id is not a UUID, or the provider is not one ovok supports. | | `429` | More than 300 calls a minute from one address. Retry after `Retry-After`. | | `503 SYNC_QUEUE_UNAVAILABLE` | The sync could not be queued. Retry after `Retry-After`. | ## Per provider - **Withings:** does not sign its notifications, so its URL ends with a token derived from a random secret ovok makes when the project saves its Withings credentials, keeps encrypted with them and never returns. ovok subscribes each patient at connect time with this URL, for measurements such as heart rate and SpO2 (`appli` 4), activity (16) and sleep (44); there is nothing to paste. Disconnecting revokes those three only. Changing the client secret keeps the URL; changing the client ID makes a new one. Until the secret exists, Withings has no `webhookUrl` and every call answers `401`. The body is form fields `userid`, `appli`, `startdate` and `enddate`; ovok reads `userid`. - **Polar:** ovok creates the webhook when the project saves its Polar credentials switched on, and deletes it when the project removes them; `webhookUrl` is for information only. Polar signs each notification with `Polar-Webhook-Signature`, an HMAC-SHA256 of the body under the webhook's signing key, which ovok keeps encrypted with the credentials. Notifications for `SLEEP` and `ACTIVITY_SUMMARY` queue a sync. - **Suunto:** in the Suunto developer portal, open your app's settings, paste `webhookUrl` as its notification URL and set a notification secret. Give ovok the same secret as `webhookSecret` with `POST` or `PATCH /v1/wearables/providers`. Suunto signs each notification with `X-HMAC-SHA256-Signature`, the HMAC-SHA256 of the body under that secret, and names the account in `username`. Until the secret is stored, every Suunto notification answers `401`. - **Ultrahuman:** sends no notifications; its data is synced daily and on demand. # Check a wearable webhook URL with a token Canonical page: https://docs.ovok.com/api/wearables/check-a-wearable-webhook-url-with-a-token `HEAD /v1/wearables/webhooks/{projectId}/{provider}/{token}` Answers whether a webhook URL is live, for a provider that checks it before it sends notifications (Withings does). You never call it yourself. **Auth:** none. A token at the end of the URL is not checked here. **Scope:** the project in the path. ## Answers - `200` with no body when the project has set up and switched on the provider, and ovok takes notifications from it. - Otherwise the same `404` and `422` answers as `POST` on the same URL. # Get application health Canonical page: https://docs.ovok.com/api/healthcheck/get-application-health `GET /` Returns the health of the Ovok backend and its Redis and FHIR store dependencies, together with build identity. Use it for liveness probes and as the source for a monitor that reads the response body. **Auth:** none. The route needs no bearer token. ## Behaviour - Also served at `/` and `/_health`. - Redis and FHIR store are probed in parallel. Each probe has a 2000 ms limit. A timeout or an error counts as `ok: false` for that dependency. - `ok` is `true` only when both `dependencies.redis.ok` and `dependencies.fhirStore.ok` are `true`. Email is not checked. - The HTTP status is always `200`, even when a dependency is down. Read `ok` and `dependencies` from the body. To get a non-2xx status on failure, use `GET /healthcheck/ready`. - `version`, `buildEnv`, `commitHash` and `buildDate` identify the build and are `null` when the build did not set them. `runningSince` is the process start time. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck' ``` ```json { "ok": true, "dependencies": { "redis": { "ok": true }, "fhirStore": { "ok": true } }, "buildEnv": "production", "runningSince": "2026-04-12T17:21:21.410Z" } ``` # Get application health Canonical page: https://docs.ovok.com/api/healthcheck/get-application-health-2 `GET /_health` Returns the health of the Ovok backend and its Redis and FHIR store dependencies, together with build identity. Use it for liveness probes and as the source for a monitor that reads the response body. **Auth:** none. The route needs no bearer token. ## Behaviour - Also served at `/` and `/_health`. - Redis and FHIR store are probed in parallel. Each probe has a 2000 ms limit. A timeout or an error counts as `ok: false` for that dependency. - `ok` is `true` only when both `dependencies.redis.ok` and `dependencies.fhirStore.ok` are `true`. Email is not checked. - The HTTP status is always `200`, even when a dependency is down. Read `ok` and `dependencies` from the body. To get a non-2xx status on failure, use `GET /healthcheck/ready`. - `version`, `buildEnv`, `commitHash` and `buildDate` identify the build and are `null` when the build did not set them. `runningSince` is the process start time. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck' ``` ```json { "ok": true, "dependencies": { "redis": { "ok": true }, "fhirStore": { "ok": true } }, "buildEnv": "production", "runningSince": "2026-04-12T17:21:21.410Z" } ``` # Get application health Canonical page: https://docs.ovok.com/api/healthcheck/get-application-health-3 `GET /healthcheck` Returns the health of the Ovok backend and its Redis and FHIR store dependencies, together with build identity. Use it for liveness probes and as the source for a monitor that reads the response body. **Auth:** none. The route needs no bearer token. ## Behaviour - Also served at `/` and `/_health`. - Redis and FHIR store are probed in parallel. Each probe has a 2000 ms limit. A timeout or an error counts as `ok: false` for that dependency. - `ok` is `true` only when both `dependencies.redis.ok` and `dependencies.fhirStore.ok` are `true`. Email is not checked. - The HTTP status is always `200`, even when a dependency is down. Read `ok` and `dependencies` from the body. To get a non-2xx status on failure, use `GET /healthcheck/ready`. - `version`, `buildEnv`, `commitHash` and `buildDate` identify the build and are `null` when the build did not set them. `runningSince` is the process start time. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck' ``` ```json { "ok": true, "dependencies": { "redis": { "ok": true }, "fhirStore": { "ok": true } }, "buildEnv": "production", "runningSince": "2026-04-12T17:21:21.410Z" } ``` # Get application readiness Canonical page: https://docs.ovok.com/api/healthcheck/get-application-readiness `GET /ready` Returns the same body as the liveness healthcheck, but with the verdict in the HTTP status. Use it for monitors and alerts that page on status code. **Auth:** none. The route needs no bearer token. ## Behaviour - Runs the same bounded Redis and FHIR store probes as `GET /healthcheck`. - Answers `200` when `ok` is `true` and `503` when it is `false`. The `503` body is the same healthcheck result, so `dependencies` still names the failing dependency. - Do not use this route for container liveness probes: a failing dependency would make the orchestrator restart a backend that is merely degraded. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/ready' ``` # Get application readiness Canonical page: https://docs.ovok.com/api/healthcheck/get-application-readiness-2 `GET /_health/ready` Returns the same body as the liveness healthcheck, but with the verdict in the HTTP status. Use it for monitors and alerts that page on status code. **Auth:** none. The route needs no bearer token. ## Behaviour - Runs the same bounded Redis and FHIR store probes as `GET /healthcheck`. - Answers `200` when `ok` is `true` and `503` when it is `false`. The `503` body is the same healthcheck result, so `dependencies` still names the failing dependency. - Do not use this route for container liveness probes: a failing dependency would make the orchestrator restart a backend that is merely degraded. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/ready' ``` # Get application readiness Canonical page: https://docs.ovok.com/api/healthcheck/get-application-readiness-3 `GET /healthcheck/ready` Returns the same body as the liveness healthcheck, but with the verdict in the HTTP status. Use it for monitors and alerts that page on status code. **Auth:** none. The route needs no bearer token. ## Behaviour - Runs the same bounded Redis and FHIR store probes as `GET /healthcheck`. - Answers `200` when `ok` is `true` and `503` when it is `false`. The `503` body is the same healthcheck result, so `dependencies` still names the failing dependency. - Do not use this route for container liveness probes: a failing dependency would make the orchestrator restart a backend that is merely degraded. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/ready' ``` # Check Redis health Canonical page: https://docs.ovok.com/api/healthcheck/check-redis-health `GET /redis` Checks whether the backend can reach Redis. **Auth:** none. The route needs no bearer token. ## Behaviour - Sends a `PING` to Redis. `ok` is `true` only when Redis answers `PONG`, and `false` on any error. - The status is `200` in both cases. - Unlike `GET /healthcheck`, this probe has no time limit of its own. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/redis' ``` ```json { "ok": true } ``` # Check Redis health Canonical page: https://docs.ovok.com/api/healthcheck/check-redis-health-2 `GET /_health/redis` Checks whether the backend can reach Redis. **Auth:** none. The route needs no bearer token. ## Behaviour - Sends a `PING` to Redis. `ok` is `true` only when Redis answers `PONG`, and `false` on any error. - The status is `200` in both cases. - Unlike `GET /healthcheck`, this probe has no time limit of its own. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/redis' ``` ```json { "ok": true } ``` # Check Redis health Canonical page: https://docs.ovok.com/api/healthcheck/check-redis-health-3 `GET /healthcheck/redis` Checks whether the backend can reach Redis. **Auth:** none. The route needs no bearer token. ## Behaviour - Sends a `PING` to Redis. `ok` is `true` only when Redis answers `PONG`, and `false` on any error. - The status is `200` in both cases. - Unlike `GET /healthcheck`, this probe has no time limit of its own. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/redis' ``` ```json { "ok": true } ``` # Check email service health Canonical page: https://docs.ovok.com/api/healthcheck/check-email-service-health `GET /email` Reports the email service status. **Auth:** none. The route needs no bearer token. ## Behaviour - Contacts nothing. It always answers `{ "ok": true, "skipped": true }`, so the result says nothing about whether email delivery works. - `GET /healthcheck` does not include email for the same reason. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/email' ``` # Check email service health Canonical page: https://docs.ovok.com/api/healthcheck/check-email-service-health-2 `GET /_health/email` Reports the email service status. **Auth:** none. The route needs no bearer token. ## Behaviour - Contacts nothing. It always answers `{ "ok": true, "skipped": true }`, so the result says nothing about whether email delivery works. - `GET /healthcheck` does not include email for the same reason. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/email' ``` # Check email service health Canonical page: https://docs.ovok.com/api/healthcheck/check-email-service-health-3 `GET /healthcheck/email` Reports the email service status. **Auth:** none. The route needs no bearer token. ## Behaviour - Contacts nothing. It always answers `{ "ok": true, "skipped": true }`, so the result says nothing about whether email delivery works. - `GET /healthcheck` does not include email for the same reason. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/email' ``` # Check FHIR store health Canonical page: https://docs.ovok.com/api/healthcheck/check-fhir-store-health `GET /healthcheck/fhir` Checks whether the backend can reach the FHIR store and returns the FHIR store's own health report. Its old paths, `GET /healthcheck/fhir-store` and `GET /healthcheck/medplum`, answer `301` with `Location: /healthcheck/fhir`. **Auth:** none. The route needs no bearer token. ## Behaviour - Calls the FHIR store's `healthcheck` endpoint and returns `ok`, `version`, `platform`, `runtime`, `postgres` and `redis` from its answer. - When the call fails, the route still answers `200`, with `ok`, `postgres` and `redis` set to `false` and `version`, `platform` and `runtime` set to empty strings. - Unlike `GET /healthcheck`, this probe has no time limit of its own. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/fhir' ``` # Check CMS health Canonical page: https://docs.ovok.com/api/healthcheck/check-cms-health `GET /healthcheck/cms` Checks whether the backend can reach the CMS. **Auth:** none. The route needs no bearer token. ## Behaviour - Calls the CMS's own health endpoint, `GET /api/_ovok/health`. `ok` is `true` only when it answers `200` with `status: "ok"`, which it does once it has read its database. - `ok` is `false` when the CMS answers anything else, cannot be reached, takes longer than 2 seconds, or no CMS URL is configured. - The status is `200` in every case. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/cms' ``` ```json { "ok": true } ``` # Check Signals health Canonical page: https://docs.ovok.com/api/healthcheck/check-signals-health `GET /healthcheck/signals` Checks whether the backend can reach Signals. **Auth:** none. The route needs no bearer token. ## Behaviour - Calls Signals' own `GET /health`. `ok` is `true` only when Signals answers with `ok: true`, which it does while its database answers. - `ok` is `false` when Signals reports `ok: false`, cannot be reached, takes longer than 2 seconds, or no Signals URL is configured. - The status is `200` in every case. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/healthcheck/signals' ``` ```json { "ok": true } ``` # List alerts, or the episodes they were folded into Canonical page: https://docs.ovok.com/api/signals-api---alerts/list-alerts-or-the-episodes-they-were-folded-into `GET /v1/signals/api/alert` The dashboard view. By default this is one row per breach, in v1's alert shape plus every nest alert field, inside v1's paginate envelope (`items`, `totalItems`, `page`, `totalPages`, …) with nest's `nextCursor` beside it. Page with v1's `page` and `limit` (a page may start at most 10000 rows in), or walk with `cursor`: pass `nextCursor` back verbatim. `sort` is v1's `time-desc` (the default) or `time-asc`; `ids` narrows to those patients. It works whether or not the tenant has `episodicAlerts`. Without `project` it is tenant-wide: a per-facility view must send `project`, which keeps only patients stamped with it. `?episodes=true` answers with episodes instead, as `{items, nextCursor}`: one row per clinical event, which opens on the first breaching reading, absorbs the rest, and closes on recovery, on going stale, or by hand. That grain REQUIRES `project`. It defaults to the tenant's `feedCodes` (`PATCH /api/tenant`), every code when it lists none; alerts have no code default. `codes`, `since` and `acknowledged` filter either grain. `until`, `page` and `ids` are alerts only: sending one with `episodes=true` is a 422, not a filter that silently did nothing. `status` reads ACTIVE/RESOLVED for alerts and OPEN/CLOSED for episodes. Episodes are newest first by `sort`: `openedAt`, the default, or `lastFiringAt`, the newest firing reading (the opening, for an episode that has none). `since` and the cursor use the same time. `openedAt` never changes, so walking every page lists each episode once. On `lastFiringAt` an episode that fires mid-walk moves above the cursor: it is never listed twice, but that walk misses it. A `sort` value from the other grain is a 422. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_alerts:read`. Project admins have every capability; client applications get no admin bypass. - ovok sets `project` to your project, so you can leave it out. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), name them with `patientId` or `ids`, each one you can read, at most 100. Signals then pages over just those patients, so pages and totals stay true. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Get one alert, or one episode with its readings Canonical page: https://docs.ovok.com/api/signals-api---alerts/get-one-alert-or-one-episode-with-its-readings `GET /v1/signals/api/alert/{id}` The path segment is an alert id, or an episode id with `episodes=true`. An alert reads whether or not the tenant has `episodicAlerts`. An episode comes with its summary, its acknowledgement and every value recorded for its code while it ran. The series starts at the first breaching reading. A long episode returns a capped series and sets `truncated`. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_alerts:read`. Project admins have every capability; client applications get no admin bypass. - ovok sets `project` to your project, so you can leave it out. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the alert's patient must be one you can read: ovok reads the alert first. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Acknowledge an alert, or an episode Canonical page: https://docs.ovok.com/api/signals-api---alerts/acknowledge-an-alert-or-an-episode `POST /v1/signals/api/alert/{id}/ack` The path segment is an alert id, or an episode id with `episodes=true`. Acknowledging closes it: an alert resolves, an episode ends its alerting window, and the next breaching reading opens a new one. The patient's triggers decide what else closing does (their `onAck` hooks). Under the default pack, acknowledging an open out-of-bed alert (103214-3) also silences the absence under way. Idempotent: acknowledging again returns the original time and actor. Acknowledging one that already closed only stamps the acknowledgement. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_alerts:update`. Project admins have every capability; client applications get no admin bypass. - ovok sets `project` to your project, so you can leave it out. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the alert's patient must be one you can update: ovok reads the alert first. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Submit a reading by patient refId Canonical page: https://docs.ovok.com/api/signals-api---observations/submit-a-reading-by-patient-refid `POST /v1/signals/api/observation` The patient is `patientRefId` in the body, else `subject.reference` (`Patient/`). The body is a FHIR R4 Observation: `code`, `value[x]` (any of FHIR R4's eleven) or `dataAbsentReason`, and a combined device sample's vitals as `component[]` (each `code`, `value[x]`, optional `dataAbsentReason`). The clinical time is `effectiveDateTime`, `effectiveInstant` or `effectivePeriod.start`, else `issued`, else the server's receipt; `device` is `{reference, display}`; the first `identifier`'s `value` is stored as v1's `refId`. Other FHIR elements (`meta`, `extension`, `performer`, `interpretation`, `referenceRange`, …) are accepted and ignored. v1's `observedAt` (it wins over `effective[x]`), `refId`, string `dataAbsentReason` and `device.id` still work. A node with `dataAbsentReason` and no value is judged as carrying no value, and the rules read the reason as `absent`. `valueSampledData` is judged by its latest sample and stored whole, and the rules read every sample as `samples`. A `valueDateTime`, on the reading or a component, is judged and aggregated as epoch ms (`valueNumber`) and listed as sent. A `valueBoolean` is judged as 1 or 0. A `valueTime` is judged as ms since midnight, a `valuePeriod` as its length in ms (none while open or without an offset), a `valueRatio` as its quotient, and each is also kept as text (`valueString`); a `valueRange` is judged as the text `low..high`. **History is never judged.** A reading whose `category` has a coding the tenant names as history (its `historyCategories`; the default pack's: `batch-data`, `statistics`, `presence-batch`, `derived`) is stored and deduplicated like any other, answered with no alerts, and never judged nor read by the rules. The caller must be one of the patient's submitters, admins included: a known patient it is not attached to is a 403, an unknown one a 404 with type `PATIENT_NOT_FOUND`. **Idempotent.** A reading is named by its first `identifier` (`system|value`), else by its clinical time, code, device and `refId`. A resend of one stored within the last hour is a 409 `DUPLICATE_READING` whose `data.observationId` is the stored reading, and is neither stored nor evaluated again. A reading with neither an identifier nor a clinical time is not deduplicated. Concurrent requests are batched server-side. With `Prefer: respond-sync` evaluation finishes first and the reply adds `alertIds`, `alerts` (`[{id, code}]`), `resolvedAlertIds` and `ruleCoverage`; without it `mode` is `async` and alerts are delivered by webhook. ### Through ovok - **Who can call it:** Submitter apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_observations:create`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. - Each reading counts its patient as monitored for billing. # List a patient's readings Canonical page: https://docs.ovok.com/api/signals-api---observations/list-a-patient-s-readings `GET /v1/signals/api/observation/{patientId}` Newest first by clinical time, in v1's envelope `{items, total, page, pageSize, totalPages}` with nest's `nextCursor`. `from`, `to` and `code` (comma-separated) filter as in v1; `category` (comma-separated) keeps the readings carrying any of those FHIR category codes. With `from`, a reading whose clinical time is more than an hour ahead of when it was stored is not found: the read skips the storage older than that, so it never waits on it. `pageSize` defaults to 10; above 200 it needs both `from` and `to`, and then reaches 10000. A page may start at most 10000 rows in; walk further with `cursor`. Each item is a flat timeline entry (`code`, `valueNumber`, `observedAt`, `category`, `valueSampledData`, `components`, `effectiveStart`, `effectiveEnd`, `deviceId`, …) with v1's `_id`, `id`, `patient`, `valueQuantity` and `createdAt` beside it. `fields=code,valueNumber` returns exactly those keys instead. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_observations:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can read. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Submit a reading for a patient id Canonical page: https://docs.ovok.com/api/signals-api---observations/submit-a-reading-for-a-patient-id `POST /v1/signals/api/observation/{patientId}` `subject` is ignored: the path names the patient. The body is a FHIR R4 Observation: `code`, `value[x]` (any of FHIR R4's eleven) or `dataAbsentReason`, and a combined device sample's vitals as `component[]` (each `code`, `value[x]`, optional `dataAbsentReason`). The clinical time is `effectiveDateTime`, `effectiveInstant` or `effectivePeriod.start`, else `issued`, else the server's receipt; `device` is `{reference, display}`; the first `identifier`'s `value` is stored as v1's `refId`. Other FHIR elements (`meta`, `extension`, `performer`, `interpretation`, `referenceRange`, …) are accepted and ignored. v1's `observedAt` (it wins over `effective[x]`), `refId`, string `dataAbsentReason` and `device.id` still work. A node with `dataAbsentReason` and no value is judged as carrying no value, and the rules read the reason as `absent`. `valueSampledData` is judged by its latest sample and stored whole, and the rules read every sample as `samples`. A `valueDateTime`, on the reading or a component, is judged and aggregated as epoch ms (`valueNumber`) and listed as sent. A `valueBoolean` is judged as 1 or 0. A `valueTime` is judged as ms since midnight, a `valuePeriod` as its length in ms (none while open or without an offset), a `valueRatio` as its quotient, and each is also kept as text (`valueString`); a `valueRange` is judged as the text `low..high`. **History is never judged.** A reading whose `category` has a coding the tenant names as history (its `historyCategories`; the default pack's: `batch-data`, `statistics`, `presence-batch`, `derived`) is stored and deduplicated like any other, answered with no alerts, and never judged nor read by the rules. The caller must be one of the patient's submitters, admins included: a known patient it is not attached to is a 403, an unknown one a 404 with type `PATIENT_NOT_FOUND`. **Idempotent.** A reading is named by its first `identifier` (`system|value`), else by its clinical time, code, device and `refId`. A resend of one stored within the last hour is a 409 `DUPLICATE_READING` whose `data.observationId` is the stored reading, and is neither stored nor evaluated again. A reading with neither an identifier nor a clinical time is not deduplicated. Concurrent requests are batched server-side. With `Prefer: respond-sync` evaluation finishes first and the reply adds `alertIds`, `alerts` (`[{id, code}]`), `resolvedAlertIds` and `ruleCoverage`; without it `mode` is `async` and alerts are delivered by webhook. ### Through ovok - **Who can call it:** Submitter apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_observations:create`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. - Each reading counts its patient as monitored for billing. # Submit several readings for one patient Canonical page: https://docs.ovok.com/api/signals-api---observations/submit-several-readings-for-one-patient `POST /v1/signals/api/observation/{patientId}/batch` `{observations: []}`, each as `POST /api/observation/:patientId` takes it. In one transaction, evaluated in the order given. Answers v1's array, one entry per reading in request order: the reading as stored, or for a resend the 409 `DUPLICATE_READING` error body in its place. An array has nowhere to carry the ingest outcome, so a caller that needs `alertIds` posts them singly. The body is a FHIR R4 Observation: `code`, `value[x]` (any of FHIR R4's eleven) or `dataAbsentReason`, and a combined device sample's vitals as `component[]` (each `code`, `value[x]`, optional `dataAbsentReason`). The clinical time is `effectiveDateTime`, `effectiveInstant` or `effectivePeriod.start`, else `issued`, else the server's receipt; `device` is `{reference, display}`; the first `identifier`'s `value` is stored as v1's `refId`. Other FHIR elements (`meta`, `extension`, `performer`, `interpretation`, `referenceRange`, …) are accepted and ignored. v1's `observedAt` (it wins over `effective[x]`), `refId`, string `dataAbsentReason` and `device.id` still work. A node with `dataAbsentReason` and no value is judged as carrying no value, and the rules read the reason as `absent`. `valueSampledData` is judged by its latest sample and stored whole, and the rules read every sample as `samples`. A `valueDateTime`, on the reading or a component, is judged and aggregated as epoch ms (`valueNumber`) and listed as sent. A `valueBoolean` is judged as 1 or 0. A `valueTime` is judged as ms since midnight, a `valuePeriod` as its length in ms (none while open or without an offset), a `valueRatio` as its quotient, and each is also kept as text (`valueString`); a `valueRange` is judged as the text `low..high`. **History is never judged.** A reading whose `category` has a coding the tenant names as history (its `historyCategories`; the default pack's: `batch-data`, `statistics`, `presence-batch`, `derived`) is stored and deduplicated like any other, answered with no alerts, and never judged nor read by the rules. The caller must be one of the patient's submitters, admins included: a known patient it is not attached to is a 403, an unknown one a 404 with type `PATIENT_NOT_FOUND`. **Idempotent.** A reading is named by its first `identifier` (`system|value`), else by its clinical time, code, device and `refId`. A resend of one stored within the last hour is a 409 `DUPLICATE_READING` whose `data.observationId` is the stored reading, and is neither stored nor evaluated again. A reading with neither an identifier nor a clinical time is not deduplicated. Concurrent requests are batched server-side. With `Prefer: respond-sync` evaluation finishes first and the reply adds `alertIds`, `alerts` (`[{id, code}]`), `resolvedAlertIds` and `ruleCoverage`; without it `mode` is `async` and alerts are delivered by webhook. ### Through ovok - **Who can call it:** Submitter apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_observations:create`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. - Each reading counts its patient as monitored for billing. # List patients Canonical page: https://docs.ovok.com/api/signals-api---patients/list-patients-2 `GET /v1/signals/api/patient` Scoped to what the caller may see: a MANAGER gets the tenant, a SUBMITTER or SUBSCRIBER only the patients it is attached to. Newest first. v1's paginate envelope, driven by `page` and `limit` (default 10). A page may start at most 10000 rows in; past that, walk with the keyset `cursor`: pass `nextCursor` back verbatim, and `null` means the last page. ### Through ovok - **Who can call it:** Manager apps and Submitter apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), name them with `ids`, each one you can read, at most 100. Signals then pages over just those patients, so pages and totals stay true. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Create patients Canonical page: https://docs.ovok.com/api/signals-api---patients/create-patients `POST /v1/signals/api/patient` Upserts on `refId`: posting a patient that already exists updates it rather than duplicating it, so a replayed provisioning run is safe. Each entry's `config` — flags and triggers — is applied in the same call, and `metadata` is merged. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:update`. Project admins have every capability; client applications get no admin bypass. - ovok adds your project's submitter to each new patient and stamps `metadata.project` with your project. Sending `config` also needs `signals_config:update` and `signals_silence:update`. New patients count toward your plan's monitored-patient cap. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Resolve refIds to Signals ids Canonical page: https://docs.ovok.com/api/signals-api---patients/resolve-refids-to-signals-ids `GET /v1/signals/api/patient/ids` An object from each `patientRefId` this tenant holds to its Signals id. A refId the tenant does not hold is left out rather than failing the request. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), name them with `patientRefId`, each one you can read, at most 100. Signals then pages over just those patients, so pages and totals stay true. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Get one patient Canonical page: https://docs.ovok.com/api/signals-api---patients/get-one-patient `GET /v1/signals/api/patient/{id}` The patient with its config, triggers keyed by code. A SUBMITTER or SUBSCRIBER reads only patients it is attached to. ### Through ovok - **Who can call it:** Manager apps and Submitter apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can read. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Update a patient Canonical page: https://docs.ovok.com/api/signals-api---patients/update-a-patient `POST /v1/signals/api/patient/{id}` Only the fields present are changed; `metadata` is merged, not replaced. Answered with the v1 document. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:update`. Project admins have every capability; client applications get no admin bypass. - When you send `submitters` or `metadata`, ovok keeps your project's submitter and stamp in them. Sending `alertsPaused`, `alertIfEmpty`, `alertIfNote` or `alertInactiveDays` also needs `signals_config:update` and `signals_silence:update`. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient, and one a `refId` in the body names, must be ones you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Delete a patient Canonical page: https://docs.ovok.com/api/signals-api---patients/delete-a-patient `DELETE /v1/signals/api/patient/{id}` Deletes the patient with its triggers, alerts, episodes and readings. This can't be undone through the API. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_patients:delete`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can delete. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # List a submitter's patients Canonical page: https://docs.ovok.com/api/signals-api---patients/list-a-submitter-s-patients `GET /v1/signals/api/submitter/{id}/patients` The ids of the patients in this tenant the submitter may post readings for. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:read`. Project admins have every capability; client applications get no admin bypass. - 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. # Attach patients to a submitter Canonical page: https://docs.ovok.com/api/signals-api---patients/attach-patients-to-a-submitter `POST /v1/signals/api/submitter/{id}/patients` Grants the client permission to post readings for those patients. Unknown patient ids are skipped, so a caller can re-post a superset of ids without a 404. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:update`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Detach a patient from a submitter Canonical page: https://docs.ovok.com/api/signals-api---patients/detach-a-patient-from-a-submitter `DELETE /v1/signals/api/submitter/{id}/patients/{patientId}` The submitter may no longer post readings for the patient. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:update`. Project admins have every capability; client applications get no admin bypass. - Your project's own submitter stays attached to its patients. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # List a subscriber's patients Canonical page: https://docs.ovok.com/api/signals-api---patients/list-a-subscriber-s-patients `GET /v1/signals/api/subscriber/{id}/patients` The ids of the patients in this tenant the subscriber reads and receives alerts for. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:read`. Project admins have every capability; client applications get no admin bypass. - 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. # Attach patients to a subscriber Canonical page: https://docs.ovok.com/api/signals-api---patients/attach-patients-to-a-subscriber `POST /v1/signals/api/subscriber/{id}/patients` Grants the client permission to read those patients' records and receive their alert webhooks. Unknown patient ids are skipped, so a caller can re-post a superset of ids without a 404. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:update`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Detach a patient from a subscriber Canonical page: https://docs.ovok.com/api/signals-api---patients/detach-a-patient-from-a-subscriber `DELETE /v1/signals/api/subscriber/{id}/patients/{patientId}` The subscriber no longer reads the patient's records or receives its alerts. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_associations:update`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Write one config to many patients Canonical page: https://docs.ovok.com/api/signals-api---patient-config/write-one-config-to-many-patients `POST /v1/signals/api/patient/config` Applies the same triggers, flags and metadata to every id named. An id may be the Signals id or the `refId`. Unknown ids are reported in `misses[]` rather than failing the batch. `modifiedCount` counts patients where a row actually changed; `status.triggerWrites` gives the row counts behind it. Trigger `metadata` is MERGED and left untouched when absent. Send `resolvedAt` (the instant the configuration was COMPUTED, not sent) to have this push refused rather than applied when the patient already carries a configuration resolved strictly later. Refusal is a silent no-op reported as `staleIgnoredCount`, never an error. Omitting it applies the push unconditionally. ### 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. - A patient stamped with another project is refused. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Write a different config to each of many patients Canonical page: https://docs.ovok.com/api/signals-api---patient-config/write-a-different-config-to-each-of-many-patients `POST /v1/signals/api/patient/config/batch` The per-patient form, each entry with its own triggers, flags, `metadata` and `resolvedAt`. `results[]` has v1's `{id, matched, modified}` per entry; `staleIgnored` and `misses` are additions. ### 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. - A patient stamped with another project is refused. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Read the config status of many patients Canonical page: https://docs.ovok.com/api/signals-api---patient-config/read-the-config-status-of-many-patients `POST /v1/signals/api/patient/config/bulk-status` Each patient's `configUpdatedAt` and trigger codes, so a caller can confirm a push landed without re-reading every trigger; `triggerFingerprints` adds what each rule says. Exactly one row per requested id, in the order asked. An id that resolves to nothing answers `refId: null` with no codes, as v1 did. A POST because the id list is the request; it writes nothing. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_config:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), every patient the body names must be one you can read. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # List users Canonical page: https://docs.ovok.com/api/signals-api---clients/list-users `GET /v1/signals/api/user` The tenant's API clients, newest first, in v1's paginate envelope (`page`, `limit` defaulting to 10) with nest's `nextCursor`. `role` and `name` filter as in v1. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_clients:read`. Project admins have every capability; client applications get no admin bypass. # Create a user Canonical page: https://docs.ovok.com/api/signals-api---clients/create-a-user `POST /v1/signals/api/user` Mints an API client. `clientId` and `secret` are the Basic credential, chosen by the caller and never returned. `role` may be v1's lowercase. A SUBSCRIBER needs `webhookUrl` and at least one event. It is on `eventSchema` 2 unless the body says 1: on 2 its first Standard Webhooks signing secret is returned this once as `signingSecret`; on 1 it needs `webhookSecret` (v1 called it `secret`). `reach` is `attached` (default: the patients attached to it, as v1's) or `all` (every patient of the tenant, those enrolled later included). ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`, `signals_events:read`. Project admins have every capability; client applications get no admin bypass. - Only subscribers are created through ovok, on event schema 2. ovok generates their id and Signals login, which they never use, and Signals generates the webhook signing secret. - 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. # Get one user Canonical page: https://docs.ovok.com/api/signals-api---clients/get-one-user `GET /v1/signals/api/user/{id}` Without its secret, which is not retrievable. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_clients:read`. Project admins have every capability; client applications get no admin bypass. # Update a user Canonical page: https://docs.ovok.com/api/signals-api---clients/update-a-user `POST /v1/signals/api/user/{id}` Sets the name, webhook target, signing secret, events, event schema, reach or credential secret. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`, `signals_events:read`. Project admins have every capability; client applications get no admin bypass. - Only subscribers are changed through ovok. Their `role`, `eventSchema`, `clientId`, `secret` and `webhookSecret` can't be sent. - 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. # Delete a user Canonical page: https://docs.ovok.com/api/signals-api---clients/delete-a-user `DELETE /v1/signals/api/user/{id}` Revokes the credential at once and drops its undelivered webhook events. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:delete`. Project admins have every capability; client applications get no admin bypass. - Only subscribers are deleted through ovok. - 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. # Read the webhook endpoint Canonical page: https://docs.ovok.com/api/signals-api---clients/read-the-webhook-endpoint `GET /v1/signals/api/subscriber/{id}/webhook` The URL, whether it is `enabled`, `failing` or `disabled` (and why), when its current run of failures began, and its newest delivered and failed attempts. Five days of failures with no delivery, or one 410, disable it. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:read`. Project admins have every capability; client applications get no admin bypass. # Enable the webhook endpoint Canonical page: https://docs.ovok.com/api/signals-api---clients/enable-the-webhook-endpoint `POST /v1/signals/api/subscriber/{id}/webhook/enable` Resumes deliveries of new events. It re-queues nothing: events held while it was disabled go out only through `POST /api/events/redeliver?status=held`. Enabling an enabled endpoint changes nothing. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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. # Disable the webhook endpoint Canonical page: https://docs.ovok.com/api/signals-api---clients/disable-the-webhook-endpoint `POST /v1/signals/api/subscriber/{id}/webhook/disable` Stops deliveries. Queued events and new ones are held, not dropped, for a redeliver once it is enabled again. Disabling a disabled endpoint keeps its first reason. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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. # Send a test event Canonical page: https://docs.ovok.com/api/signals-api---clients/send-a-test-event `POST /v1/signals/api/subscriber/{id}/webhook/test` Sends a signed `webhook.test` event (`{ event, subscriber, sentAt }`) now, with every header a real delivery carries, and answers what the receiver did. It is not queued, retried or listed, and it works on a disabled endpoint, so a receiver can be checked before it is enabled. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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. # Rotate the webhook signing secret Canonical page: https://docs.ovok.com/api/signals-api---clients/rotate-the-webhook-signing-secret `POST /v1/signals/api/subscriber/{id}/webhook/rotate-secret` Mints a new Standard Webhooks signing secret (`whsec_` and 32 random bytes) and returns it this once. Every delivery carries `webhook-id` and `webhook-timestamp`; once the subscriber has a secret it also carries `webhook-signature`, so a receiver verifies with the Standard Webhooks library. The secret it replaces keeps signing until `previousSecretExpiresAt` (24 h), so `webhook-signature` holds both and the receiver switches with no gap. Each rotation keeps only the secret it replaces, so rotate again only once the receiver uses the new one. The first call mints the subscriber's first secret. A MANAGER rotates any subscriber of its tenant; a SUBSCRIBER only its own. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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. # Get the caller's tenant Canonical page: https://docs.ovok.com/api/signals-api---tenants/get-the-caller-s-tenant `GET /v1/signals/api/tenant` The tenant is resolved from the credential; there is no id to pass. `orgSettings` is its tenant-wide rule settings, `{}` when none were written. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_config:read`. Project admins have every capability; client applications get no admin bypass. # Update tenant settings Canonical page: https://docs.ovok.com/api/signals-api---tenants/update-tenant-settings `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, and a tenant that states no `historyCategories` keeps the default pack's. `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`. A band it changes ends the episodes judged under the old one, and a code it switches off (its band `"NO_THRESHOLD"`, or out of bed `enabled: false`) has its active alerts resolved and its open episodes closed `THRESHOLD_CHANGED` at the save, for every patient judged by the tenant's settings (an acknowledged out-of-bed absence, whose episode the ack closed, has its still-active alert resolved); a band deleted closes nothing. 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 - **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. # Get a patient's own rule settings Canonical page: https://docs.ovok.com/api/signals-api---settings/get-a-patient-s-own-rule-settings `GET /v1/signals/api/patient/{id}/settings` `{}` when none were written. Signals stores `settings` as given and reads it only through the triggers it holds (`triggers`, the home's and the resident's own): what each other key means is theirs, so the object is checked for shape and size only. The default pack reads `bands` — per code `{ low?, high? }`, `{ mode: 'baseline', pct, low?, high? }` (outside either band fires; a patient's own baseline band with no sides of its own is judged alone) or `"NO_THRESHOLD"` — and `outOfBed`: `{ limitSeconds, enabled?, returnSeconds?, window?: { start: 'HH:MM', end: 'HH:MM', timeZone } }`. A patient's own key wins over the org's; extra keys are ignored. See tech/RULES-ENGINE.md. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_config:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can read. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # Replace a patient's own rule settings Canonical page: https://docs.ovok.com/api/signals-api---settings/replace-a-patient-s-own-rule-settings `PUT /v1/signals/api/patient/{id}/settings` Replaced whole. The triggers read them beside the org's, as `settings.individual`. Audited as `UPDATE_PATIENT_SETTINGS`. For each patient the write reaches, judged by its own settings over the org's: a band changed ends the episode judged under the old one `THRESHOLD_CHANGED`; a code switched off (its band `"NO_THRESHOLD"`, or out of bed `enabled: false`) has its active alert resolved and its open episode closed `THRESHOLD_CHANGED` at the save, the other codes' left alone; an acknowledged out-of-bed absence, whose episode the ack closed, has its still-active alert resolved; a band deleted closes nothing. A body whose `settings` has no `triggers` key keeps the stored `triggers` (the home defaults seeded by Signals, or triggers pushed through the config routes); a body that sends `triggers`, `{}` included, replaces them. The body may carry `resolvedAt` (ISO 8601), when the caller resolved this write: it lands only over a stored write resolved earlier, or stored without one, and is otherwise refused 409 `STALE_SETTINGS` with nothing written or audited. A write without `resolvedAt` always lands and keeps the stored stamp. Signals stores `settings` as given and reads it only through the triggers it holds (`triggers`, the home's and the resident's own): what each other key means is theirs, so the object is checked for shape and size only. The default pack reads `bands` — per code `{ low?, high? }`, `{ mode: 'baseline', pct, low?, high? }` (outside either band fires; a patient's own baseline band with no sides of its own is judged alone) or `"NO_THRESHOLD"` — and `outOfBed`: `{ limitSeconds, enabled?, returnSeconds?, window?: { start: 'HH:MM', end: 'HH:MM', timeZone } }`. A patient's own key wins over the org's; extra keys are ignored. See tech/RULES-ENGINE.md. ### 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. - `resolvedAt` may be at most 5 minutes ahead of now. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can update. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # List webhook events Canonical page: https://docs.ovok.com/api/signals-api---events/list-webhook-events `GET /v1/signals/api/events` Every event addressed to the caller, oldest first and keyset paged by `cursor`, each with its delivery status and payload: expired, failed and held ones too. An event is listed once it is two minutes old, so a page never moves past one a slower transaction has yet to commit. Filter by `types`, `status`, `patientId`, or (for a MANAGER) `subscriberId`. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_events:read`. Project admins have every capability; client applications get no admin bypass. - If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), name them with `patientId`, each one you can read, at most 100. Signals then pages over just those patients, so pages and totals stay true. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is. # List a delivery's attempts Canonical page: https://docs.ovok.com/api/signals-api---events/list-a-delivery-s-attempts `GET /v1/signals/api/events/{id}/attempts` Each POST made for it, oldest first: when, how long, the status code or the error, and the first 2 KB of the answer. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_events:read`. Project admins have every capability; client applications get no admin bypass. - 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. # Redeliver events Canonical page: https://docs.ovok.com/api/signals-api---events/redeliver-events `POST /v1/signals/api/events/redeliver` Queues the oldest 1 000 deliveries in `status` (default `failed`) queued since `since` to be sent again, each with a fresh retry ladder: the same `webhook-id`, so receivers dedupe, and a new `webhook-timestamp`. An alert is sent whatever its age. Deliveries to a disabled endpoint, and ones being sent right now, are skipped. While it answers `queued: 1000`, call it again for the next ones. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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. # Redeliver one event Canonical page: https://docs.ovok.com/api/signals-api---events/redeliver-one-event `POST /v1/signals/api/events/{id}/redeliver` Queues this delivery to be sent now, whatever its status, with a fresh retry ladder: the same `webhook-id` and a new `webhook-timestamp`. An alert is sent whatever its age. ### Through ovok - **Who can call it:** Manager apps, and users whose access policy grants the capabilities. - **Capabilities, all required:** `signals_webhooks:update`. Project admins have every capability; client applications get no admin bypass. - 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. # Liveness Canonical page: https://docs.ovok.com/api/signals-api---health/liveness `GET /v1/signals/api/health` Unauthenticated, always 200: the HTTP status reports that the process is serving, not that its dependencies are well, because this route gates container liveness. `healthy` is false while the database does not answer (`db.ok`); page on it. ### Through ovok - **Who can call it:** any caller with an ovok access token, or a client id and secret. It needs no capability.