Skip to main content

Oxygen Data

Overnight oximeter readings, parsed locally and stored in your browser. Use the import page on the dashboard to add a night.

Read the companion guide: Pulse oximetry for CPAP

If you also have Oura ring data, the dashboard joins your nights. Open Oura data

Overnight pulse oximetry, paired with your CPAP data

A pulse oximeter is a small device that clips to your finger or wraps around your wrist and records your blood-oxygen saturation (SpO2) and heart rate every few seconds. Used overnight, it answers a question your CPAP machine cannot: did the air your machine delivered actually keep your oxygen up while you slept? The CPAP machine knows when its flow sensor sees an event. The oximeter knows when your blood oxygen actually dipped.

CPAP Clarity reads the ViHealth CSV that the Wellue O2 Ring (and the OxySmart fingertip clip and the next-generation O2Ring S) produce, including the LOOKEE-branded O2Ring and the CSV from Lookee's own app, parses it client-side, and shows three numbers that matter most: min SpO2 (how low your oxygen dipped), ODI 3% (how often it dropped more than 3 percent below your stable overnight level, motion-rejected), and time below 88% (the clinically significant hypoxemia threshold). The dashboard joins each oximeter night to the CPAP session on the same calendar date, so a night with good CPAP data but persistent low SpO2 stands out clearly.

Like every other surface on this site, parsing happens entirely in your browser. Your overnight oximetry data does not pass through any server. There is no account; nothing leaves the tab.

Shopping for an O2 Ring?

This page reads the overnight CSV from the Wellue O2 Ring family. If you do not have a recording oximeter yet, the Wellue O2Ring is the model the import is built around.

Overnight SpO2 and ODI tracking

Wellue O2Ring

Records SpO2 and pulse every few seconds all night and exports the CSV this page reads. FDA-cleared for at-home use and rechargeable.

How to read these numbers

An overnight pulse oximeter records your blood oxygen saturation (SpO2) and pulse every few seconds while you sleep. Three numbers carry most of the signal: min SpO2, ODI 3%, and time below 88%. Together they tell you whether your CPAP is reaching your oxygen, not just whether the machine's flow sensor is happy.

SpO2 readings can be affected by motion, finger temperature, skin pigmentation, and nail polish. A consumer pulse oximeter is a tracking and screening tool, not a diagnostic device. If you see persistent low SpO2at rest, talk to a sleep physician.

No published standard sets a normal range for these numbers in people on CPAP. This site's reference lines are a drop rate of 5an hour or more (the AASM's AHI cut-off, reused), a lowest reading under 90 percent, and any time below 88 percent. Readings past those lines on several nights, especially when your CPAP logs fewer than 5 events an hour, are the pattern to bring to your sleep clinic.

Read the full guide: pulse oximetry for CPAP users →

Frequently asked questions

How do I export the overnight CSV from my Wellue O2 Ring?

Open the ViHealth app, tap the night you want, then tap the share / export icon. Choose CSV (not PDF). On iOS, save to Files; on Android, save to Downloads. Drop the resulting file into the Dashboard import zone on cpapclarity.com. The OxySmart fingertip clip and the new O2Ring S follow the same flow with slightly different CSV column shapes; CPAP Clarity dispatches by header automatically and writes all three into the same Dexie store keyed by date. If your ring is the LOOKEE-branded O2Ring (the same hardware sold under a different name), the CSV from Lookee's own app imports too, so you can export from whichever app you prefer.

What is ODI 3% and why is it not the same as my AHI?

ODI (oxygen desaturation index) counts how often per hour your blood-oxygen saturation drops more than 3 percent below your stable overnight level, motion-rejected. AHI counts apnea and hypopnea events scored from CPAP airflow. They measure related but distinct things. A treated CPAP user often has AHI under 1 and a slightly elevated ODI, because some events are too brief to score on flow but still produce a measurable oxygen dip. Use both to triangulate, not to argue with each other.

How does CPAP Clarity calculate ODI, and does it match my ViHealth app?

It is built to line up with the count your ViHealth app shows. Your typical stable SpO2 for the night is the baseline, any reading more than 3 percent (or more than 4 percent) below it counts as a drop, it ends when your oxygen climbs back near the baseline, and motion-flagged readings are set aside. That is the same shape your oximeter's own app uses, so on the nights we have checked against a Wellue device report the drop counts match the number on the device screen. On an unusually busy night our count can read lower than your device's, because the ring computes its official count on the device itself from second-by-second readings the exported file does not contain; when the two differ, treat the report on your monitor as the reference. There is a way to remove even that gap: import the raw session file instead (see below) and CPAP Clarity reads your ring's own counts directly. The nightly drop count and the events-per-hour ODI count the exact same events, so they always agree with each other.

Can CPAP Clarity show exactly the numbers my ring's app shows?

It depends on the model and the file. Wellue's O2 Insight desktop program saves a raw file per session when you connect the ring over USB, named like 20260705220726 with no file extension, and you can drop those files into the import zone. For the ones checked against the app's own reports, on a Checkme O2 Max and on the O2Ring S, the file carries the drop counts and O2 Score the device itself computed, and CPAP Clarity shows those numbers with a note saying where they came from. A raw file from a ring we have not checked that way still imports its readings, and the drop counts are worked out from them instead. Same if the ring's own summary could not be true of that night, which the site checks before showing it. A raw file in a format the site does not recognize is refused and named on screen, never guessed at. If you import both the CSV and a raw file with the device's own numbers for the same night, the raw file's numbers win.

Why does my dashboard sometimes show 'n/a' for ODI instead of a number?

ODI is only defensible when the recording produced enough usable data to score. Two cases trigger 'n/a' instead of a number: a recording shorter than the 60-second minimum the scorer needs, and a night where motion rejection (rolling over, hand against the sheets) flagged every sample as unreliable. A short late-night spot check or a particularly restless night can hit either case. We surface 'n/a (recording too short)' or 'n/a (motion-saturated)' in those cases instead of displaying 0.0, which would imply a perfect night when the algorithm actually had no clean data to work with. The mean SpO2, minimum SpO2, and time-below-88% values are still scored on whatever clean samples exist, so those headlines remain trustworthy even when ODI cannot be computed.

Why match the ViHealth count instead of a clinical formula?

Because your monitor's own app is the number you actually see, and a consumer oximeter has no sleep-study reading to defer to. If CPAP Clarity showed a different drop count than the device sitting on your finger, the mismatch would just make you distrust both. So we reproduce the count your ring app shows, checked against real device reports. The steps this site shades the drop rate on (5, 15, 30 an hour) reuse the American Academy of Sleep Medicine's cut-offs for AHI. No published standard sets bands for a consumer oximeter's drop count, so read them as this site's reference lines, not a diagnosis.

Why does the dashboard show motion-rejected periods?

Pulse oximeters lose contact with their reading when you move your hand against the sheets. The O2 Ring writes a motion column on every reading; CPAP Clarity excludes motion-flagged readings from the drop count so a movement artifact cannot create a false desaturation. The OxySmart fingertip clip has no motion column (the clip itself does not produce useful motion data), so motion rejection is a no-op for OxySmart nights and the dashboard renders motion percent as n/a.

Do I need to wear the oximeter every night?

No. The O2 Ring is most useful as a periodic check rather than nightly wear. A pattern that works well for established CPAP users: one night of overnight oximeter data per month, plus extra nights if your CPAP data trends out of range. New CPAP users sometimes wear it nightly for the first two weeks to establish a baseline, then taper to monthly. The night-by-night join with CPAP data lights up automatically on the dates where both data sources exist.

How does the join with CPAP data work?

CPAP sessions and oximeter nights are joined by calendar date through a shared rollup layer. A 9 PM to 7 AM oximeter session pairs with the CPAP session that started during the same calendar night by default. The dashboard, history page, and AI export all surface paired nights together; the standalone oximeter page shows oximeter-only nights. The two data stores stay independent; deleting one does not affect the other.