Apple Health Export to CSV
Load export.xml, choose one metric and a date range, and download a clean CSV. Raw rows or a daily summary. Runs in your browser.
Preview
Runs entirely in your browser. The export is never sent anywhere and is discarded when you close the tab.
How this works
Apple Health exports as a single XML file called export.xml. Every measurement is a Record element with a type identifier, a start and end time, a value, a unit, and the device that wrote it. Workouts are separate Workout elements. The file is flat, one element per line, which is why it can be streamed instead of loaded into memory all at once.
The page makes two passes. The first pass reads the file line by line, counts records per type, and tracks the earliest and latest start date. That produces the metric list and the default date range. The second pass runs only after you click Build CSV, and it extracts only records whose type matches your choice and whose start date falls inside the range. Nothing is stored between passes.
This is the part that general converters skip. A whole-export CSV mixes steps, heart rate, sleep, and hundreds of other types into one table, which is unusable for a chart or a pivot table. Choosing one metric first produces a table with one consistent unit and one value column. The date range keeps the download small enough to open in Excel.
Sleep is handled differently from the quantity types. Apple stores it as a category, so the value is a label such as HKCategoryValueSleepAnalysisAsleepCore or HKCategoryValueSleepAnalysisInBed. The useful number is the duration, calculated from the start and end timestamps. Daily aggregation is disabled for sleep because the stages are already intervals, and summing them would double count.
Common metrics and what the CSV contains
| Metric | Type identifier | Unit | Best rows setting |
|---|---|---|---|
| Steps | HKQuantityTypeIdentifierStepCount | count | Daily total |
| Heart rate | HKQuantityTypeIdentifierHeartRate | count/min | Raw or daily average |
| Resting heart rate | HKQuantityTypeIdentifierRestingHeartRate | count/min | Daily average |
| HRV (SDNN) | HKQuantityTypeIdentifierHeartRateVariabilitySDNN | ms | Daily average |
| Distance walking or running | HKQuantityTypeIdentifierDistanceWalkingRunning | km or mi | Daily total |
| Active energy | HKQuantityTypeIdentifierActiveEnergyBurned | kcal | Daily total |
| Resting energy | HKQuantityTypeIdentifierBasalEnergyBurned | kcal | Daily total |
| Weight | HKQuantityTypeIdentifierBodyMass | kg or lb | Raw |
| Oxygen saturation | HKQuantityTypeIdentifierOxygenSaturation | % | Raw |
| Respiratory rate | HKQuantityTypeIdentifierRespiratoryRate | count/min | Daily average |
| VO2 max | HKQuantityTypeIdentifierVO2Max | mL/kg/min | Raw |
| Exercise minutes | HKQuantityTypeIdentifierAppleExerciseTime | min | Daily total |
| Flights climbed | HKQuantityTypeIdentifierFlightsClimbed | count | Daily total |
| Sleep analysis | HKCategoryTypeIdentifierSleepAnalysis | category | Raw |
The metric list is built from your file, so a type that is not in the table above still appears with its raw identifier and a count. Units are whatever Apple wrote in each record, usually the unit set in the Health app, so a US phone may write miles and pounds where a UK phone writes kilometres and stone.
When you would use this
You want to chart your sleep stages over the last six months and the full export is too large to open. Choosing Sleep analysis and a date range produces one table of intervals that a spreadsheet can chart directly.
You are preparing a heart rate or HRV table for a coach or a clinician. They need one metric with consistent dates and units, not a mixed export with every category Apple tracks.
You want steps per day for a year. Raw step samples are dozens per day and meaningless in a chart. Daily total collapses them into 365 rows with one number each.
You are building a personal dataset for a script and need to know which type identifiers your phone actually writes. The scan shows every type found with a count before you export anything.
You switched phones and want to compare a metric across two exports. Run each file separately with the same metric and date range, then join the two CSVs on the date column.
What this does and does not handle
It handles:
- Streaming a large
export.xmlwithout loading the whole DOM. - Discovery of every record type in the file, with counts and date bounds.
- Filtering by metric and by start-date range.
- Raw rows, daily total, and daily average.
- Duration in seconds for interval records such as sleep.
- Workout elements with activity type, duration, energy, and distance.
- UTF-8 CSV with a byte order mark for Excel.
It does not handle:
- Parsing the ZIP that Apple wraps around the XML. Unzip it first, then load
export.xml. - Workout route points, splits, or child events. Only the attributes on the Workout element are exported.
- Correlation records such as blood pressure pairs. They appear as their own type but their child records are not merged.
- Clinical records from Health Records. Those use a different element and are not read.
- Unit conversion. The value and unit are exported as Apple wrote them.
- Deduplication across sources. If an iPhone and a watch both recorded steps, both records appear. Daily total sums both, which double counts overlapping sources.
- Files that are not XML. The page checks the first line and reports a clear error.
Questions
How do I convert Apple Health export.xml to CSV for one metric?
Load export.xml, pick a metric from the list the tool discovers, choose a date range, and click Build CSV. The download contains only that metric, not the entire export. The file is read in your browser and never uploaded.
How do I get my sleep data out of Apple Health as a CSV?
Export all health data from the Health app, then load export.xml here and choose Sleep analysis. The CSV has one row per sleep sample with the start and end time, the stage value such as AsleepCore or InBed, the source device, and a duration in seconds. Daily aggregation is turned off for sleep because the stages are already intervals.
How do I export heart rate from Apple Health to CSV?
Choose Heart rate in the metric list. The CSV has one row per reading with startDate, endDate, value in counts per minute, and the source device. If you want one row per day instead, choose Daily average, which averages all readings for that day.
How do I export steps per day as a CSV?
Choose Steps and set aggregation to Daily total. Apple records step count as many small samples through the day, so raw rows are noisy. Daily total sums each day into one row with a date and a step count, which is the shape a spreadsheet or chart expects.
Can I filter by date range before exporting?
Yes. After the file is scanned, the earliest and latest dates are filled in automatically. Change either date to narrow the range. Only records whose start date falls inside the range are written to the CSV, which keeps the download small and avoids loading years of data you do not need.
Does it handle the 2 GB export.xml file?
It streams the file line by line instead of parsing it into a DOM, so memory use stays low. A multi-gigabyte export can still take a minute to scan on a slow device, but it does not fail the way a DOM parser does. The first pass counts records and dates. The second pass extracts only the metric you chose.
What metrics does it recognise?
It discovers whatever types are in your file and labels the common ones, including steps, heart rate, resting heart rate, HRV, distance, active and resting energy, weight, oxygen saturation, respiratory rate, VO2 max, exercise minutes, flights climbed, and sleep analysis. Unknown types appear with their raw identifier so nothing is hidden.
What is the difference between raw rows and daily summary?
Raw rows keep every record exactly as Apple stored it, which is right for sleep stages, workouts, and anything where the time of day matters. Daily total sums numeric values per day, which is right for steps, distance, and energy. Daily average averages numeric values per day, which is right for heart rate and weight.
Why is my sleep value text instead of a number?
Apple stores sleep as a category, not a quantity. The value is a label such as HKCategoryValueSleepAnalysisAsleepCore or HKCategoryValueSleepAnalysisInBed. The useful number is the duration, which the CSV calculates from the start and end timestamps in seconds.
Is my health data uploaded?
No. The file is read with the browser File API and streamed with TextDecoderStream. There is no network request during scanning, preview, or export. You can confirm this by switching the browser to offline mode after the page loads and running an export.
Can I export workouts as well as records?
Yes, if the export contains Workout elements. A Workouts option appears in the metric list with columns for activity type, start and end time, duration, energy burned, and distance. Workout child elements are not expanded, so splits and route points are not included.
Why are some records missing from the CSV?
Check the date range first. Then check the metric. A record whose type differs by a suffix is a different metric, for example Apple Exercise Time against Exercise Minutes. The metric list shows every type found with a count, so you can see whether the data is under a name you did not expect.
What columns are in the CSV?
Raw export columns are type, sourceName, unit, startDate, endDate, duration_seconds, and value. Daily summary columns are date, type, unit, value, and records, where records is the number of samples that went into that day. The file is UTF-8 with a byte order mark so Excel opens it correctly.
How is this different from applehealthdata.com?
applehealthdata.com converts the whole export to CSV, JSON, or Excel and lets you choose the output format. This page is built around one metric at a time and a date range, with raw and daily modes. It is the tool you want when you need a clean sleep or heart rate table, not a copy of every record in the file.