Interfejs Google Health API korzysta z wyrażeń filtra, aby ograniczać zwracane punkty danych podczas wywoływania standardowych metod pobierania. Filtry są używane w przypadku:
listpunkty końcowe: zapytania dotyczące surowych punktów danych.reconcilePunkty końcowe: zapytania dotyczące uzgodnionych punktów danych strumienia.
Z tego przewodnika dowiesz się, jak działa filtrowanie, jaka jest jego składnia i konwencje, a także znajdziesz przykłady dla każdego typu rekordu.
.Konwencje filtrowania
Interfejs Google Health API implementuje filtry zgodnie ze standardem Google API Improvement Proposals (AIP-160).
Parametry zapytania
Filtry są przekazywane za pomocą ciągu zapytania adresu URL w parametrze filter.
Filtry zawierają znaki specjalne (np. <, >= i cudzysłowy), dlatego podczas przesyłania w żądaniu HTTP muszą być zakodowane na potrzeby adresu URL.
Na przykład żądanie z filtrem
steps.interval.civil_start_time >= "2026-03-04T00:00:00"
należy zakodować w ten sposób:
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
Format nazwy
Jeśli typ danych składa się z więcej niż 1 słowa, format identyfikatora różni się w zależności od ścieżki zasobu i filtra:
- Ścieżka punktu końcowego: używaj łączników (np.
/dataTypes/body-fat). - Ciąg znaków filtra: używaj podkreśleń (np.
body_fat).
Jeśli w identyfikatorze filtra użyjesz łączników, interfejs API zwróci 400 Bad Request z wyjaśnieniem błędu INVALID_DATA_POINT_FILTER.
Typy i pola filtrów
Pola używane w filtrze zależą od typu rekordu typu danych, o który wysyłasz zapytanie. W tabeli poniżej znajdziesz opis pól obsługiwanych w przypadku poszczególnych typów rekordów:
| Typ rekordu | Opis | Obsługiwane pola filtra |
|---|---|---|
| Interwał | Punkty danych zarejestrowane w określonym czasie (np. steps, distance, calories). |
{dataType}.interval.start_time{dataType}.interval.civil_start_time
Przykład: steps.interval.civil_start_time
|
| Próbka | Obserwacje natychmiastowe lub krótkie pomiary (np. weight, body-fat, blood-glucose). |
{dataType}.sample_time.physical_time{dataType}.sample_time.civil_time
Przykład: body_fat.sample_time.physical_time
|
| Codziennie | codzienne dane i podsumowania (np. daily-heart-rate-variability); |
{dataType}.date
Przykład: daily_heart_rate_variability.date
|
| Sesja | Wydłużone sesje użytkowników ze specjalnymi regułami czasowymi. |
Ćwiczenia: {dataType}.interval.civil_start_timeSen: sleep.interval.end_time, sleep.interval.civil_end_timeEKG: electrocardiogram.interval.start_time
Przykład: sleep.interval.civil_end_time
|
Obsługiwane operatory i reguły formatowania
Wyrażenia filtra muszą być zgodne z tymi regułami formatowania:
Operatory porównania
Obsługiwane są tylko 2 operatory porównania:
| Operator | Opis |
|---|---|
>= |
Dolna granica (włącznie). |
< |
Górna granica (wyłączona). |
Użycie innych operatorów porównania (np. >, <= lub =) zwraca wartość 400 Bad Request z wartością INVALID_DATA_POINT_FILTER_RESTRICTION_COMPARATOR.
Operatory logiczne
| Operator | Pomoc |
|---|---|
AND |
Domyślny i jedyny obsługiwany operator. Służy do łączenia granic początku i końca. |
OR |
Nieobsługiwane. Użycie OR zwraca błąd 400 Bad Request z przyczyną INVALID_DATA_POINT_FILTER_EXPRESSION_STRUCTURE („Filtr musi być koniunkcją lub sekwencją ograniczeń. Znaleziono: DISJUNCTION”). |
Literały czasu
Literały czasu w wyrażeniach filtra muszą mieć te formaty:
| Typ czasu | Wymagania | Przykłady |
|---|---|---|
| Czas fizyczny | Format RFC 3339, kończący się znakiem Z lub przesunięciem względem czasu UTC. Reprezentuje rzeczywiste wydarzenia w strefie czasowej UTC. |
Prawidłowe: "2026-03-01T00:00:00Z", "2026-03-01T00:00:00-08:00"Nieprawidłowe: "2026-03-01" |
| czas cywilny, | Format ISO 8601: YYYY-MM-DD[THH:mm:ss]. Reprezentuje czas na zegarze użytkownika, niezależnie od lokalizacji i przesunięcia strefy czasowej. |
Prawidłowo: "2026-03-01", "2026-03-01T08:30:00" |
Filtrowanie reguł weryfikacji
Filtry działają zgodnie z tymi regułami:
| Reguła | Opis | Przykłady |
|---|---|---|
| Brak mieszanych typów czasu | Nie mieszaj granic czasu fizycznego i cywilnego. | Nieprawidłowy: steps.interval.start_time >= "2026-03-01T00:00:00Z" AND steps.interval.civil_start_time < "2026-03-02"Błąd: INVALID_DATA_POINT_FILTER_MIXED_TIME_RESTRICTIONS („Filtr nie może zawierać zakresów czasu fizycznego i cywilnego”) |
| Brak mieszanych typów danych | Używaj w ścieżce żądania pól należących do typu danych. | Nieprawidłowy: ścieżka /users/.../dataTypes/steps/... z filtrem distance.interval.start_time >= "..."Błąd: INVALID_DATA_POINT_FILTER_COLLECTION_MISMATCH („Typ danych w filtrze nie pasuje do kolekcji typu danych nadrzędnych”) |
| Logika kolejności czasowej | Górna granica musi być większa od dolnej. | Nieprawidłowy: steps.interval.start_time >= "2026-03-02T00:00:00Z" AND steps.interval.start_time < "2026-03-01T00:00:00Z"Błąd: INVALID_TIME_RANGE („Czas zakończenia zapytania musi być późniejszy niż czas rozpoczęcia”) |
| Format wielkości liter | Użyj notacji snake case, która pasuje do nazwy typu danych. | Nieprawidłowy: body-fat.sample_time.physical_time >= "..."Błąd: INVALID_DATA_POINT_FILTER („Nieprawidłowy filtr”) |
W przypadku nieprawidłowych filtrów interfejs API zwraca kod HTTP 400 Bad Request. Sprawdź error.details[].metadata.detailedReasons, aby znaleźć kod przyczyny błędu.
Wymagane zakresy OAuth
Aby wysyłać zapytania o punkty danych za pomocą filtrów, autoryzowany użytkownik musi przyznać odpowiedni zakres OAuth dla danego typu danych. Jeśli brakuje wymaganego zakresu, interfejs API zwraca stan 403 Forbidden z kodem MISSING_OAUTH_SCOPE.
W tabeli poniżej znajdziesz zakresy protokołu OAuth i typy danych, do których przyznają one dostęp do odczytu. Tabela zawiera zakresy w formacie względnym (np..activity_and_fitness.readonly oznaczahttps://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly):
| Wymagany zakres OAuth | Typy danych |
|---|---|
.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 |
elektrokardiogram |
.health_metrics_and_measurements.readonly |
glukoza, zawartość tkanki tłuszczowej, temperatura ciała, dzienna zmienność rytmu serca, dzienne strefy tętna, dzienne nasycenie krwi tlenem, dzienna częstość oddechów, dzienne tętno spoczynkowe, dzienne pochodne temperatury podczas snu, tętno, zmienność rytmu serca, wzrost, nasycenie krwi tlenem, podsumowanie częstości oddechów podczas snu, czujniki temperatury skóry, waga |
.irn.readonly |
irregular-rhythm-notification |
.nutrition.readonly |
food, food-measurement-unit, hydration-log, nutrition-log |
.sleep.readonly |
sen |
Jeśli klient otrzyma tylko zakres zapisu (np. .activity_and_fitness.writeonly) dla żądanego typu danych, nadal możesz wysyłać zapytania o punkty danych zapisane przez Twojego klienta. W tym przypadku żądania są niejawnie ograniczone do self-sources rodziny źródeł danych. Szczegółowe informacje i ograniczenia dotyczące typów danych znajdziesz w artykule Filtrowanie według rodziny źródeł danych.
Przykłady użycia
Poniższe przykłady pokazują, jak tworzyć filtry w przypadku typowych scenariuszy:
Kroki zapytania według zakresu czasu fizycznego
Kroki zapytania zarejestrowane w zakresie od 2026-03-01T00:00:00Z (włącznie) do 2026-03-02T00:00:00Z (wyłącznie):
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"
Wykonywanie zapytań o kroki według zakresu czasu cywilnego
Kroki zapytania dotyczące całego dnia 4 marca 2026 r. w odniesieniu do lokalnego zegara użytkownika:
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"
Pobieranie danych o tkance tłuszczowej według czasu pobrania próbki fizycznej
Zapytanie o pomiary tkanki tłuszczowej zarejestrowane od marca 2026 r. (w formacie 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"
Waga zapytania według czasu cywilnego próbki
Logi wagi zapytania zarejestrowane po określonej godzinie lokalnej:
GET https://health.googleapis.com/v4/users/me/dataTypes/weight/dataPoints ?filter=weight.sample_time.civil_time >= "2026-03-01T08:00:00"
Wysyłanie zapytań o dzienne podsumowania zmienności rytmu serca
Sprawdź dzienne podsumowania zmienności rytmu serca (HRV) zarejestrowane przed określoną datą:
GET https://health.googleapis.com/v4/users/me/dataTypes/daily-heart-rate-variability/dataPoints ?filter=daily_heart_rate_variability.date < "2026-08-15"
Wykonywanie zapytań o sesje ćwiczeń według czasu rozpoczęcia
Zapytanie o sesje ćwiczeń, które miały miejsce w określonym tygodniu w lokalnej strefie czasowej użytkownika:
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"
Wykonywanie zapytań o sesje snu według czasu zakończenia
Wyślij zapytanie o rekordy snu według czasu zakończenia sesji:
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"
Wykonywanie zapytań dotyczących elektrokardiogramów według czasu rozpoczęcia
Wykonywanie zapytań dotyczących nagrań EKG od określonego momentu w czasie UTC. Pamiętaj, że zapytania ECG obsługują tylko porównanie >= w przypadku start_time:
GET https://health.googleapis.com/v4/users/me/dataTypes/electrocardiogram/dataPoints ?filter=electrocardiogram.interval.start_time >= "2026-03-10T12:00:00Z"
Filtrowanie według rodziny źródeł danych
Rodzina źródeł danych to logiczne zgrupowanie źródeł danych (takich jak zegarki, aplikacje mobilne czy wpisy ręczne). Umożliwia to wyodrębnianie lub agregowanie danych z określonych typów źródeł (np. z urządzeń do noszenia, wpisów ręcznych lub danych zapisanych przez własnego klienta).
Punkty końcowe list, reconcile, rollUp i dailyRollUp obsługują parametr dataSourceFamily. Mechanizm przekazywania zależy od punktu końcowego:
| Punkt końcowy (metoda HTTP) | Mechanizm |
|---|---|
list (GET) |
Przekaż dataSourceFamily jako parametr zapytania w adresie URL. |
reconcile (GET) |
Przekaż dataSourceFamily jako parametr zapytania w adresie URL. |
rollUp (POST) |
Przekaż dataSourceFamily jako pole w treści żądania w formacie JSON. |
dailyRollUp (POST) |
Przekaż dataSourceFamily jako pole w treści żądania w formacie JSON. |
Obsługiwane rodziny źródeł danych
W tabeli poniżej znajdziesz opis obsługiwanych wartości dataSourceFamily:
| Opcja | Opis |
|---|---|
users/me/dataSourceFamilies/all-sources |
Wartość domyślna (gdy przyznano zakres odczytu). Obejmuje punkty danych ze wszystkich dostępnych źródeł danych własnych i innych firm. W przypadku tej opcji zwracane są dane aplikacji innych firm (np. kroki z zegarka, kroki z aplikacji innych firm, kroki z telefonu komórkowego i kroki wprowadzone ręcznie). |
users/me/dataSourceFamilies/google-wearables |
Obejmuje dane rejestrowane przez urządzenia śledzące Google i Fitbit (takie jak trackery Fitbit i zegarki Pixel Watch). Wyklucza dane rejestrowane ręcznie i dane szacowane przez telefon. Użyj tej opcji, jeśli integracja wymaga surowych danych telemetrycznych z czujników rejestrowanych bezpośrednio przez urządzenie do noszenia. |
users/me/dataSourceFamilies/google-sources |
Obejmuje źródła własne Google i Fitbita. Obejmuje to dane z urządzeń śledzących aktywność, dane z Health Connect i wszystkie dane wprowadzone ręcznie w aplikacjach własnych (takich jak aplikacja Fitbit czy Google Fit). |
users/me/dataSourceFamilies/self-sources |
Obejmuje tylko dane zapisane przez klienta wywołującego za pomocą interfejsu Google Health API (punkty danych, których źródło danych zostało zarejestrowane za pomocą interfejsu API z tym samym identyfikatorem klienta OAuth co klient wywołujący). |
Jeśli żaden punkt danych nie pasuje do żądanej rodziny źródeł danych, odpowiedź jest pustą listą, a nie błędem.
Zakresy tylko do zapisu i źródła własne
Wywołujący, którzy mają tylko zakresy zapisu (np..activity_and_fitness.writeonly) dla żądanych typów danych, mogą odczytywać tylko dane, które sami zapisali.
- Żądania bez wyraźnego parametru
dataSourceFamilylub z parametremdataSourceFamilyustawionym nausers/me/dataSourceFamilies/self-sourcessą domyślnie ograniczone doself-sources. - Wysłanie prośby o dostęp do dowolnej innej rodziny źródeł danych (np.
all-sources,google-wearableslubgoogle-sources) z zakresem uprawnień tylko do zapisu kończy się niepowodzeniem i błędem403 Forbidden(PERMISSION_DENIED).
Ograniczenia dotyczące typów danych w punkcie końcowym listy
W przypadku punktu końcowego list (users.dataTypes.dataPoints.list) filtrowanie według dataSourceFamily nie jest obsługiwane w przypadku typów danych sleep, food i food-measurement-unit:
- Jawne ustawienie parametru
dataSourceFamilyw przypadkulistdlasleep,foodlubfood-measurement-unitkończy się niepowodzeniem i wyświetla błąd400 Bad Request(INVALID_ARGUMENT). - Wywołanie funkcji
listw przypadku tych typów danych, gdy przyznano tylko zakres zapisu (w którym ograniczenie doself-sourcesjest implikowane przez zakresy wywołującego), kończy się niepowodzeniem z błędem403 Forbidden(PERMISSION_DENIED). - Aby filtrować punkty danych
sleepwedługdataSourceFamily, użyjreconcilepunktu końcowego.
Przykłady rodzin źródeł danych
Aby wyświetlić listę surowych punktów danych zapisanych przez Twojego klienta dla użytkownika, wywołaj punkt końcowy list, ustawiając parametr zapytania dataSourceFamily na users/me/dataSourceFamilies/self-sources.
Na przykład to żądanie GET zawiera listę surowych pomiarów body-fat zapisanych przez klienta wywołującego od 2026-03-01:
Żądanie
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
Odpowiedź
{
"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": ""
}Aby uzyskać uzgodniony strumień danych z określonej rodziny źródeł danych, wywołaj punkt końcowy reconcile z parametrem zapytania dataSourceFamily.
Na przykład to żądanie GET pobiera dane o śnie zarejestrowane przez tracker w dniu po 3 marca 2026 r.:
Żądanie
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
Odpowiedź
{
"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": ""
}Aby agregować punkty danych w określonym rozmiarze okna ograniczonym do konkretnej rodziny źródeł danych, wywołaj punkt końcowy rollUp i przekaż pole dataSourceFamily w treści żądania JSON.
Poniższe żądanie POST wysyła zapytanie o liczbę kroków z dnia w interwałach godzinowych (3600s), zagregowaną wyłącznie na podstawie danych z urządzeń do noszenia:
Żądanie
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"
}Odpowiedź
{
"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"
}
}
]
}Aby agregować dzienne punkty danych dla konkretnej rodziny źródeł, wywołaj punkt końcowy dailyRollUp i przekaż pole dataSourceFamily w treści żądania.
Na przykład to żądanie oblicza dzienne podsumowania kroków użytkownika, w tym wszystkie źródła własne Google i Fitbita (urządzenia do noszenia i wpisy ręczne):
Żądanie
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"
}Odpowiedź
{
"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"
}
}
]
}