Daten filtern

Die Google Health API verwendet Filterausdrücke, um die zurückgegebenen Datenpunkte beim Aufrufen von Standardabrufmethoden einzuschränken. Insbesondere werden Filter für Folgendes verwendet:

In diesem Leitfaden wird beschrieben, wie die Filterung implementiert wird. Außerdem werden die Syntax und Konventionen erläutert und es sind Beispiele für jeden Datensatztyp enthalten.

Filterkonventionen

Die Google Health API implementiert Filter gemäß dem Standard Google API Improvement Proposals (AIP-160).

Suchparameter

Filter werden über den URL-Abfragestring im Parameter filter übergeben. Da Filter Sonderzeichen wie <, >= und Anführungszeichen enthalten, müssen sie bei der Übertragung in der HTTP-Anfrage URL-codiert werden.

Eine Anfrage mit dem Filter steps.interval.civil_start_time >= "2026-03-04T00:00:00" sollte beispielsweise so codiert werden:

GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints
  ?filter=steps.interval.civil_start_time%20%3E%3D%20%222026-03-04T00%3A00%3A00%22

Namensformat

Wenn ein Datentyp aus mehreren Wörtern besteht, unterscheidet sich das Format des Bezeichners zwischen dem Ressourcenpfad und dem Filter:

  • Endpunktpfad: Verwenden Sie Bindestriche (z. B. /dataTypes/body-fat).
  • Filterstring: Verwenden Sie Unterstriche (z. B. body_fat).

Wenn Sie Bindestriche in der Filter-ID verwenden, gibt die API einen 400 Bad Request mit dem Fehlergrund INVALID_DATA_POINT_FILTER zurück.

Filtertypen und ‑felder

Die Felder, die Sie in einem Filter verwenden, hängen vom Datensatztyp des Datentyps ab, den Sie abfragen. In der folgenden Tabelle werden die Felder beschrieben, die für die einzelnen Datensatztypen unterstützt werden:

Eintragstyp Beschreibung Unterstützte Filterfelder
Intervall Datenpunkte, die über einen bestimmten Zeitraum aufgezeichnet wurden (z. B. steps, distance, calories). {dataType}.interval.start_time
{dataType}.interval.civil_start_time

Beispiel
steps.interval.civil_start_time
Probe Momentane Beobachtungen oder kurze Messungen (z. B. weight, body-fat, blood-glucose). {dataType}.sample_time.physical_time
{dataType}.sample_time.civil_time

Beispiel
body_fat.sample_time.physical_time
Täglich Tägliche Messwerte und Zusammenfassungen (z. B. daily-heart-rate-variability). {dataType}.date

Beispiel
daily_heart_rate_variability.date
Sitzung Längere Nutzersitzungen mit speziellen Zeitregeln. Training:{dataType}.interval.civil_start_time
Schlaf:sleep.interval.end_time, sleep.interval.civil_end_time
EKG:electrocardiogram.interval.start_time

Beispiel:
sleep.interval.civil_end_time

Unterstützte Operatoren und Formatierungsregeln

Filterausdrücke müssen den folgenden Formatierungsregeln entsprechen:

Vergleichsoperatoren

Es werden nur zwei Vergleichsoperatoren unterstützt:

Operator Beschreibung
>= Untere Grenze (einschließlich).
< Obergrenze (ausschließlich).

Bei Verwendung anderer Vergleichsoperatoren (z. B. >, <= oder =) wird ein 400 Bad Request mit INVALID_DATA_POINT_FILTER_RESTRICTION_COMPARATOR zurückgegeben.

Logische Operatoren

Operator Support
AND Standardoperator und einziger unterstützter Operator. Wird verwendet, um Start- und Endgrenzen zu kombinieren.
OR Nicht unterstützt. Bei Verwendung von OR wird ein 400 Bad Request mit dem Fehlergrund INVALID_DATA_POINT_FILTER_EXPRESSION_STRUCTURE zurückgegeben („Der Filter muss eine Konjunktion oder Folge von Einschränkungen sein. Gefunden: DISJUNCTION“).

Uhrzeitliterale

Zeitliterale in Filterausdrücken müssen diese Formate verwenden:

Time-Typ Voraussetzungen Beispiele
Physische Zeit RFC 3339-Format, das mit Z oder einem UTC-Offset endet. Stellt Ereignisse in der realen Welt in UTC dar. Richtig: "2026-03-01T00:00:00Z", "2026-03-01T00:00:00-08:00"
Falsch: "2026-03-01"
Bürgerliche Zeit ISO 8601-Format: YYYY-MM-DD[THH:mm:ss]. Stellt die Zeit auf der Uhr eines Nutzers dar, unabhängig von Standort oder Zeitzonenabweichungen. Richtig: "2026-03-01", "2026-03-01T08:30:00"

Validierungsregeln filtern

Für Filter gelten die folgenden Regeln:

Regel Beschreibung Beispiele
Keine gemischten Zeittypen Mischen Sie keine physischen und bürgerlichen Zeitgrenzen. Ungültig: steps.interval.start_time >= "2026-03-01T00:00:00Z" AND steps.interval.civil_start_time < "2026-03-02"
Fehler: INVALID_DATA_POINT_FILTER_MIXED_TIME_RESTRICTIONS („Filter cannot contain both physical and civil time ranges“)
Keine gemischten Datentypen Verwenden Sie Felder, die zum Datentyp gehören, im Anfragepfad. Ungültig: Pfad /users/.../dataTypes/steps/... mit Filter distance.interval.start_time >= "..."
Fehler: INVALID_DATA_POINT_FILTER_COLLECTION_MISMATCH („Datentyp im Filter stimmt nicht mit der übergeordneten Datentyp-Sammlung überein“)
Logik für die Zeitreihenfolge Die Obergrenze muss größer als die Untergrenze sein. Ungültig: steps.interval.start_time >= "2026-03-02T00:00:00Z" AND steps.interval.start_time < "2026-03-01T00:00:00Z"
Fehler: INVALID_TIME_RANGE („Query end time must be strictly larger than start time“)
Gehäuseformat Verwenden Sie die Snake-Case-Schreibweise, die dem Namen des Datentyps entspricht. Ungültig: body-fat.sample_time.physical_time >= "..."
Fehler: INVALID_DATA_POINT_FILTER („Ungültiger Filter“)

Die API gibt HTTP-Statuscode 400 Bad Request für ungültige Filter zurück. Sehen Sie in error.details[].metadata.detailedReasons nach dem Fehlergrundcode.

Erforderliche OAuth-Bereiche

Wenn Sie Datenpunkte mit Filtern abfragen möchten, muss der autorisierte Nutzer den entsprechenden OAuth-Bereich für diesen Datentyp gewähren. Wenn der erforderliche Bereich fehlt, gibt die API den Status 403 Forbidden mit MISSING_OAUTH_SCOPE zurück.

In der folgenden Tabelle werden OAuth-Bereiche den Datentypen zugeordnet, für die sie Lesezugriff gewähren. In der Tabelle werden Bereiche im relativen Format angezeigt (z. B. .activity_and_fitness.readonly für https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly):

Erforderlicher OAuth-Bereich Datentypen
.activity_and_fitness.readonly active-energy-burned, active-minutes, active-zone-minutes, activity-level, altitude, calories-in-heart-rate-zone, daily-vo2-max, distance, exercise, floors, run-vo2-max, sedentary-period, steps, swim-lengths-data, time-in-heart-rate-zone, total-calories, vo2-max
.ecg.readonly Elektrokardiogramm
.health_metrics_and_measurements.readonly blutzucker, körperfett, körpertemperatur, tägliche-herzfrequenzvariabilität, tägliche-herzfrequenzzonen, tägliche-sauerstoffsättigung, tägliche-atemfrequenz, tägliche-ruheherzfrequenz, tägliche-schlaftemperatur-ableitungen, herzfrequenz, herzfrequenzvariabilität, größe, sauerstoffsättigung, atemfrequenz-schlafzusammenfassung, hauttemperatursensoren, gewicht
.irn.readonly Benachrichtigung über einen unregelmäßigen Herzrhythmus
.nutrition.readonly food, food-measurement-unit, hydration-log, nutrition-log
.sleep.readonly Schlaf

Wenn Ihrem Client für einen angeforderten Datentyp nur ein Schreibbereich (z. B. .activity_and_fitness.writeonly) gewährt wird, können Sie trotzdem Datenpunkte abfragen, die von Ihrem eigenen Client geschrieben wurden. In diesem Fall sind Anfragen implizit auf die Datenquellenfamilie self-sources beschränkt. Weitere Informationen und Einschränkungen für Datentypen finden Sie unter Nach Datenquellenfamilie filtern.

Anwendungsfälle und Beispiele

Die folgenden Beispiele zeigen, wie Sie Filter für gängige Szenarien erstellen:

Schritte nach physischem Zeitraum abfragen

Schritte, die zwischen 2026-03-01T00:00:00Z (einschließlich) und 2026-03-02T00:00:00Z (ausschließlich) aufgezeichnet wurden:

GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints
  ?filter=steps.interval.start_time >= "2026-03-01T00:00:00Z"
  AND steps.interval.start_time < "2026-03-02T00:00:00Z"

Schritte nach bürgerlichem Zeitbereich abfragen

Schritte für einen ganzen Tag am 4. März 2026 abfragen, bezogen auf die Ortszeit des Nutzers:

GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints
  ?filter=steps.interval.civil_start_time >= "2026-03-04"
  AND steps.interval.civil_start_time < "2026-03-05"

Körperfett nach physischer Probenahmezeit abfragen

Körperfettmessungen abfragen, die ab März 2026 aufgezeichnet wurden (in UTC):

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

Gewichtung der Abfrage nach ziviler Stichprobenzeit

Gewichtsprotokolle abrufen, die nach einer bestimmten Ortszeit aufgezeichnet wurden:

GET https://health.googleapis.com/v4/users/me/dataTypes/weight/dataPoints
  ?filter=weight.sample_time.civil_time >= "2026-03-01T08:00:00"

Tageszusammenfassungen zur Herzfrequenzvariabilität abfragen

Tageszusammenfassungen zur Herzfrequenzvariabilität (HFV) abfragen, die vor einem bestimmten Datum aufgezeichnet wurden:

GET https://health.googleapis.com/v4/users/me/dataTypes/daily-heart-rate-variability/dataPoints
  ?filter=daily_heart_rate_variability.date < "2026-08-15"

Trainingseinheiten nach zivilem Startzeitpunkt abfragen

Abfrage von Trainingseinheiten, die in einer bestimmten Woche in der lokalen Zeitzone des Nutzers stattgefunden haben:

GET https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints
  ?filter=exercise.interval.civil_start_time >= "2026-03-01"
  AND exercise.interval.civil_start_time < "2026-03-08"

Schlafeinheiten nach bürgerlicher Endzeit abfragen

Schlafaufzeichnungen nach der Endzeit der Sitzung abfragen:

GET https://health.googleapis.com/v4/users/me/dataTypes/sleep/dataPoints
  ?filter=sleep.interval.civil_end_time >= "2026-03-04T05:00:00"
  AND sleep.interval.civil_end_time < "2026-03-04T12:00:00"

EKGs nach Startzeit abfragen

EKG-Aufzeichnungen ab einem bestimmten UTC-Zeitpunkt abfragen. Beachten Sie, dass EKG-Anfragen nur einen >=-Vergleich für start_time unterstützen:

GET https://health.googleapis.com/v4/users/me/dataTypes/electrocardiogram/dataPoints
  ?filter=electrocardiogram.interval.start_time >= "2026-03-10T12:00:00Z"

Nach Datenquellenfamilie filtern

Eine Datenquellenfamilie ist eine logische Gruppierung von Datenquellen (z. B. Smartwatches, mobile Apps oder manuelle Einträge). Damit können Sie Daten aus bestimmten Quelltypen isolieren oder zusammenfassen, z. B. von körperlichen Wearables, manuellen Einträgen oder Daten, die von Ihrem eigenen Client geschrieben wurden.

Die Endpunkte list, reconcile, rollUp und dailyRollUp unterstützen alle den Parameter dataSourceFamily. Der Übergabemechanismus hängt vom Endpunkt ab:

Endpunkt (HTTP-Methode) Mechanismus
list (GET) Übergeben Sie dataSourceFamily als URL-Suchparameter.
reconcile (GET) Übergeben Sie dataSourceFamily als URL-Suchparameter.
rollUp (POST) Übergeben Sie dataSourceFamily als Feld im JSON-Anfragetext.
dailyRollUp (POST) Übergeben Sie dataSourceFamily als Feld im JSON-Anfragetext.

Unterstützte Datenquellenfamilien

In der folgenden Tabelle werden die unterstützten dataSourceFamily-Werte beschrieben:

Option Beschreibung
users/me/dataSourceFamilies/all-sources Standardwert (wenn ein Lesebereich gewährt wird) Enthält Datenpunkte aus allen verfügbaren selbst erhobenen (1P) und Drittanbieterdatenquellen (3P). Bei dieser Option werden Daten aus Drittanbieter-Apps zurückgegeben, z. B. Schritte von der Smartwatch, Schritte aus Drittanbieter-Apps, Schritte vom Smartphone und manuell eingegebene Schritte.
users/me/dataSourceFamilies/google-wearables Enthält Daten, die von Google- und Fitbit-Trackern (z. B. Fitbit-Wearables und Pixel Watch) aufgezeichnet wurden. Manuell erfasste Daten und vom Smartphone geschätzte Daten sind ausgeschlossen. Verwenden Sie diese Option, wenn für Ihre Integration rohe Sensortelemetriedaten erforderlich sind, die direkt von der Wearable-Hardware aufgezeichnet werden.
users/me/dataSourceFamilies/google-sources Beinhaltet selbst erhobene Daten von Google und Fitbit. Dazu gehören Aufzeichnungen von Tracker-Geräten, Daten von Health Connect und alle manuellen Einträge, die über Erstanbieter-Apps wie die Fitbit App oder Google Fit protokolliert wurden.
users/me/dataSourceFamilies/self-sources Enthält nur die Daten, die der aufrufende Client über die Google Health API geschrieben hat (Datenpunkte, deren Datenquelle über die API mit derselben OAuth-Client-ID wie der Aufrufer registriert wurde).

Wenn kein Datenpunkt der angeforderten Datenquellenfamilie entspricht, ist die Antwort eine leere Liste und kein Fehler.

Bereiche mit Schreibzugriff und eigene Quellen

Aufrufer, denen nur Schreibbereiche (z. B. .activity_and_fitness.writeonly) für die angeforderten Datentypen gewährt werden, können nur die Daten lesen, die sie selbst geschrieben haben.

  • Anfragen ohne expliziten dataSourceFamily-Parameter oder mit dataSourceFamily auf users/me/dataSourceFamilies/self-sources festgelegt sind implizit auf self-sources beschränkt.
  • Wenn Sie eine andere Datenquellenfamilie (z. B. all-sources, google-wearables oder google-sources) mit nur einem Schreibbereich anfordern, schlägt die Anfrage mit dem Fehler 403 Forbidden (PERMISSION_DENIED) fehl.

Datentypbeschränkungen für den Listenendpunkt

Beim list-Endpunkt (users.dataTypes.dataPoints.list) wird das Filtern nach dataSourceFamily für die Datentypen sleep, food und food-measurement-unit nicht unterstützt:

  • Wenn Sie dataSourceFamily für sleep, food oder food-measurement-unit explizit auf list festlegen, schlägt der Vorgang mit dem Fehler 400 Bad Request (INVALID_ARGUMENT) fehl.
  • Wenn Sie list für diese Datentypen aufrufen und nur ein Schreibbereich gewährt wurde (wobei die Einschränkung auf self-sources durch die Bereiche des Aufrufers impliziert wird), schlägt der Aufruf mit dem Fehler 403 Forbidden (PERMISSION_DENIED) fehl.
  • Wenn Sie sleep-Datenpunkte nach dataSourceFamily filtern möchten, verwenden Sie stattdessen den reconcile-Endpunkt.

Beispiele für Datenquellenfamilien

Wenn Sie Rohdatensätze auflisten möchten, die von Ihrem eigenen Client für einen Nutzer geschrieben wurden, rufen Sie den list-Endpunkt auf und setzen Sie den Abfrageparameter dataSourceFamily auf users/me/dataSourceFamilies/self-sources.

Mit der folgenden GET-Anfrage werden beispielsweise die vom aufrufenden Client ab dem 01.03.2026 geschriebenen Rohmesswerte für body-fat aufgelistet:

Anfrage

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

Antwort

{
  "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": ""
}

Wenn Sie einen abgeglichenen Datenstream aus einer bestimmten Datenquellenfamilie abrufen möchten, rufen Sie den reconcile-Endpunkt mit dem Abfrageparameter dataSourceFamily auf.

Mit der folgenden GET-Anfrage wird beispielsweise der von einem Tracker aufgezeichnete Schlaf für den Tag nach dem 03.03.2026 abgerufen:

Anfrage

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

Antwort

{
  "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": ""
}

Wenn Sie Datenpunkte über eine bestimmte Fenstergröße hinweg aggregieren möchten, die auf eine bestimmte Datenquellenfamilie beschränkt ist, rufen Sie den Endpunkt rollUp auf und übergeben Sie das Feld dataSourceFamily im JSON-Anfragetext.

Mit der folgenden POST-Anfrage werden die Anzahl der Schritte pro Stunde (3600s) für den aktuellen Tag abgefragt, die ausschließlich von Wearables erfasst wurden:

Anfrage

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

Antwort

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

Wenn Sie tägliche Datenpunkte für eine bestimmte Quellfamilie zusammenfassen möchten, rufen Sie den Endpunkt dailyRollUp auf und übergeben Sie das Feld dataSourceFamily im Anfragetext.

Im folgenden Beispiel werden die täglichen Zusammenfassungen für die Schritte des Nutzers berechnet, einschließlich aller Google- und Fitbit-Quellen von Erstanbietern (Wearables + manuelle Einträge):

Anfrage

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

Antwort

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