# 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/<id>`. |
| `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/<id>`. |
| `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/<id>` |
| A patient's alerts | `GET /fhir/R4/DetectedIssue?patient=Patient/<id>` |
| The alerts of one episode | `GET /fhir/R4/DetectedIssue?identifier=https://signals.actimi.com/episode\|<episodeId>` |
| A patient's open episodes | `GET /fhir/R4/Flag?patient=Patient/<id>&status=active&identifier=https://signals.actimi.com/episode\|` |
| One alert | `GET /fhir/R4/DetectedIssue?identifier=https://signals.actimi.com/alert\|<alertId>` |

```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)
