Highlights
Support for Google Health Connect and Samsung Health
We added support for another two major health aggregators 🚀
To make it possible, we've redesigned the SDK payload into a single, consistent format shared across all integrations. This means we now support Samsung Health and Google Health Connect out of the box, alongside Apple HealthKit.
The Sync SDK is available as three packages - pick the one that fits your stack:
- open_wearables_ios_sdk - Native Swift SDK for Apple HealthKit sync. The core implementation that powers health data collection on iOS.
- open_wearables_android_sdk - Native Kotlin SDK for Samsung Health and Health Connect sync. Supports dual provider selection, background sync via WorkManager, and resumable sessions.
- open_wearables_health_sdk - Cross-platform Flutter SDK. A wrapper around the native iOS and Android SDKs - one integration for all three health data sources.
(React Native SDK is coming!)
All SDKs share the same push-based architecture: health data lives on-device, and the SDK handles secure background sync to the Open Wearables platform using incremental (anchored) queries.
We've also published comprehensive update to SDK docs:
- New: Full Android SDK docs - overview, integration guide, and troubleshooting
- Updated: iOS SDK docs - refreshed to match the latest SDK surface
- Updated: Flutter SDK docs - now covers invitation-code auth, host-based configuration, and Android provider selection
Open Wearables App on Android
Together with Samsung Health and Google Health Connect support, we have prepared a sample app for Android that will allow you to test the integration in just a few minutes! It's currently in beta - join our Discord to get an invite and try it out.
You can find the full documentation on how to use the application here.
One-click deployment on Railway
You can now deploy your own Open Wearables instance on Railway with a single click.
Garmin stability
Garmin integration got a major reliability pass. Backfill has been overhauled, user permissions are now handled properly, we support deregistration webhooks, and error recovery is much more robust (no more stuck retry loops on 401s or 409s).
Docs
We know the docs aren't perfect yet, but we've been putting a lot of work into improving them - new integration guides, expanded data type references, and better setup instructions across the board. More to come.
What's Changed
Integrations
- feat: Save Garmin activities from push notifications to database by @farce1 in #275
- feat(whoop): add body measurement syncing and data handling by @healthkowshik in #286
- Add Python SDK for Open Wearables API (#119) by @TudorGR in #124
- feat: add complete WHOOP workout type mappings by @healthkowshik in #305
- feat: add Garmin historical data backfill by @farce1 in #311
- feat: Add sleep handling for Apple SDK by @czajkub in #334
- feat: add recovery data handling to Whoop247Data service by @healthkowshik in #321
- feat(api): add Samsung SDK sync endpoint (BETA) and update documentation by @bartmichalak in #391
- feat: add Strava provider integration by @piotrsedzik in #446
- refactor(integrations): add trace IDs, batch inserts, and clean up webhook logging for Garmin
integration by @farce1 in #410 - refactor(backend): Garmin services refactor (from #410) by @czajkub in #467
- feat(backend): [alpha] Samsung Health integration by @KaliszS in #436
- feat(backend): update Suunto integration by @KaliszS in #482
- feat(backend): add missing statistics from Apple Health SDK by @czajkub in #447
- feat(backend): adapt SDK import services to new payload by @czajkub in #534
- feat: Garmin backfill reliability overhaul by @farce1 in #504
- feat: Handle Garmin user permissions flow properly by @bartmichalak in #532
- feat: handle Garmin deregistration webhook by @bartmichalak in #533
- feat: add request body validation and documentation for Apple Health Sync by @bartmichalak in #393
- feat: display data scope on user's connection card by @bartmichalak in #525
- feat(mcp): initial implementation of MCP server by @KaliszS in #349
- feat(mcp): add workout data retrieval and integration into MCP server by @healthkowshik in #364
- feat(mcp): add list_activity tool and present_health_data prompt by @healthkowshik in #378
- feat(mcp): added CI steps for MCP by @KaliszS in #432
API & Backend
- feat(api): implement daily activity summary with metrics calculation by @Gasiek in #273
- feat: body summary api by @Gasiek in #300
- refactor(api): restructure body summary with semantic metric grouping by @Gasiek in #377
- feat: generate user sdk token by admin by @bartmichalak in #344
- feat(backend): add refresh token support for SDK and developer authentication by @bartmichalak in
#431 - feat(backend): add invitation code for smoother demo app onboarding by @bartmichalak in #455
- feat: add priority lists for providers & device types by @KaliszS in #417
- feat(backend): auto seed admin on backend app startup by @bartmichalak in #479
- feat(backend): add --email and --password CLI args to seed_admin script by @bartmichalak in #451
- feat: add structured logging with batch tracking for Apple SDK by @bartmichalak in #395
- Propagate user_id through Celery tasks to enable Flower filtering by @bartmichalak in #315
- refactor(backend): user connection & device data model simplification by @KaliszS in #376
- refactor: reorganize Apple Health related endpoints by @bartmichalak in #381
- refactor(backend): Update logging across repo by @czajkub in #475
- feat: remove unused SQL Admin integration by @Copilot in #398
Frontend
- Add XML upload buttons to frontend by @czajkub in #296
- feat: Update user page, adding more data by @Gasiek in #318
- refactor(frontend): implementation of reusable Button, Dialog, and Input components by @Gasiek in
#386 - feat(frontend): add copy button for User ID on user detail page by @healthkowshik in #471
- feat(frontend): replace SDK token with invitation code generation by @bartmichalak in #456
- fix: redirect to dashboard after login instead of users page by @bartmichalak in #372
Docs
- docs: provider coverage matrix by @Gasiek in #258
- feat: add contributing guidelines by @farce1 in #250
- docs: encourage Discord discussion before contributions by @bartmichalak in #336
- docs: add PR title convention guidelines to contributing documentation by @bartmichalak in #340
- docs: add ngrok setup guide for local backend exposure by @bartmichalak in #379
- docs(integrations): Flutter Health Sync SDK docs by @kmlpiekarz in #374
- docs(integrations): iOS SDK docs by @kmlpiekarz in #484
- docs: update iOS SDK docs by @kmlpiekarz in #505
- docs(integrations): suunto integration update by @KaliszS in #483
- docs: add setup guide and update provider coverage matrix for Whoop integration by @bartmichalak in
#462 - docs: add OAuth flow and sync steps to Whoop integration guide by @healthkowshik in #473
- docs: add documentation for MCP Server by @bartmichalak in #437
- docs(mcp): improve setup guides and add demo video by @bartmichalak in #449
- docs(mcp): add an MCP server section to the Overview in the documentation by @bartmichalak in #406
- docs: add Railway deployment guide by @bartmichalak in #481
- docs: update Open Wearables app documentation page by @bartmichalak in #469
- docs: update Flutter example app page with new demo sections by @bartmichalak in #498
- docs: add Garmin webhook endpoint configuration guide by @bartmichalak in #516
- docs: update Garmin coverage matrix to match actual implementation by @bartmichalak in #522
- docs: add 30 missing timeseries types and expand workout types reference by @bartmichalak in #546
- docs: add data source priority architecture document by @bartmichalak in #411
- docs: reorganize navigation for providers and data types by @bartmichalak in #464
- docs: add Discord link to docs navigation, welcome page, and support page by @bartmichalak in #520
- docs: correct default admin account password by @makeusabrew in #518
- fix(docs): Strava docs update by @czajkub in #460
Fixes
- fix(api): Return 400 Bad Request for invalid datetime query parameters by @healthkowshik in #272
- Fix timeseries duplicates issue by @czajkub in #297
- fix: .env.example missing redirect_uris by @KaliszS in #304
- fix(event_record_service): update calorie and distance calculations in event records by
@healthkowshik in #306 - fix: Datapoint bulk by @KaliszS in #319
- fix: ForeignKeyViolation in Apple HealthKit import for non-existent users by @farce1 in #332
- fix: map calories and distance fields in Garmin, Suunto, and Polar by @Gasiek in #345
- fix(frontend): align workout field names with backend Workout schema by @Gasiek in #343
- fix(backend): Add missing statistics from workoutStatistics by @czajkub in #365
- fix(backend): fix multiple Apple Health issues by @czajkub in #373
- fix(backend): update apple payload handling logic by @czajkub in #387
- fix: Garmin REM parsing, sleep date display, and date range issues by @Gasiek in #388
- fix(backend): batched inserts by @elmariachi111 in #390
- fix(frontend): use date range as limit for activity summary API request by @healthkowshik in #422
- fix(backend): change "/" → "" on the developers and invitations routers by @farce1 in #452
- fix(backend): map skin_temperature correctly by @czajkub in #476
- fix: handle UUID serialization in structured logging (#496) by @kaifcodec in #503
- fix(backend): truncate fractional step count from Apple Health SDK by @bartmichalak in #510
- fix(backend): change timeseries sampling and remove sleep score calculations by @czajkub in #383
- fix: skip 5-min timeout on 409 duplicate and stop backfill chain on 401 by @bartmichalak in #528
- fix: limit Garmin backfill to 30 days (API constraint) by @bartmichalak in #529
- fix: skip Garmin backfill when HISTORICAL_DATA_EXPORT permission not granted by @bartmichalak in
#552 - fix(worker): update Celery worker command to use thread pool by @bartmichalak in #301
- fix: Added sentry handling celery exceptions by @KaliszS in #309
- fix(backend): create user provider connections in seed script by @bartmichalak in #415
Other
- Change seeding to .yaml by @czajkub in #207
- Update workout types mapping to Other by @czajkub in #329
- chore(backend): add date prefix to migration filenames by @bartmichalak in #414
- chore(backend): add WHOOP 5.0 to seed data by @healthkowshik in #419
- chore: fix docker build by @bartmichalak in #418
- chore: remove unused prestart.sh script by @bartmichalak in #433
- chore(backend): add structured logging to base OAuth template and Whoop oauth by @bartmichalak in
#494 - feat: add reset_db target to Makefile and implement reset_database script by @bartmichalak in #405
- feat(backend): add HealthKit payload generator script and fixtures by @bartmichalak in #412
- feat: remove redundant admin seeding from make file and update docs by @bartmichalak in #485
- ci: add PR title validation to workflow by @bartmichalak in #338
- ci: separate PR validation to dedicated workflow by @bartmichalak in #348
- ci: add paths to pull request trigger conditions in CI workflow by @bartmichalak in #371
- Fix test warnings in Garmin webhook tests by @healthkowshik in #322
- Update PR template to include pre-commit instead of separate commands by @KaliszS in #325
New Contributors
- @TudorGR made their first contribution in #124
- @kmlpiekarz made their first contribution in #374
- @Copilot made their first contribution in #398
- @piotrsedzik made their first contribution in #446
- @elmariachi111 made their first contribution in #390
- @kaifcodec made their first contribution in #503
- @makeusabrew made their first contribution in #518
Full Changelog: 0.2.2...0.3