이 페이지에서는 일반적인 Google Health API 작업의 색인과 각 작업의 예시와 함께 REST API 규칙의 개요를 제공합니다.
REST API 규칙
Google Health API는 Google API 개선 제안 (AIP) 표준, 특히 AIP-127 (HTTP 및 gRPC 트랜스코딩) 및 AIP-131~ AIP-135 (표준 메서드)를 따릅니다. 이러한 표준은 프로토 메시지에서 HTTP 요청으로 데이터를 매핑하는 방법을 정의합니다.
쿼리 매개변수
쿼리 매개변수는 데이터가 URL의 일부일 때 사용됩니다. 이는 주로 GET 요청 (리소스 가져오기) 또는 LIST 요청(필터링/페이지 나누기)에 사용되지만 DELETE 작업에도 사용됩니다.
- 위치:
?뒤에 URL에 추가됩니다. - 구문: 키-값 쌍이
&로 구분됩니다. - 매핑: URL 경로 템플릿의 일부가 아닌 요청 메시지의 모든 필드는 쿼리 매개변수에 매핑됩니다.
- 가장 적합한 경우: 단순 유형 (문자열, 정수, enum) 및 반복 필드
구문 예시:
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 작업에 사용됩니다.
- 위치: 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"
}하이브리드 사례
AIP-134를 준수하는 Update 메서드 또는 PATCH 작업에서는 둘 다 사용됩니다.
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 표준을 지원합니다.
- 4자리 연도
YYYY - 0000~9999 범위의 연도 값
- ISO-8601 표준 또는 기타 에포크에서 암시하는 시작 날짜 제한사항을 적용하지 않음
헤더
Google Health API 엔드포인트를 실행하려면 적절한 헤더와 액세스 토큰을 사용해야 합니다. GET 및 POST 요청 모두에 다음 헤더를 사용하는 것이 좋습니다.
Authorization: Bearer access-token Accept: application/json
API 작업 색인
이 섹션에서는 일반적인 Google Health API 작업의 색인과 각 작업의 예시를 제공합니다.
Fitbit 또는 Google 사용자 ID 가져오기
사용자가 Google OAuth 2.0을 통해 동의한 후 토큰 응답에 Fitbit 또는 Google 사용자 ID가 포함되지 않습니다. 사용자 ID를 가져오려면
getIdentity 엔드포인트를 호출합니다. getIdentity
는 Fitbit 기존 사용자 ID와 Google 사용자 ID를 모두 반환합니다.
새 사용자가 OAuth를 통해 동의하는 즉시 getIdentity 엔드포인트를 호출하고 두 사용자 ID를 모두 저장하는 것이 좋습니다. 이렇게 하면 통합에서 이전 버전과의 호환성 및 이후 버전과의 호환성이 제공됩니다.
예를 들면 다음과 같습니다.
요청
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
endpoint를 사용하여 해당 데이터 유형에
지원되는 간격으로 하루 동안 수집된 일중 또는 세부 데이터를 가져옵니다.
예를 들면 다음과 같습니다.
요청
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"
}간격 시민 시작 시간으로 데이터 필터링
filter 매개변수가 있는 list 엔드포인트를 사용하여 시민 시간 또는 간격으로 데이터를 필터링합니다.
예를 들면 다음과 같습니다.
요청
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"
}샘플 관찰 실제 시간으로 데이터 필터링
filter 매개변수가 있는 list 엔드포인트를 사용하여 샘플 관찰 실제 시간으로 데이터를 필터링합니다.
예를 들면 다음과 같습니다.
요청
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/2515055256096816351/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
엔드포인트를 사용하여 특정 "데이터 소스 패밀리"의 데이터를 가져옵니다. 이렇게 하려면 dataSourceFamily 매개변수를 쿼리 매개변수로 지정합니다.
다음 표에서는 지원되는 dataSourceFamily 옵션을 설명합니다.
| 옵션 | 설명 |
|---|---|
users/me/dataSourceFamilies/all-sources |
기본값. 사용 가능한 모든 데이터 소스의 데이터를 포함합니다. |
users/me/dataSourceFamilies/google-wearables |
Google 및 Fitbit 트래커 기기 (예: Fitbit 트래커 및 Pixel Watch)의 데이터를 포함합니다. 수동으로 기록된 데이터는 제외됩니다. |
users/me/dataSourceFamilies/google-sources |
트래커 기기의 데이터 및 수동으로 기록된 데이터와 같은 퍼스트 파티 Google 데이터를 포함합니다. |
다음은 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
엔드포인트를 사용하여 사용자의 실제 시간 (UTC)을 기준으로 datetime 범위에 걸쳐 초 단위의 기간을 기준으로 데이터 포인트의 집계를 반환합니다.
rollUp 엔드포인트를 호출할 때는 사용자의 시민 시간으로 필요한 날짜 범위를 나타내는 요청 본문을 제공해야 합니다. 예를 들면 다음과 같습니다.
요청
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": "30s"
}응답
{
"rollupDataPoints": [
{
"startTime": "2026-02-17T17:55:00Z",
"endTime": "2026-02-17T17:55:30Z",
"steps": {
"countSum": "41"
}
},
{
"startTime": "2026-02-17T17:54:00Z",
"endTime": "2026-02-17T17:54:30Z",
"steps": {
"countSum": "31"
}
},
...
]
}하루 또는 여러 날에 걸쳐 데이터 집계
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"
}
}
]
}사용자의 건강 데이터 삽입 또는 업데이트
patch
엔드포인트를 사용하여 사용자의 Fitbit 앱 데이터를 삽입하거나
업데이트합니다.
다음은 사용자가 'Scales R Us'라는 회사의 'HumanScale'이라는 체중계에서 체지방을 기록한 예입니다. 사용자의 새 체지방 측정값은 2026-03-10의 경우 20% 입니다.
요청
PATCH https://health.googleapis.com/v4/users/me/dataTypes/body-fat/dataPoints/1234567890
Authorization: Bearer access-token
content-length: 329
{
"name": "bodyFatName",
"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/2515055256096816351/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
}
}
}음식 항목 기록
음식 항목을 기록하려면 POST 요청을 nutrition-log 데이터 포인트 엔드포인트로 보냅니다. 요청 본문에는 nutritionLog 객체가 있는 DataPoint가 포함됩니다.
자세한 내용은 영양 가이드를 참고하세요.
예를 들면 다음과 같습니다.
요청
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/2515055256096816351/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"
}
}
}사용자 건강 데이터 삭제
사용자의 Fitbit 앱 데이터 배열을 삭제하려면 batchDelete
endpoint를 사용합니다.
다음은 사용자가 이전에 체중계에서 체지방을 기록했지만 기록을 삭제하려는 예입니다. 원래 삽입 작업의 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/2515055256096816351/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는 애플리케이션에서 사용할 수 있는 이전 데이터의 양에 제한을 두지 않습니다.
하지만 이전 데이터 쿼리는 여전히 표준 속도 제한의 적용을 받습니다. 이러한 제한사항과 관련된 API 호출 수를 줄이기 위해 Google Health API는 날짜 범위에 걸쳐 데이터를 쿼리하는 것을 지원합니다. 다음 페이지 나누기 및 요청 경계를 참고하세요.
- 각 엔드포인트는 페이지당 최대 10,000개의 데이터 포인트를 반환합니다.
- 쿼리 날짜 범위는 요청당 14일에서 90일로 제한됩니다.
애플리케이션에 필요한 이전 데이터의 양에 따라 전체 데이터 세트를 가져오려면 여러 개의 순차적 요청이 필요하고 시간이 더 걸릴 수 있습니다. 애플리케이션의 데이터 동기화 프로세스를 설계할 때 이 점을 염두에 두세요.
최적의 성능을 보장하고 API 오류를 방지하려면 이전 데이터를 쿼리할 때 다음 가이드라인을 따르세요.
단계별 데이터 동기화 (핫 로드 대 콜드 로드)
- 초기 "핫" 로드: 기본 로드 시퀀스 중에 가장 최근 7~14일의 데이터만 가져오고 렌더링합니다. 이렇게 하면 사용자가 장기 실행 쿼리를 기다리지 않고도 데이터를 즉시 볼 수 있습니다.
- 백그라운드 '콜드' 로드: 기본 UI가 렌더링된 후 이전 이전 데이터 가져오기를 비동기식의 우선순위가 낮은 대기열 또는 백그라운드 프로세스 에 위임합니다.
시간 기반 쿼리 청크
- 단일 API 호출에서 여러 연도 또는 여러 달의 기간을 요청하지 마세요. 대규모 이전 쿼리를 더 작은 순차적 간격으로 나눕니다 (예: 요청당 1주).
- 동시 실행 제한사항을 준수하고 안정적인 UI 진행률 표시기를 유지하기 위해 이러한 하위 쿼리를 일괄 처리하거나 순서 지정합니다.
사전 집계된 롤업 활용
사전 집계된 요약 엔드포인트 (예: DailyRollUpDataPoints)를 사용하도록 개요 대시보드와 추세 차트를 재구성합니다. 이렇게 하면 백엔드의 컴퓨팅 오버헤드와 클라이언트로의 네트워크 전송 시간이 크게 줄어듭니다.
복원력 있는 오류 처리 (스마트 재시도)
- 속도
제한 (
429 Too Many Requests) 및 서버 게이트웨이 시간 초과 (504 Gateway Timeout)가 발생하면 엄격한 지수 백오프 처리를 구현합니다. 실패한 대규모 페이로드 를 즉시 재시도하지 마세요. 즉시 재시도하면 백엔드 정체가 증가하고 시스템 성능 저하가 심화됩니다. - 쿼리가 반복적으로 시간 초과되는 경우 더 작은 시간 창으로 자동 대체합니다 (예: 1주 청크를 3일로 줄임).