Skip to main content

How to understand and troubleshoot “ROOK Signals - Health Monitoring” alerts?

Written by JP Gomez

HMS emits two kinds of document. alert_event is near-immediate but exists only for oxygen saturation in this version; alert_summary arrives once a day, can cover any of the five signals, holds at most one entry per signal, and is not sent at all on days when nothing breached. Both travel through your existing Data Webhook, and neither can be fetched again afterwards — so persist them on receipt. This article walks through both payloads with worked examples, explains what an alert does and does not claim, and then works through the ten most common reasons why you might see no alerts at all. Silence is the normal state of this product, and nearly every case has an innocent explanation.

Topics

  • The two alert documents: alert_event and alert_summary

  • Worked example: alert_event — SpO2 out of range

  • Worked example: alert_summary — the daily digest

  • How alerts are delivered, and why you must store them

  • What an alert does and does not tell you

  • Troubleshooting: we aren't receiving any alerts (10-point checklist)

Key terms

alert_event · alert_summary · data_structure · once a day · no empty summaries · no retrieval endpoint · baseline not ready · "no alerts received"


The two alert documents

HMS produces two document types. They are not interchangeable, and only one of them can arrive shortly after a measurement.


alert_event

  • Created for oxygen saturation only in this release.

  • Generated when an eligible SpO2 measurement breaches its effective fixed-range rule.

  • Near-immediate, but the timing depends on when the data source sends the measurement to ROOK. HMS cannot deliver an alert for data it has not received yet.

alert_summary

  • A daily document covering the evaluated local day, delivered once a day (usually after the sleep_summary of the user was collected)

  • Can contain breaches for any of the five supported signals: resting heart rate, HRV, resting breathing rate, oxygen saturation, and sleep duration.

  • Contains at most one entry per signal per day.

  • Not created at all when no supported signal breached its effective rule. There are no empty summaries.

Example: alert_event — SpO2 out of range

Simplified example. The real document also carries identifiers, unit, metadata, and timestamps.

{
"data_structure": "alert_event",
"alerts": {
"alert_signals_array": [
{
"signal_type_string": "oxygenation",
"measured_value_float": 91.0,
"threshold_type_string": "fixed_range",
"threshold_min_float": 92.0,
"breach_direction_string": "below",
"source_of_data_string": "Apple Health"
}
]
}
}


The reading was 91% against an effective minimum of 92%, so it was breached downward. The document always includes the measured value, the evaluated threshold, the direction, and the data source.

Example: alert_summary — the daily digest

Simplified example.

{
"data_structure": "alert_summary",
"alerts": {
"alert_signals_array": [
{ "signal_type_string": "resting_heart_rate",
"measured_value_float": 71.0,
"baseline_value_float": 60.0,
"threshold_max_float": 66.0 },

{ "signal_type_string": "hrv",
"measured_value_float": 28.0,
"baseline_value_float": 52.0,
"threshold_min_float": 36.4 }
]
}
}


Two signals went out of range that day: resting heart rate above and HRV below.

The baseline travels inside the document, so you can compare the value against what is normal for that user without calculating anything yourself.


This example also shows the ROOK defaults at work. The resting heart rate baseline of 60 with a +10% default gives a threshold of 66. The HRV baseline of 52 with a −30% default gives a threshold of 36.4. If you have configured your own percentages, the thresholds in the document will reflect yours instead.

How alerts are delivered

Both document types are sent through your existing ROOK Data Webhook. There is nothing separate to configure.

Two consequences worth designing around:

  1. There is no endpoint for retrieving previously generated alerts. If your webhook endpoint is down or your handler throws, the alert is not something you can fetch later from an HMS API. Persist alert documents on receipt.

  2. Your webhook handler should branch on data_structure so it recognizes alert_event and alert_summary alongside the data documents it already processes.

What an alert does and does not tell you

An alert tells you that a valid measurement breached its effective threshold, and whether it was above or below the range.


It does not carry a clinical severity level, a diagnosis, a cause, or a recommended action. HMS is a monitoring and notification feature, not an emergency service or a clinical decision system. Any interpretation or escalation logic belongs in your application, ideally with appropriate clinical review.

Troubleshooting: we aren't receiving any alerts

Silence is the normal state of this product, and most cases have an innocent explanation. Work through these in order.

1. Has anything actually breached a threshold?

HMS does not create an empty daily summary. No breach means no document. Confirm against the raw data whether any measurement should have triggered a breach under the effective rule.

2. Was the minimum absolute delta exceeded?

Baseline signals apply a floor in addition to the percentage: 4 bpm for resting heart rate, 5 ms for HRV, 1 breath/min for resting breathing rate. A deviation that clears the percentage but not the floor will not raise an alert. This matters most for users with low baselines.

3. Is the baseline ready?

Resting heart rate, HRV, and resting breathing rate require a personal baseline. If no eligible pre-existing history was available at activation, HMS needs seven valid days of data for that user and signal. Until then it skips evaluation entirely for that signal.

Oxygen saturation and sleep duration use fixed ranges and are not affected by this.

4. Are you expecting an alert_event for the wrong signal?

Only oxygen saturation produces alert_event. A resting heart rate breach will appear in the daily summary, not as a near-immediate event.

5. Is there a default that simply does not fire in that direction?

HRV has no default upper threshold, and oxygenation has no default upper bound. Readings above those ranges will not alert unless you configure it.

6. Is the signal actually reaching ROOK for that user?

The user must be synchronizing at least one supported signal. Check whether the data source is connected and the relevant permission granted, whether that specific device even produces the signal you expect, and how often that source syncs. Infrequent syncing delays evaluation. Coverage is not uniform across signals and providers.

7. Are the values valid?

HMS skips null and invalid measurements. Missing data is never interpreted as a breach.

8. Is the effective rule what you think it is?

A user-specific rule silently overrides your client-level rule. GET returns only the stored rule for one scope — it does not return the resolved effective threshold. Read both scopes and apply the precedence order (user, then client, then ROOK default) yourself.

9. Is your Data Webhook healthy?

Confirm the endpoint is reachable, returning success, and that your handler is not silently discarding unrecognized values of data_structure. Since alerts cannot be re-fetched, a dropped delivery is a lost alert.

10. Is HMS enabled in the right environment?

Sandbox is enabled by default. Production requires explicit activation — contact ROOK support or your account manager.

Did this answer your question?