Skip to content
AF
Reference

HealthKit ↔ Health Connect: The Data-Type Reference

If you’re building the same health feature on iOS and Android, you need the matching type on each platform — and to know where they quietly disagree. Here are 10 common metrics side by side, checked against Apple’s and Google’s own docs.

Apple HealthKit and Android Health Connect type identifiers for ten common health metrics
MetricApple HealthKit (iOS)Health Connect (Android)
Heart rateHKQuantityTypeIdentifier.heartRate, .restingHeartRateHeartRateRecord, RestingHeartRateRecordWatch out: Both expose samples plus a separate resting value — don't derive resting yourself.
HRVHKQuantityTypeIdentifier.heartRateVariabilitySDNNHeartRateVariabilityRmssdRecordWatch out: 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.
VO2 maxHKQuantityTypeIdentifier.vo2MaxVo2MaxRecordWatch out: An estimate on both platforms, not a lab measurement. Health Connect tags a measurement method.
Blood oxygenHKQuantityTypeIdentifier.oxygenSaturationOxygenSaturationRecordWatch out: 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.
SleepHKCategoryTypeIdentifier.sleepAnalysis (values: inBed, awake, asleepCore, asleepDeep, asleepREM, asleepUnspecified)SleepSessionRecord (carries stages)Watch out: 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).
StepsHKQuantityTypeIdentifier.stepCount (CMPedometer for live counts)StepsRecord, StepsCadenceRecordWatch out: 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.
WorkoutsHKWorkout (HKWorkoutBuilder)ExerciseSessionRecord, PlannedExerciseSessionRecordWatch out: Activity-type taxonomies differ between platforms — map them explicitly rather than by name.
GPS routeHKWorkoutRoute (array of CLLocation), HKWorkoutRouteQueryExerciseRoute with ExerciseRoute.LocationWatch out: Health Connect gates routes behind their own permission (READ_EXERCISE_ROUTES) and restricts background reads of other apps' routes.
CaloriesHKQuantityTypeIdentifier.activeEnergyBurned, .basalEnergyBurnedActiveCaloriesBurnedRecord, TotalCaloriesBurnedRecordWatch out: Modelled estimates, not measurements. Note the asymmetry: Apple splits active/basal, Android offers active and total — don't add active to total.
Body compositionHKQuantityTypeIdentifier.bodyMass, .bodyFatPercentage, .leanBodyMass, .bodyMassIndexWeightRecord, BodyFatRecord, LeanBodyMassRecord, BoneMassRecord, BodyWaterMassRecord, BasalMetabolicRateRecordWatch out: The store holds it, but something has to write it — usually a smart scale or manual entry. Body fat is a bioimpedance estimate.

Apple HealthKit

  • On-device on iPhone and Apple Watch — there is no cloud or server endpoint to call.
  • Authorization is per data type, requested with requestAuthorization(toShare:read:).
  • Your app cannot tell whether a read permission was granted or denied — a denied read simply returns only the samples your own app wrote. Design for empty results.
  • Gate availability on HKHealthStore.isHealthDataAvailable().

Android Health Connect

  • On-device too — the client library talks to the Health Connect APK over IPC, not to a server.
  • Read windows are limited: Android 14+ allows 30 days of other apps' data (unlimited for your own); Android 13 and lower caps all reads at 30 days.
  • From the June 2026 update, on-device steps carry a device-specific Synthetic Package Name instead of the generic "android" origin. Filter for both to catch historical and new records.

Sources

Every row above was checked against Apple’s and Google’s own documentation as of 2026. Type identifiers change — confirm against the live docs before you build.

The HealthKit types above, in the full reference

Each links to its row on its HealthKit group page, where the aggregation, unit and iOS columns are read from Apple’s documentation.

Looking up one type rather than reading the table? The identifier translator finds the Health Connect record for a HealthKit identifier, or the reverse — verified pairs only, and where nothing was checked it says so.

Every record class in the Android column links to its page in the Health Connect record reference, with Google’s fields, permission strings and aggregate metrics for each.

The three things that actually bite

HRV is not one metric. Apple Watch records SDNN into HealthKit; Health Connect gives you RMSSD. They’re computed differently and don’t convert, so a single normalized “hrv” column in your database will silently mix two incompatible measures. iOS 27 adds a HealthKit RMSSD identifier, but as of October 2, 2026 Apple’s documentation does not say what it holds, so nothing yet says it closes the gap. Keep the platform and measure with the value — the HRV guide goes deeper.

Neither store has a server API. Both are on-device, so there’s no backend integration to write — your app reads locally and syncs. Teams routinely plan a server-to-server integration and discover this late.

Permission and presence are different problems. On iOS you cannot tell whether a read was denied or simply had no data. On Android, read windows are capped, routes need their own permission, and from the June 2026 update on-device steps carry a per-device synthetic package name you must resolve at runtime rather than hardcode.

Two more traps in the pairs

Do not add active calories to total calories. Apple splits active and basal; Health Connect offers active and total. Those are not the same split, and the rule for the Android pair is simply that you must not add active to total — the result is a plausible number that nothing will flag. Both figures are modelled estimates on both platforms, not measurements.

Do not hardcode the steps data source on Android. From the June 2026 update, on-device steps are attributed to a per-device Synthetic Package Name. Read it with getCurrentDeviceDataSource(). A literal package name in your de-duplication logic will work on the device you tested on and quietly stop filtering on everyone else’s — and de-duplication matters here, because a phone and a watch both write steps for the same walk.

Same metric, different shape

All ten metrics exist on both platforms, but when we compared the rows on September 1, 2026, several did not have the same shape. Body composition is a short list of Apple quantity identifiers against a longer set of Health Connect records, and bone mass and body water mass have no counterpart in the Apple column. In the other direction, Apple stores bodyMassIndex as a first-class type while Health Connect’s records include no BMI, so the same product either reads BMI or computes it, and the two will not agree. Decide whether BMI is stored or derived in your own model, apply that on both platforms, and discard the platform’s answer where it conflicts with yours.

Sleep differs in what a row is. Apple stores sleepAnalysis category samples, each an interval tagged with one value, and “last night” is something you assemble from many of them; Health Connect stores a SleepSessionRecord that is the night, with its stages inside. Pick one as your canonical row before you decide how a nap, or a night that crosses a timezone change, is handled. Routes differ in access rather than shape: Health Connect gates them behind their own permission, so a user can grant you workouts and still withhold the map, and your workout screen needs a state for a session with no route. Workout activity types do not map by name either; keep the mapping in a table you own and log the misses.

Where to go next

Setting one up? The HealthKit and Health Connect integration guides walk the wiring. Deciding between them — or whether you need both — is covered in HealthKit vs Health Connect and, if you’re adding a second platform, adding Android to a HealthKit app. For what each metric means and whether it’s measured or estimated, see health data by metric.

Why only these two platforms?

Because these are the rows we could verify. A reference table is only worth publishing if its cells are actually checked against primary sources, and every entry above comes from Apple’s or Google’s own documentation. We’d rather ship a narrow table you can trust than a wide one padded with guesses. For cloud providers, the per-metric guides and head-to-head comparisons cover what each one exposes.

Frequently asked questions

Can I map HealthKit HRV to Health Connect HRV?
Not directly. The heart-rate variability Apple Watch records into HealthKit is SDNN (HKQuantityTypeIdentifier.heartRateVariabilitySDNN), while Health Connect stores RMSSD (HeartRateVariabilityRmssdRecord). SDNN and RMSSD are different calculations over the interval series and are not interconvertible, so treating them as one normalized 'HRV' field will produce values that aren't comparable between your iOS and Android users. iOS 27 added HKQuantityTypeIdentifier.heartRateVariabilityRMSSD, but as of October 2, 2026 Apple's documentation does not describe it, so it is not a verified counterpart to Health Connect's record. Store the platform and the measure alongside the number.
Can I read HealthKit or Health Connect from my server?
No. Both are on-device stores, not cloud APIs — there is no server endpoint to call. Your app reads them on the device with the user's permission and syncs to your backend itself. If you need server-to-server access to user health data, you need a cloud provider API or a health-data aggregator instead.
Does a type existing mean the data will be there?
No, and this trips up a lot of integrations. These types are containers — something still has to write to them. Blood oxygen needs a device that measures SpO2, body composition usually needs a smart scale or manual entry, and on iOS a denied read permission is indistinguishable from an empty result, because HealthKit deliberately doesn't tell your app that read access was refused. Always design for the empty case.
Which Health Connect records match Apple's calorie types?
ActiveCaloriesBurnedRecord and TotalCaloriesBurnedRecord sit opposite Apple's activeEnergyBurned and basalEnergyBurned. The split is not the same on both sides, so map them explicitly and never add the active figure to the total figure. Both platforms are giving you modelled estimates rather than measurements.

A free reference from AIFitnessAPI. Independent and not sponsored — please cite or link if you find it useful.