A API Google Health oferece endpoints de agregação dedicados que agrupam e resumem históricos de saúde em períodos. Em vez de recuperar e somar registros brutos individuais no cliente, use os endpoints de agregação para calcular métricas (como totais, médias, mínimos e máximos) em um fluxo de dados reconciliado:
- O endpoint
rollUpagrega pontos de dados em intervalos de tempo físicos em UTC usando uma duração de janela configurável em segundos (windowSize). - O endpoint
dailyRollUpagrega pontos de dados em um ou mais dias corridos (windowSizeDays) usando o horário civil em relação ao relógio local do usuário.
Os dois endpoints reconciliam automaticamente pontos de dados sobrepostos em dispositivos conectados e excluem períodos em que o wearable não está no pulso para tipos de dados que oferecem suporte à detecção no pulso.
Comparar endpoints de agregação
Escolha o endpoint de agregação que corresponde à forma como seu aplicativo agrupa e exibe as métricas de saúde de séries temporais:
| Recurso | Endpoint rollUp |
Endpoint dailyRollUp |
|---|---|---|
| Solicitação 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 |
| Representação de tempo | Horário físico em UTC (startTime e endTime no formato RFC 3339). |
Horário civil (start e end como objetos CivilDateTime). |
| Parâmetro de janela | windowSize (string de duração obrigatória em segundos, mínimo de "1s"). |
windowSizeDays (número inteiro opcional de dias, o padrão é 1). |
| Objeto de resposta | RollupDataPoint |
DailyRollupDataPoint |
| Ordenação de respostas | Ordem cronológica inversa (janela mais recente primeiro). | Ordem cronológica inversa (janela mais recente primeiro). |
| Ideal para | Gráficos intradiários, histogramas por hora ou minuto e análise de UTC de duração fixa. | Painéis diários, tendências de vários dias e resumos que consideram viagens entre fusos horários ou o horário de verão. |
Os dois endpoints aplicam limites máximos de intervalo de consulta com base no tipo de dados:
- Um intervalo máximo de consulta de 14 dias se aplica a
calories-in-heart-rate-zone,heart-rate,active-minutesetotal-calories. - Um intervalo máximo de consulta de 90 dias se aplica a todos os outros tipos de dados compatíveis.
Para verificar quais tipos de dados são compatíveis com rollup e dailyRollup, consulte a
referência de tipos de dados da API Google Health.
Agregação em intervalos de tempo físicos
Use o endpoint rollUp para agregar pontos de dados em um horário físico range (em UTC) agrupados por uma duração de janela em segundos (windowSize).
Ao chamar o endpoint rollUp, forneça um corpo de solicitação JSON que contenha o
range fechado-aberto (startTime inclusivo, endTime exclusivo) e
windowSize. Lembre-se dos seguintes requisitos do windowSize:
- A duração de
windowSizeprecisa ser de pelo menos 1 segundo ("1s"). A API rejeita durações de menos de um segundo, zero ou negativas com um erro400 Bad Request(INVALID_ROLLUP_WINDOW). - Para evitar a distribuição desigual de dados agregados entre sub-buckets, escolha
um
windowSizeigual ou maior que a resolução de armazenamento subjacente do tipo de dados (como"60s"para intervalos de passos de 1 minuto). Para mais detalhes, consulte Janela de rollup e resolução de armazenamento.
Por exemplo, a solicitação a seguir acumula as contagens de passos em intervalos de 1 minuto
(60s):
Solicitação
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"
}Resposta
{
"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"
}
},
...
]
}Agregar em dias corridos
Use o endpoint dailyRollUp para agregar dados de um único dia ou de vários dias (windowSizeDays). Forneça o horário civil fechado-aberto range (start e end) no corpo da solicitação. Dependendo do tipo de dados, o endpoint retorna valores agregados, como
a soma ou a média de cada janela civil.
Como dailyRollUp opera no horário civil usando os deslocamentos de UTC registrados com
cada ponto de dados, ele reconcilia automaticamente as durações variáveis de dias causadas por
transições de horário de verão ou viagens entre fusos horários.
Por exemplo, a solicitação a seguir agrega contagens de passos em um único dia
civil (windowSizeDays: 1):
Solicitação
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
}Resposta
{
"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"
}
}
]
}Agregação por família de fontes de dados
Tanto rollUp quanto dailyRollUp aceitam um campo dataSourceFamily opcional no corpo da solicitação JSON para restringir a agregação a grupos de origem específicos:
- A opção
users/me/dataSourceFamilies/all-sources(padrão) agrega dados reconciliados em todas as fontes próprias e de terceiros registradas. - A opção
users/me/dataSourceFamilies/google-wearablesagrega dados registrados por dispositivos de monitoramento wearable do Google e do Fitbit, excluindo dados registrados manualmente e estimados pelo smartphone. - A opção
users/me/dataSourceFamilies/google-sourcesagrega dados de fontes próprias do Google e do Fitbit, incluindo rastreadores de atividade física, Conexão Saúde e entradas manuais em apps próprios.
Para ver todos os requisitos de parâmetros e exemplos de solicitação e resposta, consulte Filtrar por família de fonte de dados no guia "Filtrar dados".
Janela de rollup e resolução de armazenamento
Embora o endpoint rollUp aceite qualquer windowSize de 1 segundo ("1s") ou
mais, diferentes tipos de dados registram e mantêm medições em diferentes
taxas de amostragem ou durações de intervalo no armazenamento subjacente. Por exemplo,
as métricas de atividade física de wearables, como steps, distance,
active-minutes e active-energy-burned, geralmente são registradas em intervalos de 1 minuto
(60s).
A tabela a seguir lista as resoluções de armazenamento subjacentes e os valores mínimos
recomendados de windowSize para tipos de dados comuns:
| Resolução de armazenamento | Mínimo recomendado: windowSize |
Tipos de dados |
|---|---|---|
1 segundo (1s) |
"1s" |
heart-rate |
1 minuto (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 |
Ao agregar tipos de dados de intervalo, o endpoint rollUp coloca cada ponto de dados registrado no bucket que contém o startTime do ponto de dados. A API
não divide, interpola ou distribui dados de intervalo em buckets de
subintervalo.
Se você especificar um windowSize menor que o intervalo de armazenamento de dados
subjacente (por exemplo, solicitar uma janela de 10 segundos para steps armazenado em
intervalos de 1 minuto):
- O primeiro sub-bucket que corresponde ao
startTimedo intervalo (por exemplo,10:00:00a10:00:10) recebe a contagem acumulada de todo o minuto (por exemplo, todas as 100 etapas registradas para esse minuto). - Os sub-buckets restantes no mesmo minuto (
10:00:10a10:00:20,10:00:20a10:00:30e assim por diante) não recebem pontos de dados, porque nenhum intervalo começa nessas janelas.
Isso produz dados com picos em que o valor de todo o intervalo é concentrado na primeira subjanela, como mostrado na Figura 1.
Para receber agregações distribuídas de maneira uniforme e significativas, sempre defina windowSize
como uma duração igual ou maior que a resolução de armazenamento subjacente do
tipo de dados de destino (por exemplo, "60s" ou maior para steps). Para ver a resolução de armazenamento
e a janela de rollup mínima recomendada de cada tipo de dados, consulte a
referência de tipos de dados da API Google Health.
Agrupamento quando o intervalo não é um múltiplo do tamanho da janela
Se o intervalo solicitado não for um múltiplo exato de windowSize (ou
windowSizeDays), o bucket cronológico final será truncado no endpoint
superior do intervalo e cobrirá uma duração menor que o tamanho da janela. A API aceita sua solicitação sem modificações e não realiza arredondamentos, mudanças de horário ou interpolação de dados.
Para cobrir todo o intervalo solicitado, a API usa a divisão de teto para calcular o número total de janelas de agregação:
Number of windows = ceiling(Range duration / Window size)
Cada bucket começa sequencialmente no início do intervalo. Se a adição de outra janela de tamanho completo ultrapassar o horário de término solicitado, a janela final será truncada (fixada) no horário de término do intervalo.
Como funciona o agrupamento
Quando você solicita rollups com intervalos não divisíveis, a API aplica as seguintes regras:
- O agrupamento começa no início do intervalo solicitado
(
range.startTimeourange.start) e avança pelo tamanho da janela (windowSizeouwindowSizeDays). - O último bucket cronológico é fixado no final do intervalo solicitado (
range.endTimeourange.end), cobrindo uma duração menor do que o tamanho da janela solicitada. - Os objetos
RollupDataPointouDailyRollupDataPointretornados incluem os próprios carimbos de data/hora de início e término explícitos, que podem ser usados para inspecionar a duração real do bucket truncado. - Como a API retorna dados de rollup em ordem cronológica inversa (do mais recente
para o mais antigo), o bucket cronológico final (o bucket truncado) aparece como
o primeiro elemento (
index 0) na lista retornada.
A Figura 2 ilustra como a API agrupa um intervalo não divisível a partir de
range.startTime, fixa o último bucket em range.endTime e retorna os
buckets resultantes em ordem cronológica inversa.
Exemplo de intervalo de 12 minutos com uma janela de 5 minutos
Suponha que um cliente solicite um rollup em um intervalo de 12 minutos com um windowSize de 5 minutos ("300s"):
- O valor de
range.startTimeé10:00:00Z. - O valor de
range.endTimeé10:12:00Z, para uma duração total de 12 minutos. - O valor de
windowSizeé"300s"(5 minutos).
Como 12 minutos não é um múltiplo exato de 5 minutos (12 = 5 * 2 + 2),
a API calcula o número de janelas como ceiling(12 / 5) = 3. Isso produz
três buckets cronológicos:
| Bucket | Intervalo | Duração | Status do período |
|---|---|---|---|
| Bucket 1 | [10:00:00Z, 10:05:00Z) |
5 minutos | Janela cheia |
| Bucket 2 | [10:05:00Z, 10:10:00Z) |
5 minutos | Janela cheia |
| Bucket 3 | [10:10:00Z, 10:12:00Z) |
2 minutos | Truncado em range.endTime |
Impacto nos valores agregados
Como a janela cronológica final tem uma duração menor, as métricas aditivas (como a soma ou a contagem de etapas) são menores no bucket truncado devido ao período mais curto.
Se um usuário caminhar em um ritmo constante de 100 passos por minuto durante todo esse intervalo de 12 minutos, os buckets vão conter os seguintes totais:
- O bucket 1 (
10:00:00Za10:05:00Z) registra 500 passos (5 minutos a 100 passos por minuto). - O bucket 2 (
10:05:00Za10:10:00Z) registra 500 passos (5 minutos a 100 passos por minuto). - O bucket 3 (
10:10:00Za10:12:00Z) registra 200 passos (2 minutos a 100 passos por minuto).
A contagem de passos menor de 200 passos no Bucket 3 é devido à duração de 2 minutos da janela truncada, não a uma queda na atividade do usuário. Ao representar ou analisar esses dados, normalize as contagens usando a duração explícita de cada bucket para evitar uma queda enganosa na atividade do usuário.
A Figura 3 compara os totais de passos aditivos brutos (countSum) com as taxas normalizadas por duração nos três buckets.
Exemplo de resposta da API mostrando a ordenação
Como a API retorna resultados em ordem cronológica inversa, o bucket truncado aparece como o primeiro elemento na lista retornada:
{
"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"
}
}
]
}