{
  "apiVersion": "v1",
  "self": "https://aifitnessapi.com/api/v1/matrix",
  "title": "HealthKit to Health Connect type matrix",
  "description": "One row per common health metric: the Apple HealthKit type identifier, the Android Health Connect record type, and the cross-platform gotcha where one exists. Narrow on purpose: only cells verified against both vendors' documentation.",
  "source": "https://aifitnessapi.com/matrix",
  "verified": {
    "date": "2026-07-26",
    "meaning": "The review date of https://aifitnessapi.com/matrix, the page that carries these rows and their sources."
  },
  "license": "CC-BY-4.0",
  "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
  "attribution": "aifitnessapi.com",
  "citeAs": "AIFitnessAPI, \"Health Data Type Matrix 2026 (HealthKit ↔ Health Connect),\" version 2026.1, aifitnessapi.com, https://aifitnessapi.com/datasets/health-data-type-matrix-2026.json",
  "dataset": {
    "slug": "health-data-type-matrix-2026",
    "name": "Health Data Type Matrix 2026 (HealthKit ↔ Health Connect)",
    "version": "2026.1",
    "json": "https://aifitnessapi.com/datasets/health-data-type-matrix-2026.json",
    "csv": "https://aifitnessapi.com/datasets/health-data-type-matrix-2026.csv"
  },
  "methodology": "One row per common health metric, pairing Apple's HealthKit type identifier with Android Health Connect's record type. Every identifier was confirmed against Apple's and Google's own developer documentation (HKQuantityTypeIdentifier, HKCategoryTypeIdentifier, and the Health Connect data-types guide) before publication; the full source list and the platform-level notes are on https://aifitnessapi.com/matrix. Scope is deliberately narrow — only the two on-device platform stores, because those are the cells we could verify. watchOut is null where the module records no cross-platform gotcha; it is never a guess.",
  "key": "id",
  "itemUrl": "https://aifitnessapi.com/api/v1/matrix/{id}",
  "count": 10,
  "excluded": [],
  "fields": {
    "id": "Stable metric slug used across aifitnessapi.com",
    "label": "Human-readable metric name",
    "appleHealthKit": "Apple HealthKit type identifier(s) for this metric",
    "androidHealthConnect": "Android Health Connect record type(s) for this metric",
    "watchOut": "The cross-platform gotcha, where one exists (null = none recorded)",
    "source": "aifitnessapi.com page carrying the verified claims for this metric"
  },
  "items": [
    {
      "id": "heart-rate",
      "label": "Heart rate",
      "appleHealthKit": "HKQuantityTypeIdentifier.heartRate, .restingHeartRate",
      "androidHealthConnect": "HeartRateRecord, RestingHeartRateRecord",
      "watchOut": "Both expose samples plus a separate resting value — don't derive resting yourself.",
      "source": "https://aifitnessapi.com/data/heart-rate-api"
    },
    {
      "id": "hrv",
      "label": "HRV",
      "appleHealthKit": "HKQuantityTypeIdentifier.heartRateVariabilitySDNN",
      "androidHealthConnect": "HeartRateVariabilityRmssdRecord",
      "watchOut": "The big one: the HRV Apple Watch records into HealthKit is SDNN, while Health Connect's record is RMSSD. They are different measures and are not interconvertible — do not normalize one into the other. iOS 27 added HKQuantityTypeIdentifier.heartRateVariabilityRMSSD, but as of October 2, 2026 Apple's documentation gives it no description, so it is not paired with Health Connect's record here: what it holds, how it is computed and whether Apple Watch writes it are not stated.",
      "source": "https://aifitnessapi.com/data/hrv-api"
    },
    {
      "id": "vo2-max",
      "label": "VO2 max",
      "appleHealthKit": "HKQuantityTypeIdentifier.vo2Max",
      "androidHealthConnect": "Vo2MaxRecord",
      "watchOut": "An estimate on both platforms, not a lab measurement. Health Connect tags a measurement method.",
      "source": "https://aifitnessapi.com/data/vo2-max-api"
    },
    {
      "id": "blood-oxygen",
      "label": "Blood oxygen",
      "appleHealthKit": "HKQuantityTypeIdentifier.oxygenSaturation",
      "androidHealthConnect": "OxygenSaturationRecord",
      "watchOut": "The type existing doesn't mean data exists — SpO2 is device-gated, and Apple Watch availability in the US has been subject to litigation. Verify current status.",
      "source": "https://aifitnessapi.com/data/blood-oxygen-api"
    },
    {
      "id": "sleep",
      "label": "Sleep",
      "appleHealthKit": "HKCategoryTypeIdentifier.sleepAnalysis (values: inBed, awake, asleepCore, asleepDeep, asleepREM, asleepUnspecified)",
      "androidHealthConnect": "SleepSessionRecord (carries stages)",
      "watchOut": "Stage vocabularies differ and stages are estimated, not measured. Apple deprecated .asleep in iOS 16.0 and points to .asleepCore, .asleepDeep, .asleepREM or .asleepUnspecified instead (.asleepUnspecified is the rename).",
      "source": "https://aifitnessapi.com/data/sleep-tracking-api"
    },
    {
      "id": "steps",
      "label": "Steps",
      "appleHealthKit": "HKQuantityTypeIdentifier.stepCount (CMPedometer for live counts)",
      "androidHealthConnect": "StepsRecord, StepsCadenceRecord",
      "watchOut": "De-duplicate: phone and watch both write steps. On Android, from the June 2026 update on-device steps are attributed to a per-device Synthetic Package Name — read it via getCurrentDeviceDataSource(), never hardcode it.",
      "source": "https://aifitnessapi.com/data/step-counting-api"
    },
    {
      "id": "workouts",
      "label": "Workouts",
      "appleHealthKit": "HKWorkout (HKWorkoutBuilder)",
      "androidHealthConnect": "ExerciseSessionRecord, PlannedExerciseSessionRecord",
      "watchOut": "Activity-type taxonomies differ between platforms — map them explicitly rather than by name.",
      "source": "https://aifitnessapi.com/data/workout-detection-api"
    },
    {
      "id": "gps-route",
      "label": "GPS route",
      "appleHealthKit": "HKWorkoutRoute (array of CLLocation), HKWorkoutRouteQuery",
      "androidHealthConnect": "ExerciseRoute with ExerciseRoute.Location",
      "watchOut": "Health Connect gates routes behind their own permission (READ_EXERCISE_ROUTES) and restricts background reads of other apps' routes.",
      "source": "https://aifitnessapi.com/data/gps-activity-api"
    },
    {
      "id": "calories",
      "label": "Calories",
      "appleHealthKit": "HKQuantityTypeIdentifier.activeEnergyBurned, .basalEnergyBurned",
      "androidHealthConnect": "ActiveCaloriesBurnedRecord, TotalCaloriesBurnedRecord",
      "watchOut": "Modelled estimates, not measurements. Note the asymmetry: Apple splits active/basal, Android offers active and total — don't add active to total.",
      "source": "https://aifitnessapi.com/data/calorie-tracking-api"
    },
    {
      "id": "body-composition",
      "label": "Body composition",
      "appleHealthKit": "HKQuantityTypeIdentifier.bodyMass, .bodyFatPercentage, .leanBodyMass, .bodyMassIndex",
      "androidHealthConnect": "WeightRecord, BodyFatRecord, LeanBodyMassRecord, BoneMassRecord, BodyWaterMassRecord, BasalMetabolicRateRecord",
      "watchOut": "The store holds it, but something has to write it — usually a smart scale or manual entry. Body fat is a bioimpedance estimate.",
      "source": "https://aifitnessapi.com/data/body-composition-api"
    }
  ]
}