# Datos de wearables en FHIR (Apple Health, Health Connect)

> Obtenga datos de smartwatches, anillos y básculas en un registro FHIR: qué dispositivos acceden a qué almacén de salud, una tabla de mapeo LOINC, resúmenes diarios y una operación de inserción (upsert) probada.

Source: https://developers.anpheros.com/es/guides/wearable-data-fhir

**Para obtener datos de un smartwatch, anillo o báscula inteligente en un registro médico, léalos en el teléfono desde el almacén de salud del sistema operativo — Apple Health en iOS, Health Connect en Android — resúmalos por día, mapee cada métrica a un código LOINC y una unidad UCUM, y escríbalos como Observaciones FHIR R4 marcadas como datos de dispositivo.** Leer desde el almacén de salud del teléfono en lugar de desde la nube de cada proveedor permite que una sola integración cubra Apple Watch, Galaxy Watch, Pixel Watch, Garmin, Fitbit, Oura y Withings, siempre que la persona haya permitido compartir a su aplicación de proveedor. Esta página proporciona la ruta de los datos, una tabla de mapeo que puede reutilizar, un ejemplo FHIR validado y el código que se ejecutó en la plataforma.

## La ruta de los datos

```
 watch, ring, scale ──► vendor app (Garmin Connect, Fitbit, Oura, Withings, Samsung Health…)
                              │  shares, with the person's permission
                              ▼
                 Apple Health (iOS)  /  Health Connect (Android)
                              │  your app reads, with the person's permission, on the phone
                              ▼
                 your app ──► your backend ──► FHIR R4 Observations in the person's record
```

Ni Apple Health ni Health Connect tienen una API de servidor: los datos solo pueden ser leídos por una aplicación en el teléfono de la persona. Tu aplicación los lee, envía valores diarios compactos a tu backend, y el backend los escribe en el registro.

## Qué dispositivos llegan a qué almacén de salud

Lo que cada proveedor comparte cambia con las versiones de la aplicación; la documentación propia del proveedor es la referencia.

| Dispositivo o aplicación | Apple Health (iOS) | Health Connect (Android) | Notas |
|---|---|---|---|
| Apple Watch | Sí, de forma nativa | — | Todo lo que mide el reloj llega a Apple Health |
| Samsung Galaxy Watch, Samsung Health | — | Parcialmente | Samsung Health decide qué tipos exporta y con qué frecuencia; consulte [Samsung Health](https://developers.anpheros.com/es/guides/samsung-health-fhir) |
| Pixel Watch, Fitbit | Sincronización no oficial | Sí, a través de la aplicación Fitbit ([Ayuda de Google](https://support.google.com/fitbit/answer/14506680)) | |
| Garmin | Sí, desde Garmin Connect después de cada sincronización del dispositivo | Sí, Garmin Connect es compatible con Health Connect en Android 14 y versiones posteriores ([Android Developers, agosto de 2025](https://developer.android.com/health-and-fitness/community/newsletters/2025/08)) | Las puntuaciones específicas de Garmin, como Body Battery, no se comparten |
| Oura | Sí | Sí ([Oura](https://ouraring.com/blog/data-sharing-partner-integrations/)) | Readiness y otras puntuaciones de Oura permanecen en la aplicación Oura |
| Withings | Sí, a través de Health Mate | Sí ([Blog de Android Developers](https://android-developers.googleblog.com/2023/03/withings-reduces-data-sync-code-with--health-and-fitness-api-health-connect.html)) | Básculas, tensiómetros, relojes |

Dos consecuencias prácticas. Primero, su aplicación depende de que la persona haya activado el uso compartido en su aplicación de proveedor; la incorporación debería indicarlo. Segundo, el almacén de salud puede contener los mismos pasos de dos fuentes (un teléfono y un reloj); lea los totales diarios del propio almacén en lugar de sumar muestras, porque Apple Health y Health Connect ya eliminan duplicados de fuentes superpuestas.

## Tabla de mapeo: tipo de almacén de salud → FHIR Observation

Los códigos que Anpheros Daily utiliza al escribir datos de wearables en un registro FHIR:

| Métrica | Apple HealthKit | Health Connect | LOINC | Unidad UCUM | Categoría |
|---|---|---|---|---|---|
| Frecuencia cardíaca | `heartRate` | `HeartRateRecord` | 8867-4 | `/min` | vital-signs |
| Frecuencia cardíaca en reposo | `restingHeartRate` | `RestingHeartRateRecord` | 40443-4 | `/min` | vital-signs |
| Variabilidad de la frecuencia cardíaca | `heartRateVariabilitySDNN` | `HeartRateVariabilityRmssdRecord` | 80404-7 (solo SDNN) | `ms` | vital-signs |
| Oxígeno en sangre (SpO₂) | `oxygenSaturation` | `OxygenSaturationRecord` | 59408-5 | `%` | vital-signs |
| Frecuencia respiratoria | `respiratoryRate` | `RespiratoryRateRecord` | 9279-1 | `/min` | vital-signs |
| Pasos por día | `stepCount` | `StepsRecord` | 41950-7 | `{steps}` | activity |
| Energía activa | `activeEnergyBurned` | `ActiveCaloriesBurnedRecord` | 41981-2 | `kcal` | activity |
| Duración del sueño | `sleepAnalysis` (categoría) | `SleepSessionRecord` | 93832-4; etapas 93831-6 profundo, 93830-8 ligero, 93829-0 REM | `min` | activity |
| Peso corporal | `bodyMass` | `WeightRecord` | 29463-7 | `kg` | vital-signs |
| Presión arterial | `bloodPressure` (correlación) | `BloodPressureRecord` | 85354-9 con 8480-6 y 8462-4 | `mm[Hg]` | vital-signs |
| Glucosa en sangre (medidor) | `bloodGlucose` | `BloodGlucoseRecord` | 2339-0 | `mg/dL` | vital-signs |
| Temperatura corporal | `bodyTemperature` | `BodyTemperatureRecord` | 8310-5 | `Cel` | vital-signs |

Observe la fila de variabilidad de la frecuencia cardíaca: Apple Health almacena **SDNN**, Health Connect almacena **RMSSD**. Son estadísticas diferentes y no deben registrarse bajo el mismo código. LOINC 80404-7 es SDNN; para RMSSD, Anpheros Daily utiliza su propio sistema de códigos en lugar de pretender que ambos son lo mismo.

## Resúmenes, no cada muestra

Un reloj produce miles de muestras de frecuencia cardíaca al día. Un registro médico necesita algo que una persona o un médico pueda leer:

- **Una Observation por métrica por día**, con `effectivePeriod` que cubran el día local de la persona, el promedio o total diario en `valueQuantity` y, para las tasas, el mínimo y el máximo como componentes.
- **Las series más finas permanecen donde son útiles.** Anpheros Daily mantiene resúmenes de frecuencia cardíaca de 4 horas para sus propios gráficos y escribe valores diarios en el registro FHIR.
- **Los eventos están separados.** Una notificación de ritmo irregular o una única lectura de presión arterial es su propia Observation con su propia hora, no parte de un promedio diario.

Un resumen diario de frecuencia cardíaca como FHIR R4 (pasa el validador [FHIR R4](https://developers.anpheros.com/tools/fhir-validator)):

```json
{
  "resourceType": "Observation",
  "status": "final",
  "identifier": [{"system": "https://your-app.test/fhir/sid/daily-wearable", "value": "p-123:2026-10-01:heart_rate"}],
  "category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "vital-signs"}]}],
  "code": {"coding": [{"system": "http://loinc.org", "code": "8867-4", "display": "Heart rate"}]},
  "subject": {"reference": "Patient/p-123"},
  "effectivePeriod": {"start": "2026-10-01T00:00:00-04:00", "end": "2026-10-02T00:00:00-04:00"},
  "valueQuantity": {"value": 71.4, "unit": "/min", "system": "http://unitsofmeasure.org", "code": "/min"},
  "component": [
    {"code": {"text": "minimum"}, "valueQuantity": {"value": 52, "unit": "/min", "system": "http://unitsofmeasure.org", "code": "/min"}},
    {"code": {"text": "maximum"}, "valueQuantity": {"value": 138, "unit": "/min", "system": "http://unitsofmeasure.org", "code": "/min"}}
  ],
  "device": {"display": "Apple Watch (via Apple Health)"}
}
```

## Escribir valores diarios sin duplicados

Los teléfonos se sincronizan varias veces al día, y el último valor de un día cambia hasta la medianoche. Asigne a cada Observation un identificador estable —persona, día, métrica— y actualícelo en lugar de crear uno nuevo. Con el SDK de TypeScript de Anpheros, en su backend:

```ts
import { Anpheros, apiKey } from '@anpheros/sdk';

const anpheros = new Anpheros({ auth: apiKey(process.env.ANPHEROS_KEY!) });

// What the phone sends: one value per metric per local day
type DailyValue = { metric: 'heart_rate' | 'steps'; day: string; value: number; min?: number; max?: number };

const CODES = {
  heart_rate: { code: '8867-4', display: 'Heart rate', unit: '/min', category: 'vital-signs' },
  steps: { code: '41950-7', display: 'Number of steps in 24 hour Measured', unit: '{steps}', category: 'activity' },
} as const;

// One Observation per person, metric and day: re-sending a day updates it instead of adding a copy.
async function upsertDaily(patientId: string, v: DailyValue, source: string) {
  const c = CODES[v.metric];
  const identifier = { system: 'https://your-app.test/fhir/sid/daily-wearable', value: `${patientId}:${v.day}:${v.metric}` };
  const resource: any = {
    resourceType: 'Observation', status: 'final',
    identifier: [identifier],
    category: [{ coding: [{ system: 'http://terminology.hl7.org/CodeSystem/observation-category', code: c.category }] }],
    code: { coding: [{ system: 'http://loinc.org', code: c.code, display: c.display }] },
    subject: { reference: `Patient/${patientId}` },
    effectivePeriod: { start: `${v.day}T00:00:00Z`, end: `${v.day}T23:59:59Z` },
    valueQuantity: { value: v.value, unit: c.unit, system: 'http://unitsofmeasure.org', code: c.unit },
  };
  if (v.min !== undefined && v.max !== undefined) {
    resource.component = [
      { code: { text: 'minimum' }, valueQuantity: { value: v.min, unit: c.unit, system: 'http://unitsofmeasure.org', code: c.unit } },
      { code: { text: 'maximum' }, valueQuantity: { value: v.max, unit: c.unit, system: 'http://unitsofmeasure.org', code: c.unit } },
    ];
  }
  const found = await anpheros.fhir.search('Observation', { identifier: `${identifier.system}|${identifier.value}` });
  const existing = found.entry?.[0]?.resource;
  return existing
    ? anpheros.fhir.update({ ...resource, id: existing.id }, { author_type: 'device' })
    : anpheros.fhir.create(resource, { author_type: 'device', source_system: source });
}
```

Ejecutar contra una instancia local de la plataforma con una clave de sandbox, dos valores diarios seguidos de una sincronización posterior de los pasos del mismo día dejó **dos** Observations, la de pasos en la versión 2 con el nuevo valor, y la procedencia `v1 device apple-health · v2 device`. El historial conserva el valor anterior, y cada lector puede ver que los datos provienen de un dispositivo, no de un clínico.

En producción, utilice los límites reales del día en la zona horaria de la persona (el ejemplo anterior utiliza UTC por brevedad), como lo hacen el código de HealthKit y Health Connect en las páginas de la plataforma.

## Lectura en el teléfono

- **iPhone y Apple Watch:** [Apple Health (HealthKit) a FHIR](https://developers.anpheros.com/es/guides/apple-health-fhir), con código Swift para estadísticas diarias.
- **Android, Wear OS, Fitbit, Garmin, Oura, Withings:** [Health Connect a FHIR](https://developers.anpheros.com/es/guides/health-connect-fhir), con código Flutter que funciona en ambas plataformas.
- **Samsung Galaxy Watch y Samsung Health:** [Samsung Health a FHIR](https://developers.anpheros.com/es/guides/samsung-health-fhir): lo que llega a Health Connect y lo que necesita el SDK propio de Samsung.

## Reglas que vale la pena seguir

- **Lea solo lo que usa** y solicite cada tipo por separado; las personas otorgan permisos parciales.
- **Etiquete la fuente.** Los wearables de consumo no son dispositivos de diagnóstico. Escriba sus datos como datos del dispositivo (`author_type: device`) y especifique de qué aplicación provienen, para que un médico pueda evaluarlos en consecuencia.
- **Respete las reglas de la plataforma.** Las Directrices de revisión de aplicaciones de Apple (5.1.3) prohíben el uso de datos de salud para publicidad y el almacenamiento de información personal de salud en iCloud; Google Play requiere una declaración de aplicaciones de salud para las aplicaciones que utilizan Health Connect.
- **Permita que las personas se desconecten** y decidan si los datos ya copiados permanecen en el registro.

## Lo que Anpheros hace y no hace

La Plataforma Anpheros no se conecta a Apple Health, Health Connect ni a ninguna nube de proveedor por sí sola: tu aplicación lee los datos en el teléfono y los escribe a través de la API. La propia aplicación de Anpheros, **Anpheros Daily**, hace exactamente eso: lee Apple Health en iPhone y Health Connect en Android, mantiene resúmenes diarios y los escribe en el registro FHIR de la persona con los códigos anteriores. La conexión de dispositivos es parte de sus planes Plus y Max.

## Preguntas frecuentes

### ¿Cómo obtengo datos del Apple Watch en un servidor FHIR?
Léalos en el iPhone desde Apple Health con HealthKit (no hay API de servidor), resúmalos por día y haga que su backend escriba cada métrica como una Observation con un código LOINC y una unidad UCUM, marcada como datos del dispositivo.

### ¿Existe una API en la nube para Health Connect o Apple Health?
No. Ambos mantienen los datos en el teléfono; una aplicación instalada en el teléfono los lee con el permiso de la persona. Las nubes de proveedores como Garmin, Fitbit u Oura tienen sus propias API, pero leer el almacén de salud del teléfono cubre la mayoría de ellas con una sola integración.

### ¿Qué código LOINC debo usar para los pasos?
41950-7, "Number of steps in 24 hour Measured", con un `effectivePeriod` diario. Para la frecuencia cardíaca use 8867-4, para SpO₂ 59408-5, para la duración del sueño 93832-4.

### ¿Debo almacenar cada muestra de frecuencia cardíaca en FHIR?
Generalmente no. Un resumen diario con promedio, mínimo y máximo es lo que una persona o un clínico lee; las lecturas individuales pertenecen al registro solo cuando importan por sí solas, como un evento de ritmo irregular.

### ¿Puedo usar un solo código para HRV de Apple Health y Health Connect?
No. Apple Health informa SDNN y Health Connect informa RMSSD; miden cosas diferentes y necesitan códigos diferentes.

## Relacionado

- [APIs de wearables: Fitbit, Garmin, Oura y Withings](https://developers.anpheros.com/es/guides/wearable-apis)
- [API de Health tracker](https://developers.anpheros.com/es/guides/health-tracker-api): almacenamiento de datos de tracker en un servidor, con consentimiento
- [Cómo crear una aplicación de registro de salud personal](https://developers.anpheros.com/es/guides/personal-health-record-app)
- [Integraciones de atención médica](https://developers.anpheros.com/es/guides/healthcare-integrations): dispositivos junto a laboratorios, clínicas y aplicaciones
- [Sistemas de códigos FHIR](https://developers.anpheros.com/es/guides/fhir-code-systems): LOINC y UCUM
- [Procedencia de datos médicos explicada](https://developers.anpheros.com/es/guides/medical-data-provenance)
- [Cómo normalizar datos médicos](https://developers.anpheros.com/es/guides/normalize-medical-data)
- [Monitorización remota de pacientes con FHIR](https://developers.anpheros.com/es/guides/remote-patient-monitoring-fhir): lecturas individuales, webhooks y alertas
