Open Wearables 0.6.2: data integrity for multi-source health apps
Some providers send the same data in more than one format at the same time. Garmin and Oura, for example, each send both a daily total and granular intraday records for the same period. Before 0.6.2, the platform summed all records together, which inflated daily step and energy totals for users on affected providers. Apple Health sends only intraday data and was not affected by this issue.
This is the class of problem 0.6.2 addresses.
What shipped
is_daily_total: authoritative daily values
The data_point_series table has a new is_daily_total boolean column. When a provider sends a daily aggregate alongside granular intraday records for steps or energy, the platform marks the daily record with is_daily_total = true and uses it as the authoritative value. When no daily total exists, the platform sums the intraday records as before.
Applications using the summary API get corrected values without any changes on their side.
Migration behavior: on the next startup after upgrading, an automated script sets is_daily_total = true for existing daily records. Intraday aggregates are not flagged as false during migration for performance reasons. Any null value in is_daily_total should be treated as equivalent to false. New records written after the upgrade will be handled correctly from the point of ingestion.
Active minutes as a native series type
Active minutes were previously derived from step cadence: any minute with 30 or more steps counted as active. Garmin, Oura, Polar, and Ultrahuman supply active minutes directly from the device. From 0.6.2, Open Wearables retrieves them as a first-class series type from these four providers. For providers that do not report active minutes natively, the 30+ steps/minute fallback remains in place.
The platform's science team is working on an improved calculation method, which will be released in a future version.
This change applies to new syncs only. Data already stored in the database is not updated automatically. To get correct active minutes for historical data:
- Garmin: delete the stored data first, then resynchronize.
- Oura, Polar, Ultrahuman: existing records are overwritten during a historical sync. No deletion required.
If you surface active time in coaching recommendations, fitness goals, or health summaries, the values will reflect what the device actually recorded rather than a step-cadence approximation, for users on these four providers, going forward.
Sleep session priority filtering
Some devices connect to Open Wearables through more than one path. Oura, for example, can connect directly to Open Wearables and also via Apple Health. When both connections are active, sleep sessions arrive through both paths and produce duplicate records for the same night.
The /users/{user_id}/events/sleep endpoint now accepts an optional filter_by_priority flag. When enabled, duplicate sleep sessions are filtered out. The flag is disabled by default, so existing integrations are unaffected unless they explicitly enable it.
The filtering option is also available as a toggle in the hosted data summary UI.
Garmin respiratory rate
Garmin respiratory rate was not being saved to the database at all. The platform was searching for the parameter under the wrong field name in Garmin's raw payload. The lookup is now corrected, and respiratory rate will be stored on each sync going forward.
Historical data is not available because nothing was stored before this fix. If historical respiratory rate values matter, a resync is needed.
Data summary: time-based filtering
Data summaries now support filtering by a specific day or a custom time period. The visual design has also been updated.
Bug fixes
- #1114 Apple Health: convert walking units from HealthKit
- #1232 Aggregation fix: take daily data or sum intraday data (Garmin 15-minute chunk conflict)
- #1235 Garmin respiratory rate: fix field name lookup in raw payload
- #1203 Mark connection as revoked on failed token refresh; fire connection.revoked outgoing webhook
- #1242 Active minutes series implementation fixes
- #1249 Sleep session priority filtering implementation fixes
Additional changes
- connection.revoked webhook: a new outgoing webhook event fires when a provider connection is revoked. Applications can update connection state without polling the status endpoint.
- Manual invitation links: the connection invitation flow now supports copying the link manually. Useful when email is not configured. Contributed by edsammy in their first contribution to the project.
- iOS/Android coverage: the platform now tracks iOS and Android coverage separately.
Upgrading
docker pull ghcr.io/the-momentum/open-wearables:0.6.2
The is_daily_total migration runs on startup. Before deploying, check:
- If you query data_point_series directly, treat null in is_daily_total as false.
- If you use the /users/{user_id}/events/sleep events endpoint, decide whether to enable filter_by_priority=true. Summary endpoint users already had sleep deduplication and see no change here.
- If active minutes matter for your application, plan a resync for Garmin users after upgrading. For Garmin, delete existing data before resyncing. For Oura, Polar, and Ultrahuman, historical sync overwrites the values.
New to the platform:
git clone https://github.com/the-momentum/open-wearables.git
cd open-wearables
cp .env.example .env
docker-compose up -d
Quickstart guide: docs.openwearables.io/quickstart.
Contributors
Six contributors shipped this release. Welcome to edsammy, who contributed for the first time with PR #1230.
The project is at 1,997 GitHub stars, 361 forks, and 31 contributors.
What's next
The issue tracker and Discussions reflect what the community needs next. If a data integrity scenario for a specific provider or metric affects your application, open an issue or start a GitHub Discussion.
- GitHub: github.com/the-momentum/open-wearables
- Release notes: github.com/the-momentum/open-wearables/releases/tag/0.6.2
- Documentation: docs.openwearables.io
Open Wearables
Open Wearables is an open-source platform that connects your application to wearable and health data providers through a single API. One normalized data model, multi-provider support in a single self-hosted deployment, no per-user fees, MIT licensed, and health intelligence built in: normalized recovery, sleep, activity and biometric data ready for your product layer.
We offer custom deployment and integration support through Momentum. If your team needs help getting to production faster, we can set up and configure Open Wearables as part of a managed engagement. Let's talk.
Book a demo to see how Open Wearables fits your use case.
See related articles
Garmin Connect API: developer guide for activities and health metrics