ב-Google Health API יש נקודות קצה ייעודיות לצבירה, שמקבצות ומסכמות את סיכומי המצב הבריאותי בחלונות זמן. במקום לאחזר ולסכם רשומות גולמיות נפרדות בצד הלקוח, אתם יכולים להשתמש בנקודות הקצה של הצבירה כדי לחשב מדדים (כמו סכומים, ממוצעים, ערכי מינימום וערכי מקסימום) על מקור נתונים מותאם:
- נקודת הקצה (endpoint)
rollUpצוברת נקודות על הגרף במרווחי זמן פיזיים ב-UTC, באמצעות משך חלון שניתן להגדרה בשניות (windowSize). - נקודת הקצה (endpoint)
dailyRollUpצוברת נקודות נתונים על פני יום קלנדרי אחד או יותר (windowSizeDays) באמצעות זמן אזרחי ביחס לשעון המקומי של המשתמש.
שתי נקודות הקצה מתאימות באופן אוטומטי נקודות על הגרף חופפות במכשירים מחוברים, ומוציאות מהחישוב תקופות שבהן המשתמש לא ענד את המכשיר הלביש, בסוגי נתונים של מכשירים לבישים שתומכים בזיהוי ענידה.
השוואה בין נקודות קצה (endpoints) של צבירה
בוחרים את נקודת הקצה לצבירת נתונים שתואמת לאופן שבו האפליקציה מקבצת ומציגה מדדי בריאות בסדרת זמנים:
| תכונה | נקודת קצה (endpoint) אחת (rollUp) |
נקודת קצה (endpoint) אחת (dailyRollUp) |
|---|---|---|
| בקשת HTTP | POST https://health.googleapis.com/v4/users/me/dataTypes/data-type/dataPoints:rollUp |
POST https://health.googleapis.com/v4/users/me/dataTypes/data-type/dataPoints:dailyRollUp |
| ייצוג של זמן | זמן פיזי ב-UTC (startTime ו-endTime בפורמט RFC 3339). |
זמן אזרחי (start ו-end כאובייקטים של CivilDateTime). |
| פרמטר של חלון | windowSize (משך הזמן הנדרש של המחרוזת בשניות, מינימום "1s"). |
windowSizeDays (מספר שלם אופציונלי של ימים, ברירת המחדל היא 1). |
| אובייקט התגובה | RollupDataPoint |
DailyRollupDataPoint |
| סדר הצגת התשובות | סדר כרונולוגי הפוך (החלון החדש ביותר מופיע ראשון). | סדר כרונולוגי הפוך (החלון החדש ביותר מופיע ראשון). |
| הכי טוב עבור | תרשימים תוך-יומיים, היסטוגרמות לפי שעה או דקה וניתוח UTC למשך זמן קבוע. | מרכזי בקרה יומיים, מגמות לאורך כמה ימים וסיכומים שמביאים בחשבון מעבר בין אזורי זמן או שעון קיץ. |
שתי נקודות הקצה אוכפות מגבלות מקסימליות של טווח שאילתות על סמך סוג הנתונים:
- טווח השאילתות המקסימלי של 14 ימים חל על
calories-in-heart-rate-zone,heart-rate,active-minutesו-total-calories. - טווח השאילתות המקסימלי של 90 ימים חל על כל שאר סוגי הנתונים הנתמכים.
כדי לבדוק אילו סוגי נתונים תומכים ב-rollup וב-dailyRollup, עיינו במאמר העזר בנושא סוגי הנתונים של Google Health API.
צבירה לפי מרווחי זמן פיזיים
משתמשים בנקודת הקצה (endpoint) rollUp כדי לצבור נקודות על הגרף בפרק זמן פיזי range (ב-UTC) שמקובצות לפי משך חלון בשניות (windowSize).
כששולחים קריאה לנקודת הקצה (endpoint) של rollUp, צריך לספק גוף בקשת JSON שמכיל את range (כולל startTime, לא כולל endTime) ואת windowSize. חשוב לזכור את הדרישות הבאות של windowSize:
- משך הזמן של
windowSizeחייב להיות לפחות שנייה אחת ("1s"). ה-API דוחה משכי זמן של פחות משנייה, אפס או משכי זמן שליליים עם שגיאה400 Bad Request(INVALID_ROLLUP_WINDOW). - כדי למנוע חלוקה לא אחידה של נתונים נצברים בין קטגוריות משנה, צריך לבחור ערך של
windowSizeששווה לרזולוציית האחסון הבסיסית של סוג הנתונים או גדול ממנה (למשל,"60s"למרווחים של דקה אחת בין הצעדים). לפרטים נוספים, קראו את המאמר חלון סיכום ורזולוציית אחסון.
לדוגמה, הבקשה הבאה אוספת את ספירת הצעדים במרווחים של דקה אחת (60s):
בקשה
POST https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints:rollUp
Authorization: Bearer access-token
Accept: application/json
{
"range": {
"startTime": "2026-02-17T17:00:00Z",
"endTime": "2026-02-17T17:59:59Z"
},
"windowSize": "60s"
}תשובה
{
"rollupDataPoints": [
{
"startTime": "2026-02-17T17:55:00Z",
"endTime": "2026-02-17T17:56:00Z",
"steps": {
"countSum": "72"
}
},
{
"startTime": "2026-02-17T17:54:00Z",
"endTime": "2026-02-17T17:55:00Z",
"steps": {
"countSum": "85"
}
},
...
]
}צבירה לפי ימים קלנדריים
משתמשים בנקודת הקצה dailyRollUp כדי לצבור נתונים ביום קלנדרי אחד או בכמה ימים (windowSizeDays). מספקים את הזמן האזרחי הסגור-פתוח range (start ו-end) בגוף הבקשה. בהתאם לסוג הנתונים, נקודת הקצה מחזירה ערכים נצברים כמו הסכום או הממוצע בכל חלון אזרחי.
מכיוון ש-dailyRollUp פועל לפי זמן אזרחי באמצעות הפרשי הזמן מ-UTC שמתועדים בכל נקודה על הגרף, הוא מתאים באופן אוטומטי את אורכי הימים המשתנים שנגרמים כתוצאה ממעבר לשעון קיץ או מנסיעה בין אזורי זמן.
לדוגמה, הבקשה הבאה צוברת את ספירת הצעדים ביום אזרחי אחד (windowSizeDays: 1):
בקשה
POST https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints:dailyRollUp
Authorization: Bearer access-token
Accept: application/json
{
"range": {
"start": {
"date": {
"year": 2026,
"month": 2,
"day": 26
},
"time": {
"hours": 0,
"minutes": 0,
"seconds": 0,
"nanos": 0
}
},
"end": {
"date": {
"year": 2026,
"month": 2,
"day": 26
},
"time": {
"hours": 23,
"minutes": 59,
"seconds": 59,
"nanos": 0
}
}
},
"windowSizeDays": 1
}תשובה
{
"rollupDataPoints": [
{
"civilStartTime": {
"date": {
"year": 2026,
"month": 2,
"day": 26
},
"time": {}
},
"civilEndTime": {
"date": {
"year": 2026,
"month": 2,
"day": 26
},
"time": {
"hours": 23,
"minutes": 59,
"seconds": 59
}
},
"steps": {
"countSum": "3822"
}
}
]
}צבירה לפי משפחת מקורות נתונים
גם rollUp וגם dailyRollUp מקבלים שדה dataSourceFamily אופציונלי בגוף הבקשה בפורמט JSON, כדי להגביל את הצבירה לקבוצות מקור ספציפיות:
- האפשרות
users/me/dataSourceFamilies/all-sources(ברירת המחדל) צוברת נתונים שתואמים לכל המקורות הרשומים של הצד הראשון והצד השלישי. - האפשרות
users/me/dataSourceFamilies/google-wearablesצוברת נתונים שתועדו על ידי מכשירי מעקב לבישים של Google ו-Fitbit, לא כולל נתונים שתועדו באופן ידני ונתונים משוערים מהטלפון. - האפשרות
users/me/dataSourceFamilies/google-sourcesצוברת נתונים ממקורות של Google ו-Fitbit מאינטראקציה ישירה (First-Party), כולל מכשירים לבישים למעקב, Health Connect ורשומות ידניות באפליקציות מאינטראקציה ישירה.
כדי לראות את כל הדרישות לגבי הפרמטרים ודוגמאות לבקשות ולתגובות, קראו את הקטע סינון לפי משפחה של מקור נתונים במדריך לסינון נתונים.
חלון סיכום ורזולוציית אחסון
למרות שנקודת הקצה rollUp מקבלת כל windowSize של שנייה אחת ("1s") או יותר, סוגי נתונים שונים מתעדים ושומרים מדידות בתדירויות דגימה שונות או במרווחי זמן שונים באחסון הבסיסי. לדוגמה, מדדי פעילות גופנית של מכשירים לבישים כמו steps, distance, active-minutes ו-active-energy-burned מתועדים בדרך כלל במרווחים של דקה אחת (60s).
בטבלה הבאה מפורטות רזולוציות האחסון הבסיסיות וערכי windowSize המינימליים המומלצים לסוגי נתונים נפוצים:
| פתרון בעיות באחסון | מינימום מומלץ: windowSize |
סוגי נתונים |
|---|---|---|
שנייה אחת (1s) |
"1s" |
heart-rate |
דקה אחת (60s) |
"60s" |
active-energy-burned, active-minutes, active-zone-minutes, altitude, calories-in-heart-rate-zone, distance, floors, steps, time-in-heart-rate-zone, total-calories |
כשצוברים סוגי נתונים של מרווחים, נקודת הקצה rollUp ממקמת כל נקודה על הגרף שנרשמה בקטגוריה שמכילה את ה-startTime של נקודת הנתונים. ה-API לא פורס, מבצע אינטרפולציה או מפיץ נתוני מרווחים בין קטגוריות של מרווחי משנה.
אם מציינים windowSize קטן יותר ממרווח הזמן של אחסון הנתונים הבסיסי (לדוגמה, בקשה לחלון של 10 שניות ל-steps שמאוחסן במרווחים של דקה):
- הדלי המשני הראשון שתואם ל-
startTimeשל המרווח (לדוגמה,10:00:00עד10:00:10) מקבל את כל הספירה המצטברת של הדקה (לדוגמה, כל 100 הצעדים שתועדו באותה דקה). - שאר קטגוריות המשנה באותה דקה (
10:00:10עד10:00:20,10:00:20עד10:00:30וכן הלאה) לא מקבלות נקודות על הגרף, כי אין מרווח שמתחיל בחלונות האלה.
כך נוצרים נתונים עם קפיצות חדות, שבהם הערך של כל המרווח מרוכז בחלון המשנה הראשון, כמו שמוצג באיור 1.
כדי לקבל נתונים נצברים משמעותיים ומפוזרים באופן שווה, תמיד צריך להגדיר את windowSize למשך זמן ששווה לרזולוציית האחסון הבסיסית של סוג נתוני היעד או גדול ממנה (לדוגמה, "60s" או יותר בשביל steps). כדי לראות את רזולוציית האחסון ואת חלון הסיכום המינימלי המומלץ לכל סוג נתונים, אפשר לעיין במאמר העזר בנושא סוגי הנתונים של Google Health API.
חלוקה לקטגוריות כשהטווח הוא לא כפולה של גודל החלון
אם הטווח המבוקש הוא לא כפולה מדויקת של windowSize (או windowSizeDays), הקטגוריה הכרונולוגית האחרונה נחתכת בנקודת הקצה העליונה של הטווח, והיא מכסה משך זמן קצר יותר מגודל החלון. ה-API מקבל את הבקשה ללא שינוי ולא מבצע עיגול, שינויי זמן או אינטרפולציה של נתונים.
כדי לכסות את כל הטווח המבוקש, ה-API משתמש בחלוקה עם עיגול כלפי מעלה כדי לחשב את המספר הכולל של חלונות הצבירה:
Number of windows = ceiling(Range duration / Window size)
כל קטגוריה מתחילה ברצף מתחילת הטווח. אם הוספת חלון נוסף בגודל מלא חורגת משעת הסיום שביקשתם, החלון האחרון נחתך (מוגבל) בשעת הסיום של הטווח.
איך פועל תהליך החלוקה לקטגוריות
כשמבקשים סיכומים עם טווחים שלא ניתנים לחלוקה, ה-API מחיל את הכללים הבאים:
- החלוקה לקטגוריות מתחילה בתחילת הטווח המבוקש (
range.startTimeאוrange.start) ומתקדמת קדימה לפי גודל החלון (windowSizeאוwindowSizeDays). - הקטגוריה הכרונולוגית האחרונה מוגבלת לסוף הטווח המבוקש (
range.endTimeאוrange.end), והיא מכסה משך זמן קצר יותר מגודל החלון המבוקש. - האובייקטים
RollupDataPointאוDailyRollupDataPointשמוחזרים כוללים חותמות זמן מפורשות משלהם להתחלה ולסיום, שבהן אפשר להשתמש כדי לבדוק את משך הזמן בפועל של הקטגוריה המקוצרת. - מכיוון שה-API מחזיר נתונים מצטברים בסדר כרונולוגי הפוך (החדש ביותר קודם), הקטגוריה הכרונולוגית האחרונה (הקטגוריה המקוצרת) מופיעה כרכיב הראשון (
index 0) ברשימה שמוחזרת.
באיור 2 מוצג איך ה-API מחלק לקטגוריות טווח שלא ניתן לחלוקה קדימה מ-range.startTime, מצמיד את הקטגוריה האחרונה ל-range.endTime ומחזיר את הקטגוריות שנוצרו בסדר כרונולוגי הפוך.
דוגמה לטווח של 12 דקות עם חלון של 5 דקות
נניח שלקוח מבקש אוסף נתונים בטווח של 12 דקות עם windowSize של 5 דקות ("300s"):
- הערך של
range.startTimeהוא10:00:00Z. - הערך של
range.endTimeהוא10:12:00Z, למשך זמן כולל של 12 דקות. - הערך של
windowSizeהוא"300s"(5 דקות).
מכיוון ש-12 דקות הן לא כפולה מדויקת של 5 דקות (12 = 5 * 2 + 2), ה-API מחשב את מספר החלונות כ-ceiling(12 / 5) = 3. כך נוצרות שלוש קטגוריות כרונולוגיות:
| קטגוריה | מרווח | משך | סטטוס חלון הזמן |
|---|---|---|---|
| קטגוריה 1 | [10:00:00Z, 10:05:00Z) |
5 דקות | חלון מלא |
| קטגוריה 2 | [10:05:00Z, 10:10:00Z) |
5 דקות | חלון מלא |
| קטגוריה 3 | [10:10:00Z, 10:12:00Z) |
2 דקות | נחתך ב-range.endTime |
ההשפעה על ערכים נצברים
בגלל שחלון הזמן הכרונולוגי האחרון קצר יותר, המדדים המצטברים (כמו סכום או ספירת השלבים) נמוכים יותר בקטגוריה המקוצרת בגלל משך הזמן הקצר יותר.
אם משתמש הולך בקצב קבוע של 100 צעדים לדקה במהלך כל הטווח של 12 הדקות, הקטגוריות מכילות את הסכומים הבאים:
- בקטגוריה 1 (
10:00:00Zעד10:05:00Z) נרשמים 500 צעדים (5 דקות בקצב של 100 צעדים לדקה). - קבוצה 2 (
10:05:00Zעד10:10:00Z) מתעדת 500 צעדים (5 דקות בקצב של 100 צעדים לדקה). - קבוצה 3 (
10:10:00Zעד10:12:00Z) מתעדת 200 צעדים (2 דקות בקצב של 100 צעדים לדקה).
מספר הצעדים הנמוך יותר (200 צעדים) בקבוצה 3 נובע ממשך הזמן של 2 דקות בחלון המקוצר, ולא מירידה בפעילות של המשתמש. כשמשרטטים או מנתחים את הנתונים האלה, צריך לנרמל את הספירות באמצעות משך הזמן המפורש של כל קטגוריה כדי להימנע מהצגת ירידה מטעה בפעילות המשתמשים.
איור 3 משווה בין סך הצעדים המצטברים הגולמיים (countSum) לבין שיעורים מנורמלים לפי משך זמן בשלוש הקטגוריות.
דוגמה לתגובה מה-API שמציגה את הסדר
מכיוון שה-API מחזיר תוצאות בסדר כרונולוגי הפוך, הקטגוריה המקוצרת מופיעה כרכיב הראשון ברשימה שמוחזרת:
{
"rollupDataPoints": [
{
"startTime": "2026-08-20T10:10:00Z",
"endTime": "2026-08-20T10:12:00Z",
"steps": {
"countSum": "200"
}
},
{
"startTime": "2026-08-20T10:05:00Z",
"endTime": "2026-08-20T10:10:00Z",
"steps": {
"countSum": "500"
}
},
{
"startTime": "2026-08-20T10:00:00Z",
"endTime": "2026-08-20T10:05:00Z",
"steps": {
"countSum": "500"
}
}
]
}