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:
User-specific rule — a rule stored for that individual user_id.
Client-level rule — one rule that applies to all of your users.
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
Set your client-level rule first and let it govern the majority of your population.
Add user-specific rules only for genuine exceptions.
Before any write, GET the current rule for that scope and keep the response.
Send the complete modified configuration via PUT.
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. |