# Sync a connected wearable provider now

Canonical page: https://docs.ovok.com/api/wearables/sync-a-connected-wearable-provider-now

`POST /v1/wearables/connections/{provider}/sync`

Pulls the signed-in patient's latest data from a connected wearable provider now, instead of waiting for the daily sync, and writes it as Observations.

**Auth:** bearer token of a patient.
**Scope:** the caller's project and Patient profile (from the token).

## Behaviour

- Oura, WHOOP, Strava, Withings, Polar, Ultrahuman and Suunto can be synced. Other providers answer `501 SYNC_NOT_SUPPORTED` for now; they can still be connected.
- The first sync reads the last 30 days. Each later sync reads from 2 days before `syncedThrough`, because providers revise recent records.
- Each reading becomes one Observation about the patient, created once. A reading already held is updated in place, so a value the provider revised within the re-read window replaces the earlier one, and `created` counts only new ones.
- What is synced:
  - heart rate, resting heart rate, heart-rate variability (RMSSD), SpO2, respiratory rate;
  - daily steps;
  - sleep duration and its light, deep, REM and awake parts.
- What each provider gives:
  - Oura: per sleep period, heart rate, resting heart rate, HRV, respiratory rate and the sleep stages; daily SpO2 and steps.
  - WHOOP: resting heart rate, HRV and SpO2 from each recovery; respiratory rate and the sleep stages; each day's average heart rate.
  - Strava records workouts only, so it gives each workout's average heart rate.
  - Withings gives heart-rate and SpO2 measurements, daily steps, and per night its sleep summary: the night's average heart rate, average respiratory rate and RMSSD, and the sleep durations.
  - Polar gives each night's sleep stages, and from its nightly recharge the night's average heart rate, heart-rate variability (RMSSD) and breathing rate, dated by the night. Its daily steps are dated by the watch's local day.
  - Ultrahuman: SpO2 (when given as one value), resting heart rate during sleep, daily steps and the sleep stages. Its per-sample heart rate and HRV are not synced. It is asked one day at a time, so a first sync makes 31 requests. It gives no respiratory rate.
  - Suunto: daily steps only, for now.
- `heart_rate` is not the same kind of value everywhere: for Oura, Withings and Polar it is a sleep or nightly average (Withings adds its heart-rate measurements), for WHOOP the day's average, and for Strava the average of one workout.
- Codes are LOINC, except heart-rate variability: LOINC has no RMSSD code, so it is `https://api.ovok.com/fhir/CodeSystem/wearables|hrv-rmssd`.
- Every Observation carries the provider in `meta.tag` (`https://api.ovok.com/fhir/CodeSystem/wearables-source`) and in `device.display`.
- Wearable Observations are not forwarded to Signals.
- A daily sync runs for every connection at 08:00 UTC; this route only brings it forward, at most once every 15 minutes.
- Withings also tells ovok when a patient has new data, and a sync of that connection follows about 30 seconds later. ovok subscribes each patient when they connect; nothing needs setting up in the Withings portal beyond the redirect URL.
- Withings Sleep Analyzer mats on ovok's own Withings device integration are separate: their bed presence and sleep series do not come through this connection, and this connection does not change them.
- A sync never reads further back than 30 days: when the provider or the connection is out of reach for longer, the oldest days are lost.
- Polar lists sleep and nightly recharge for its last 28 days only, so a first Polar sync holds 28 days of those and 30 of steps.
- Polar's access is long-lived and cannot be refreshed: once Polar stops accepting it, the sync answers `409 RECONNECT_REQUIRED`.

## Errors

- `404 CONNECTION_NOT_FOUND`: the patient has not connected this provider, or disconnected it during the sync.
- `404 PROVIDER_NOT_AVAILABLE`: the project removed or switched off the provider.
- `409 SYNC_IN_PROGRESS`: a sync of this connection is already running.
- `409 CONNECTION_CHANGED`: the patient reconnected the provider while it was syncing; nothing was written over the new connection. Sync again.
- `409 RECONNECT_REQUIRED`: the provider no longer accepts the connection, for example after the patient removed the app's access. Connect it again with `POST /v1/wearables/connections/<provider>/authorize`. `GET /v1/wearables/connections` shows `reconnectRequired: true` meanwhile.
- `429 SYNC_TOO_SOON`: the last sync was under 15 minutes ago. Retry after the seconds in `Retry-After`; the provider was not asked.
- `500 SYNC_FAILED`: the sync failed on our side; nothing moved, so try again later.
- `502 PROVIDER_UNAVAILABLE`: the provider failed, could not be reached, or answered something unreadable; nothing moved, so try again later.
- `503 PROVIDER_RATE_LIMITED`: the provider is limiting requests. Retry after the seconds in `Retry-After`.

## Example

```bash
curl -X POST 'https://api.sandbox.ovok.com/v1/wearables/connections/oura/sync' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk'
```
