Signals API - Alerts

Get one alert, or one episode with its readings

  • Sandbox: available
  • Staging: available
  • Production: unknown
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.

Authorization

headerAuthorizationBearer <JWT>

Path Parameters

id*string

Query Parameters

episodes?boolean

Read the id as an episode id rather than an alert id.

Response Body

The alert, or the episode and its value series.

application/json
  1. response
id*string
tenantId*string
patientId*string
observationId*string
status*string
Value in"ACTIVE""RESOLVED"
code*string
dedupKey*string

What this alert deduplicates against while it stays open. Repeated breaches of the same trigger refresh one alert rather than opening more.

message*string

Supplied by the rule when it returns one. ECH rules return a JSON document here describing which bound was crossed.

valueNumber*number
valueString*string

The rule's own payload; carries the level and colour the UI paints.

triggerCode*string
triggerVersion*number
createdAt*string
Formatdate-time
resolvedAt*string
Formatdate-time
acknowledgedAt*string

When this alert was acknowledged, or null. Acknowledging resolves it; an alert that resolved on its own stays unacknowledged until someone acknowledges it.

Formatdate-time
acknowledgedBy*string

The client that acknowledged it, or null.

acknowledgedActor*

The person the caller says acknowledged it, or null. Distinct from acknowledgedBy, which is the API client: one deployment holds one credential, so that field answers "which system" and this one answers "which person".

observationEffectivePeriod*

Out of bed (103214-3) only: the absence the alert is about, from when Signals first saw the resident absent to the reading or tick that last fired it. The start holds through a presence flicker shorter than the return time, as the out-of-bed clock does. Null for every other code, and for out-of-bed alerts raised before it was recorded.

limitSeconds*number

Out of bed (103214-3) only: the limit in force when it last fired, in seconds — the absolute limit floored to the minute, or the tighter baseline limit. Null for every other code, and for out-of-bed alerts raised before it was recorded.

_id*string

The same value as id, under v1's name.

reason*string

v1's lowercase reason. trigger is a threshold breach; empty a reading with no value; note a clinician note; inactive a patient who stopped reporting.

Value in"trigger""empty""note""inactive"
observation*string

The observation id.

component*

The reading that fired, rebuilt from its stored code and value.

trigger*
updatedAt*string

The last change: raised, resolved or acknowledged.

Formatdate-time
patient*
Example Request
curl -X GET 'https://api.sandbox.ovok.com/v1/signals/api/alert/string'
Example Response
{  "id": "string",  "tenantId": "string",  "patientId": "string",  "observationId": "string",  "status": "ACTIVE",  "code": "string",  "dedupKey": "string",  "message": "string",  "valueNumber": 0,  "valueString": "string",  "triggerCode": "string",  "triggerVersion": 0,  "createdAt": "2019-08-24T14:15:22Z",  "resolvedAt": "2019-08-24T14:15:22Z",  "acknowledgedAt": "2019-08-24T14:15:22Z",  "acknowledgedBy": "string",  "acknowledgedActor": {    "reference": "string",    "display": "string"  },  "observationEffectivePeriod": {    "start": "2019-08-24T14:15:22Z",    "end": "2019-08-24T14:15:22Z"  },  "limitSeconds": 0,  "_id": "string",  "reason": "trigger",  "observation": "string",  "component": {    "code": {},    "valueQuantity": {},    "valueString": "string"  },  "trigger": {},  "updatedAt": "2019-08-24T14:15:22Z",  "patient": {    "id": "string",    "tags": {},    "metadata": {},    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z"  }}

List alerts, or the episodes they were folded into GET

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.

Acknowledge an alert, or an episode POST

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.