נקודות קצה

בדף הזה מופיעה סקירה כללית של מוסכמות API בארכיטקטורת REST, וגם אינדקס של משימות נפוצות ב-Google Health API ודוגמאות לכל אחת מהן.

מוסכמות של API בארכיטקטורת REST

ה-Google Health API פועל לפי התקנים של הצעות לשיפור Google API‏ (AIP), ובאופן ספציפי לפי AIP-127 (קידוד טרנסקריפציה של HTTP ו-gRPC) ו-AIP-131 עד AIP-135 (שיטות סטנדרטיות). התקנים האלה מגדירים איך נתונים ממופים מהודעת פרוטו לבקשת HTTP.

פרמטרים של שאילתה

פרמטרים של שאילתה משמשים כשהנתונים הם חלק מכתובת ה-URL. השדה הזה מיועד בעיקר לבקשות GET (שליפת משאב) או לבקשות LIST (סינון/חלוקה לדפים), אבל הוא משמש גם לפעולות DELETE.

  • מיקום: מצורף לכתובת ה-URL אחרי ?.
  • תחביר: צמדי מפתח/ערך מופרדים על ידי &.
  • מיפוי: כל שדה בהודעת הבקשה שלא נכלל בתבנית של נתיב כתובת ה-URL ממופה לפרמטר של שאילתה.
  • הכי מתאים ל: סוגים פשוטים (מחרוזות, מספרים שלמים, ספירות) ושדות חוזרים.

תחביר לדוגמה:

GET https://health.googleapis.com/v4/users/me/dataTypes/data-type/dataPoints?page_size=10&filter=data_type.interval.start_time >= "2025-10-01T00:00:00Z"

גוף הבקשה

גוף הבקשה משמש כשהנתונים משנים את מצב המשאב או כשהם גדולים מדי בשביל כתובת URL. התוכן הוא בדרך כלל ייצוג JSON של המשאב עצמו. בדרך כלל משתמשים בו לפעולות POST, PATCH ו-PUT.

  • מיקום: בתוך מטען הייעודי (payload) של HTTP (לא גלוי בכתובת ה-URL).
  • תחביר: בפורמט של אובייקט JSON.
  • מיפוי: מוגדר בהערה google.api.http.
    • ‫body: "*" מציין שכל ההודעה היא הגוף.
    • ‫body: "resource_name" אומר שרק שדה ספציפי בפרוטו הוא הגוף.
  • הכי מתאים ל: אובייקטים מורכבים, הודעות בתצוגת עץ ומידע אישי רגיש.

תחביר לדוגמה:

POST https://health.googleapis.com/v4/users/me/dataTypes/data-type/dataPoints:rollUp
Content-Type: application/json

{
  "range": {
    "startTime": "2025-11-05T00:00:00Z",
    "endTime": "2025-11-13T00:00:00Z"
  },
  "windowSize": "3600s"
}

המקרה ההיברידי

בשיטת Update או בפעולת PATCH שתואמות ל-AIP-134, נעשה שימוש בשניהם. כתובת ה-URL מכילה את שם המשאב, הגוף מכיל את נתוני המשאב המעודכנים, ופרמטר של שאילתה (בדרך כלל update_mask) מציין אילו שדות לשנות.

PATCH https://health.googleapis.com/v4/projects/project-id/subscribers/subscriber-id
Content-Type: application/json

{
  "endpointUri": "https://myapp.com/new-webhooks/health"
}

הבדלים מרכזיים במבט מהיר

תכונה פרמטרי שאילתה גוף הבקשה
הנחיות לשימוש ב-AIP משמש לחיפוש, לסינון ולפעולות קריאה. משמש לפעולות כתיבה.
חשיפה אפשר לראות את הנתונים האלה בהיסטוריית הגלישה וביומני השרת. מוסתר מכתובת ה-URL.
מורכבות מוגבל למבנים שטוחים או חוזרים. תומך באובייקטים של JSON עם קינון עמוק.
קידוד צריך להשתמש בקידוד URL (לדוגמה, רווחים הופכים ל-%20). קידוד JSON רגיל.

תאריכים

כל התאריכים ב-Google Health API מוצגים בפורמט YYYY-MM-DD. ‫Nutrition API תומך בתקן ISO-8601 לערכי תאריך, בתנאים הבאים:

  • שנה בארבע ספרות YYYY
  • ערכי השנה בטווח 0000-9999
  • אין אכיפה של הגבלות על תאריך התחלה שמשתמעות מתקן ISO-8601 או מתקופה אחרת

כותרות

כדי להפעיל את נקודות הקצה של Google Health API, צריך להשתמש בכותרות המתאימות ובאסימון גישה. מומלץ להשתמש בכותרת הבאה גם בבקשות GET וגם בבקשות POST:

Authorization: Bearer access-token
Accept: application/json

אינדקס משימות API

בקטע הזה מופיע אינדקס של משימות נפוצות ב-Google Health API ודוגמאות לכל אחת מהן.

איך מקבלים את מזהה המשתמש ב-Fitbit או ב-Google

אחרי שמשתמש נותן הסכמה באמצעות Google OAuth 2.0, תגובת האסימון לא כוללת את מזהה המשתמש ב-Fitbit או ב-Google. כדי לקבל את ה-User-ID, קוראים לנקודת הקצה getIdentity. ‫getIdentity מחזירה גם את מזהה המשתמש בגרסה הקודמת של Fitbit וגם את מזהה המשתמש ב-Google.

מומלץ, ברגע שמשתמש חדש נותן הסכמה דרך OAuth, לקרוא לנקודת הקצה getIdentity ולאחסן את שני מזהי המשתמש. כך השילוב שלכם יהיה תואם לדורות קודמים ולדורות הבאים.

לדוגמה:

בקשה

GET https://health.googleapis.com/v4/users/me/identity
Authorization: Bearer access-token
Accept: application/json

תשובה

{
  "name": "users/me/identity",
  "legacyUserId": "A1B2C3",
  "healthUserId": "111111256096816351"
}

קבלת נתונים מפורטים או נתונים שמתקבלים במהלך היום

כדי לקבל נתונים יומיים או נתונים מפורטים שנאספו במהלך היום במרווחי זמן נתמכים עבור סוג נתונים מסוים, משתמשים בנקודת הקצה list של סוג הנתונים הזה.

לדוגמה:

בקשה

GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints
Authorization: Bearer access-token
Accept: application/json

תשובה

{
  "dataPoints": [
    {
      "dataSource": {
        "recordingMethod": "PASSIVELY_MEASURED",
        "device": {
          "manufacturer": "",
          "displayName": "Charge 6"
        },
        "platform": "FITBIT"
      },
      "steps": {
        "interval": {
          "startTime": "2026-03-04T07:05:00Z",
          "startUtcOffset": "0s",
          "endTime": "2026-03-04T07:06:00Z",
          "endUtcOffset": "0s",
          "civilStartTime": {
            "date": {
              "year": 2026,
              "month": 3,
              "day": 4
            },
            "time": {
              "hours": 7,
              "minutes": 5
            }
          },
          "civilEndTime": {
            "date": {
              "year": 2026,
              "month": 3,
              "day": 4
            },
            "time": {
              "hours": 7,
              "minutes": 6
            }
          }
        },
        "count": "40"
      }
    },
...
  ],
  "nextPageToken": "Xm5h-6L0viZxIlRuWjx5bmvy98zj85uG34tuMn16mu2pntsnZI32iqhq"
}

איך מקבלים תצוגה מאוחדת של נתונים במרווחי זמן

כדי לאחזר נתונים של פרקי זמן בלי רשומות חופפות או התנגשויות בין מכשירים, צריך להתקשר אל נקודת הקצה reconcile. נקודת הקצה reconcile מסירה באופן אוטומטי כפילויות של מרווחי זמן חופפים בין קבוצות של נתוני סנכרון ומכמה מכשירי הקלטה, ומחזירה נתונים רציפים ומהימנים שמתאימים לעיבוד של ציר זמן של פעילות ולחישוב משכי זמן.

כדי לקבל מידע נוסף על הסיבה לכך שמכשירים מחוברים יוצרים מרווחי זמן חופפים ועל השוואה תפעולית בין list לבין reconcile, אפשר לעיין במדריך לניהול נתונים.

בדוגמה הבאה מוצגת השוואה בין התגובה של list (שמחזירה את שני הרשומות החופפות) לבין התגובה של reconcile (שפותרת את הבעיה על ידי החזרת הרשומה הסמכותית) עבור משתמש עם שתי סשנים חופפים של פעילות גופנית:

רשימה גולמית

GET https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints
Authorization: Bearer access-token
Accept: application/json
{
  "dataPoints": [
    {
      "name": "users/111111256096816351/dataTypes/exercise/dataPoints/7797422996486764704",
      "exercise": {
        "interval": {
          "startTime": "2026-09-03T11:20:00Z",
          "endTime": "2026-09-03T11:50:00Z"
        },
        "exerciseType": "RUNNING"
      }
    },
    {
      "name": "users/111111256096816351/dataTypes/exercise/dataPoints/4389052750481144696",
      "exercise": {
        "interval": {
          "startTime": "2026-09-03T11:00:00Z",
          "endTime": "2026-09-03T11:30:00Z"
        },
        "exerciseType": "RUNNING"
      }
    }
  ]
}

ההזמנה הוסדרה

GET https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints:reconcile
Authorization: Bearer access-token
Accept: application/json
{
  "dataPoints": [
    {
      "dataPointName": "users/111111256096816351/dataTypes/exercise/dataPoints/7797422996486764704",
      "exercise": {
        "interval": {
          "startTime": "2026-09-03T11:20:00Z",
          "endTime": "2026-09-03T11:50:00Z"
        },
        "exerciseType": "RUNNING"
      }
    }
  ]
}

תהליך ההתאמה פותר סתירות בין סשנים על ידי ביטול כפילויות ובחירה ברשומה הסמכותית, במקום ליצור איחוד מלאכותי של הזמנים (למשל, 11:00:00Z עד 11:50:00Z). בתגובה אחרי ההתאמה מוחזרת נקודת הנתונים המנצחת (7797422996486764704) עם מרווח הזמן המקורי שלה (11:20:00Z עד 11:50:00Z), וכך נשמרת השלמות של הטלמטריה והמדדים שנמדדו בסשן הזה.

סנן נתונים

כדי לאחזר קבוצות משנה ספציפיות של רשומות של נקודות נתונים שתואמות לקריטריונים כמו מרווח זמן, תאריך או זמן תצפית, משתמשים בנקודת הקצה list או reconcile עם הפרמטר filter.

הנחיות מפורטות, כללי עיצוב, שגיאות אימות ודוגמאות לשאילתות זמינים במדריך לסינון נתונים.

סינון לפי משפחת מקורות נתונים

כדי לבודד או לצבור נתונים מסוגים ספציפיים של מקורות (לדוגמה, מכשירים פיזיים לבישים לעומת נתונים שהוזנו ידנית), משתמשים בdataSourceFamilyהפרמטר.

הנחיות מפורטות, משפחות נתמכות ודוגמאות לבקשות ולתגובות של reconcile, rollUp ו-dailyRollUp זמינות במאמר סינון לפי משפחה של מקור נתונים במדריך לסינון נתונים.

סינון נתונים לפי שעת התחלה אזרחית של מרווח זמן

משתמשים בנקודת הקצה list עם הפרמטר filter כדי לסנן נתונים לפי זמן אזרחי או לפי מרווח.

לדוגמה:

בקשה

GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints?filter=steps.interval.civil_start_time >= "2026-03-04T00:00:00"
Authorization: Bearer access-token
Accept: application/json

תשובה

{
  "dataPoints": [
    {
      "dataSource": {
        "recordingMethod": "PASSIVELY_MEASURED",
        "device": {
          "manufacturer": "",
          "displayName": "Charge 6"
        },
        "platform": "FITBIT"
      },
      "steps": {
        "interval": {
          "startTime": "2026-03-04T07:05:00Z",
          "startUtcOffset": "0s",
          "endTime": "2026-03-04T07:06:00Z",
          "endUtcOffset": "0s",
          "civilStartTime": {
            "date": {
              "year": 2026,
              "month": 3,
              "day": 4
            },
            "time": {
              "hours": 7,
              "minutes": 5
            }
          },
          "civilEndTime": {
            "date": {
              "year": 2026,
              "month": 3,
              "day": 4
            },
            "time": {
              "hours": 7,
              "minutes": 6
            }
          }
        },
        "count": "40"
      }
...
  ],
  "nextPageToken": "Xm5h-6L0viZxIlRuQjp5bml1bZ4ve2dhNmZvMnt4Yn7qIGQhbHN3YQ"
}

סינון נתונים לפי זמן פיזי של תצפית לדוגמה

משתמשים בנקודת הקצה list עם הפרמטר filter כדי לסנן נתונים לפי זמן פיזי של תצפית לדוגמה.

לדוגמה:

בקשה

GET https://health.googleapis.com/v4/users/me/dataTypes/body-fat/dataPoints?filter=body_fat.sample_time.physical_time >= "2026-03-01T00:00:00Z"
Authorization: Bearer access-token
Accept: application/json

תשובה

{
  "dataPoints": [
    {
      "name": "users/123456789/dataTypes/body-fat/dataPoints/1234567890",
      "dataSource": {
        "recordingMethod": "UNKNOWN",
        "application": {
          "packageName": "",
          "webClientId": "",
          "googleWebClientId": "google-web-client-id"
        },
        "platform": "GOOGLE_WEB_API"
      },
      "bodyFat": {
        "sampleTime": {
          "physicalTime": "2026-03-10T10:00:00Z",
          "utcOffset": "0s",
          "civilTime": {
            "date": {
              "year": 2026,
              "month": 3,
              "day": 10
            },
            "time": {
              "hours": 10
            }
          }
        },
        "percentage": 20
      }
    }
  "nextPageToken": ""
}

סינון וצבירה לפי משפחת מקורות נתונים

משפחה של מקורות נתונים היא קיבוץ לוגי של מקורות נתונים (כמו שעונים חכמים, אפליקציות לנייד או רשומות שהוזנו באופן ידני). היא מאפשרת לכם לבודד או לצבור נתונים מסוגים ספציפיים של מקורות (לדוגמה, מכשירים לבישים פיזיים לעומת נתונים שהוזנו ידנית).

כל נקודות הקצה reconcile, rollUp ו-dailyRollUp תומכות בפרמטר dataSourceFamily. מנגנון ההעברה תלוי בנקודת הקצה:

נקודת קצה (שיטת HTTP) מנגנון
reconcile (GET) מעבירים את dataSourceFamily כפרמטר של שאילתה בכתובת URL.
‫rollUp (POST) מעבירים את dataSourceFamily כשדה בגוף בקשת ה-JSON.
‫dailyRollUp (POST) מעבירים את dataSourceFamily כשדה בגוף בקשת ה-JSON.

משפחות של מקורות נתונים נתמכים

בטבלה הבאה מפורטים הערכים הנתמכים של dataSourceFamily:

אפשרות תיאור
users/me/dataSourceFamilies/all-sources ערך ברירת מחדל. מחזירה נקודות נתונים שעברו התאמה בין כל מקורות הנתונים הרשומים מאינטראקציה ישירה (First-Party) ומצד שלישי (3P). האפשרות הזו תחזיר נתוני האפליקציה של צד שלישי (למשל, צעדים בשעון חכם + צעדים באפליקציה של צד שלישי + צעדים בטלפון נייד + צעדים שהוזנו ידנית).
users/me/dataSourceFamilies/google-wearables כולל נתונים שתועדו על ידי מכשירי מעקב של Google ו-Fitbit (כמו מכשירי מעקב לבישים של Fitbit ו-Pixel Watch). לא כולל נתונים שנרשמו באופן ידני ונתונים משוערים מהטלפון. משתמשים באפשרות הזו כשהשילוב דורש טלמטריה של חיישנים גולמיים שנרשמת ישירות על ידי חומרה של מכשיר לביש.
users/me/dataSourceFamilies/google-sources כולל מקורות מאינטראקציה ישירה של Google ו-Fitbit. הנתונים האלה כוללים רשומות של מכשירי מעקב פיזי, נתונים מ-Health Connect וכל נתון שהוזן ידנית דרך אפליקציות של צד ראשון (כמו אפליקציית Fitbit או Google Fit).

כדי לקבל מקור נתונים שעבר תהליך התאמה ממשפחה ספציפית של מקורות נתונים, מפעילים את נקודת הקצה reconcile עם פרמטר השאילתה dataSourceFamily.

לדוגמה, בקשת ה-GET הבאה מאחזרת את נתוני השינה שתועדו על ידי מכשיר המעקב ביום שאחרי 2026-03-03:

בקשה

GET https://health.googleapis.com/v4/users/me/dataTypes/sleep/dataPoints:reconcile?dataSourceFamily=users/me/dataSourceFamilies/google-wearables&filter=sleep.interval.civil_end_time >= "2026-03-03"
Authorization: Bearer access-token
Accept: application/json

תשובה

{
  "dataPoints": [
    {
      "name": "users/2515055256096816351/dataTypes/sleep/dataPoints/2724123844716220216",
      "dataSource": {
        "recordingMethod": "DERIVED",
        "device": {
          "displayName": "Charge 6"
        },
        "platform": "FITBIT"
      },
      "sleep": {
        "interval": {
          "startTime": "2026-03-03T20:57:30Z",
          "startUtcOffset": "0s",
          "endTime": "2026-03-04T04:41:30Z",
          "endUtcOffset": "0s"
        },
        "type": "STAGES",
        "stages": [
          {
            "startTime": "2026-03-03T20:57:30Z",
            "startUtcOffset": "0s",
            "endTime": "2026-03-03T20:59:30Z",
            "endUtcOffset": "0s",
            "type": "AWAKE",
            "createTime": "2026-03-04T04:43:40.937183Z",
            "updateTime": "2026-03-04T04:43:40.937183Z"
          },
          {
            "startTime": "2026-03-04T04:07:30Z",
            "startUtcOffset": "0s",
            "endTime": "2026-03-04T04:41:30Z",
            "endUtcOffset": "0s",
            "type": "AWAKE",
            "createTime": "2026-03-04T04:43:40.937183Z",
            "updateTime": "2026-03-04T04:43:40.937183Z"
          }
        ],
        "metadata": {
          "stagesStatus": "SUCCEEDED",
          "processed": true,
          "main": true
        },
        "summary": {
          "minutesInSleepPeriod": "464",
          "minutesAfterWakeUp": "0",
          "minutesToFallAsleep": "0",
          "minutesAsleep": "407",
          "minutesAwake": "57",
          "stagesSummary": [
            {
              "type": "AWAKE",
              "minutes": "56",
              "count": "12"
            },
            {
              "type": "LIGHT",
              "minutes": "198",
              "count": "19"
            },
            {
              "type": "DEEP",
              "minutes": "114",
              "count": "10"
            },
            {
              "type": "REM",
              "minutes": "94",
              "count": "4"
            }
          ]
        },
        "createTime": "2026-03-04T04:43:40.337983Z",
        "updateTime": "2026-03-04T04:43:40.937183Z"
      }
    }
  ],
  "nextPageToken": ""
}

כדי לצבור נקודות נתונים בחלון זמן מסוים שמוגבל למשפחה מסוימת של מקורות נתונים, מפעילים את נקודת הקצה rollUp ומעבירים את השדה dataSourceFamily בגוף הבקשה ב-JSON.

בקשת ה-POST הבאה שולחת שאילתה לגבי מספר הצעדים היומיים במרווחי שעה (3600s), שמצטברים רק ממכשירים לבישים:

בקשה

POST https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints:rollUp
Authorization: Bearer access-token
Accept: application/json

{
  "range": {
    "startTime": "2026-07-29T00:00:00Z",
    "endTime": "2026-07-29T23:59:59Z"
  },
  "windowSize": "3600s",
  "dataSourceFamily": "users/me/dataSourceFamilies/google-wearables"
}

תשובה

{
  "rollupDataPoints": [
    {
      "startTime": "2026-07-29T08:00:00Z",
      "endTime": "2026-07-29T09:00:00Z",
      "steps": {
        "countSum": "1200"
      }
    },
    {
      "startTime": "2026-07-29T09:00:00Z",
      "endTime": "2026-07-29T10:00:00Z",
      "steps": {
        "countSum": "3450"
      }
    }
  ]
}

כדי לצבור נקודות נתונים יומיות של משפחת מקורות ספציפית, מפעילים את נקודת הקצה dailyRollUp ומעבירים את השדה dataSourceFamily בגוף הבקשה.

לדוגמה, הבקשה הבאה מחשבת את הסיכומים היומיים של הצעדים של המשתמש, כולל כל המקורות של Google ו-Fitbit (מכשירים לבישים + הזנות ידניות):

בקשה

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": 7,
        "day": 28
      },
      "time": {
        "hours": 0,
        "minutes": 0,
        "seconds": 0,
        "nanos": 0
      }
    },
    "end": {
      "date": {
        "year": 2026,
        "month": 7,
        "day": 30
      },
      "time": {
        "hours": 0,
        "minutes": 0,
        "seconds": 0,
        "nanos": 0
      }
    }
  },
  "windowSizeDays": 1,
  "dataSourceFamily": "users/me/dataSourceFamilies/google-sources"
}

תשובה

{
  "rollupDataPoints": [
    {
      "civilStartTime": {
        "date": {
          "year": 2026,
          "month": 7,
          "day": 28
        },
        "time": {}
      },
      "civilEndTime": {
        "date": {
          "year": 2026,
          "month": 7,
          "day": 28
        },
        "time": {
          "hours": 23,
          "minutes": 59,
          "seconds": 59
        }
      },
      "steps": {
        "countSum": "8430"
      }
    },
    {
      "civilStartTime": {
        "date": {
          "year": 2026,
          "month": 7,
          "day": 29
        },
        "time": {}
      },
      "civilEndTime": {
        "date": {
          "year": 2026,
          "month": 7,
          "day": 29
        },
        "time": {
          "hours": 23,
          "minutes": 59,
          "seconds": 59
        }
      },
      "steps": {
        "countSum": "11245"
      }
    }
  ]
}

צבירת נקודות נתונים בטווח זמן מסוים

משתמשים בנקודת הקצה rollUp כדי להחזיר את צבירת נקודות הנתונים על סמך חלון בזמן של שניות, בטווח datetime על סמך הזמן הפיזי של המשתמשים (ב-UTC).

כשמתקשרים לנקודת הקצה rollUp, צריך לספק את גוף הבקשה שמייצג את טווח הזמן הנדרש ואת windowSize. חשוב לשים לב לדרישות הבאות לגבי windowSize:

  • גודל החלון המינימלי: משך הזמן windowSize צריך להיות שנייה אחת לפחות ("1s"). משכי זמן של פחות משנייה, אפס או משכי זמן שליליים יידחו עם שגיאה 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 כשרוצים לצבור נתונים על פני יום אחד או כמה ימים, שנקראים windowSize. בגוף הבקשה, מציינים את טווח הזמן האזרחי הסגור-פתוח של המרווח הנדרש. בהתאם לסוג הנתונים, תקבלו את הסכום או את הממוצע של הנתונים במהלך המרווח.

לדוגמה:

בקשה

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"
      }
    }
  ]
}

חלוקה לקטגוריות כשטווח הערכים הוא לא כפולה של גודל החלון

אם הטווח המבוקש הוא לא כפולה מדויקת של windowSize (או של windowSizeDays), החלק האחרון של הנתונים יקוצר בנקודת הקצה העליונה של הטווח, והמשך שלו יהיה קצר יותר מגודל חלון הזמן. ה-API מקבל את הבקשה שלכם ללא שינוי, ולא מבצע עיגול, הזזות זמן או אינטרפולציה של נתונים.

כדי לכסות את כל הטווח המבוקש, ה-API משתמש בחלוקה עם עיגול כלפי מעלה כדי לחשב את המספר הכולל של חלונות הצבירה:

Number of windows = ceiling(Range duration / Window size)

כל דלי מתחיל ברצף מתחילת הטווח. אם הוספה של חלון נוסף בגודל מלא תגרום לחריגה משעת הסיום שביקשתם, החלון האחרון ייחתך (clamp) בשעת הסיום של הטווח.

איך פועל תהליך הסיווג למשפכים

כשמבקשים נתוני סיכום עם טווחי תאריכים שלא מתחלקים, ה-API מחיל את הכללים הבאים:

  • החלוקה לקבוצות מתחילה בתחילת הטווח המבוקש (range.startTime או range.start) ומתקדמת קדימה לפי גודל החלון (windowSize או windowSizeDays).
  • המשבצת האחרונה לפי סדר כרונולוגי מוגבלת לסוף הטווח המבוקש (range.endTime או range.end), כלומר היא מכסה משך זמן קצר יותר מגודל החלון המבוקש.
  • באובייקטים RollupDataPoint או DailyRollupDataPoint שמוחזרים מצוינים באופן מפורש חותמות הזמן של ההתחלה והסיום שלהם, שאפשר להשתמש בהן כדי לבדוק את משך הזמן בפועל של הקטגוריה שקוצצה.
  • ה-API מחזיר נתונים מצטברים בסדר כרונולוגי הפוך (החדשים ביותר קודם), ולכן הקטגוריה הכרונולוגית האחרונה (זו שקוצצה) מופיעה כרכיב הראשון (index 0) ברשימה שמוחזרת.

תרחיש: טווח של 12 דקות עם חלון של 5 דקות

נניח שלקוח מבקש איחוד לתצוגה אחת של נתונים בטווח של 12 דקות עם מרווח של 5 דקות בין כל איחוד לתצוגה אחת:windowSize

  • range.startTime: 10:00:00
  • ‫range.endTime: 10:12:00 (משך כולל: 12 דקות)
  • windowSize: 5 minutes

‫12 דקות הן לא כפולה של 5 דקות (12 = 5 * 2 + 2), ולכן ה-API מקבל את הבקשה ומחשב את מספר החלונות כ-ceiling(12 / 5) = 3.

כך נוצרות שלוש קטגוריות כרונולוגיות:

  1. תא 1: [10:00:00, 10:05:00) — משך זמן: 5 דקות (חלון מלא)
  2. מאגר 2: [10:05:00, 10:10:00) — משך זמן: 5 דקות (חלון מלא)
  3. ‫Bucket 3 (Truncated): [10:10:00, 10:12:00) — Duration: 2 minutes (truncated at range.endTime)

ההשפעה על ערכים מצטברים

מכיוון שהחלון הסופי קצר יותר, מדדים מצטברים (כמו סכום או מספר השלבים) יהיו נמוכים יותר בדלי שקוצץ רק בגלל ציר הזמן הקצר יותר.

אם משתמש הולך בקצב קבוע של 100 צעדים בדקה במהלך כל טווח 12 הדקות הזה:

  • קבוצה 1 (10:00 עד 10:05): 500 צעדים (5 דקות × 100 צעדים בדקה)
  • קבוצה 2 (10:05 עד 10:10): 500 צעדים (5 דקות × 100 צעדים לדקה)
  • קבוצה 3 (10:10 עד 10:12): 200 צעדים (2 דקות × 100 צעדים לדקה)

דוגמה לתגובה מה-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"
      }
    }
  ]
}

גודל חלון הסיכום והרזולוציה של האחסון הבסיסי

למרות שנקודת הקצה rollUp מקבלת כל windowSize של שנייה אחת או יותר, סוגי נתונים שונים מתעדים ושומרים מדידות בקצבי דגימה שונים או במרווחי זמן שונים באחסון הבסיסי. לדוגמה, מדדים של פעילות גופנית שמתבצעת עם מכשיר לביש, כמו steps, distance, active-minutes ו-active-energy-burned, בדרך כלל נרשמים במרווחי זמן של דקה אחת (60s).

כשמצטברים נתונים מסוגי נתונים של מרווחי זמן, נקודת הקצה rollUp ממקמת כל נקודה על הגרף שנרשמה בדלי שמכיל את startTime של נקודה על הגרף. ה-API לא מבצע פילוח, אינטרפולציה או חלוקה של נתונים של מרווחי זמן בין משבצות של מרווחי זמן משנה.

אם מציינים windowSize שקטן ממרווח אחסון הנתונים הבסיסי (לדוגמה, אם מבקשים חלון זמן של 10 שניות לנתוני steps שאוחסנו במרווחים של דקה אחת):

  1. הדלי המשני הראשון שתואם ל-startTime של המרווח (לדוגמה, 10:00:00 עד 10:00:10) מקבל את הספירה המצטברת של הדקה כולה (לדוגמה, כל 100 הצעדים שתועדו באותה דקה).
  2. המשבצות הנותרות באותה דקה (10:00:10 עד 10:00:20,‏ 10:00:20 עד 10:00:30 וכן הלאה) לא מקבלות נקודות נתונים, כי אף מרווח לא מתחיל בחלונות האלה.

התוצאה היא נתונים עם עליות וירידות חדות, שבהם הערך של כל המרווח מרוכז בחלון המשנה הראשון.

כדי לקבל נתונים מצטברים משמעותיים ומפוזרים באופן שווה, צריך תמיד להגדיר את windowSize למשך זמן ששווה לזמן של רזולוציית האחסון הבסיסית של סוג נתוני היעד או גדול ממנו (לדוגמה, 60s או יותר עבור steps). למידע על רזולוציית האחסון וחלון הצבירה המומלץ המינימלי לכל סוג נתונים, אפשר לעיין בהפניה סוגי נתונים ב-Google Health API.

עדכון נתוני בריאות וכושר של משתמש

כדי לעדכן את נתוני הבריאות וכושר של משתמש, משתמשים בנקודת הקצה patch.

נקודת הקצה patch מעדכנת רשומה קיימת על סמך המזהה שצוין בכתובת ה-URL של הבקשה. מזינים את המזהה של נקודה על הגרף שהוזנה קודם. ה-API מחליף את הרשומה הקיימת.

בעלי הרשומה יכולים גם לעדכן את חותמות הזמן של המרווח של נקודת נתונים (startTime ו-endTime), או להעביר אותן מפלטפורמות במעלה הזרם כמו Health Connect. פרטים על שינוי חותמות זמן מופיעים במדריך לניהול נתונים. דוגמה לעדכון חותמות זמן של מרווחי זמן זמינה במאמר בנושא עדכון חותמות זמן של מרווחי זמן לנתונים קיימים.

מתי כדאי להשתמש במזהה של נקודה על הגרף

מזהה נקודת הנתונים חיוני בתרחישים הבאים:

  • עדכונים ממוקדים: כדי לעדכן מדידה ספציפית, צריך לספק את המזהה שלה בבקשת patch.
  • מחיקות: שמירת המזהה מאפשרת לאפליקציה למחוק את הרשומה בשלב מאוחר יותר באמצעות נקודת הקצה batchDelete.

לדוגמה, משתמש מעדכן את נתוני אחוז השומן בגוף שלו במשקל שנקרא HumanScale של חברת Scales R Us. התוצאה החדשה של מדידת אחוז השומן בגוף של המשתמש היא 20% בתאריך 2026-03-10:

בקשה

PATCH https://health.googleapis.com/v4/users/me/dataTypes/body-fat/dataPoints/1234567890
Authorization: Bearer access-token
Content-Type: application/json

{
  "name": "users/me/dataTypes/body-fat/dataPoints/1234567890",
  "dataSource": {
    "recordingMethod": "ACTIVELY_MEASURED",
    "device": {
      "formFactor": "SCALE",
      "manufacturer": "Scales R Us",
      "displayName": "HumanScale"
    }
  },
  "bodyFat": {
    "sampleTime": {
      "physicalTime": "2026-03-10T10:00:00Z"
    },
    "percentage": 20
  }
}

תשובה

{
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.devicesandservices.health.v4main.DataPoint",
    "name": "users/123456789/dataTypes/body-fat/dataPoints/1234567890",
    "dataSource": {
      "recordingMethod": "ACTIVELY_MEASURED",
      "device": {
        "formFactor": "SCALE",
        "manufacturer": "Scales R Us",
        "displayName": "HumanScale"
      },
      "application": {
        "googleWebClientId": "618308034039.apps.googleusercontent.com"
      },
      "platform": "GOOGLE_WEB_API"
    },
    "bodyFat": {
      "sampleTime": {
        "physicalTime": "2026-03-10T10:00:00Z"
      },
      "percentage": 20
    }
  }
}

עדכון חותמות הזמן של מרווחי העדכון לנתונים קיימים

כדי לעדכן את חותמות הזמן של המרווח (startTime ו-endTime במטען ייעודי (payload) של JSON ב-REST, או start_time ו-end_time ב-gRPC) של נקודה על הגרף קיימת, שולחים בקשת PATCH אל ה-URI של משאב נקודה על הגרף. רק היוצר או הבעלים המקוריים של רשומה יכולים לשנות את השדות שלה. אפליקציות לא יכולות לערוך נקודות נתונים שהן לא יצרו.

מידע נוסף על שינוי חותמות זמן, על עדכונים במעלה הזרם מ-Health Connect ועל השלכות של שמירת נתונים במטמון זמין במדריך לניהול נתונים.

בדוגמה הבאה מוצג עדכון של חותמות הזמן של המרווחים ביומן הידרציה קיים באמצעות נקודת הקצה patch על ידי אפליקציית הבעלים:

בקשה

PATCH https://health.googleapis.com/v4/users/me/dataTypes/hydration-log/dataPoints/4093039283164890826
Authorization: Bearer access-token
Content-Type: application/json

{
  "hydrationLog": {
    "interval": {
      "startTime": "2026-09-03T10:05:00Z",
      "endTime": "2026-09-03T10:19:59Z"
    },
    "amountConsumed": {
      "milliliters": 350
    }
  }
}

תשובה

{
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.devicesandservices.health.v4.DataPoint",
    "name": "users/111111256096816351/dataTypes/hydration-log/dataPoints/4093039283164890826",
    "hydrationLog": {
      "interval": {
        "startTime": "2026-09-03T10:05:00Z",
        "endTime": "2026-09-03T10:19:59Z",
        "civilStartTime": {
          "date": {
            "year": 2026,
            "month": 9,
            "day": 3
          },
          "time": {
            "hours": 10,
            "minutes": 5
          }
        },
        "civilEndTime": {
          "date": {
            "year": 2026,
            "month": 9,
            "day": 3
          },
          "time": {
            "hours": 10,
            "minutes": 19,
            "seconds": 59
          }
        }
      },
      "amountConsumed": {
        "milliliters": 350
      }
    }
  }
}

רישום פריט מזון

כדי לתעד פריט מזון, שולחים בקשת POST לנקודת הקצה nutrition-log dataPoints. גוף הבקשה מכיל DataPoint עם אובייקט nutritionLog. מידע נוסף זמין במדריך התזונה.

לדוגמה:

בקשה

POST https://health.googleapis.com/v4/users/me/dataTypes/nutrition-log/dataPoints
Authorization: Bearer access-token
Content-Type: application/json

{
  "nutritionLog": {
    "interval": {
      "startTime": "2026-06-16T12:00:00Z",
      "endTime": "2026-06-16T12:30:00Z"
    },
    "foodDisplayName": "Banana",
    "mealType": "LUNCH",
    "energy": {
      "kcal": 105
    },
    "totalCarbohydrate": {
      "grams": 27
    },
    "totalFat": {
      "grams": 0.3
    }
  }
}

תשובה

{
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.devicesandservices.health.v4.DataPoint",
    "name": "users/123456789/dataTypes/nutrition-log/dataPoints/567890",
    "dataSource": {
      "recordingMethod": "ACTIVELY_MEASURED",
      "platform": "GOOGLE_WEB_API"
    },
    "nutritionLog": {
      "interval": {
        "startTime": "2026-06-16T12:00:00Z",
        "startUtcOffset": "0s",
        "endTime": "2026-06-16T12:30:00Z",
        "endUtcOffset": "0s"
      },
      "energy": {
        "kcal": 105
      },
      "totalCarbohydrate": {
        "grams": 27
      },
      "totalFat": {
        "grams": 0.3
      },
      "mealType": "LUNCH",
      "foodDisplayName": "Banana"
    }
  }
}

מחיקת נתוני בריאות וכושר של משתמשים

אפשר להשתמש בbatchDelete שיטה כדי למחוק מערך של נתוני האפליקציה של משתמש באפליקציית Fitbit.

לדוגמה, משתמש שרשם בעבר את אחוז השומן בגוף שלו באמצעות משקל, אבל רוצה למחוק את הרשומה. שימוש ב-user-id וב-data-point-id מפעולת ההוספה המקורית:

בקשה

POST https://health.googleapis.com/v4/users/me/dataTypes/body-fat/dataPoints:batchDelete
Authorization: Bearer access-token
Accept: application/json
content-length: 93

{
  "names": [
    "users/123456789/dataTypes/body-fat/dataPoints/1234567890"
  ]
}

תשובה

{
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.devicesandservices.health.v4main.BatchDeleteDataPointsResponse"
  }
}

איך מוצאים את פרטי המכשיר

אפשר להשתמש בנקודת הקצה list כדי לאחזר את רשימת המכשירים שמשויכים לחשבון של משתמש. המידע הזה כולל את פרטי הדגם של המכשיר (deviceVersion) ואת הפעם האחרונה שבה הוא סונכרן עם אפליקציית Google Health לנייד (lastSyncTime).

ההגדרה של הרשימה ופרטי הסנכרון שימושיים לפתרון בעיות בסנכרון או לאחזור נתונים היסטוריים מאז זמן הסנכרון האחרון.

לדוגמה:

בקשה

GET https://health.googleapis.com/v4/users/me/pairedDevices
Authorization: Bearer access-token
Accept: application/json

תשובה

{
  "pairedDevices": [
    {
      "name": "users/me/pairedDevices/123456",
      "deviceType": "TRACKER",
      "batteryStatus": "High",
      "batteryLevel": 88,
      "lastSyncTime": "2026-03-04T07:05:00Z",
      "deviceVersion": "Charge 6",
      "macAddress": "00:11:22:33:44:55",
      "features": [
        "STEPS",
        "HEART_RATE"
      ]
    }
  ]
}

שאילתת נתונים היסטוריים

אחד היתרונות המרכזיים של Google Health API הוא היכולת לעקוב אחרי הביצועים של המשתמש ולנטר את המדדים החיוניים שלו לאורך תקופות ארוכות. אפשר לשלוח שאילתה לגבי נתוני משתמשים עד לנקודה שבה הם נרשמו. ה-API לא מטיל מגבלות על כמות הנתונים ההיסטוריים שאפשר להשתמש בהם באפליקציה.

עם זאת, שאילתות של נתונים היסטוריים עדיין כפופות למגבלות הקצב הרגילות. כדי לשמור על יציבות המערכת ולמנוע עומס יתר על השרתים, Google Health API משתמש בחלוקה אוטומטית לדפים עם גדלים ספציפיים של דפים לנקודות קצה. חשוב לשים לב לגבולות ולמאפיינים הבאים:

  • חלוקה אוטומטית לדפים: אם מבצעים שאילתה על טווח ארוך של נתונים, ה-API יחזיר רק את הדף הראשון של התוצאות עד למגבלת גודל הדף של נקודת הקצה הזו, יחד עם nextPageToken. כדי לבקש דפים נוספים, צריך להשתמש ב-nextPageToken.
  • גדלים משתנים של דפים: מגבלות ה-capping תלויות בנקודת הקצה ובסוג הנתונים. ברוב סוגי הנתונים, גודל הדף מוגבל ל-10,000. עם זאת, עבור סוגי נתונים מסוימים כמו exercise ו-sleep, גודל הדף המקסימלי וגודל הדף שמוגדר כברירת מחדל מוגבל ל-25. לדוגמה, אם לקוח מבקש את כל נתוני השינה ב-10 השנים האחרונות, ה-API עדיין יחזיר רק 25 סשנים של שינה בדף הראשון.
  • הגבלות על טווחי תאריכים של נתונים מצטברים: בנקודות קצה של נתונים מצטברים (כמו rollUp ו-dailyRollUp), טווחי התאריכים של השאילתות מוגבלים על סמך סוג הנתונים:
    • טווח מקסימלי של 14 ימים ל-calories-in-heart-rate-zone, heart-rate,‏ active-minutes ו-total-calories.
    • טווח מקסימלי של 90 ימים לכל שאר סוגי הנתונים המצטברים.

בהתאם לנפח הנתונים ההיסטוריים שנדרשים לאפליקציה, כדי לאחזר את מערך הנתונים כולו צריך להשתמש בהחלפה בין דפים באופן רציף. חשוב לזכור את זה כשמתכננים את תהליך סנכרון הנתונים של האפליקציה.

כדי להבטיח ביצועים אופטימליים ולמנוע שגיאות ב-API, כדאי לפעול לפי ההנחיות הבאות כששולחים שאילתות לגבי נתונים היסטוריים:

סנכרון נתונים בשלבים (טעינה חמה לעומת הפעלה מההתחלה)

  • טעינה ראשונית של נתונים עדכניים: במהלך רצף הטעינה הראשי, המערכת מאחזרת ומציגה רק את הנתונים מ-7 עד 14 הימים האחרונים. כך המשתמשים רואים את הנתונים באופן מיידי בלי לחכות לשאילתות ארוכות.
  • טעינה 'קרה' ברקע: אחזור של נתונים היסטוריים ישנים יותר מועבר לתור אסינכרוני בעדיפות נמוכה יותר או לתהליך ברקע אחרי שהממשק הראשי מוצג.

חלוקת שאילתות לצורך צבירה

  • בגלל שבנקודות הקצה של סיכום הנתונים וסיכום הנתונים היומי יש מגבלה על טווח התאריכים (14 או 90 יום, בהתאם לסוג הנתונים), צריך לפצל שאילתות גדולות של נתונים היסטוריים מצטברים למרווחי זמן קטנים יותר ועוקבים, במסגרת המגבלות האלה.
  • כדי לכבד את מגבלות הריצה המקבילית ולשמור על אינדיקטורים יציבים של התקדמות ממשק המשתמש, כדאי להריץ את שאילתות המשנה האלה בקבוצות או ברצף.

שימוש בסיכומי נתונים מצטברים

ארגון מחדש של לוחות הבקרה של הסקירה הכללית ושל תרשימי המגמות כדי להשתמש בנקודות קצה של סיכום (כמו DailyRollUpDataPoints) שעברו צבירה מראש. כך יצטמצם באופן משמעותי העומס על העיבוד בעורף וזמן ההעברה ברשת ללקוח.

טיפול בשגיאות בצורה גמישה (ניסיונות חוזרים חכמים)

  • כדאי להטמיע טיפול קפדני בהשהיה מעריכית לפני ניסיון חוזר (exponential backoff) כשנתקלים במגבלות קצב (429 Too Many Requests) ובפסק זמן של שער השרת (504 Gateway Timeout). לעולם אל תנסו לשלוח שוב מטען ייעודי גדול שנכשל באופן מיידי. ניסיונות חוזרים מיידיים מגבירים את העומס על השרתים ומחמירים את הירידה בביצועי המערכת.