Purpose

Compare the two major mobile health data platforms and document methods for extracting personal health data from each.

Overview

Both Android and iOS provide on-device health data storage with API access for developers. Neither platform offers cloud-based APIs - all data access must occur through native mobile apps on the user’s device.

Critical Clarification: Local API, Not HTTP API

These are NOT web/HTTP APIs. Health Connect and HealthKit are local operating system APIs that can only be accessed by native mobile apps running on the device. There is no REST endpoint, no cloud service, no way to call these from a server or web browser.

❌ Cannot do: curl https://healthconnect.googleapis.com/v1/steps
❌ Cannot do: fetch('https://api.apple.com/healthkit/data')
✅ Must do: Build native app → User grants permission → App reads local data

Why? Privacy. Your health data never leaves your device unless you explicitly use an app that sends it somewhere.


FAQ: Common Questions

Q1: As an engineer, do I need to build an app to extract data?

Yes. You must build a native mobile app:

PlatformRequired
AndroidKotlin/Java app using Health Connect SDK
iOSSwift/Objective-C app using HealthKit framework

There is no alternative. You cannot:

  • Query from a server or backend
  • Use a web app or browser extension
  • Run a Python/Node script on your computer to pull data
  • Use any HTTP/REST API

The only way to programmatically access this data is through a native app installed on the user’s phone.

Q2: As a normal user, is there an export/dump feature?

PlatformBuilt-in Export?Details
iOS✅ YesHealth app → Profile icon → Export All Health Data → Produces ZIP with XML
Android❌ NoNo built-in export. Must install a third-party app that uses Health Connect

iOS Export Details:

  • Exports everything: steps, heart rate, sleep, workouts, etc.
  • Format: XML files in a ZIP archive
  • Size: Can be several GB for long-time users
  • Location: Can AirDrop, save to Files, email, etc.

Android Workaround:

  • Install an app like “Health Connect Toolbox” or similar
  • The app reads your data via Health Connect API
  • The app provides its own export feature (JSON, CSV, etc.)

Q3: What is HKExportSession?

HKExportSession is an Apple API introduced in iOS 19 (2025) for programmatic bulk exports.

Before HKExportSession:

  • Apps had to query data type by type
  • No standardized export format
  • Manual export was the only bulk option

With HKExportSession:

  • Apps can trigger bulk exports programmatically
  • Exports up to 10GB of data as XML/JSON ZIP
  • Can be integrated with iOS Shortcuts
  • Still requires a native iOS app to use
// Example: Using HKExportSession (iOS 19+)
let exportSession = HKExportSession(healthStore: healthStore)
exportSession.exportData(to: destinationURL) { result in
// Handle exported ZIP file
}

Use cases:

  • Health apps offering “Download my data” feature
  • Backup utilities
  • Data portability tools

Q4: What is FHIR?

FHIR (Fast Healthcare Interoperability Resources) is a healthcare data standard - not an Apple or Google product.

What it is:

  • An international standard for exchanging healthcare data
  • Defines JSON/XML schemas for medical records
  • Created by HL7 (Health Level Seven International)
  • Used by hospitals, EHRs, insurance companies, health apps

Example FHIR resource (Patient):

{
"resourceType": "Patient",
"id": "example",
"name": [{"family": "Smith", "given": ["John"]}],
"birthDate": "1990-01-15",
"gender": "male"
}

FHIR resource types:

  • Patient, Practitioner, Organization
  • Condition (diagnoses), Medication, Allergy
  • Observation (lab results, vitals)
  • Immunization, Procedure

How it relates to Health Connect / HealthKit:

PlatformFHIR Support
Apple HealthKitHealth Records feature - imports FHIR data from 500+ hospitals/clinics
Android Health ConnectMedical Records API - reads/writes FHIR-formatted clinical data

Practical meaning: If you connect your health app to your hospital’s patient portal, your lab results and medications come in FHIR format and are stored in Health Connect / HealthKit.

Q5: Can I build an app that syncs users’ health data to my server?

Yes, this is a common and supported use case.

Architecture:

┌─────────────────────────────────────────────────────────────┐
│ User's Phone │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Fitbit App │ ──▶ │ Health │ ◀── │ Apple Watch │ │
│ │ Garmin App │ │ Connect / │ │ Sensors │ │
│ │ MyFitnessPal│ │ HealthKit │ │ │ │
│ └─────────────┘ └──────┬──────┘ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Your App │ │
│ │ (Native iOS or │ │
│ │ Android) │ │
│ └────────┬────────┘ │
└──────────────────────────────┼──────────────────────────────┘
│ HTTPS
┌─────────────────┐
│ Your Server │
│ (REST API) │
└────────┬────────┘
┌─────────────────┐
│ Your Database │
│ (PostgreSQL, │
│ MongoDB, etc) │
└─────────────────┘

What you need to build:

  1. Native mobile app (or cross-platform with React Native/Flutter)

    • Requests health data permissions from user
    • Reads data from Health Connect / HealthKit
    • Sends data to your backend via HTTPS
  2. Backend API

    • Receives health data from mobile app
    • Stores in your database
    • Handles authentication, rate limiting, etc.

Example sync flow (Android):

// In your Android app
suspend fun syncHealthData() {
val steps = healthConnectClient.readRecords(
ReadRecordsRequest(StepsRecord::class, timeRangeFilter = lastSync..now)
)
// Send to your server
yourApi.postHealthData(
userId = currentUser.id,
data = steps.records.map { it.toJson() }
)
}

Existing services that do this for you:

  • Thryve - aggregates Health Connect + HealthKit, provides unified API
  • Human API - similar aggregation service
  • Health Auto Export (iOS) - user-facing app that syncs to REST endpoints
  • Vital - health data API platform

Privacy/compliance considerations:

  • Health data is sensitive - ensure HIPAA compliance if in US
  • Get explicit user consent
  • Encrypt data in transit (HTTPS) and at rest
  • Provide data deletion capability
  • Consider GDPR if serving EU users

AspectAndroid Health ConnectApple HealthKit
PlatformAndroid 9+ (SDK 28)iOS 8+
Framework LocationAndroid Framework (14+) / JetpackiOS SDK
Data StorageOn-device, encryptedOn-device, encrypted
Cloud APINoneNone
Current VersionJetpack 1.1.0 (Jan 2026)iOS 19+
ReplacesGoogle Fit APIs (deprecated 2026)N/A (original platform)

Android Health Connect

What is Health Connect?

Health Connect is Android’s unified platform for health and fitness data management. It serves as a centralized hub where multiple health apps can read and write data with user permission. Starting in 2026, it replaces the deprecated Google Fit APIs.

Key Features

  • 50+ data types: Steps, heart rate, sleep, nutrition, body measurements, vitals
  • Medical records: FHIR format support for clinical data
  • Background sync: Continuous data access even when app isn’t active
  • On-device steps: Android 14+ automatically captures mobile steps
  • User control: Granular permissions, data deletion, access revocation

Supported Data Types

Activity & Fitness:

  • Steps (cumulative over time)
  • Exercise sessions and routes (GPS)
  • Distance, calories, power, speed

Body Measurements:

  • Weight, height, body fat
  • Basal metabolic rate

Vitals:

  • Heart rate, blood pressure
  • Blood glucose, oxygen saturation
  • Body temperature

Sleep & Wellness:

  • Sleep sessions and stages
  • Mindfulness sessions

Nutrition:

  • Meals, hydration
  • Macro/micronutrients

Medical Records (FHIR):

  • Allergies, conditions, medications
  • Immunizations, lab results

API Access

Setup

// Add dependency
implementation("androidx.health.connect:connect-client:1.1.0")
// Check availability
val availabilityStatus = HealthConnectClient.getSdkStatus(context)
if (availabilityStatus == HealthConnectClient.SDK_AVAILABLE) {
val healthConnectClient = HealthConnectClient.getOrCreate(context)
}

Request Permissions

val PERMISSIONS = setOf(
HealthPermission.getReadPermission(StepsRecord::class),
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getReadPermission(SleepSessionRecord::class)
)
// Request via ActivityResultContract
val requestPermissionLauncher = registerForActivityResult(
PermissionController.createRequestPermissionResultContract()
) { granted ->
// Handle permission result
}
requestPermissionLauncher.launch(PERMISSIONS)

Read Data

// Read raw records
suspend fun readSteps(
client: HealthConnectClient,
start: Instant,
end: Instant
): List<StepsRecord> {
val response = client.readRecords(
ReadRecordsRequest(
StepsRecord::class,
timeRangeFilter = TimeRangeFilter.between(start, end)
)
)
return response.records
}
// Read aggregated data (recommended for cumulative types)
suspend fun readTotalSteps(
client: HealthConnectClient,
start: Instant,
end: Instant
): Long? {
val response = client.aggregate(
AggregateRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(start, end)
)
)
return response[StepsRecord.COUNT_TOTAL]
}

Historical Data Access

By default, apps can only read 30 days of data. To access older data:

// Request history permission
val HISTORY_PERMISSION = HealthPermission.PERMISSION_READ_HEALTH_DATA_HISTORY
// Then read with data origin filter
val response = client.readRecords(
ReadRecordsRequest(
recordType = HeartRateRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
dataOriginFilter = setOf(DataOrigin("com.example.app"))
)
)

Pagination

var pageToken: String? = null
val allRecords = mutableListOf<HeartRateRecord>()
do {
val response = client.readRecords(
ReadRecordsRequest(
recordType = HeartRateRecord::class,
timeRangeFilter = TimeRangeFilter.between(start, end),
pageToken = pageToken
)
)
allRecords.addAll(response.records)
pageToken = response.pageToken
} while (pageToken != null)

Data Export Methods

  1. Build Android app: Full programmatic access via Health Connect SDK
  2. Third-party apps: Apps like Thryve provide Health Connect integration
  3. No manual export: Unlike Apple Health, no built-in export feature in Settings

Apple HealthKit

What is HealthKit?

HealthKit is Apple’s framework for health and fitness data on iOS and watchOS. Introduced in iOS 8, it provides a centralized, secure repository for health data that apps can access with user permission.

Key Features

  • 150+ data types: Comprehensive health metrics
  • Health Records: FHIR-based medical records from 500+ hospitals
  • Workout routes: GPS tracking for exercises
  • On-device storage: All data encrypted with device passcode
  • Manual export: Built-in XML export feature
  • HKExportSession (iOS 19+): Bulk exports up to 10GB

Supported Data Types

Activity:

  • Steps, distance, flights climbed
  • Workouts with routes
  • Stand hours, exercise minutes

Body Measurements:

  • Weight, height, BMI
  • Body fat percentage, lean body mass

Vitals:

  • Heart rate, HRV, resting heart rate
  • Blood pressure, respiratory rate
  • Blood oxygen, body temperature

Sleep:

  • Sleep analysis
  • Time in bed

Nutrition:

  • Dietary energy, water
  • Macronutrients, vitamins, minerals

Reproductive Health:

  • Menstrual cycle tracking
  • Ovulation, fertility

Medical Records (FHIR):

  • Allergies, conditions, immunizations
  • Lab results, medications, procedures, vitals

API Access

Setup

import HealthKit
let healthStore = HKHealthStore()
// Check availability
if HKHealthStore.isHealthDataAvailable() {
// HealthKit is available
}

Request Authorization

let readTypes: Set<HKObjectType> = [
HKObjectType.quantityType(forIdentifier: .stepCount)!,
HKObjectType.quantityType(forIdentifier: .heartRate)!,
HKObjectType.categoryType(forIdentifier: .sleepAnalysis)!
]
healthStore.requestAuthorization(toShare: nil, read: readTypes) { success, error in
if success {
// Authorization granted
}
}

Query Data

// Sample query for steps
func readSteps(from start: Date, to end: Date, completion: @escaping ([HKQuantitySample]) -> Void) {
let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
let predicate = HKQuery.predicateForSamples(withStart: start, end: end)
let query = HKSampleQuery(
sampleType: stepType,
predicate: predicate,
limit: HKObjectQueryNoLimit,
sortDescriptors: [NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: true)]
) { query, samples, error in
guard let samples = samples as? [HKQuantitySample] else { return }
completion(samples)
}
healthStore.execute(query)
}
// Statistics query for aggregated data
func readTotalSteps(from start: Date, to end: Date, completion: @escaping (Double?) -> Void) {
let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
let predicate = HKQuery.predicateForSamples(withStart: start, end: end)
let query = HKStatisticsQuery(
quantityType: stepType,
quantitySamplePredicate: predicate,
options: .cumulativeSum
) { query, statistics, error in
let sum = statistics?.sumQuantity()?.doubleValue(for: .count())
completion(sum)
}
healthStore.execute(query)
}

Background Delivery

// Enable background delivery for a data type
healthStore.enableBackgroundDelivery(
for: HKObjectType.quantityType(forIdentifier: .heartRate)!,
frequency: .immediate
) { success, error in
// Handle result
}

Data Export Methods

1. Manual Export (Built-in)

  1. Open Health app on iPhone
  2. Tap profile picture → Export All Health Data
  3. Produces export.zip containing XML files
  4. Can be up to 10GB for long-time users

2. Build iOS App

Full programmatic access via HealthKit SDK (see code examples above)

3. Third-Party Apps

Health Auto Export (recommended for non-developers):

  • Exports 150+ metrics
  • Syncs to REST API, CSV, JSON
  • Supports automations via Shortcuts
  • TCP server for direct device access

Limitations:

  • Automations don’t run while device is locked
  • iOS restricts background execution

4. Python Parsing (Post-Export)

After manual export, use apple-health-parser:

from apple_health_parser import HealthData
# Load exported data
health_data = HealthData("path/to/export.xml")
# Access specific metrics
steps = health_data.get_record_type("StepCount")
heart_rate = health_data.get_record_type("HeartRate")
# Convert to DataFrame for analysis
df = steps.to_dataframe()

Comparison Summary

Data Access

FeatureHealth ConnectHealthKit
Historical data30 days default, unlimited with permissionUnlimited
Background syncYes (with permission)Yes (with background delivery)
AggregationBuilt-in aggregate() APIStatistics queries
PaginationpageToken-basedAnchor queries
Real-time updatesChange notificationsObserver queries

Export Options

MethodHealth ConnectHealthKit
Manual export UINoYes (XML)
Programmatic exportYes (build app)Yes (build app)
Third-party appsLimitedHealth Auto Export, others
Export formatJSON (programmatic)XML (manual), any (programmatic)

Development

AspectHealth ConnectHealthKit
LanguageKotlin/JavaSwift/Objective-C
Min SDKAndroid 9 (API 28)iOS 8
FrameworkJetpack libraryiOS SDK built-in
Testing toolsHealth Connect ToolboxXcode Health simulator

Recommendations

For Personal Data Extraction

If you use Android:

  1. Use a third-party app with Health Connect integration
  2. Or build a simple Android app to export your data

If you use iOS:

  1. Easiest: Manual export from Health app (Settings → Export)
  2. Automated: Use Health Auto Export app
  3. Custom: Build iOS app with HealthKit

For Developers Building Health Apps

  • Support both platforms for maximum reach
  • Use standardized formats (FHIR) for medical data
  • Implement proper permission flows - users are sensitive about health data
  • Consider using aggregation services like Thryve or Human API for cross-platform support

Sources