Quickstart
This guide takes you from a fresh VitaSync installation to your first health data query. By the end you will have:
- VitaSync running locally with Docker
- A user created and connected to a wearable provider
- Real health metrics in the database and queryable via the API
Prerequisites
Section titled “Prerequisites”- Docker Desktop installed
- A wearable device account (Fitbit, Garmin, WHOOP, or Strava) with some historical data
- An OAuth developer app for one of the providers (see below)
Step 1 — Create Provider OAuth Credentials
Section titled “Step 1 — Create Provider OAuth Credentials”Before you can connect a wearable, you need OAuth credentials from the provider’s developer portal.
- Go to dev.fitbit.com/apps/new
- Fill in the form:
- Application Type: Personal
- OAuth 2.0 Application Type: Server
- Callback URL:
http://localhost:3001/v1/oauth/fitbit/callback
- After creation, copy the OAuth 2.0 Client ID and Client Secret
- Go to developer.garmin.com/gc-developer-program/overview/
- Apply for API access (may take 1-2 business days for approval)
- Once approved, create an app and note the Consumer Key and Consumer Secret
- Set the OAuth Callback URL to:
http://localhost:3001/v1/oauth/garmin/callback
- Go to developer.whoop.com
- Create a new application
- Set the Redirect URI to:
http://localhost:3001/v1/oauth/whoop/callback - Copy the Client ID and Client Secret
- Go to strava.com/settings/api
- Create a new application
- Set Authorization Callback Domain to
localhost - Copy the Client ID and Client Secret
Step 2 — Configure Your Environment
Section titled “Step 2 — Configure Your Environment”Clone the repository and create your environment file:
git clone https://github.com/your-org/vitasync.gitcd vitasynccp .env.example .envEdit .env with your credentials:
# Required: generate a 64-character hex string for token encryptionENCRYPTION_KEY=your-64-hex-chars-here
# Required: your admin API key (prefix must be vs_live_)ADMIN_API_KEY=vs_live_changeme_replace_in_production
# Required: workspace identifierADMIN_WORKSPACE_SLUG=my-workspace
# OAuth redirect base URLOAUTH_CALLBACK_URL=http://localhost:3000/connections/callback
# Add the provider you created credentials for:FITBIT_CLIENT_ID=your_fitbit_client_idFITBIT_CLIENT_SECRET=your_fitbit_client_secret
# GARMIN_CONSUMER_KEY=your_garmin_consumer_key# GARMIN_CONSUMER_SECRET=your_garmin_consumer_secret
# WHOOP_CLIENT_ID=your_whoop_client_id# WHOOP_CLIENT_SECRET=your_whoop_client_secret
# STRAVA_CLIENT_ID=your_strava_client_id# STRAVA_CLIENT_SECRET=your_strava_client_secretGenerate the encryption key with:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Step 3 — Start VitaSync
Section titled “Step 3 — Start VitaSync”docker compose up -dThis starts PostgreSQL, Redis, the API server, background worker, and web dashboard. Wait about 15 seconds for everything to be ready, then verify:
curl http://localhost:3001/health# {"status":"ok"}Step 4 — Create Your First User
Section titled “Step 4 — Create Your First User”export API_KEY=vs_live_changeme_replace_in_production
curl -X POST http://localhost:3001/v1/users \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"externalId": "user-001", "displayName": "Test User"}'Response:
{ "id": "01JA4MNPQR8STUVWXYZ00001", "externalId": "user-001", "displayName": "Test User", "metadata": {}, "createdAt": "2025-06-01T10:00:00.000Z"}Save the id — you will need it in the next steps.
export USER_ID=01JA4MNPQR8STUVWXYZ00001Step 5 — Connect a Wearable
Section titled “Step 5 — Connect a Wearable”Open this URL in your browser (replace fitbit with your provider if needed):
http://localhost:3001/v1/oauth/fitbit/authorize?userId=01JA4MNPQR8STUVWXYZ00001You will be redirected to the provider’s login page. After granting access, you will be redirected back and see something like:
http://localhost:3000/connections/callback?connectionId=01JA4MNPQR8STUVWXYZ00002&providerId=fitbitSave the connection ID:
export CONNECTION_ID=01JA4MNPQR8STUVWXYZ00002Step 6 — Trigger the First Sync
Section titled “Step 6 — Trigger the First Sync”curl -X POST \ "http://localhost:3001/v1/users/$USER_ID/connections/$CONNECTION_ID/sync" \ -H "Authorization: Bearer $API_KEY"Response:
{"jobId": "sync-job-01JA4...", "status": "queued"}The sync runs asynchronously and pulls the last 30 days of data. It typically completes in a few seconds to a minute. Watch progress in the worker logs:
docker compose logs -f workerStep 7 — Query Your Health Data
Section titled “Step 7 — Query Your Health Data”Once the sync completes, query your data:
# Steps for the last 7 dayscurl "http://localhost:3001/v1/users/$USER_ID/health?metricType=steps&limit=7" \ -H "Authorization: Bearer $API_KEY"Response:
{ "data": [ { "id": "01JA4...", "metricType": "steps", "value": 9823, "unit": "count", "recordedAt": "2025-06-06T00:00:00.000Z", "providerId": "fitbit" } ], "total": 7, "limit": 7, "offset": 0}Try other queries:
# Summary: how many data points per metric type?curl "http://localhost:3001/v1/users/$USER_ID/health/summary" \ -H "Authorization: Bearer $API_KEY"
# Timeseries: average heart rate by day for Junecurl "http://localhost:3001/v1/users/$USER_ID/health/timeseries?metricType=heart_rate&from=2025-06-01&to=2025-06-30&bucket=day" \ -H "Authorization: Bearer $API_KEY"
# Daily summary: steps + calories + resting HR for last weekcurl "http://localhost:3001/v1/users/$USER_ID/health/daily-summaries?from=2025-06-01&to=2025-06-07&metricTypes=steps,calories,resting_heart_rate" \ -H "Authorization: Bearer $API_KEY"
# Recent workoutscurl "http://localhost:3001/v1/users/$USER_ID/events?eventType=workout&limit=5" \ -H "Authorization: Bearer $API_KEY"
# Personal recordscurl "http://localhost:3001/v1/users/$USER_ID/personal-records" \ -H "Authorization: Bearer $API_KEY"What Is Available
Section titled “What Is Available”After the first sync, data is available depending on which provider you connected:
| Metric | Fitbit | Garmin | WHOOP | Strava |
|---|---|---|---|---|
| Steps | Yes | Yes | — | — |
| Heart rate | Yes | Yes | Yes | Yes |
| Sleep | Yes | Yes | Yes | — |
| HRV | Yes | Yes | Yes | — |
| Workouts | — | Yes | Yes | Yes |
| Recovery score | — | — | Yes | — |
| SpO2 | Yes | Yes | Yes | — |
| Body weight | Yes | — | — | — |
See the Providers section for full coverage tables.
Next Steps
Section titled “Next Steps”- Connect multiple users — the flow scales to millions of users
- Set up webhooks — get notified when syncs complete
- Deploy to production — Docker and Kubernetes deployment guides
- Add a new provider — extend VitaSync with a provider not yet supported