The earlier chapters fixed the shapes of sessions, stages, respiratory events, arousals and scoring metadata, and the HTTP and federation behaviour around them. This chapter asks how an implementer shows that a device, host or scoring service really behaves that way. In sleep medicine the question is practical. An apnoea-hypopnoea index (AHI) computed from mis-ordered events, or a "clinical-grade" flag on an uncleared wrist device, ends up in a chart that a physician relies on. The checks below are therefore built around the places where sleep data most often goes wrong.
The source material describes requirements, not a shipped test product. Where this chapter describes a suite or a container, it is describing what the published rules imply a harness must exercise, not an artefact the standard distributes.
A suite for WIA-MED-021 divides naturally into three layers. The shape layer checks that payloads carry the Phase 1 fields: snake_case keys, RFC 3339 UTC timestamps with a Z suffix, and sub-second precision wherever an event is tied to a waveform sample, such as 2026-04-26T23:45:12.300Z on a respiratory event. The consistency layer checks that the numbers inside a payload agree with each other. The behaviour layer checks what a host does when it is handed something it must refuse. The shape layer is the cheapest, but the other two catch the defects that matter clinically.
| Check | Source rule | Passing behaviour |
|---|---|---|
| Version gate | Phase 1 §2.1 | A major version the host does not implement is refused |
| Unknown session kind | Phase 1 §3.1 | Treated as unrecognised, not coerced into polysomnography |
| Clinical-grade claim | Phase 1 §3.2, Phase 2 §11 | clinical_grade: true without clearance proof is refused |
| Epoch arithmetic | Phase 1 §4 | epoch_start equals session start plus epoch_index times epoch_duration_seconds |
| Arousal floor | Phase 2 §7 | An arousal under 3 seconds is rejected with a problem-detail body |
| Idempotent bulk writes | Phase 2 §5 | Resubmitting a stage batch with the same Idempotency-Key creates no duplicate epochs |
| Event ordering | Phase 2 §6 | Events come back ordered by started_at, so an AHI recomputation is stable |
| Replay defence | Phase 3 §5 | Skew beyond ±300 s is rejected; a repeated signer-and-nonce pair within 600 s is rejected |
| Audience matrix | Phase 3 §6 | An ehr_bridge caller cannot read raw events without elevated consent |
| Supersession | Phase 2 §8 | A recompute keeps the original scoring metadata; the new record points at it through supersedes |
The epoch check is a good example of a consistency test because it needs no clinical knowledge. The Phase 1 sample session starts at 22:30:00Z, and its stage record has epoch_index 142 and epoch_start 23:41:00Z. Epoch 142 of 30 seconds is 71 minutes, which lands exactly on 23:41, so the sample is consistent with zero-based indexing. A harness can run the same arithmetic over every epoch in a session:
from datetime import datetime, timedelta, timezone
def expected_epoch_start(session_started_at, epoch_index, epoch_seconds=30):
t0 = datetime.fromisoformat(session_started_at.replace("Z", "+00:00"))
return t0 + timedelta(seconds=epoch_index * epoch_seconds)
assert expected_epoch_start("2026-04-26T22:30:00Z", 142) == \
datetime(2026, 4, 26, 23, 41, tzinfo=timezone.utc)
The same idea applies to the epoch count. The 22:30 to 07:00 session spans 8.5 hours, which is 1,020 thirty-second epochs. The Phase 2 text uses 960 epochs for an eight-hour night. A stage batch that is short by a block of epochs usually means a dropped chunk during upload, and a count check finds it before a scorer silently averages over the gap.
Summary metrics deserve the same scrutiny. The older API document's sample session lists 420 minutes of total sleep time, 510 minutes in bed and a sleep efficiency of 88.4 percent. With the conventional definition of sleep efficiency as sleep time divided by time in bed, 420 over 510 is about 82.4 percent. The sample is illustrative, but it shows what a cross-field check will flag. A real suite should recompute efficiency, stage-minute totals and (from the event list) the AHI, and compare them with what the producer declared.
A behaviour check worth writing early is the arousal floor. Submitting an arousal with duration_seconds of 2 must produce the Phase 2 problem-detail response, and a suite should assert the status, the error type and the instance path rather than just "some 4xx":
{
"type": "https://wiastandards.com/sleep-monitoring/errors/arousal-too-short",
"title": "Arousal duration below AASM minimum",
"status": 422,
"detail": "arousal.duration_seconds=2 violates AASM 3-second minimum",
"instance": "/sm/arousal/ar_01HXY-23"
}
The replay checks need a controllable clock. A harness submits a correctly signed envelope with a timestamp pushed outside the ±300 second window, then a duplicate nonce inside the 600 second window. If the host uses a Bloom filter for high-volume stage ingestion, a false positive must lead to a re-fetch through the pull endpoints, not a silently dropped batch. That path is easy to forget and hard to trigger by accident, so a suite should force it.
The most useful way to run these checks is against a disposable reference host that implements the Phase 2 surface and can be started and torn down per test run. The material does not name a published image, so treat the following as a design sketch of what such a container should hold.
/.well-known/wia-sleep-monitoring listing the five endpoints (session, stage, event, arousal, scoring), the supported signature algorithm (Ed25519), the supported session kinds and scoring algorithms, and the anonymous and authenticated rate limits.epoch_start, and an event list out of order.The first smoke test is simply to read the discovery document and check that every advertised endpoint answers:
curl -s https://sm.example/.well-known/wia-sleep-monitoring
Discovery responses are cacheable for 300 seconds. A good harness therefore asserts that the host does not advertise an endpoint it has not implemented, and that the list of supported scoring algorithms matches what the host will accept in a scoring submission.
The recording itself needs care. Clinical EDF files run to hundreds of megabytes, so the container should serve them from a separate object store and put only the URL and SHA-256 hash in the session record. That arrangement lets a test verify the integrity check: alter one byte of the stored EDF and confirm that a consumer comparing against edf_sha256 notices.
WIA-MED-021 does not restate the scoring rules of the American Academy of Sleep Medicine (AASM). It supplies the data shape that AASM-compliant scorers read and write, and it keeps enough per-event detail that the rules can be audited afterwards. Several rules are visible directly in the data model:
wake, n1, n2, n3 and rem, with unscored allowed for epochs the algorithm could not classify.epoch_duration_seconds says which was used.Which scoring rules were applied is recorded in scoring_algorithm. The initial registry lists AASM-2024-default, AASM-2018-default (kept so older cohorts stay comparable), AASM-2024-paediatric and a reference vendor algorithm for consumer wearables. On top of that sits an aasm_compliance_level ladder whose values named in the material are full, partial and consumer_estimate. A sleep clinic would filter for full, a research consortium may accept partial if the rule deviations are documented, and a wellness app lives at consumer_estimate. The HealthKit bridge, for instance, labels everything it imports as a consumer estimate, which stops phone-derived sleep periods from being mistaken for scored studies.
Separately from rule compliance, the overview document sets accuracy targets against concurrent polysomnography. Sleep-wake classification should reach at least 85 percent accuracy, with total sleep time off by no more than 30 minutes on average and a sleep-efficiency correlation of at least 0.70. Optional four-stage classification (wake, light, deep, REM) should reach at least 70 percent accuracy and a Cohen's kappa of at least 0.60. Kappa matters because it discounts the agreement expected by chance, and stage distributions are lopsided enough that raw accuracy flatters a model that over-predicts light sleep. Validation needs at least 100 participants drawn across age, sex, ethnicity and BMI, including people with insomnia and sleep apnoea. A device tuned only on healthy young sleepers tends to degrade where fragmented sleep and frequent awakenings are common, so that last requirement is the one most likely to expose a weak algorithm.
The three device classes in the overview scale the same logic. Class I (clinical) asks for at least 90 percent agreement with polysomnography plus FDA or MFDS approval and diagnostic support, Class II (wellness) asks for at least 85 percent, and Class III (research) asks for at least 80 percent with a research-only restriction. The labels travel in the device record, for example WIA-MED-021-Class-II.
Two inconsistencies in the draft should be resolved before anyone certifies against it. The overview cites AASM manual version 2.6 (2020), while the Phase 4 registry names 2018 and 2024 editions. The overview and API documents also describe stages as light, deep and REM, while Phase 1 uses AASM tokens. The next section returns to both.
The documents are marked version 1.0.0, and the Phase 1 to 4 files are marked Draft. The material contains no dated schedule, so what follows is a reading of the open items the text itself exposes, not a publication plan.
light/deep in one and n1/n2/n3 in the other. Apnoea is spelled obstructive_apnea in one and obstructive_apnoea in the other. The desaturation field is spo2_drop_percent in one and associated_oxygen_desaturation_pct in the other. The routes also differ: /api/v1/sleep/sessions against /sm/session. A mapping table, or a retirement of one side, is the first job.spec/profiles/ documenting scopes, field mappings and polling cadence.The draft does not state a formal promise, but several rules already add up to one. A receiver must refuse a major version it does not implement, so a breaking change cannot slip in unnoticed. Unknown session kinds degrade to unrecognised instead of causing a failure, which lets the vocabulary grow without breaking older readers. Re-scoring never overwrites. Scoring recomputation preserves the original metadata and links the new one through supersedes, and the Phase 3 recompute flow leaves both on the recording host. Historic scoring algorithms stay in the registry, which is why a research cohort scored under the 2018 rules can stay pinned to them.
Retention rules back this up. Deletion is a tombstone with a 25-year audit retention, federation receipts persist for at least 25 years, and a relocated session returns 301 Moved Permanently at its old URL for at least 12 months.
A fair reading is that data written today should stay readable and re-scorable for the life of a clinical record. What the draft does not yet define is how the field-name differences listed in the roadmap will be bridged. An implementer who has to read old payloads should expect that reconciliation to arrive as a published mapping, not as silent renaming.
For an implementer, the chapter reduces to a short checklist. Emit the AASM stage tokens and keep the 30-second epoch unless you are a consumer device that says otherwise. Keep the per-event respiratory metadata so AHI can always be recomputed. Never claim clinical grade without clearance. Refuse arousals under 3 seconds. Honour idempotency on bulk writes. Reject stale and replayed envelopes. Keep every scoring generation and say which algorithm produced it. A harness that exercises these behaviours with broken fixtures, instead of only well-formed ones, will find most of the defects that would otherwise reach a clinician.
For the EDF integrity story, read the EDF and EDF+ bridge in Phase 4, which explains why the original file is never modified and scoring results are written to a parallel scoring-metadata record. For clinical records, the FHIR bridge maps scoring summaries such as total sleep time, AHI, minimum SpO2, slow-wave minutes and REM minutes to LOINC-coded observations. For wearable-derived data, the sister standard WIA-MED-020 explains how a measurement stream becomes a consumer-estimate session.
Conformance matters to a sleeper because it decides what a number means. A patient who sees "AHI 12.5" in an app should be able to tell whether it came from a scored polysomnography, a home apnoea test or a wristband estimate, and the combination of session kind, clinical_grade and compliance level is how that distinction survives the trip into a chart. A clinician reviewing a patient's study should be able to ask which algorithm and which scorer produced each event, and see earlier scorings alongside any re-scoring. Guardians of paediatric patients are the custodians of consent and are the ones who decide whether a child's recording goes to a clinic or a research cohort.
The limits are worth stating plainly. Consumer estimates are estimates. A wearable that agrees with polysomnography at the stated accuracy still misclassifies a meaningful share of epochs, and a draft standard whose vocabularies are still being reconciled should not be treated as settled. Clinicians should treat consumer_estimate data as context for a conversation, not as a diagnosis.
That brings the technical half of the book to a close: the formats, the interfaces, the federation rules and now the means of checking them. What remains is carrying the standard into daily use. The next chapter turns from what the specification requires to how clinics, vendors and research groups adopt it, starting with the questions each of them should ask before sending their first signed session.