Self-hosted health data aggregation platform. Collects metrics from WHOOP, Withings, and manual entries, stores in InfluxDB/PostgreSQL, visualizes via Grafana.

WHOOP/Withings APIs → Aggregator (cron 7am) → InfluxDB/PostgreSQL
↓
FastAPI
↓
myVitals Frontend
| Source |
Status |
Data |
| WHOOP |
✅ Live |
Sleep, Recovery, Strain, HRV, RHR |
| Withings |
✅ Live |
Weight, Body Composition |
| Oura |
🔧 Ready |
Sleep, Readiness (waiting for Kellee's ring ~Jan 23) |
| Keto-Mojo |
🔧 Ready |
Glucose, Ketones (waiting for API approval) |
| Chronometer |
❌ Skipped |
No public API |
| Manual GKI |
✅ Live |
Via myVitals form |
- Bucket: health_metrics
- Org: cowens
| Measurement |
Fields |
Source |
| weight |
value, fat_mass, muscle_mass, water_percent, bmi |
Withings |
| body_composition |
body_fat_percent, bone_mass |
Withings |
| recovery |
score, hrv, rhr, spo2, skin_temp |
WHOOP |
| sleep |
duration, deep, rem, light, awake, efficiency, score |
WHOOP |
| strain |
score, average_hr, max_hr, calories |
WHOOP |
| gki |
glucose, ketones, gki, time |
Manual |
| Table |
Records |
Purpose |
| user_profiles |
1 |
Chuck's profile |
| protocols |
2 |
Nutrition protocols |
| supplements |
19 |
Supplement stack |
| quotes |
28 |
Motivational quotes |
| goals |
4 |
Health & martial arts goals |
| milestones |
8 |
Weight loss journey |
| key_dates |
2 |
Important dates |
| waist_measurements |
3+ |
Manual tracking |
| Endpoint |
Method |
Description |
/api/v1/users/{id}/metrics/latest |
GET |
Dashboard snapshot |
/api/v1/users/{id}/metrics/weight |
GET |
Weight history |
/api/v1/users/{id}/metrics/recovery |
GET |
Recovery history |
/api/v1/users/{id}/metrics/sleep |
GET |
Sleep history |
/api/v1/users/{id}/metrics/strain |
GET |
Strain history |
/api/v1/users/{id}/metrics/gki |
GET |
GKI history |
/api/v1/users/{id}/metrics/gki |
POST |
Create GKI reading |
| Endpoint |
Method |
Description |
/api/v1/users/{id}/profile |
GET |
User profile |
/api/v1/users/{id}/protocols/active |
GET |
Current protocol |
/api/v1/users/{id}/supplements |
GET |
Supplement stack |
/api/v1/users/{id}/goals |
GET |
Goals with progress |
/api/v1/users/{id}/milestones |
GET |
Timeline milestones |
/api/v1/users/{id}/waist |
GET |
Waist measurements |
/quotes |
GET |
Quotes |
- ✅ Health Overview
- ✅ Body Composition (10%/18% thresholds)
- ✅ Sleep Analysis
- ✅ Recovery Metrics
- ✅ Daily Health Overview
- ✅ Nutrition (ready for data)
| Entity |
ID |
| Chuck's User ID |
36b97660-94b9-4c1e-a564-a6f4bec00474 |
maekbak/
├── aggregator/ # Data sync service
│ └── sources/ # WHOOP, Withings, etc.
├── api/ # FastAPI backend
│ ├── routers/ # Endpoints
│ └── schemas/ # Pydantic models
├── docker/ # Docker Compose
├── grafana/ # Dashboard JSON
│ └── dashboards/
├── docs/ # Documentation
│ └── sessions/ # Session logs
└── maekbak_mcp/ # MCP Server (blocked)
¶ Commands
sudo bash -c 'cd /opt/maekbak && source <(grep -E "^[A-Z]" docker/.env | sed "s/^/export /") && export POSTGRES_HOST=localhost INFLUXDB_URL=http://localhost:8086 && python3 -m aggregator'
cd /opt/maekbak/docker
sudo docker compose build api && sudo docker compose up -d api
- Server: UTC
- Chuck: America/Chicago (CST, UTC-6)
- InfluxDB: Stores UTC
- Grafana:
today() uses UTC - add option location = loadLocation(name: "America/Chicago") for local time