aidR: Glooko export format

library(aidR)

Overview

A Glooko export is a folder (possibly zipped) containing CSV files for several data types:

 [1] "alarms_data_1.csv"                    
 [2] "bg_data_1.csv"                        
 [3] "cgm_carbs_data_1.csv"                 
 [4] "cgm_data_1.csv"                       
 [5] "Insulin data/basal_data_1.csv"        
 [6] "Insulin data/bolus_data_1.csv"        
 [7] "Insulin data/insulin_data_1.csv"      
 [8] "Manual data/exercise_data_1.csv"      
 [9] "Manual data/food_data_1.csv"          
[10] "Manual data/manual_insulin_data_1.csv"
[11] "Manual data/medication_data_1.csv"    
[12] "Manual data/notes_data_1.csv"         

A single data type may be split across two or more files, which are then numbered cgm_data_1.csv, cgm_data_2.csv, and so on; aidR reads and concatenates all files matching a given type.

Every file begins with a one-line header, such as Name:Jane Doe,Date Range:2024-01-01 - 2024-03-01, followed by the column headers. Both the one-line header and the column headers are language-specific and vary with the language of the user’s Glooko account (example in German):

Name:XXX XXX,Datumsbereich:22.06.2026 - 22.06.2026
Zeitstempel,CGM-Glukosewert (mg/dl),Seriennummer
22.06.2026 23:55,"215,0",00000000-000000000
22.06.2026 23:50,"220,0",00000000-000000000
22.06.2026 23:45,"222,0",00000000-000000000
22.06.2026 23:40,"225,0",00000000-000000000
22.06.2026 23:35,"229,0",00000000-000000000
22.06.2026 23:30,"233,0",00000000-000000000
22.06.2026 23:25,"238,0",00000000-000000000
22.06.2026 23:20,"240,0",00000000-000000000

How aidR detects this format

Because the headers in a Glooko export are language-specific, aidR cannot identify a file from its header names. It relies instead on the structure of the first line (something:something,something:date - date), and then distinguishes between data types by the expected number of columns, which columns are numeric, and, where available, a language-independent keyword such as "(g)" for carbohydrates or "Insulin" for the bolus, basal, and total-insulin files.

Files and the data types they produce

To inspect the files, we parse the export with clean = FALSE, which returns the full information provided by Glooko:

data <- parse_data(id = "1", paths = path, clean = FALSE)
#> Parsing data for id 1...

Each entry below describes one raw file and shows an example.

  • alarms_data_*.csv: pump alarms.
head(data$alarm)
          Zeitstempel                                       Alarm.Ereignis
1 2026-06-22 12:44:00 Pod läuft zum vom Benutzer festgelegten Zeitpunkt ab
2 2026-06-22 16:44:00                                    Pod läuft bald ab
        Seriennummer
1 00000000-000000000
2 00000000-000000000
  • bg_data_*.csv: self-monitored blood glucose (SMBG).
head(data$SMBG)
          Zeitstempel Glukosewert..mg.dl. Manuelles.Lesen       Seriennummer
1 2026-06-22 07:19:00                  72               M 00000000-000000000
  • carbs_data_*.csv / cgm_carbs_data_*.csv: carbohydrate/meal events recorded by or imported from a CGM system. These are different from carbohydrate amounts entered into a pump’s bolus calculator. In practice, these files are almost always empty in exports of AID users. They are therefore ignored when building the clean carbs output, which instead uses carbohydrate amounts recorded in the bolus files (see below).
head(data$carbs_manual)
NULL
  • cgm_data_*.csv: CGM data.
head(data$cgm)
          Zeitstempel CGM.Glukosewert..mg.dl.       Seriennummer
1 2026-06-22 00:02:00                     109 00000000-000000000
2 2026-06-22 00:22:00                     129 00000000-000000000
3 2026-06-22 00:27:00                     138 00000000-000000000
4 2026-06-22 00:32:00                     147 00000000-000000000
5 2026-06-22 00:37:00                     156 00000000-000000000
6 2026-06-22 00:57:00                     191 00000000-000000000
  • Insulin data/basal_data_*.csv: basal rates. For Omnipod users these are often very sparse or missing. For these users, the few entries that do appear correspond to basal rates delivered while in manual mode; basal delivered in automated mode is unknown and can only be roughly approximated from the daily aggregated insulin.
head(data$basal)
          Zeitstempel Insulin.Typ Dauer..Minuten. Prozentsatz.... Rate
1 2026-06-22 21:12:00  Eingeplant               7              NA  0.7
  Abgegebenes.Insulin..E.       Seriennummer
1                      NA 00000000-000000000
  • Insulin data/bolus_data_*.csv: boluses. Also records whether a bolus was normal, square-wave, or dual-wave through the amounts listed under initial and extended delivery (although the duration is unknown).
head(data$bolus)
          Zeitstempel Insulin.Typ Blutzuckereingabe..mg.dl.
1 2026-06-21 18:05:00      Normal                       112
2 2026-06-21 22:19:00      Normal                         0
3 2026-06-21 22:20:00      Normal                         0
4 2026-06-22 00:02:00      Normal                       112
5 2026-06-22 00:07:00      Normal                       126
6 2026-06-22 11:37:00      Normal                       124
  Kohlenhydrataufnahme..g. Kohlenhydratverhältnis Abgegebenes.Insulin..E.
1                       10                     10                    1.25
2                      403                     NA                    0.00
3                       40                      5                    8.00
4                       10                     10                    1.25
5                        5                      6                    1.00
6                       41                      7                    6.00
  Anfängliche.Abgabe..E. Verzögerte.Abgabe..E.       Seriennummer
1                     NA                    NA 00000000-000000000
2                     NA                    NA 00000000-000000000
3                     NA                    NA 00000000-000000000
4                     NA                    NA 00000000-000000000
5                     NA                    NA 00000000-000000000
6                     NA                    NA 00000000-000000000
  • Insulin data/insulin_data_*.csv: daily aggregated bolus, basal, and total insulin.
head(data$total_insulin)
          Zeitstempel Bolus.gesamt..U. Insulin.gesamt..U. Basal.gesamt..U.
1 2026-06-22 23:55:00            16.25              37.45             21.2
        Seriennummer
1 00000000-000000000
  • Manual data/ files (exercise_data_*, food_data_*, manual_insulin_data_*, medication_data_*, notes_data_*): self-reported entries made by the user in the Glooko app - exercise, food intake, manual insulin deliveries, medication, and free-text notes, respectively. These are often very sparse or missing entirely. If present, they are available through data$exercise, data$food, data$manual_insulin, data$medication and data$notes, respectively.

Cleaning files

When parse_data is run with clean = TRUE, the cleaned data types are built from the following raw files and attributes:

Cleaned data type Used files Used attributes of clean = FALSE
cgm cgm_data_*.csv data$cgm
basal Insulin data/basal_data_*.csv data$basal
bolus Insulin data/bolus_data_*.csv data$bolus
carbs Insulin data/bolus_data_*.csv data$bolus
SMBG bg_data_*.csv data$SMBG
total_basal Insulin data/insulin_data_*.csv data$total_insulin
total_bolus Insulin data/insulin_data_*.csv data$total_insulin

Notes

  • CGM and SMBG values are reported in mg/dL or mmol/L depending on account settings; aidR converts to mg/dL automatically.
  • timezone_offset is always NA, since Glooko exports report only local (wall-clock) time.
  • Serial numbers are reported for some data types (e.g. basal, bolus) but are not mapped to a device/pump name.
  • Glooko is the only supported platform that reports the daily aggregated insulin itself, so total_basal and total_bolus both have source = "reported". This matters for Omnipod users, whose basal rates cover manual mode only: their basal is sparse, while total_basal still holds the full amount delivered.
  • sensor_name for CGM is always NA, since Glooko exports do not report it.
  • Each row of the bolus file holds a bolus together with the carbohydrates entered for it, so bolus and carbs are linked by link_id. Boluses without carbohydrates have link_id = NA.
  • Glooko exports from CamAPS FX users may contain slowly absorbed carbohydrate entries, which are encoded as a series of equal-sized entries, one every 30 minutes. Such entries are automatically detected and merged into a single entry by aidR, (see Slowly absorbed carbohydrates in Glooko)).