Connect WHOOP
Authorize VitalTrends to read your WHOOP data in a few clicks. Once connected, recovery, sleep, strain, and HRV sync automatically in the background.
Steps
An active subscription is required to connect integrations. Go to Pricing to get started.
After logging in, go to Settings → Connections. You will see a WHOOP card showing "Not connected".
You will be redirected to WHOOP's OAuth authorization page. Log in with your WHOOP credentials if prompted.
Review the permissions and click Authorize. VitalTrends requests read-only access to your health data, nothing is written back to WHOOP.
After authorization, a background job imports up to 6 months of historical data, and attempts to pull as far back as your WHOOP account allows. This may take a minute or two. Refresh the dashboard once the sync banner clears.
How data stays fresh
VitalTrends uses three mechanisms to keep your WHOOP data current:
Webhooks (real-time)
WHOOP sends a push notification whenever sleep, workout, or recovery data is created or updated. VitalTrends processes these events immediately, so your dashboard typically updates within seconds of WHOOP finalizing a metric. Recovery webhooks are also self-healing: WHOOP v2 sends the associated sleep ID for recovery events, and VitalTrends resolves the matching cycle before applying the recovery.
Recent recovery refresh (on open)
When you open the WHOOP dashboard and the latest recovery looks stale, VitalTrends queues a small recent-window refresh for the last few days. This handles the common morning case where recovery already appears in the WHOOP app but the webhook has not landed yet.
Catch-up sync (background)
Every hour, VitalTrends checks whether your data is stale or has recent gaps. If so, it fetches a dynamic recent window from the WHOOP API as a safety net. Users with working webhooks cost zero extra API calls.
Understanding WHOOP fields
WHOOP data is organized around cycles, sleeps, workouts, and recovery. VitalTrends keeps the WHOOP names where possible so the API and dashboard remain traceable back to WHOOP, but a few fields are easy to misread.
| Field | Meaning |
|---|---|
date | The legacy daily date, based on the WHOOP cycle end. For explicit local dates, use cycle_start_date and cycle_end_date. |
is_partial | True only for the user's current local-day cycle while it is still open or not fully scored. |
recovery_score | WHOOP's recovery score for the cycle. VitalTrends does not recompute or approve it. |
strain | WHOOP strain for a daily cycle or workout. This is WHOOP's 0-21 strain scale, not calories or effort minutes. |
last_recovery_data_changed_at | When the stored recovery values last changed in VitalTrends. |
last_recovery_synced_at | When VitalTrends last checked or applied recovery data, even if the values did not change. |
zone_*_milli | Workout heart-rate zone durations in milliseconds, directly from WHOOP. |
kilojoule | Workout energy in kilojoules, directly from WHOOP. It is not the same unit as food calories. |
For the current morning, use /api/v1/whoop/daily as the source of truth for recovery plus sleep availability. Select the row where cycle_start_date matches the user's local date and require both recovery_score and sleep_duration_minutes. /api/v1/whoop/recovery-status is advisory freshness metadata only and should not be used as a hard gate for whether today's daily row exists.
Disconnecting WHOOP
Go to Settings → Connections and click Disconnect next to WHOOP. This revokes the OAuth token and stops all future syncs. Your historical data remains in VitalTrends unless you delete your account.
Force sync
Force sync re-imports the last 6 months of your WHOOP data from scratch, replacing any incomplete or outdated records. You can trigger it from Settings → Connections by clicking the Force Sync button on the WHOOP card.
Use force sync when:
- Your dashboard is missing data that already appears in the WHOOP app.
- You see gaps in your charts that should have data.
- You recently resolved a connection issue and want to backfill missed records.
Troubleshooting
Dashboard shows no data after connecting
The initial sync is still running. Wait 1-2 minutes and refresh. If data still does not appear, disconnect and reconnect to trigger a fresh sync.
Data is a few hours behind
WHOOP finalizes recovery and sleep scores on its own schedule. If WHOOP already shows the recovery, open the VitalTrends WHOOP dashboard once; that queues a targeted recent recovery refresh. API users can call /api/v1/whoop/recovery-status to inspect freshness timestamps, but current-day availability should be checked through /api/v1/whoop/daily.
The daily date looks one day off
WHOOP cycles often span overnight. The legacy date field follows the cycle end date for closed cycles; use cycle_start_date, cycle_end_date, and is_partial when you need the exact local cycle boundary.
Connection shows "Reconnection needed"
Your OAuth token has expired or was revoked. Click Reconnect on the Connections page to re-authorize.