Open Wearables 0.6.3: nap detection and HTTP logs middleware
Key takeaways
- Nap detection is now supported for Apple and Oura. The is_nap field appears on the existing sleep session record with no changes to how you query sleep data.
- HTTP logs are now structured JSON and controlled via a new ACCESS_LOG_LEVEL variable. Production deployments default to errors-only after this upgrade.
- Outgoing webhooks were previously always active. Version 0.6.3 introduces OUTGOING_WEBHOOKS_ENABLED, the default is false, so set it to true to keep them running after the upgrade.
- High-frequency workout sample ingestion is now available for Strava via INGEST_WORKOUT_SAMPLES=true, matching the mechanism introduced for Garmin in 0.6.0.
- Six new contributors made their first contribution in this release.
Introduction
Version 0.6.3 is released. The main additions are nap detection for Apple and Oura, a structured HTTP logging middleware with configurable log levels, an explicit enable/disable flag for outgoing webhooks, and Strava workout samples. The release also includes provider-specific fixes across Apple, Oura, Suunto, Garmin, and Fitbit.
Nap detection for Apple and Oura
Sleep data is not uniform. A 25-minute afternoon nap and an 8-hour overnight session are both sleep records, but treating them the same way adds noise to any downstream calculation that uses sleep as a signal, recovery scores, sleep debt, readiness metrics.
Apple and Oura both include an explicit nap flag in their sleep data. Open Wearables now reads that flag and surfaces it as is_nap on the normalized sleep session record. Your application queries the same sleep endpoints as before, is_nap is an additional boolean field on the record.
For providers that do not themselves flag which sleep sessions are naps, we will develop our own detection algorithms in a future release.
HTTP logs middleware
In most Open Wearables deployments, HTTP request logs account for over 80% of total log volume. Until now, those logs were plain-text strings emitted by uvicorn with no structured fields, which made them difficult to filter or query in log aggregation tools.
Version 0.6.3 replaces this with a JSON middleware. Each HTTP log entry now includes timestamp, level, message, provider, method, path, status, and duration_ms.
A new ACCESS_LOG_LEVEL environment variable controls what gets logged:
- ACCESS_LOG_LEVEL=all, all HTTP requests
- ACCESS_LOG_LEVEL=errors, 4xx and 5xx only
- ACCESS_LOG_LEVEL=off, no HTTP logs
If the variable is not set, the level is inferred from ENVIRONMENT: production defaults to errors, everything else defaults to all.
If you run with ENVIRONMENT=production and do not set ACCESS_LOG_LEVEL, your deployment will stop logging most HTTP requests after upgrading. Add ACCESS_LOG_LEVEL=all to retain the previous behavior.
This change covers uvicorn HTTP logs only. Application-level logs from Open Wearables are not affected.
Outgoing webhooks enable flag
Outgoing webhooks, events that Open Wearables sends to your backend when health data arrives, were previously always active. Version 0.6.3 introduces OUTGOING_WEBHOOKS_ENABLED, which gives you explicit control over this behavior. The default is false.
If your deployment relies on outgoing webhooks, set OUTGOING_WEBHOOKS_ENABLED=true before upgrading, otherwise webhook delivery will stop.
This flag has no effect on incoming webhooks from providers. Data arriving from Strava, Garmin, or any other provider continues to be ingested regardless of this setting.
This release also fixes an event emission issue: the Disconnect button in the Open Wearables frontend was not generating a connection revoked event. This has been fixed. Svix startup logs are now silenced.
Strava workout samples
High-frequency workout sample ingestion was introduced for Garmin in 0.6.0 via the INGEST_WORKOUT_SAMPLES variable. Version 0.6.3 extends that to Strava. When the variable is set to true, Strava will start ingesting workout data at a high frequency.
The variable defaults to false because the additional data volume is substantially higher than summary-only ingestion. The full mechanism is described in the "Ingest workout samples" entry for Garmin in the 0.6.0 release notes.
Provider fixes
Apple: Blood glucose values from Health Connect are now converted from mmol/L to mg/dL on ingestion.
Oura: Resting heart rate derived from sleep data now persists correctly.
Suunto: Float values for totalDistance in the workout schema are now accepted.
Garmin: Dead sleep parameters have been removed.
Fitbit: Workout distance is now correctly converted from kilometers to meters on ingestion.
Data coverage tab
Women's Health has been added to the Data Coverage tab in the admin panel. The tab shows which data types each connected provider supports within Open Wearables.
Redis: AOF persistence
Redis has been switched from RDB to AOF mode to avoid errors in certain edge cases. Details are in PR #1188. Existing data stored in Redis is preserved during the upgrade.
Docker dev image
The development Docker image is approximately 40% smaller after tightening the .dockerignore file and removing unused layers from the Dockerfile. This applies only to the local development image. The production build is unchanged.
Upgrading
Official Docker images are available on Docker Hub and are updated on every release:
- Backend: https://hub.docker.com/r/themomentum/open-wearables-backend
- Frontend: https://hub.docker.com/r/themomentum/open-wearables-frontend
docker compose pull
docker compose up -d
Two environment variables require attention before upgrading:
- If ENVIRONMENT=production is set and ACCESS_LOG_LEVEL is not, HTTP logging will default to errors-only after the upgrade. Set ACCESS_LOG_LEVEL=all to retain full logging.
- Outgoing webhooks were previously always active. Version 0.6.3 defaults them to false. Set OUTGOING_WEBHOOKS_ENABLED=true to keep them running.
All other changes are backward compatible. Database migrations run automatically on startup.
Community
Six contributors made their first contribution in this release. Full source, issue tracker, and contribution guidelines are at github.com/the-momentum/open-wearables.
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
Apple HealthKit API: what data you can access and how
How to use Oura ring data in your app
How to integrate Strava without building OAuth from scratch
Frequently asked questions
Which providers support nap detection?
Apple and Oura. Both providers include an explicit nap flag in their data. Detection for additional providers will follow in a future release.
Does OUTGOING_WEBHOOKS_ENABLED affect incoming provider webhooks?
No. It only controls events that Open Wearables sends to client backends. Incoming data from providers is unaffected.
I was using outgoing webhooks before 0.6.3. Do I need to do anything?
Yes. Outgoing webhooks were previously always active. Version 0.6.3 defaults them to off. Set OUTGOING_WEBHOOKS_ENABLED=true in your environment before upgrading to retain the previous behavior.
What is the ACCESS_LOG_LEVEL default?
If not set, it is inferred from ENVIRONMENT. Production defaults to errors. All other environments default to all.
Does the Redis change affect my stored data?
No. Existing data is preserved during the upgrade.