Dados agregados

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 rollUp agrega pontos de dados em intervalos de tempo físicos em UTC usando uma duração de janela configurável em segundos (windowSize).
  • O endpoint dailyRollUp agrega 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-minutes e total-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 windowSize precisa ser de pelo menos 1 segundo ("1s"). A API rejeita durações de menos de um segundo, zero ou negativas com um erro 400 Bad Request (INVALID_ROLLUP_WINDOW).
  • Para evitar a distribuição desigual de dados agregados entre sub-buckets, escolha um windowSize igual 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-wearables agrega 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-sources agrega 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):

  1. O primeiro sub-bucket que corresponde ao startTime do intervalo (por exemplo, 10:00:00 a 10:00:10) recebe a contagem acumulada de todo o minuto (por exemplo, todas as 100 etapas registradas para esse minuto).
  2. Os sub-buckets restantes no mesmo minuto (10:00:10 a 10:00:20, 10:00:20 a 10:00:30 e 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.

Agrupamento de rollup de subintervalo em comparação com a resolução de armazenamento
Figura 1: agrupamento de subintervalos em que um intervalo de 1 minuto é atribuído ao primeiro subagrupamento de 10 segundos por startTime

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.startTime ou range.start) e avança pelo tamanho da janela (windowSize ou windowSizeDays).
  • O último bucket cronológico é fixado no final do intervalo solicitado (range.endTime ou range.end), cobrindo uma duração menor do que o tamanho da janela solicitada.
  • Os objetos RollupDataPoint ou DailyRollupDataPoint retornados 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.

Agrupamento de rollup, truncamento e ordenação de respostas
Figura 2: agrupamento de rollup, truncamento de fim de intervalo e ordenação de resposta cronológica reversa

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:00Z a 10:05:00Z) registra 500 passos (5 minutos a 100 passos por minuto).
  • O bucket 2 (10:05:00Z a 10:10:00Z) registra 500 passos (5 minutos a 100 passos por minuto).
  • O bucket 3 (10:10:00Z a 10: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.

Comparação entre os totais de passos brutos do bucket e as taxas de passos normalizadas
Figura 3: totais aditivos brutos em comparação com taxas normalizadas por duração para um bucket de rollup truncado

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