A sample health application demonstrating integration with Open Wearables - a platform that enables easy collection of wearable data from various manufacturers in one unified API.
Healthion showcases how to build a complete health dashboard that displays data from multiple wearable devices through Open Wearables integration. All wearable data flows through Open Wearables API, which handles:
- Device connections via OAuth (Garmin, Polar, Suunto, Withings, Whoop, Oura)
- Data normalization across different device formats
- Deduplication when data comes from multiple sources
| Category | Data Types |
|---|---|
| Heart | Heart Rate, HRV (RMSSD/SDNN), Blood Pressure |
| Activity | Steps, Calories, Distance, Floors Climbed |
| Body | Weight, Body Fat %, BMI, Body Temperature |
| Respiratory | SpO2, Respiratory Rate, VO2 Max |
| Blood | Blood Glucose, Blood Oxygen |
| Sleep | Sleep stages, Sleep score |
| Other | Stress, Energy, Mindfulness minutes, and more... |
- Workouts - All training types with duration, calories, heart rate zones
- Sleep Sessions - Sleep phases, quality metrics, interruptions
- Activity - Steps, calories burned, active minutes, distance
- Sleep - Total sleep time, phases, efficiency, score
- Recovery - HRV trends, recovery score, readiness
- Body - Weight, BMI, body composition metrics
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ healthion-web │────▶│ healthion-api │────▶│ Open Wearables │
│ (React + TS) │ │ (FastAPI) │ │ API │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Garmin, Polar, │
│ Suunto, Withings│
│ Whoop, Oura... │
└─────────────────┘
FastAPI-based REST API that:
- Proxies requests to Open Wearables API
- Handles user authentication (Auth0)
- Automatically registers users with Open Wearables on first login
- Manages OAuth flows for device connections
See healthion-api/README.md for setup instructions.
React + TypeScript application with:
- Dashboard - Overview of all health metrics
- Heart Rate - Detailed heart rate timeseries and trends
- Workouts - Training history and statistics
- Sleep - Sleep sessions and quality metrics
- Activity - Daily activity summaries
- Recovery - HRV and recovery metrics
- Body - Weight and body composition
- Settings - Connect/disconnect wearable devices
Built with Vite, Tailwind CSS, and shadcn/ui components.
See healthion-web/README.md for setup instructions.
- Docker & Docker Compose
- Node.js 18+
- Open Wearables API key
- Auth0 account for authentication
-
Clone the repository
git clone https://github.com/the-momentum/healthion.git cd healthion -
Set up the backend
cd healthion-api cp envs/.env.example envs/.env # Edit envs/.env with your Open Wearables API key and Auth0 config docker-compose up -d
-
Set up the frontend
cd healthion-web cp .env.example .env # Edit .env with your Auth0 config npm install npm run dev
-
Connect your wearables
- Open http://localhost:5173
- Log in with Auth0
- Go to Settings and connect your devices
| Variable | Description |
|---|---|
OPEN_WEARABLES_API_KEY |
Your Open Wearables API key |
AUTH0_DOMAIN |
Auth0 domain |
AUTH0_AUDIENCE |
Auth0 API audience |
| Variable | Description |
|---|---|
VITE_AUTH0_DOMAIN |
Auth0 domain |
VITE_AUTH0_CLIENT_ID |
Auth0 client ID |
VITE_AUTH0_AUDIENCE |
Auth0 API audience |
VITE_API_BASE_URL |
(Optional) Backend API URL, defaults to http://localhost:8001/api/v1 |
During implementation, we encountered several challenges worth documenting:
Problem: 401 Unauthorized errors when creating users in Open Wearables.
Solution: Ensure OPEN_WEARABLES_API_KEY is correctly set and restart Docker containers to load new environment variables.
Problem: Errors from Open Wearables were being caught and silently ignored, making debugging difficult.
Solution: Added explicit OpenWearablesConfigurationError exception and improved logging. Return HTTP 503 when Open Wearables is not configured.
Problem: Multiple simultaneous requests to authenticate created duplicate users in Open Wearables (5+ accounts for the same email).
Cause: Each concurrent request checked if user exists, got None, and created a new user - all before any creation completed.
Solution: Implemented per-email asyncio.Lock in the Open Wearables client to serialize user creation requests.
MIT License - see LICENSE for details.