Punkty końcowe

Ta strona zawiera omówienie konwencji interfejsu API typu REST oraz indeks typowych zadań interfejsu Google Health API wraz z przykładami.

Konwencje interfejsu API typu REST

Interfejs Google Health API jest zgodny ze standardami Google API Improvement Proposals (AIP), w szczególności AIP-127 (transkodowanie HTTP i gRPC) oraz AIP-131 do AIP-135 (metody standardowe). Te standardy określają, jak dane są mapowane z wiadomości proto na żądanie HTTP.

Parametry zapytania

Parametry zapytania są używane, gdy dane są częścią adresu URL. Służy on głównie do żądań GET (pobieranie zasobu) lub LIST (filtrowanie/stronicowanie), ale jest też używany do operacji DELETE.

  • Miejsce docelowe: dołączane do adresu URL po znaku ?.
  • Składnia: pary klucz-wartość rozdzielone znakiem &.
  • Mapowanie: każde pole w komunikacie żądania, które nie jest częścią szablonu ścieżki adresu URL, jest mapowane na parametr zapytania.
  • Najlepsze w przypadku: typów prostych (ciągi znaków, liczby całkowite, typy wyliczeniowe) i pól powtarzanych.

Szczegółową listę formatów filtrów, odwołań do pól, reguł sprawdzania poprawności i przykładów znajdziesz w przewodniku po filtrowaniu danych.

Przykładowa składnia:

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"

Treść żądania

Treść żądania jest używana, gdy dane modyfikują stan zasobu lub są zbyt duże dla adresu URL. Treść jest zwykle reprezentacją JSON samego zasobu. Zwykle używane do operacji POST, PATCH i PUT.

  • Miejsce: w ładunku HTTP (niewidoczne w adresie URL).
  • Składnia: sformatowane jako obiekt JSON.
  • Mapowanie: zdefiniowane w adnotacji google.api.http.
    • body: "*" oznacza, że cała wiadomość jest treścią.
    • body: "resource_name" oznacza, że tylko określone pole w proto jest treścią.
  • Najlepsze zastosowanie: złożone obiekty, zagnieżdżone wiadomości i poufne dane.

Szczegółowe wskazówki dotyczące rozmiarów okien zbiorczych, reguł grupowania i przykładów agregacji znajdziesz w przewodniku po danych zbiorczych.

Przykładowa składnia:

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

Przypadek hybrydowy

W metodzie Update zgodnej z AIP-134 lub operacji PATCH używane są obie te wartości. Adres URL zawiera nazwę zasobu, treść zawiera zaktualizowane dane zasobu, a parametr zapytania (zwykle update_mask) określa, które pola należy zmienić.

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

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

Najważniejsze różnice w skrócie

Funkcja Parametry zapytania Treść żądania
Wskazówki dotyczące AIP Używany do wyszukiwania, filtrowania i operacji odczytu. Używany do operacji zapisu.
Widoczność Widoczne w historii przeglądarki i logach serwera. Ukryty w adresie URL.
Złożoność Ograniczone do struktur płaskich lub powtarzających się. Obsługuje głęboko zagnieżdżone obiekty JSON.
Kodowanie Musi być zakodowany na potrzeby adresu URL (np. spacje stają się %20). Standardowe kodowanie JSON.

Daty

Wszystkie daty w interfejsie Google Health API są wyświetlane w formacie YYYY-MM-DD. Interfejs Nutrition API obsługuje standard ISO-8601 dla wartości daty z tymi warunkami:

  • 4-cyfrowy rok YYYY
  • Wartości roku z zakresu 0000–9999.
  • Brak egzekwowania ograniczeń daty rozpoczęcia wynikających ze standardu ISO-8601 lub innej epoki.

Nagłówki

Wykonywanie punktów końcowych interfejsu API Google Health wymaga użycia odpowiednich nagłówków i tokena dostępu. W przypadku żądań GET i POST zalecamy używanie tego nagłówka:

Authorization: Bearer access-token
Accept: application/json

Indeks zadań interfejsu API

W tej sekcji znajdziesz indeks typowych zadań interfejsu Google Health API i przykłady każdego z nich.

Uzyskiwanie identyfikatora użytkownika Fitbita lub Google

Gdy użytkownik wyrazi zgodę za pomocą Google OAuth 2.0, odpowiedź tokena nie zawiera identyfikatora użytkownika Fitbita ani Google. Wywołaj punkt końcowy getIdentity natychmiast po wymianie kodu autoryzacji, aby pobrać zarówno legacyUserId, jak i healthUserId, i sprawdzić, czy konto Google użytkownika jest połączone z Google Health. Jeśli konto nie jest jeszcze połączone, getIdentity zwraca 400 Bad Request z powodem ACCOUNT_NOT_LINKED (patrz Obsługa niepołączonych kont Google).

Na przykład:

Żądanie

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

Odpowiedź (200 OK)

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

Odpowiedź (400 ACCOUNT_NOT_LINKED)

{
  "error": {
    "code": 400,
    "message": "The account is not linked to Google Health.",
    "status": "FAILED_PRECONDITION",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "ACCOUNT_NOT_LINKED",
        "domain": "health.googleapis.com",
        "metadata": {
          "redirect_uri": "https://fitbit.google.com/auth/signup"
        }
      }
    ]
  }
}

Uzyskiwanie danych z bieżącego dnia lub szczegółowych danych zebranych w ciągu dnia

Użyj punktu końcowego list dla konkretnego typu danych, aby uzyskać dane z danego dnia lub szczegółowe dane zebrane w ciągu dnia w obsługiwanych przedziałach czasu dla tego typu danych.

Na przykład:

Żądanie

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

Odpowiedź

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

Uzyskiwanie uzgodnionego widoku danych interwałowych

Aby pobrać dane interwałowe bez nakładających się rekordów lub konfliktów na wielu urządzeniach, wywołaj punkt końcowy reconcile. Punkt końcowy uzgadniania automatycznie usuwa duplikaty nakładających się interwałów w ramach zbiorów synchronizacji i na wielu urządzeniach rejestrujących, zwracając wiarygodny, ciągły strumień, który nadaje się do renderowania osi czasu aktywności i obliczania czasu trwania.

Informacje o tym, dlaczego połączone urządzenia generują nakładające się interwały, oraz porównanie działania list i reconcile znajdziesz w przewodniku po zarządzaniu danymi.

Poniższy przykład porównuje odpowiedź list (która zwraca oba nakładające się rekordy) z odpowiedzią reconcile (która rozwiązuje konflikt, zwracając rekord nadrzędny) w przypadku użytkownika z 2 nakładającymi się sesjami ćwiczeń:

Lista nieprzetworzona

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

Uzgodniono

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

Uzgodnienie rozwiązuje problem konfliktów sesji przez usunięcie duplikatów i wybranie autorytatywnego rekordu zamiast tworzenia sztucznego przedziału czasu (np. od 11:00:00Z do 11:50:00Z). Uzgodniona odpowiedź zwraca zwycięski punkt danych (7797422996486764704) z pierwotnie zarejestrowanym interwałem (od 11:20:00Z do 11:50:00Z), zachowując integralność danych telemetrycznych i pomiarów tej sesji.

Filtruj dane

Aby pobrać określone podzbiory rekordów punktów danych spełniające kryteria takie jak przedział czasu, data lub czas obserwacji, użyj punktu końcowego list lub reconcile z parametrem filter.

Szczegółowe wskazówki, reguły formatowania, błędy weryfikacji i przykłady zapytań znajdziesz w przewodniku po filtrowaniu danych.

Filtrowanie według rodziny źródeł danych

Aby wyodrębnić lub zagregować dane z określonych typów źródeł (np. z urządzeń do noszenia lub wpisów ręcznych), użyj parametru dataSourceFamily.

Szczegółowe wytyczne, obsługiwane rodziny oraz przykłady żądań i odpowiedzi dla reconcile, rollUp i dailyRollUp znajdziesz w sekcji Filtrowanie według rodziny źródeł danych w przewodniku po filtrowaniu danych.

Filtrowanie danych według czasu rozpoczęcia interwału

Użyj punktu końcowego list z parametrem filter, aby filtrować dane według czasu cywilnego lub interwału.

Na przykład:

Żądanie

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

Odpowiedź

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

Filtrowanie danych według czasu fizycznego obserwacji próbki

Użyj punktu końcowego list z parametrem filter, aby filtrować dane według czasu fizycznego obserwacji próbki.

Na przykład:

Żądanie

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

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

Filtrowanie i agregowanie 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 wyodrębnianie lub agregowanie danych z określonych typów źródeł (np. z urządzeń do noszenia lub wpisów ręcznych).

Punkty końcowe reconcile, rollUp i dailyRollUp obsługują parametr dataSourceFamily. Mechanizm przekazywania zależy od punktu końcowego:

Punkt końcowy (metoda HTTP) Mechanizm
reconcile (GET) Przekaż dataSourceFamily jako parametr zapytania w adresie URL.
rollUp (POST) Przekaż dataSourceFamily jako pole w treści żądania JSON.
dailyRollUp (POST) Przekaż dataSourceFamily jako pole w treści żądania JSON.

Obsługiwane rodziny źródeł danych

W tabeli poniżej znajdziesz obsługiwane wartości dataSourceFamily:

Opcja Opis
users/me/dataSourceFamilies/all-sources Wartość domyślna. Zwraca punkty danych uzgodnione we wszystkich zarejestrowanych źródłach danych własnych i źródłach danych pochodzących od innych firm. W przypadku tej opcji zwracane będą dane z aplikacji innych firm (np. kroki ze smartwatcha + kroki z aplikacji innej firmy + kroki z telefonu komórkowego + kroki dodane ręcznie).
users/me/dataSourceFamilies/google-wearables Obejmuje dane zarejestrowane przez urządzenia śledzące Google i Fitbit (takie jak trackery Fitbit i zegarki Pixel Watch). Nie obejmuje danych zapisanych ręcznie ani danych szacowanych przez telefon. Użyj tej opcji, gdy integracja wymaga nieprzetworzonych danych telemetrycznych z czujników, które są rejestrowane 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 fizycznych urządzeń śledzących, dane z Health Connect oraz wszelkie wpisy ręczne zapisane w aplikacjach własnych (takich jak aplikacja Fitbit lub Google Fit).

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 2026-03-03:

Żą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 zagregować dane zbiorcze 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.

To żądanie POST wysyła zapytanie o liczbę kroków w ciągu dnia w odstępach godzinowych (3600s), zagregowaną wyłącznie 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 zagregować 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 własne źródła Google i Fitbit (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"
      }
    }
  ]
}

Agregowanie punktów danych w zakresie czasu

Użyj punktu końcowego rollUp, aby zwrócić zagregowane punkty danych na podstawie okna w sekundach (windowSize) w zakresie datetime w czasie fizycznym użytkownika (w strefie czasowej UTC).

Podczas wywoływania punktu końcowego rollUp podaj treść żądania reprezentującą wymagany przedział czasu range i windowSize (co najmniej "1s"). Szczegółowe wytyczne dotyczące wymagań windowSize, dopasowania rozdzielczości pamięci masowej, reguł grupowania oraz przykłady żądań i odpowiedzi znajdziesz w sekcji Agregowanie w fizycznych przedziałach czasu w przewodniku po danych zbiorczych.

Agregowanie danych z jednego dnia lub kilku dni

Użyj punktu końcowego dailyRollUp, aby zagregować dane z jednego dnia lub wielu dni (windowSizeDays). W treści żądania podaj czas cywilny range dla wymaganego przedziału czasu. W zależności od typu danych punkt końcowy zwraca sumę lub średnią dla każdego okna.

Szczegółowe informacje o zbiorczym przetwarzaniu danych dziennych, obsłudze czasu cywilnego, limitach zakresu na żądanie oraz przykłady żądań i odpowiedzi znajdziesz w sekcji Agregowanie danych z dni kalendarzowych w przewodniku po danych zbiorczych.

Aktualizowanie danych użytkownika dotyczących zdrowia

Aby zaktualizować dane dotyczące zdrowia użytkownika, użyj punktu końcowego patch.

Punkt końcowy patch aktualizuje istniejący rekord na podstawie identyfikatora określonego w adresie URL żądania. Podaj identyfikator wstawionego wcześniej punktu danych. Interfejs API zastępuje istniejący rekord.

Sygnatury czasowe interwału punktu danych (startTime i endTime) mogą być też aktualizowane przez właściciela rekordu lub propagowane z platform nadrzędnych, takich jak Health Connect. Szczegółowe informacje o zmienności sygnatur czasowych znajdziesz w przewodniku po zarządzaniu danymi. Przykład aktualizowania sygnatur czasowych interwałów znajdziesz w sekcji Aktualizowanie sygnatur czasowych interwałów w przypadku istniejących danych.

Kiedy używać identyfikatora punktu danych

Identyfikator punktu danych jest niezbędny w tych sytuacjach:

  • Aktualizacje ukierunkowane: aby zaktualizować konkretny pomiar, podaj jego identyfikator w żądaniu patch.
  • Usuwanie: zachowanie identyfikatora umożliwia aplikacji późniejsze usunięcie rekordu za pomocą punktu końcowego batchDelete.

Oto przykład, w którym użytkownik aktualizuje odczyt tkanki tłuszczowej na wadze o nazwie „HumanScale” firmy „Scales R Us”. Nowy odczyt tkanki tłuszczowej użytkownika wynosi 20% dla daty 2026-03-10:

Żądanie

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

Odpowiedź

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

Aktualizowanie sygnatur czasowych interwałów w przypadku istniejących danych

Aby zaktualizować sygnatury czasowe interwału (startTime i endTime w ładunkach REST JSON lub start_time i end_time w gRPC) istniejącego punktu danych, wyślij żądanie PATCH do identyfikatora URI zasobu punktu danych. Tylko pierwotny twórca lub właściciel rekordu może modyfikować jego pola. Aplikacje nie mogą edytować punktów danych, których nie utworzyły.

Informacje o możliwości zmiany sygnatury czasowej, aktualizacjach z Health Connect i konsekwencjach buforowania znajdziesz w przewodniku po zarządzaniu danymi.

Poniższy przykład pokazuje, jak aplikacja właściciela aktualizuje sygnatury czasowe interwału istniejącego wpisu dotyczącego nawodnienia za pomocą punktu końcowego patch:

Żądanie

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

Odpowiedź

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

Zapisywanie produktu spożywczego

Aby zapisać produkt spożywczy, wyślij żądanie POST do punktu końcowego nutrition-log dataPoints. Treść żądania zawiera obiekt DataPoint z obiektem nutritionLog. Więcej informacji znajdziesz w przewodniku po odżywianiu.

Na przykład:

Żądanie

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

Odpowiedź

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

Usuwanie danych użytkownika dotyczących zdrowia

Użyj metody batchDelete, aby usunąć tablicę danych aplikacji Fitbit użytkownika.

Oto przykład, w którym użytkownik wcześniej zapisał swoją tkankę tłuszczową na wadze, ale chce usunąć ten zapis. Użyj wartości user-id i data-point-id z pierwotnego działania wstawiania:

Żądanie

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

Odpowiedź

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

Znajdowanie informacji o urządzeniu

Użyj punktu końcowego list, aby pobrać listę urządzeń sparowanych z kontem użytkownika. Obejmuje to informacje o modelu urządzenia (deviceVersion) i ostatniej synchronizacji z aplikacją mobilną Google Health (lastSyncTime).

Konfiguracja listy i informacje o synchronizacji są przydatne do rozwiązywania problemów z synchronizacją lub pobierania danych historycznych od czasu ostatniej synchronizacji.

Na przykład:

Żądanie

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

Odpowiedź

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

Wykonywanie zapytań dotyczących danych historycznych

Jedną z głównych zalet interfejsu Google Health API jest możliwość śledzenia wyników użytkownika i monitorowania jego parametrów życiowych przez dłuższy czas. Możesz wysyłać zapytania o dane użytkownika od momentu ich zarejestrowania. Interfejs API nie nakłada żadnych ograniczeń na ilość danych historycznych, które może wykorzystać Twoja aplikacja.

Jednak wykonywanie zapytań dotyczących danych historycznych nadal podlega standardowym limitom liczby żądań. Aby zarządzać stabilnością systemu i zapobiegać nadmiernemu obciążeniu, interfejs Google Health API używa automatycznego podziału na strony z rozmiarami stron dostosowanymi do konkretnych punktów końcowych. Pamiętaj o tych ograniczeniach i zachowaniach:

  • Automatyczne dzielenie na strony: jeśli zapytanie dotyczy długiego okresu, interfejs API zwróci tylko pierwszą stronę wyników do limitu rozmiaru strony dla tego punktu końcowego wraz z parametrem nextPageToken. Aby poprosić o kolejne strony, musisz użyć nextPageToken.
  • Zmienne rozmiary stron: limity zależą od punktu końcowego i typu danych. W przypadku większości typów danych rozmiary stron są ograniczone do maksymalnie 10 000. Jednak w przypadku niektórych typów danych, takich jak exercise i sleep, domyślny i maksymalny rozmiar strony jest ograniczony do 25. Jeśli na przykład klient poprosi o wszystkie dane o śnie z ostatnich 10 lat, interfejs API nadal zwróci tylko 25 sesji snu na pierwszej stronie.
  • Ograniczenia zakresu dat w przypadku zestawień: w przypadku punktów końcowych zestawień i agregacji danych (takich jak rollUp i dailyRollUp) zakresy dat zapytań są ograniczone na podstawie typu danych:
    • Maksymalny zakres 14 dni w przypadku calories-in-heart-rate-zone, heart-rate, active-minutes i total-calories.
    • Maksymalny zakres 90 dni w przypadku wszystkich innych typów danych zbiorczych.

W zależności od ilości danych historycznych, których potrzebuje aplikacja, pobranie całego zbioru danych będzie wymagało sekwencyjnego przeglądania stron. Pamiętaj o tym podczas projektowania procesu synchronizacji danych w aplikacji.

Aby zapewnić optymalną wydajność i uniknąć błędów interfejsu API, podczas wysyłania zapytań o dane historyczne postępuj zgodnie z tymi wskazówkami:

Synchronizacja danych etapami (wczytywanie „na gorąco” i „na zimno”)

  • Początkowe „gorące” wczytywanie: pobieraj i renderuj tylko dane z ostatnich 7–14 dni podczas głównej sekwencji wczytywania. Dzięki temu użytkownicy od razu widzą dane i nie muszą czekać na długotrwałe zapytania.
  • Wczytywanie „na zimno” w tle: po wyrenderowaniu głównego interfejsu użytkownika przekieruj pobieranie starszych danych historycznych do asynchronicznej kolejki o niższym priorytecie lub do procesu w tle.

Dzielenie zapytań na fragmenty na potrzeby agregacji

  • Punkty końcowe zestawienia i zestawienia dziennego wymuszają maksymalny zakres dat (14 lub 90 dni w zależności od typu danych), dlatego duże zapytania dotyczące agregacji historycznej musisz podzielić na mniejsze, sekwencyjne interwały w tych granicach.
  • Bezpiecznie grupuj lub sekwencjonuj te podzapytania, aby przestrzegać limitów równoczesności i utrzymywać stałe wskaźniki postępu interfejsu.

Korzystanie ze wstępnie zagregowanych zestawień

Zmień strukturę paneli przeglądu i wykresów trendów, aby korzystać ze wstępnie zagregowanych punktów końcowych podsumowania (takich jak DailyRollUpDataPoints). Pozwoli to znacznie zmniejszyć obciążenie obliczeniowe backendu i skrócić czas przesyłania danych przez sieć do klienta.

Odporna obsługa błędów (inteligentne ponowne próby)

  • W przypadku napotkania ograniczeń liczby żądań (429 Too Many Requests) i przekroczenia limitu czasu bramy serwera (504 Gateway Timeout) stosuj rygorystyczne zasady wzrastającego czasu do ponowienia. Nigdy nie ponawiaj od razu prób przesłania dużych, nieudanych ładunków. Natychmiastowe ponowne próby zwiększają przeciążenie backendu i pogarszają działanie systemu.