# Withings Integration

## Purpose

Pluscare syncs health data from Withings wearable devices (smartwatches, scales, etc.) into the platform for dashboards, charts, and alert evaluation.

## How it works

The application integrates with Withings in two ways:

1. **Webhooks** — health data is received in near real-time when Withings pushes events to the application.
2. **Scheduled sync job (fallback)** — runs **twice per day** at **03:00** and **15:00** to catch any missed data.

If Pluscare does not receive data from Withings within the synchronization interval configured on the device, it sends a notification to all administrators.

### One-time setup (required)

Before webhooks can work, configure the **webhook callback URL** in your [Withings developer settings](https://developer.withings.com/dashboard/). This is a one-time step that tells Withings where to send webhook events for your application.

## Key entities & DB

Health data is stored in type-specific tables. Mapping from Withings API to the database:

| Type | Supplier | Endpoint | Endpoint attribute | DB table | Description |
|------|----------|----------|-------------------|----------|-------------|
| heart rate | Withings | [/v2/measure](https://developer.withings.com/api-reference/#tag/measure/operation/measurev2-getintradayactivity) | `heart_rate` | `heart_rates` | Measured heart rate (intraday) |
| steps | Withings | [/v2/measure](https://developer.withings.com/api-reference/#tag/measure/operation/measurev2-getintradayactivity) | `steps` | `steps` | Number of steps (intraday) |
| spo2 | Withings | [/v2/measure](https://developer.withings.com/api-reference/#tag/measure/operation/measurev2-getintradayactivity) | `spo2_auto` | `oxygen_saturations` | SpO2 measurement automatically tracked by a device tracker (intraday) |
| heart rate | Withings | [/measure](https://developer.withings.com/api-reference/#tag/measure/operation/measure-getmeas) | `11` | `heart_rates` | Heart pulse (bpm) — only for BPM and scale devices |
| spo2 | Withings | [/measure](https://developer.withings.com/api-reference/#tag/measure/operation/measure-getmeas) | `54` | `oxygen_saturations` | SpO2 (%) |
| sleep | Withings | [/v2/sleep](https://developer.withings.com/api-reference/#tag/sleep/operation/sleepv2-get) | `total_sleep_time` | `sleeps` | Total time spent asleep (seconds) |
| sleep | Withings | [/v2/sleep](https://developer.withings.com/api-reference/#tag/sleep/operation/sleepv2-get) | `deepsleepduration` | `sleeps` | Duration in deep sleep (seconds) |
| sleep | Withings | [/v2/sleep](https://developer.withings.com/api-reference/#tag/sleep/operation/sleepv2-get) | `lightsleepduration` | `sleeps` | Duration in light sleep (seconds) |
| ecg | Withings | [/v2/heart](https://developer.withings.com/api-reference/#tag/heart) | `heart_rate` | `ecgs` | Average recorded heart rate during ECG |
| ecg | Withings | [/v2/heart](https://developer.withings.com/api-reference/#tag/heart) | `signals` | `ecgs` | ECG signal points in micro-volt (μV) |
| ecg | Withings | [/v2/heart](https://developer.withings.com/api-reference/#tag/heart) | `sampling_frequency` | `ecgs` | Signal sampling frequency (Hz) |

## Technical flow

1. Withings sends webhook events to the configured callback URL when new health data is available.
2. The application processes and stores the data in the appropriate tables.
3. As a fallback, the scheduled sync job runs at 03:00 and 15:00.
4. If sync fails beyond the device-configured interval, administrators are notified.

## Notes / edge cases

- Manual sync is available via the `measures:sync` artisan command. See [Development Guide](../development.md#custom-commands).
- API credentials and webhook configuration are managed from the [Withings developer dashboard](https://developer.withings.com/dashboard/).

## Related documentation

- [Business Logic](../business-logic.md) — devices, alerts, and dashboards
- [Development Guide](../development.md) — `measures:sync` command
