Skip to main content

Device Integration — Wearables, Bluetooth Devices & Health Stores

This section explains how to integrate health data sources with vitalera — from consumer wearables like Garmin, Oura, WHOOP, and Dexcom (cloud API) to clinical Bluetooth devices like blood pressure monitors and glucometers (SDK).

Consumer Wearables (API-Based)

Connect popular consumer wearables and medical devices via server-to-server API integrations. No mobile SDK required for these — users link their accounts once via OAuth (or an equivalent authentication flow), and data flows automatically into vitalera as FHIR R5 Observation resources.

Fitness trackers & smartwatches

ProviderConnectionData TypesStatusLearn More
GarminGarmin Health API (OAuth 2.0 + PKCE)Workouts, HR zones, sleep stages, SpO2, stress, steps, HRV, BP, skin tempAvailableGarmin
Fitbit (legacy)Fitbit Web API (OAuth)Activity, HR, sleep, SpO2, weightDeprecated (2026-05-31) — migrate to Google HealthGoogle Health (Fitbit)
Apple WatchHealthKit (on-device SDK)HR, SpO2AvailableSDK Reference
PolarAccessLink v3 (OAuth)Exercises, daily activity, sleep, HRAvailablePolar
SuuntoSuunto Partner API (OAuth)Workouts, sleep, activity, recoveryPartnership requiredSuunto
COROSCOROS Open API (OAuth)Workouts, HR, sleep, SpO2, VO2 max, pace, cadence, running powerPartnership requiredCOROS
WahooWahoo Cloud (OAuth)Workouts, HR, power, distance, caloriesAvailableWahoo
Samsung HealthSamsung Partnership APIHR, sleep, activity, SpO2, BP, weightPartnership required (skeleton)Samsung Health
Amazfit / ZeppHuami API (reverse-engineered)HR, steps, sleep, SpO2, stress, caloriesReverse-engineeredAmazfit / Zepp
Pelotononepeloton.com (reverse-engineered)Workouts, HR, calories, performance (output/cadence/resistance)Reverse-engineeredPeloton
StravaStrava v3 (OAuth + push subs)Activities, HR streams, distance, elevationAvailableStrava

Sleep & recovery

ProviderConnectionData TypesStatusLearn More
Oura RingOura v2 (OAuth)HR, sleep stages, activity, readiness, SpO2, stress, VO2 maxAvailableOura
WHOOPWHOOP API v2 (OAuth)Recovery 0–100%, sleep, strain 0–21, cycles, body measurementsAvailableWHOOP
UltrahumanPartner API (OAuth)Sleep, activity, recovery, HRV, HR, SpO2, skin tempPartnership requiredUltrahuman
BiostrapBiostrap v2 (OAuth)Resting HR, HRV, SpO2, respiratory rate, sleep, recoveryAvailableBiostrap
Eight Sleepclient-api.8slp.net (email+password → JWT)Sleep, HR, HRV, respiratory rate, bed temperatureReverse-engineeredEight Sleep

Medical / clinical

ProviderConnectionData TypesStatusLearn More
Dexcom CGMDexcom v3 (OAuth)Glucose, insulin events, carbs, exercise events (FDA-cleared)Partnership requiredDexcom
FreeStyle LibreLibreView (reverse-engineered)Continuous glucoseReverse-engineeredFreeStyle Libre
Omron CloudOmron Connect (OAuth)BP (systolic + diastolic + pulse), weight, activityAvailableOmron
iHealthiHealth (OAuth + SC/SV)BP, glucose, SpO2, weight, temperature, activityAvailableiHealth
InBodyPartnership API (API key + OTP)Body fat %, muscle mass, BMI, BMR, body water, visceral fatPartnership (NDA)InBody
WithingsWithings v2 (OAuth)Weight, BP, HR, sleep, activity, SpO2, temperatureAvailableWithings
BodyTraceAPI key + pushWeight with battery/signal metadataAvailableBodyTrace

Migration paths

ProviderReplacesDeadlineLearn More
Google HealthFitbit Web API2026-05-31Google Health (Fitbit)

Status legend

Symbol / labelMeaning
AvailableProduction-ready, on-demand sign-up.
Partnership requiredProvider-issued partner credentials needed. vitalera onboards per-organisation.
Partnership (NDA)As above, plus NDA required before access is granted.
Reverse-engineeredNo official developer API. Best-effort; endpoints may change. Not recommended for clinical SLAs.
DeprecatedLegacy integration scheduled for shutdown. Migrate to the replacement.

Connected Accounts Framework

All provider integrations above are exposed through a single, provider-agnostic API so adding a new wearable source never requires a schema change or a new client. Each provider has the same set of endpoints, parameterised by the service_id (e.g. fitbit, garmin, oura, dexcom).

Catalog and discovery

EndpointPurpose
GET /api/connected-accounts/services/Service catalog — every provider the caller's organisation is entitled to use
GET /api/connected-accounts/status/Bulk per-user status across every connected provider
GET /api/connected-accounts/{service_id}/status/Single-provider status (connected, disconnected, reauth_required)

Connect flows

EndpointPurpose
POST /api/connected-accounts/{service_id}/oauth/initiate/Start an OAuth / API-key setup — returns the URL to redirect the user to
GET /api/connected-accounts/{service_id}/oauth/callback/Redirect target — vitalera completes the token exchange
POST /api/connected-accounts/{service_id}/oauth/disconnect/Revoke tokens and disable the connection
POST /api/connected-accounts/{service_id}/webhook/Provider-facing push endpoint (HMAC-SHA256 or JWT-verified per provider)

Embedded connect widget

For third-party apps that don't host their own OAuth UX, vitalera offers a hosted widget:

EndpointPurpose
POST /api/connected-accounts/connect-session/Issue a short-lived, single-user connect-session token
GET /api/connected-accounts/connect/?token=...Hosted connect widget — users pick a provider and complete OAuth inline

Entitlements

Every provider is gated by a per-organisation entitlement of the form connected_accounts:<service_id> (e.g. connected_accounts:dexcom). The service catalog filters by entitlement, so users only see providers the organisation has paid for / been approved to use. Partnership-gated providers (COROS, Suunto, Samsung Health, InBody, Dexcom) ship disabled by default.


Medical Devices (SDK — Bluetooth)

ProviderModule (Android)Module (iOS)Devices
Omronprovider-omronVitaleraSdkProviderOmronEvolv BPM (HEM-7600T), MC-280B Thermometer
Polarprovider-polarVitaleraSdkProviderPolarH10, Verity Sense (heart rate)
Lifevitprovider-lifevitVitaleraSdkProviderLifevitBPM 160, BPM 260, Pulse Oximeter (OL750), Scale (BL2000), Thermometer (IT45B)
Beurerprovider-beurerVitaleraSdkProviderBeurerBM85 BPM, PO60 Pulse Oximeter
Smart Peak Flowprovider-smart-peak-flowVitaleraSdkProviderSmartPeakFlowSmart Peak Flow Meter
HealthKitN/AVitaleraSdkProviderHealthKitApple Watch (heart rate, SpO2)
Health Connectprovider-health-connectN/AGoogle Health Connect (Android)
Standard BLEsdk-bleVitaleraSdkBleAny device using standard Bluetooth SIG health profiles

See the Supported Devices page for the complete device list.

General BLE Workflow

For all BLE devices, the integration follows three steps:

1. Discover

Scan for nearby BLE devices using DiscoveryFilter to filter by provider, capability, or device name:

// Android (Kotlin)
val filter = DiscoveryFilter(
capabilities = setOf(DeviceCapability.BLOOD_PRESSURE)
)
sdk.devices.discover(filter, timeoutMs = 15_000L).collect { descriptor ->
println("Found: ${descriptor.name} (${descriptor.provider})")
}
// iOS (Swift)
let filter = DiscoveryFilter(
providers: nil,
capabilities: [DeviceCapability.bloodPressure],
namePrefix: nil
)
for try await descriptor in sdk.devices.discover(filter: filter, timeoutMs: 15_000) {
print("Found: \(descriptor.name) (\(descriptor.provider))")
}

2. Connect

Create a device from the discovered descriptor and connect:

// Android
val device = sdk.devices.createDevice(descriptor)
device.connect(timeoutMs = 10_000L)
// iOS
let device = sdk.devices.createDevice(descriptor: descriptor)
try await device.connect(timeoutMs: 10_000)

3. Collect

Read typed observations from the connected device:

// Android
device.collect().collect { observation ->
when (observation) {
is BloodPressureObservation ->
println("BP: ${observation.systolic}/${observation.diastolic}")
is HeartRateObservation ->
println("HR: ${observation.heartRate} bpm")
}
}
device.disconnect()
// iOS
for try await observation in device.collect() {
if let bp = observation as? BloodPressureObservation {
print("BP: \(bp.systolic)/\(bp.diastolic) mmHg")
} else if let hr = observation as? HeartRateObservation {
print("HR: \(hr.heartRate) bpm")
}
}
try await device.disconnect()

Device-Specific Notes

Blood Pressure Monitors

  • Beurer BM85: Ensure the device is charged and turned off before scanning. Turn on the device after scanning starts and wait for Bluetooth discovery.
  • Lifevit BPM 160/260: Turn on the device, then start scanning. Once connected, call read and wait for the observation.
  • Omron Evolv (HEM-7600T): Turn on the device and start scanning. The SDK handles pairing automatically.

Pulse Oximeters

  • Lifevit OL750 / Beurer PO60: Place your finger in the oximeter and turn it on, then start scanning. Data streams continuously until you disconnect.

Thermometers

  • Lifevit IT45B / Omron MC-280B: Turn on the thermometer, start scanning, and take a measurement. The observation is returned after the reading completes.

Scales

  • Lifevit BL2000: Step on the scale when prompted. The weight observation is returned once the reading stabilizes.

Glucometers

  • Contour Next: The device must be pre-paired via system Bluetooth settings before scanning from the SDK.

Heart Rate Sensors

  • Polar H10: Wear the chest strap, start scanning, and the SDK streams heart rate data continuously.

Further Reading