Google Health API는 건강 기록을 시간대별로 그룹화하고 요약하는 전용 집계 엔드포인트를 제공합니다. 클라이언트에서 개별 원시 레코드를 검색하고 합산하는 대신 집계 엔드포인트를 사용하여 조정된 데이터 스트림에서 측정항목 (예: 총계, 평균, 최솟값, 최댓값)을 계산합니다.
rollUp엔드포인트는 구성 가능한 기간(초)(windowSize)을 사용하여 UTC의 물리적 시간 간격에 걸쳐 데이터 포인트를 집계합니다.dailyRollUp엔드포인트는 사용자의 현지 시계를 기준으로 한 시민 시간을 사용하여 하나 이상의 달력일 (windowSizeDays)에 걸쳐 데이터 포인트를 집계합니다.
두 엔드포인트 모두 연결된 기기에서 중복되는 데이터 포인트를 자동으로 조정하고 손목 감지를 지원하는 웨어러블 데이터 유형의 경우 손목에서 벗어난 기간을 제외합니다.
집계 엔드포인트 비교
애플리케이션이 시계열 건강 수치를 그룹화하고 표시하는 방식과 일치하는 집계 엔드포인트를 선택합니다.
| 기능 | 엔드포인트 rollUp개 |
엔드포인트 dailyRollUp개 |
|---|---|---|
| HTTP 요청 | POST https://health.googleapis.com/v4/users/me/dataTypes/data-type/dataPoints:rollUp |
POST https://health.googleapis.com/v4/users/me/dataTypes/data-type/dataPoints:dailyRollUp |
| 시간 표현 | UTC의 실제 시간 (RFC 3339 형식의 startTime 및 endTime)입니다. |
민간 시간 (start 및 end를 CivilDateTime 객체로 표시) |
| 기간 파라미터 | windowSize(필수 문자열 기간(초), 최소 "1s") |
windowSizeDays (선택사항, 정수 일수, 기본값은 1) |
| 응답 객체 | RollupDataPoint |
DailyRollupDataPoint |
| 응답 순서 | 시간 역순 (최신 창이 먼저 표시됨) | 시간 역순 (최신 창이 먼저 표시됨) |
| 권장 용도 | 일중 차트, 시간별 또는 분 단위 히스토그램, 고정 기간 UTC 분석 | 시간대 이동 또는 일광 절약 시간을 고려한 일일 대시보드, 여러 날의 추세, 요약 |
두 엔드포인트 모두 데이터 유형에 따라 최대 쿼리 범위 한도를 적용합니다.
calories-in-heart-rate-zone,heart-rate,active-minutes,total-calories에는 최대 14일의 쿼리 범위가 적용됩니다.- 지원되는 다른 모든 데이터 유형에는 최대 90일의 쿼리 범위가 적용됩니다.
rollup 및 dailyRollup를 지원하는 데이터 유형을 확인하려면 Google Health API 데이터 유형 참조를 확인하세요.
물리적 시간 간격에 따른 집계
rollUp 엔드포인트를 사용하여 실제 시간 range (UTC) 동안의 데이터 포인트를 초 단위의 기간 (windowSize)으로 그룹화하여 집계합니다.
rollUp 엔드포인트를 호출할 때 closed-open range (startTime 포함, endTime 제외) 및 windowSize가 포함된 JSON 요청 본문을 제공합니다. 다음 windowSize 요구사항에 유의하세요.
windowSize기간은 1초 ("1s") 이상이어야 합니다. API는 1초 미만의 기간, 0 또는 음수 기간을400 Bad Request(INVALID_ROLLUP_WINDOW) 오류로 거부합니다.- 하위 버킷에 합산 데이터가 고르지 않게 분포되지 않도록 하려면 데이터 유형의 기본 저장소 해상도 (예: 1분 걸음 수 간격의 경우
"60s")보다 크거나 같은windowSize를 선택합니다. 자세한 내용은 롤업 기간 및 스토리지 해상도를 참조하세요.
예를 들어 다음 요청은 걸음 수를 1분 간격(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 엔드포인트를 사용하여 하루 또는 여러 날 (windowSizeDays)에 걸쳐 데이터를 집계합니다. 요청 본문에 폐쇄형-개방형 민간 시간 range (start 및 end)을 제공합니다. 데이터 유형에 따라 엔드포인트는 각 시민 기간의 합계 또는 평균과 같은 집계된 값을 반환합니다.
dailyRollUp는 각 데이터 포인트에 기록된 UTC 오프셋을 사용하여 민간시를 기준으로 작동하므로 일광 절약 시간제 전환 또는 시간대 간 이동으로 인한 가변적인 하루 길이를 자동으로 조정합니다.
예를 들어 다음 요청은 하루 (windowSizeDays: 1) 동안의 걸음 수를 집계합니다.
요청
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"
}
}
]
}데이터 소스 계열별로 집계
rollUp 및 dailyRollUp는 모두 JSON 요청 본문에서 선택적 dataSourceFamily 필드를 허용하여 집계를 특정 소스 그룹으로 제한합니다.
users/me/dataSourceFamilies/all-sources옵션 (기본값)은 등록된 모든 퍼스트 파티 및 서드 파티 소스에서 조정된 데이터를 집계합니다.users/me/dataSourceFamilies/google-wearables옵션은 Google 및 Fitbit 웨어러블 트래커 기기에서 기록한 데이터를 집계하며, 수동으로 기록된 데이터와 휴대전화에서 추정한 데이터는 제외됩니다.users/me/dataSourceFamilies/google-sources옵션은 웨어러블 트래커, 헬스 커넥트, 퍼스트 파티 앱의 수동 항목을 포함하여 퍼스트 파티 Google 및 Fitbit 소스의 데이터를 집계합니다.
전체 매개변수 요구사항과 요청 및 응답 예시는 데이터 필터링 가이드의 데이터 소스 계열별 필터링을 참조하세요.
롤업 기간 및 스토리지 해상도
rollUp 엔드포인트는 1초 ("1s") 이상의 모든 windowSize를 허용하지만, 다양한 데이터 유형은 기본 저장소에서 서로 다른 샘플링 레이트 또는 간격 기간으로 측정값을 기록하고 유지합니다. 예를 들어 steps, distance, active-minutes, active-energy-burned와 같은 웨어러블 신체 활동 측정항목은 일반적으로 1분(60s) 간격으로 기록됩니다.
다음 표에는 일반적인 데이터 유형에 대한 기본 스토리지 해상도와 권장되는 최소 windowSize 값이 나와 있습니다.
| 저장용량 해결 | 최소 권장 windowSize |
데이터 유형 |
|---|---|---|
1초 (1s) |
"1s" |
heart-rate |
1분 (60s) |
"60s" |
active-energy-burned, active-minutes, active-zone-minutes, altitude, calories-in-heart-rate-zone, distance, floors, steps, time-in-heart-rate-zone, total-calories |
간격 데이터 유형을 집계할 때 rollUp 엔드포인트는 기록된 각 데이터 포인트를 데이터 포인트의 startTime가 포함된 버킷에 배치합니다. API는 하위 간격 버킷 간에 간격 데이터를 분할, 보간 또는 배포하지 않습니다.
기본 데이터 스토리지 간격보다 작은 windowSize를 지정하는 경우 (예: 1분 간격으로 저장된 steps에 대해 10초 기간을 요청하는 경우):
- 간격의
startTime(예:10:00:00~10:00:10)과 일치하는 첫 번째 하위 버킷은 전체 분의 누적 수(예: 해당 분에 기록된 100단계 모두)를 수신합니다. - 동일한 분 내의 나머지 하위 버킷 (
10:00:10~10:00:20,10:00:20~10:00:30등)은 해당 기간 내에 시작되는 간격이 없으므로 데이터 포인트를 수신하지 않습니다.
이렇게 하면 그림 1과 같이 전체 간격의 값이 첫 번째 하위 기간에 집중되는 스파이크 데이터가 생성됩니다.
균등하게 분산되고 의미 있는 집계를 얻으려면 항상 windowSize를 타겟 데이터 유형의 기본 저장소 해상도와 같거나 그보다 긴 기간으로 설정하세요 (예: steps의 경우 "60s" 이상). 각 데이터 유형의 저장소 해상도와 최소 권장 롤업 기간은 Google Health API 데이터 유형 참조를 확인하세요.
범위가 기간 크기의 배수가 아닌 경우 버케팅
요청된 범위가 windowSize (또는 windowSizeDays)의 정확한 배수가 아닌 경우 최종 시간순 버킷은 범위의 상단 엔드포인트에서 잘리고 기간 크기보다 짧은 기간을 포함합니다. API는 수정 없이 요청을 수락하며 반올림, 시간 이동 또는 데이터 보간을 수행하지 않습니다.
요청된 전체 범위를 포함하기 위해 API는 올림 나눗셈을 사용하여 총 집계 기간 수를 계산합니다.
Number of windows = ceiling(Range duration / Window size)
모든 버킷은 범위의 시작부터 순차적으로 시작됩니다. 다른 전체 크기 기간을 추가하여 요청된 종료 시간을 초과하면 최종 기간이 범위 종료 시간에 잘립니다 (고정됨).
버케팅 작동 방식
나눌 수 없는 범위로 롤업을 요청하면 API는 다음 규칙을 적용합니다.
- 버케팅은 요청된 범위(
range.startTime또는range.start)의 시작 부분에서 시작되고 기간 크기 (windowSize또는windowSizeDays)만큼 앞으로 진행됩니다. - 마지막 시간순 버킷은 요청된 범위 (
range.endTime또는range.end)의 끝에 고정되어 요청된 기간 크기보다 짧은 기간을 포함합니다. - 반환된
RollupDataPoint또는DailyRollupDataPoint객체에는 자체 명시적 시작 및 종료 타임스탬프가 포함되며, 이를 사용하여 잘린 버킷의 실제 기간을 검사할 수 있습니다. - API는 롤업 데이터를 시간 역순 (최신순)으로 반환하므로 최종 시간순 버킷 (잘린 버킷)이 반환된 목록의 첫 번째 요소 (
index 0)로 표시됩니다.
그림 2는 API가 range.startTime에서 앞으로 나눌 수 없는 범위를 버킷화하고, range.endTime에서 최종 버킷을 고정하고, 결과 버킷을 역순으로 반환하는 방법을 보여줍니다.
5분 기간이 있는 12분 범위 예시
클라이언트가 5분 windowSize ("300s")로 12분 범위에 대한 롤업을 요청한다고 가정해 보겠습니다.
range.startTime값은10:00:00Z입니다.range.endTime값은10:12:00Z이며 총 기간은 12분입니다.windowSize값은"300s"(5분)입니다.
12분은 5분 (12 = 5 * 2 + 2)의 정확한 배수가 아니므로 API는 기간 수를 ceiling(12 / 5) = 3로 계산합니다. 이렇게 하면 다음과 같은 세 가지 시간순 버킷이 생성됩니다.
| 버킷 | 간격 | 기간 | 기간 상태 |
|---|---|---|---|
| 버킷 1 | [10:00:00Z, 10:05:00Z) |
5분 | 전체 창 |
| 버킷 2 | [10:05:00Z, 10:10:00Z) |
5분 | 전체 창 |
| 버킷 3 | [10:10:00Z, 10:12:00Z) |
2분 | range.endTime에서 잘림 |
집계 값에 미치는 영향
마지막 시간순 기간의 기간이 더 짧기 때문에 잘린 버킷의 가산 측정항목(예: 걸음 수의 합계 또는 수)은 기간이 짧아 더 낮습니다.
사용자가 이 12분 동안 분당 100걸음의 일정한 속도로 걷는 경우 버킷에는 다음과 같은 총합이 포함됩니다.
- 버킷 1 (
10:00:00Z~10:05:00Z)은 500걸음 (분당 100걸음으로 5분)을 기록합니다. - 버킷 2 (
10:05:00Z~10:10:00Z)는 500걸음 (분당 100걸음으로 5분)을 기록합니다. - 버킷 3 (
10:10:00Z~10:12:00Z)은 200걸음 (분당 100걸음으로 2분)을 기록합니다.
버킷 3의 걸음 수가 200걸음으로 더 적은 것은 잘린 기간의 지속 시간이 2분이기 때문이며 사용자의 활동이 감소했기 때문이 아닙니다. 이 데이터를 표시하거나 분석할 때는 사용자 활동이 잘못 표시되지 않도록 각 버킷의 명시적 기간을 사용하여 개수를 정규화합니다.
그림 3은 세 가지 버킷에서 원시 가산 걸음 수 합계 (countSum)를 기간 정규화 비율과 비교합니다.
순서를 보여주는 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"
}
}
]
}