Guide

Apple Health in Excel

Excel can't read the Health app, and its export is one large XML file. With HealthAPI syncing your iPhone, one Power Query loads your last 4 weeks of steps, sleep, resting heart rate, HRV and workouts into a table, and refreshes it each time you open the workbook.

  • Excel for Windows
  • 4 requests a refresh
  • Updated 22 October 2026

HealthAPI: Free for 2 days, no card needed. Then an optional 7-day free trial when you subscribe.

Apple Health.xlsx
Refresh All Query: HealthAPI, refreshed when you open the file
ABCDEF
1DateStepsSleep (h)Resting heart rate (bpm)HRV (ms)Workouts
2Oct 167,3337.156580
3Oct 1710,8716.854691
4Oct 1811,2847.754681
5Oct 199,1207.955640
6Oct 2012,4086.954711
7Oct 218,0167.255620
8Oct 222,3107.053660
Refreshes when you open it
Excel for Windows

What you need

  • An iPhone on iOS 15 or later with Apple Health. Apple Watch data comes along too.
  • The HealthAPI app. Free for 2 days, no card needed. Then an optional 7-day free trial when you subscribe. The preview includes 25 requests a day. When the 2 days are up, AI apps and the API stop reading your data until you choose a plan in the app. Your synced data is kept for about 5 weeks, so subscribing picks up where you left off. Pro is $4.99 a month or $49.99 a year (100 requests a day); Developer is $9.99 a month or $99.99 a year (1,000 a day). Cancel anytime in the App Store.
  • Excel for Windows: Microsoft 365, or Excel 2016 or later.

Which Excel works

ExcelWorksWhy
Excel for WindowsYesPower Query's web source can send your key in a header and refresh on open or on a timer.
Excel for MacNoMicrosoft's list of Mac sources has no web source, so you can't build the query there, and a workbook made on Windows may not refresh on a Mac.
Excel for the webNoIt can't create a web query, and Microsoft documents only manual refresh there.

Sources per version are in Microsoft's Power Query data sources table. On a Mac or in a browser, use the Google Sheets guide instead: same columns, refreshed every morning by a free script.

Set it up in 6 steps

  1. Copy your API key

    Get HealthAPI from the App Store and let it sync. Then open Connect, tap Other tools and copy your key.
  2. Open a blank query

    In Excel for Windows, choose Data, then Get Data, From Other Sources, Blank Query. The Power Query Editor opens.
  3. Paste the query

    Select Advanced Editor on the Home tab, replace everything in it with the query below, put your key between the quotes on the Key line and select Done.
  4. Connect as Anonymous

    If Power Query asks how to connect to healthapi.app, choose Anonymous and select Connect. Your key already travels in the header the query sends. A preview of your days appears.
  5. Load it

    Give the query a name such as Health, then select Close & Load. The days land in a table on a new sheet.
  6. Make it refresh itself

    Choose Data, then Queries & Connections. Right-click the query, choose Properties, and on the Usage tab tick Refresh data when opening the file. Tick Refresh every too if you keep the workbook open all day.

The query

It asks the weekly summary for this week and the 3 before it, takes the line for each day, and leaves out days that haven't happened yet. Paste all of it into the Advanced Editor.

Advanced EditorPower Query M
let
    // Your HealthAPI key, from the app: Connect, then Other tools.
    // It is saved inside this workbook, so keep the file to yourself.
    Key = "PASTE_YOUR_KEY_HERE",
    // Weeks to show, this one included. Each refresh uses one request per week.
    Weeks = 4,

    Api = "https://healthapi.app/api/v1",
    Today = Date.From(DateTime.LocalNow()),

    // The ISO week a date falls in, such as "2026-W43".
    IsoWeek = (d as date) as text =>
        let
            Thursday = Date.AddDays(d, 3 - Date.DayOfWeek(d, Day.Monday)),
            WeekNo = Number.IntegerDivide(Date.DayOfYear(Thursday) - 1, 7) + 1
        in
            Text.From(Date.Year(Thursday)) & "-W" & Text.PadStart(Text.From(WeekNo), 2, "0"),

    // One week from HealthAPI: a record per day.
    GetWeek = (week as text) as list =>
        let
            Response = Web.Contents(Api, [
                RelativePath = "health/weekly-summary",
                Query = [week = week],
                Headers = [Authorization = "Bearer " & Key],
                ManualStatusHandling = {400, 402, 429}
            ]),
            Status = Value.Metadata(Response)[Response.Status],
            Body = Json.Document(Response)
        in
            if Status = 200 then Body[daily_breakdown]
            else error ("HealthAPI " & Text.From(Status) & ": " & Text.From(Body[detail]? ?? "")),

    Days = List.Combine(List.Transform({0 .. Weeks - 1}, each GetWeek(IsoWeek(Date.AddDays(Today, -7 * _))))),
    Rows = Table.FromRecords(List.Transform(Days, each [
        Date = Date.FromText([date]),
        Steps = [totals][steps],
        #"Sleep (h)" = [sleep_hours],
        #"Resting heart rate (bpm)" = [averages][resting_heart_rate_bpm],
        #"HRV (ms)" = [averages][hrv_ms],
        #"Active energy (kcal)" = [totals][active_energy_kcal],
        #"Exercise (min)" = [totals][exercise_time_min],
        Workouts = [workout_count],
        #"Workout time (min)" = [workout_duration_minutes]
    ])),
    UpToToday = Table.SelectRows(Rows, each [Date] <= Today),
    Sorted = Table.Sort(UpToToday, {{"Date", Order.Ascending}}),
    Typed = Table.TransformColumnTypes(Sorted, {
        {"Date", type date}, {"Steps", Int64.Type}, {"Sleep (h)", type number},
        {"Resting heart rate (bpm)", type number}, {"HRV (ms)", type number},
        {"Active energy (kcal)", type number}, {"Exercise (min)", type number},
        {"Workouts", Int64.Type}, {"Workout time (min)", type number}
    })
in
    Typed

Your key goes in the Authorization header, the same way as in every API example. Weeks sets how far back the table goes.

The columns

ColumnFrom the APINotes
Stepstotals.stepsiPhone and Apple Watch counted once, so it matches the Health app.
Sleep (h)sleep_hoursTime asleep in the night that ended that morning.
Resting heart rateaverages.resting_heart_rate_bpmBlank on days with no reading.
HRV (ms)averages.hrv_msSDNN in milliseconds, as Apple Watch records it.
Active energy, exercisetotals.active_energy_kcal, totals.exercise_time_minKilocalories and Exercise ring minutes.
Workouts, workout timeworkout_count, workout_duration_minutesWorkouts that started that day.

Today's row is the day so far. Days are in your HealthAPI account's timezone, the one your iPhone uses. The weekly summary has more per day, such as totals.distance_m and averages.spo2_pct; add a line to the Rows step to bring one in. Every field is in the API reference.

Refresh and requests

Both settings are on the Usage tab of the query's properties, as Microsoft describes in Refresh an external data connection. Refresh data when opening the file brings the table up to date each time you open it. Refresh every repeats it on a timer, only while the workbook is open in Excel.

Each refresh uses 4 requests. Refreshing every 60 minutes through a 10-hour day uses about 40, well inside Pro's 100. On the free preview's 25 a day, refresh on open only. HealthAPI has no push, so a refresh is how new data arrives: open the HealthAPI app first if you want last night's sleep in the table right away.

If something's wrong

You seeWhat to do
Power Query asks for credentials againHealthAPI turned the key down. Copy it again from the app and paste it on the Key line. Keep the credential as Anonymous (Data, Get Data, Data Source Settings).
HealthAPI 402Your free preview has ended or your plan has lapsed. Choose a plan in the HealthAPI app; your data is still there.
HealthAPI 429Today's requests are used up. They reset at 00:00 UTC.
Zeros on the last rowYour iPhone hasn't synced since then. Open HealthAPI on your iPhone, then refresh.

Questions

Can I export Apple Health straight to Excel?

Not as a spreadsheet. The Health app's export is a zip with one large XML file of every reading, which Excel isn't built to open at that size. With HealthAPI syncing your iPhone, the query on this page loads a tidy table with one row per day instead.

Does it work in Excel for Mac or Excel for the web?

Not as far as Microsoft documents. Neither lists Web among its Power Query sources, and Excel for the web describes only manual refresh. On a Mac or in a browser, the Google Sheets guide gets you the same table and refreshes on its own.

How many requests does it use?

One per week shown on each refresh, so 4 with the query as written. Pro allows 100 a day and the free preview 25, reset at 00:00 UTC. Editing the query also fetches again for the preview.

Is my key safe in the workbook?

It is saved in the query, and anyone who has the file can open the Advanced Editor and read it. Keep the workbook to yourself. Before you share a copy, delete the query or replace the key. If a copy got out, regenerate the key in the HealthAPI app.

Can I go back further than four weeks?

Yes. Change Weeks to the number you want, at one request per week on every refresh. For a long history, turn off Refresh every so the file only refreshes when you open it.

The HealthAPI app icon

Your Health data, in your workbook.

Get HealthAPI for iPhone, paste the query, and let Excel keep it current.