Skip to main content

How to configure your “ROOK Signals - Health Monitoring” rules?

Written by JP Gomez

Monitoring rules decide what counts as out of range, and HMS resolves them in a fixed order: a user-specific rule wins over your client-level rule, which wins over the ROOK default. This article documents the two endpoints, lists the ROOK defaults for all five signals, and explains the three parts of the contract that most often catch teams out — PUT fully replaces a rule rather than merging your changes, GET returns what is stored for one scope rather than the threshold that will actually be applied, and there is no way to delete a user-specific rule in Beta. Read the defaults section even if you plan to override everything, since the floor values and the missing HRV upper bound explain a lot of apparently absent alerts.

Topics

  • Before you start: auth, activation, API-only in Beta

  • The three levels of configuration and how precedence resolves

  • ROOK default rules per signal (baseline signals and fixed-range signals)

  • Endpoints: reading and writing a rule

  • Three behaviors that surprise people

    • PUT is a full replacement, not a partial update

    • GET returns what is stored, not what is in effect

    • There is no way to delete a user-specific rule

  • Recommended workflow

Key terms

rule precedence (user → client → ROOK default) · ROOK default values · PUT is a full replacement · stored vs. effective rule · no delete endpoint · floor (minimum absolute delta) · sleep_duration in seconds · HRV has no default upper threshold


Before you start

  • Health Monitoring must be enabled for your client account. In Sandbox it is on by default; for Production, contact ROOK support or your account manager.

  • Both endpoints use Basic Auth, the same credentials you already use with the ROOK API.

  • Configuration is API-only. There is no Portal UI for rules.

The three levels of configuration

HMS resolves rules in a strict order of precedence. For a given user and signal, the first rule found wins:

  1. User-specific rule — a rule stored for that individual user_id.

  2. Client-level rule — one rule that applies to all of your users.

  3. ROOK default — used when you have stored nothing for that scope.

What a rule contains depends on the signal:

  • Resting heart rate, HRV, resting breathing rate — a percentage deviation applied to each user's own personal baseline, plus a minimum absolute delta.

  • Oxygen saturation, sleep duration — a fixed minimum and maximum range.

A client-level percentage is applied separately to each user's individual baseline. It does not average or pool users together
.

ROOK default rules per signal

These apply when you have stored no client-level or user-specific rule. Use them as your starting point and only override where you have a reason to.

Baseline + percentage deviation signals

The deviation is applied to each user's individual baseline. The floor is a minimum absolute delta: the measured value must differ from the baseline by at least this much, in addition to exceeding the percentage, before HMS raises a breach. This suppresses noisy alerts on low baselines.

Signal

Below

Above

Floor (min absolute delta)

resting_heart_rate

−15%

+10%

4 bpm

hrv (RMSSD)

−30%

none (null)

5 ms

resting_breathing_rate

−15%

+10%

1 breath/min

Note that hrv has no upward threshold by default. An HRV reading above baseline does not generate an alert unless you explicitly configure one.

Fixed-range signals

Signal

Default

oxygenation (SpO2)

threshold_min_percent: 92.0, max null

sleep_duration

threshold_min_seconds: 21600.0 (6 h), threshold_max_seconds: 32400.0 (9 h)

Sleep duration is expressed in seconds, not minutes or hours. Oxygenation has no default upper bound.

Endpoints

Read a stored rule

GET /api/v2/health_monitoring/rules

  • Omit user_id to return your client-level rule.

  • Provide user_id to return that user's stored rule.

Create or replace a rule

PUT /api/v2/health_monitoring/rules

  • Omit user_id to write the client-level rule.

  • Provide user_id to write that user's rule.

Three behaviors that surprise people

1. PUT is a full replacement, not a partial update

The current contract creates or fully replaces one rule and expects a complete configuration. Sending only the field you want to change will replace the whole rule with that partial content, not merge it.

Always read the stored rule first, modify the object, then send the complete configuration back.

2. GET returns what is stored, not what is in effect

GET returns exactly what is stored for the scope you requested. It does not resolve precedence for you and does not return the effective threshold HMS will actually apply to a given user.

If GET with a user_id returns nothing, that user is not unmonitored — they are falling through to your client-level rule, or to the ROOK default. To reason about effective behavior, read both scopes and apply the precedence order yourself.

3. There is no way to delete a user-specific rule

The current version has no delete operation. To make a user behave as though they had no override, PUT that user's rule with the same values as your client-level configuration.

Because of this, keep user-specific rules to the minimum you actually need, and track on your side which users have overrides and why. Note that a user pinned this way will not follow future changes to your client-level rule — you will need to update them explicitly.

Recommended workflow

  1. Set your client-level rule first and let it govern the majority of your population.

  2. Add user-specific rules only for genuine exceptions.

  3. Before any write, GET the current rule for that scope and keep the response.

  4. Send the complete modified configuration via PUT.

  5. Log the resulting configuration on your side — it is your audit trail and your fallback if you need to revert an override.

Common mistakes

Symptom

Likely cause

A rule change wiped other settings

Partial PUT. The endpoint replaces the whole rule.

GET with user_id returns nothing

No override exists for that user. They resolve to the client-level rule or ROOK default.

Threshold change had no effect for one user

That user has a user-specific rule taking precedence over your client-level change.

Configured a percentage for SpO2 or sleep duration

Those two signals use fixed min/max ranges, not baseline percentages.

Sleep duration thresholds behaving oddly

Values are in seconds. 6 h is 21600, not 360 or 6.

No alert for a high HRV reading

HRV has no default upper threshold. Configure one if you need it.

Small deviation from baseline produced no alert

The minimum absolute delta (floor) was not exceeded.

401 / 403 on either endpoint

Basic Auth credentials, or Health Monitoring not enabled for the account.

Rule looks correct but no alerts arrive

Rules are only half the picture. See the alerts article.

Did this answer your question?