[SOLVED] HRV tracking via Garmin Body Battery

I realize this request has been made before by others but I’d like to make it again - I find the Garmin “Body Battery” HRV score to be an extremely useful piece of data for quantifying fatigue in my training. For example, prolonged periods of low Body Battery seem to be the best indicator of overtraining for me (compared to using RHR or a Form score).

I would greatly appreciate if this field could be added so I can chart it on the Fitness page. I believe the data should be available from the API: Health API | Garmin Connect Developer Program | Garmin Developers

Thanks!

1 Like

I haven’t managed to figure out how to get that. The only mention of body battery in the Health API docs is for “timeOffsetBodyBatteryValues” in stress. Here is a sample payload. I am not sure how to get a “body battery number”.

{
  "stressDetails": [
    {
      "userId": "x",
      "userAccessToken": "x",
      "summaryId": "x36eb393-643cc440-d458",
      "startTimeInSeconds": 1681704000,
      "startTimeOffsetInSeconds": -14400,
      "durationInSeconds": 54360,
      "calendarDate": "2023-04-17",
      "timeOffsetStressLevelValues": {
      },
      "timeOffsetBodyBatteryValues": {
        "0": 39,
        "180": 39,
        "360": 39,
        "540": 39,
        "720": 38,
        "900": 38,
        "1080": 38,
        "1260": 38,
        "1440": 38,
        "1620": 38,
        "1800": 38,
        "1980": 37,
        "2160": 37,
        "2340": 37,
        "2520": 37,
        "2700": 38,
        "2880": 39,
        "3060": 39,
        "3240": 39,
        "3420": 39,
        "3600": 40,
        "3780": 40,
        "3960": 40,
        "4140": 40,
        "4320": 41,
        "4500": 41,
        "4680": 42,
        "4860": 42,
        "5040": 42,
        "5220": 42,
        "5400": 42,
        "5580": 44,
        "5760": 44,
        "5940": 44,
        "6120": 44,
        "6300": 45,
        "6480": 45,
        "6660": 46,
        "6840": 46,
        "7020": 47,
        "7200": 47,
        "7380": 48,
        "7560": 49,
        "7740": 49,
        "7920": 50,
        "8100": 50,
        "8280": 51,
        "8460": 52,
        "8640": 53,
        "8820": 53,
        "9000": 54,
        "9180": 55,
        "9360": 56,
        "9540": 56,
        "9720": 57,
        "9900": 58,
        "10080": 59,
        "10260": 59,
        "10440": 60,
        "10620": 61,
        "10800": 61,
        "10980": 62,
        "11160": 63,
        "11340": 63,
        "11520": 63,
        "11700": 64,
        "11880": 64,
        "12060": 65,
        "12240": 66,
        "12420": 66,
        "12600": 66,
        "12780": 67,
        "12960": 67,
        "13140": 68,
        "13320": 68,
        "13500": 69,
        "13680": 69,
        "13860": 70,
        "14040": 70,
        "14220": 70,
        "14400": 70,
        "14580": 71,
        "14760": 72,
        "14940": 72,
        "15120": 72,
        "15300": 72,
        "15480": 73,
        "15660": 73,
        "15840": 74,
        "16020": 74,
        "16200": 75,
        "16380": 75,
        "16560": 76,
        "16740": 76,
        "16920": 76,
        "17100": 77,
        "17280": 78,
        "17460": 78,
        "17640": 78,
        "17820": 78,
        "18000": 78,
        "18180": 78,
        "18360": 79,
        "18540": 79,
        "18720": 80,
        "18900": 80,
        "19080": 80,
        "19260": 80,
        "19440": 81,
        "19620": 81,
        "19800": 81,
        "19980": 82,
        "20160": 82,
        "20340": 82,
        "20520": 82,
        "20700": 82,
        "20880": 82,
        "21060": 82,
        "21240": 82,
        "21420": 82,
        "21600": 82,
        "21780": 83,
        "21960": 83,
        "22140": 83,
        "22320": 83,
        "22500": 83,
        "22680": 83,
        "22860": 83,
        "23040": 84,
        "23220": 84,
        "23400": 85,
        "23580": 85,
        "23760": 85,
        "23940": 85,
        "24120": 85,
        "24300": 85,
        "24480": 85,
        "24660": 85,
        "24840": 85,
        "25020": 85,
        "25200": 85,
        "25380": 85,
        "25560": 86,
        "25740": 86,
        "25920": 86,
        "26100": 87,
        "26280": 87,
        "26460": 87,
        "26640": 87,
        "26820": 87,
        "27000": 87,
        "27180": 88,
        "27360": 88,
        "27540": 88,
        "27720": 89,
        "27900": 89,
        "28080": 89,
        "28260": 90,
        "28440": 90,
        "28620": 90,
        "28800": 90,
        "28980": 90,
        "29160": 90,
        "29340": 91,
        "29520": 91,
        "29700": 91,
        "29880": 91,
        "30060": 91,
        "30240": 91,
        "30420": 90,
        "30600": 90,
        "30780": 89,
        "30960": 88,
        "31140": 88,
        "31320": 87,
        "31500": 87,
        "31680": 87,
        "31860": 86,
        "32040": 86,
        "32220": 85,
        "32400": 85,
        "32580": 84,
        "32760": 84,
        "32940": 83,
        "33120": 83,
        "33300": 83,
        "33480": 82,
        "33660": 82,
        "33840": 82,
        "34020": 81,
        "34200": 81,
        "34380": 81,
        "34560": 80,
        "34740": 80,
        "34920": 80,
        "35100": 79,
        "35280": 79,
        "35460": 79,
        "35640": 78,
        "35820": 78,
        "36000": 78,
        "36180": 78,
        "36360": 77,
        "36540": 77,
        "36720": 77,
        "36900": 77,
        "37080": 77,
        "37260": 77,
        "37440": 76,
        "37620": 76,
        "37800": 76,
        "37980": 76,
        "38160": 75,
        "38340": 75,
        "38520": 75,
        "38700": 74,
        "38880": 74,
        "39060": 74,
        "39240": 74,
        "39420": 74,
        "39600": 74,
        "39780": 73,
        "39960": 73,
        "40140": 73,
        "40320": 73,
        "40500": 72,
        "40680": 72,
        "40860": 72,
        "41040": 71,
        "41220": 71,
        "41400": 71,
        "41580": 71,
        "41760": 70,
        "41940": 70,
        "42120": 70,
        "42300": 69,
        "42480": 69,
        "42660": 69,
        "42840": 69,
        "43020": 69,
        "43200": 69,
        "43380": 69,
        "43560": 69,
        "43740": 68,
        "43920": 68,
        "44100": 68,
        "44280": 68,
        "44460": 68,
        "44640": 68,
        "44820": 68,
        "45000": 68,
        "45180": 68,
        "45360": 67,
        "45540": 67,
        "45720": 67,
        "45900": 66,
        "46080": 66,
        "46260": 66,
        "46440": 66,
        "46620": 66,
        "46800": 66,
        "46980": 66,
        "47160": 66,
        "47340": 65,
        "47520": 65,
        "47700": 65,
        "47880": 65,
        "48060": 65,
        "48240": 64,
        "48420": 64,
        "48600": 64,
        "48780": 63,
        "48960": 63,
        "49140": 63,
        "49320": 63,
        "49500": 62,
        "49680": 62,
        "49860": 62,
        "50040": 61,
        "50220": 61,
        "50400": 61,
        "50580": 60,
        "50760": 60,
        "50940": 60,
        "51120": 59,
        "51300": 59,
        "51480": 59,
        "51660": 59,
        "51840": 58,
        "52020": 58,
        "52200": 57,
        "52380": 57,
        "52560": 57,
        "52740": 56,
        "52920": 56,
        "53100": 55,
        "53280": 55,
        "53460": 54,
        "53640": 54,
        "53820": 53,
        "54000": 53,
        "54180": 52
      }
    }
  ]
}

From my understanding the Body Battery is separate from a hrv recording. As you noted @david the Body Battery fluctuates over the day, generally peaks at night and depletes throughout the day. TrainingPeaks account for this by recording an absolute high and low number for the day. Think that might be the best option.

3 Likes

That JSON looks like it contains the right info - that number that starts at a value 39 at t = 0 is the body battery number. This appears to report on 3min intervals, which is perhaps too many data points to keep, especially for plotting over weeks/months like you do in the Fitness page - If so, then like @Adam said, you could just take a min and max value for the day?

2 Likes

I have deployed support for this. You need to have “Download wellness data” ticked in the Garmin box in settings and custom wellness fields configured with code of BodyBatteryMin and/or BodyBatteryMax. I have tested on my laptop faking some data from Garmin. Please give it a try and let me know if it works.

2 Likes

Success! I set it up yesterday as described and it’s now showing me the correct Body Battery mins and maxes for yesterday and today. Thanks David!

1 Like

Do you have any “how to” quides for us who aren’t not so coding experts?
I did wellness custom field as David show in picture, but nothing did appear to my chart even I updated old data from Garmin.
But I can see BodyBatteryMin/Max text top of the chart and question mark below of the text.

1 Like

No coding required, just the setup that David described. Check your chart after a day to see if a data point has appeared for the day. I’m not sure if it’s possible to get your historic data, just the data going forward from the setup date.

1 Like

Thanks! I’ll check tomorrow if dots appear :slightly_smiling_face:

Yes, BB dots appeared to my chart timeline :slightly_smiling_face::+1:t2:

I just added support for historical data. If you do “Download old data” in the Garmin box in /settings you should get the last year of body battery stuff.

2 Likes

For others wanting to use this just add the body battery min and max fields to the wellness dialog:

This is great, thanks David

That is so awesome. I’ve just downloaded all data from Garmin Connect and I have a lovely row of black dots on my graph. It’s great getting this data automatically from here and HRV4Training. Thanks!

1 Like

Hi David,
Thanks!
Body Battery Data shows up but correctly for the last 5 days since I added the resp. field.
But no historical data will be shown after downloading “old wellness data” from Garmin?

Try unticking one of the Garmin wellness options, click ok, then edit and tick it again, then do “Download old wellness data”. Garmin are very sensitive about calls for historical data so Intervals.icu tries to avoid making duplicate calls. Adding a new wellness option clears the recorded dates.

Hi David,
many thanks.Works perfect now!
All the best
Peter