Endpoints

Esta página oferece uma visão geral das convenções da API REST, além de um índice de tarefas comuns da API Google Health e exemplos de cada uma delas.

Convenções da API REST

A API Google Health segue os padrões das Propostas de melhoria da API do Google (AIPs), especificamente AIP-127 (transcodificação HTTP e gRPC) e AIP-131 a AIP-135 (métodos padrão). Esses padrões definem como os dados são mapeados de uma mensagem proto para uma solicitação HTTP.

Parâmetros de consulta

Os parâmetros de consulta são usados quando os dados fazem parte do URL. Isso é principalmente para solicitações GET (busca de um recurso) ou LIST (filtragem/paginação), mas também é usado para operações DELETE.

  • Posicionamento: anexado ao URL depois de um ?.
  • Sintaxe: pares de chave-valor separados por &.
  • Mapeamento: todos os campos da mensagem de solicitação que não fazem parte do modelo de caminho do URL são mapeados para um parâmetro de consulta.
  • Ideal para: tipos simples (strings, ints, enums) e campos repetidos.

Exemplo de sintaxe:

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"

Corpo da solicitação

O corpo da solicitação é usado quando os dados modificam o estado de um recurso ou são muito grandes para uma URL. O corpo geralmente é uma representação JSON do próprio recurso. Normalmente usado para operações POST, PATCH e PUT.

  • Posicionamento: dentro da carga útil HTTP (não visível no URL).
  • Sintaxe: formatada como um objeto JSON.
  • Mapeamento: definido na anotação google.api.http.
    • body: "*" significa que toda a mensagem é o corpo.
    • body: "resource_name" significa que apenas um campo específico no proto é o corpo.
  • Ideal para: objetos complexos, mensagens aninhadas e dados sensíveis.

Exemplo de sintaxe:

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

O caso híbrido

Em um método Update compatível com AIP-134 ou uma operação PATCH, ambos são usados. O URL contém o nome do recurso, o corpo contém os dados atualizados do recurso, e um parâmetro de consulta (geralmente update_mask) especifica quais campos mudar.

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

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

Principais diferenças em resumo

Recurso Parâmetros de consulta Corpo da solicitação
Orientações sobre a AIP Usado para operações de pesquisa, filtragem e leitura. Usado para operações de gravação.
Visibilidade Visíveis no histórico do navegador e nos registros do servidor. Oculto do URL.
Complexidade Limitado a estruturas planas ou repetidas. Compatível com objetos JSON profundamente aninhados.
Codificação Precisa ser codificado por URL (por exemplo, espaços se tornam %20). Codificação JSON padrão.

Datas

Todas as datas na API Google Health são mostradas no formato YYYY-MM-DD. A API Nutrition é compatível com o padrão ISO-8601 para valores de data com as seguintes condições:

  • Um ano com quatro dígitos YYYY
  • Valores de ano no intervalo de 0000 a 9999
  • Nenhuma aplicação de restrições de data de início implícitas pelo padrão ISO-8601 ou outra época

Cabeçalhos

Para executar os endpoints da API Google Health, é necessário usar os cabeçalhos e o token de acesso adequados. O cabeçalho a seguir é recomendado para solicitações GET e POST:

Authorization: Bearer access-token
Accept: application/json

Índice de tarefas da API

Esta seção fornece um índice de tarefas comuns da API Google Health e exemplos de cada uma delas.

Receber o ID de usuário do Fitbit ou do Google

Depois que um usuário dá consentimento pelo Google OAuth 2.0, a resposta do token não contém o ID de usuário do Fitbit ou do Google. Para conseguir o ID do usuário, chame o endpoint getIdentity. getIdentity retorna o ID do usuário legado do Fitbit e o ID do usuário do Google.

Recomendamos que, assim que um novo usuário der consentimento pelo OAuth, você chame o endpoint getIdentity e armazene os dois IDs de usuário. Isso oferece compatibilidade com versões anteriores e futuras na sua integração.

Exemplo:

Solicitação

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

Resposta

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

Receber dados intradiários ou detalhados coletados ao longo de um dia

Use o endpoint list de um tipo de dados específico para receber dados intradiários ou detalhados coletados ao longo do dia em intervalos compatíveis com esse tipo de dados.

Exemplo:

Solicitação

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

Resposta

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

Ter uma visão reconciliada dos dados de intervalo

Para extrair dados de intervalo sem registros sobrepostos ou conflitos multidispositivo, chame o endpoint reconcile. O endpoint reconcile desduplica automaticamente intervalos sobrepostos em lotes de sincronização e vários dispositivos de gravação, retornando um fluxo autoritário e contínuo adequado para renderizar linhas do tempo de atividades e calcular durações.

Para saber por que os dispositivos conectados produzem intervalos sobrepostos e uma comparação operacional entre list e reconcile, consulte o guia de gerenciamento de dados.

O exemplo a seguir compara a resposta de list (que retorna os dois registros sobrepostos) com reconcile (que resolve o conflito retornando o registro oficial) para um usuário com duas sessões de exercícios sobrepostas:

Lista bruta

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

Reconciliado

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

A conciliação resolve sessões conflitantes ao remover duplicidades e selecionar o registro oficial, em vez de sintetizar uma união de tempo artificial (como 11:00:00Z a 11:50:00Z). A resposta conciliada retorna o ponto de dados vencedor (7797422996486764704) com o intervalo registrado original (11:20:00Z a 11:50:00Z), preservando a integridade da telemetria e das métricas medidas dessa sessão.

Filtrar dados

Para recuperar subconjuntos específicos de registros de pontos de dados que correspondem a critérios como um intervalo de tempo, data ou hora de observação, use o endpoint list ou reconcile com um parâmetro filter.

Para diretrizes detalhadas, regras de formatação, erros de validação e exemplos de consultas, consulte o guia de filtragem de dados.

Filtrar por família de fonte de dados

Para isolar ou agregar dados de tipos específicos de fontes (por exemplo, dispositivos wearable físicos x entradas manuais), use o parâmetro dataSourceFamily.

Para diretrizes detalhadas, famílias compatíveis e exemplos de solicitação e resposta para reconcile, rollUp e dailyRollUp, consulte Filtrar por família de fonte de dados no guia "Filtrar dados".

Filtrar dados por um horário de início civil do intervalo

Use o endpoint list com um parâmetro filter para filtrar dados por tempo civil ou um intervalo.

Exemplo:

Solicitação

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

Resposta

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

Filtrar dados por um tempo físico de observação de amostra

Use o endpoint list com um parâmetro filter para filtrar dados por tempo físico de observação da amostra.

Exemplo:

Solicitação

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

Resposta

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

Filtrar e agregar por família de fonte de dados

Uma família de fontes de dados é um agrupamento lógico de fontes de dados (como smartwatches, apps para dispositivos móveis ou entradas manuais). Isso permite isolar ou agregar dados de tipos específicos de fontes (por exemplo, dispositivos wearable físicos x entradas manuais).

Os endpoints reconcile, rollUp e dailyRollUp são compatíveis com o parâmetro dataSourceFamily. O mecanismo de transmissão depende do endpoint:

Endpoint (método HTTP) Mecanismo
reconcile (GET) Transmita dataSourceFamily como um parâmetro de consulta do URL.
rollUp (POST) Transmita dataSourceFamily como um campo no corpo da solicitação JSON.
dailyRollUp (POST) Transmita dataSourceFamily como um campo no corpo da solicitação JSON.

Famílias de fontes de dados compatíveis

A tabela a seguir descreve os valores de dataSourceFamily compatíveis:

Opção Descrição
users/me/dataSourceFamilies/all-sources Valor padrão. Retorna pontos de dados conciliados em todas as fontes de dados registradas próprias (1P) e de terceiros (3P). Os dados de apps de terceiros serão retornados com essa opção (como etapas do smartwatch + etapas do app de terceiros + etapas do smartphone + etapas manuais).
users/me/dataSourceFamilies/google-wearables Inclui dados registrados por dispositivos de rastreamento do Google e da Fitbit (como trackers vestíveis da Fitbit e o Pixel Watch). Exclui dados registrados manualmente e estimados pelo smartphone. Use essa opção quando a integração exigir telemetria bruta do sensor gravada diretamente pelo hardware wearable.
users/me/dataSourceFamilies/google-sources Inclui fontes próprias do Google e do Fitbit. Isso inclui registros de dispositivos rastreadores físicos, dados da Conexão Saúde e entradas manuais registradas em apps próprios (como o app Fitbit ou o Google Fit).

Para receber um fluxo de dados conciliados de uma família de fontes de dados específica, chame o endpoint reconcile com o parâmetro de consulta dataSourceFamily.

Por exemplo, a solicitação GET a seguir busca o sono registrado pelo rastreador para o dia após 03/03/2026:

Solicitação

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

Resposta

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

Para agregar pontos de dados em um período específico restrito a uma determinada família de fontes de dados, chame o endpoint rollUp e transmita o campo dataSourceFamily no corpo da solicitação JSON.

A solicitação POST a seguir consulta contagens de passos de caminhada intradiárias em intervalos de uma hora (3600s), agregadas exclusivamente de dispositivos wearable:

Solicitação

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

Resposta

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

Para agregar pontos de dados diários de uma família de fontes específica, chame o endpoint dailyRollUp e transmita o campo dataSourceFamily no corpo da solicitação.

Por exemplo, a solicitação a seguir calcula os resumos diários das etapas do usuário, incluindo todas as fontes primárias do Google e do Fitbit (dispositivos wearable + entradas manuais):

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

Resposta

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

Agregar pontos de dados em um período

Use o endpoint rollUp para retornar o agregado de pontos de dados com base em uma janela em segundos, no intervalo datetime com base no tempo físico dos usuários (em UTC).

Ao chamar o endpoint rollUp, forneça o corpo da solicitação que representa o intervalo de tempo necessário e windowSize. Observe os seguintes requisitos para windowSize:

  • Tamanho mínimo da janela: a duração de windowSize precisa ser de pelo menos 1 segundo ("1s"). Durações menores que um segundo, zero ou negativas serão rejeitadas com um 400 Bad Request (INVALID_ROLLUP_WINDOW).
  • Alinhamento da resolução de armazenamento: para evitar a distribuição desigual de dados agregados em subbuckets, escolha um windowSize igual ou maior que a resolução de armazenamento do tipo de dados (como "60s" para intervalos de etapas de 1 minuto). Para mais detalhes, consulte Tamanho da janela de rollup e resolução de armazenamento subjacente.

Por exemplo, para agrupar contagens de passos em intervalos de um 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 dados em um único dia ou em vários dias

O endpoint dailyRollUp deve ser usado quando você quer agregar dados em um único dia ou em vários dias, conhecido como windowSize. Forneça o intervalo de tempo civil fechado-aberto para o intervalo necessário no corpo da solicitação. Dependendo do tipo de dados, você vai receber a soma ou a média no intervalo.

Exemplo:

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

Agrupamento em intervalos 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 último agrupamento cronológico será truncado no endpoint superior do intervalo e vai abranger uma duração menor que o tamanho da janela. A API aceita sua solicitação sem modificação e não realiza arredondamentos, mudanças de horário ou interpolação de dados.

Para abranger todo o intervalo solicitado, a API usa a divisão por teto para calcular o número total de períodos de agregação:

Number of windows = ceiling(Range duration / Window size)

Cada agrupamento começa sequencialmente desde o início do seu intervalo. Se adicionar outra janela em tamanho real ultrapassar o horário de término solicitado, a janela final será truncada (fixada) no horário de término do intervalo.

Como a inclusão em intervalos funciona

Ao solicitar resumos com intervalos não divisíveis, a API aplica as seguintes regras:

  • O agrupamento em intervalos começa no início do período 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), o que significa que ele abrange uma duração menor do que o tamanho da janela solicitada.
  • Os objetos RollupDataPoint ou DailyRollupDataPoint retornados especificam explicitamente os próprios carimbos de data/hora de início e fim, que podem ser usados para inspecionar a duração real do agrupamento truncado.
  • Como a API retorna dados de resumo em ordem cronológica inversa (mais recente primeiro), o último agrupamento cronológico (que é o truncado) aparece como o primeiro elemento (index 0) na lista retornada.

Cenário: intervalo de 12 minutos com uma janela de 5 minutos

Suponha que um cliente solicite um resumo em um intervalo de 12 minutos com um windowSize de 5 minutos:

  • range.startTime: 10:00:00
  • range.endTime: 10:12:00 (duração total: 12 minutos)
  • windowSize: 5 minutes

Como 12 minutos não é um múltiplo de 5 minutos (12 = 5 * 2 + 2), a API aceita a solicitação e calcula o número de janelas como ceiling(12 / 5) = 3.

Isso produz os três intervalos cronológicos a seguir:

  1. Bucket 1:[10:00:00, 10:05:00) — Duração: 5 minutos (janela completa)
  2. Bucket 2:[10:05:00, 10:10:00) — Duração: 5 minutos (janela completa)
  3. Bucket 3 (truncado): [10:10:00, 10:12:00) — Duração: 2 minutos (truncado em range.endTime)

Impacto nos valores agregados

Como a janela final tem uma duração menor, as métricas aditivas (como a soma ou a contagem de etapas) serão menores no agrupamento truncado apenas devido ao período mais curto.

Se um usuário caminhar em um ritmo constante de 100 passos por minuto durante todo esse período de 12 minutos:

  • Intervalo 1 (10h–10h05): 500 passos (5 minutos × 100 passos/minuto)
  • Intervalo 2 (10h05–10h10): 500 passos (5 minutos × 100 passos/minuto)
  • Intervalo 3 (10h10–10h12): 200 passos (2 minutos × 100 passos/minuto)

Exemplo de resposta da API mostrando a ordenação

Como a API retorna resultados em ordem cronológica inversa, o intervalo 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"
      }
    }
  ]
}

Tamanho da janela de agregação e resolução de armazenamento subjacente

Embora o endpoint rollUp aceite qualquer windowSize de 1 segundo ou mais, diferentes tipos de dados registram e mantêm medições em taxas de amostragem ou durações de intervalo diferentes no armazenamento subjacente. Por exemplo, as métricas de atividade física de dispositivos wearable, como steps, distance, active-minutes e active-energy-burned, geralmente são registradas em intervalos de um minuto (60s).

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 segmenta, interpola nem 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 subagrupamento 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 naquele minuto).
  2. Os subbuckets 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 resulta em dados "irregulares", em que o valor de todo o intervalo se concentra na primeira subjanela.

Para ter agregados significativos e distribuídos de maneira uniforme, sempre defina windowSize como uma duração igual ou maior que a resolução de armazenamento do tipo de dados de destino (por exemplo, 60s ou maior para steps). Para conferir a resolução de armazenamento e o período de consolidação mínimo recomendado para cada tipo de dados, consulte a referência Tipos de dados da API Google Health.

Atualizar os dados de saúde de um usuário

Use o endpoint patch para atualizar os dados de saúde de um usuário.

O endpoint patch atualiza um registro com base no identificador especificado no URL da solicitação. Forneça o identificador de um ponto de dados inserido anteriormente. A API substitui o registro atual.

Os carimbos de data/hora de intervalo de um ponto de dados (startTime e endTime) também podem ser atualizados pelo proprietário do registro ou propagados de plataformas upstream, como o app Conexão Saúde. Para detalhes sobre a mutabilidade do carimbo de data/hora, consulte o Guia de gerenciamento de dados. Para um exemplo de atualização de carimbos de data/hora de intervalo, consulte Atualizar carimbos de data/hora de intervalo para dados atuais.

Quando usar o identificador de ponto de dados

O identificador de ponto de dados é essencial nos seguintes cenários:

  • Atualizações segmentadas:para atualizar uma medição específica, forneça o identificador dela na solicitação patch.
  • Exclusões:manter o identificador permite que seu aplicativo exclua o registro mais tarde usando o endpoint batchDelete.

Confira um exemplo em que um usuário atualiza a leitura de gordura corporal em uma balança chamada "HumanScale" da empresa "Scales R Us". A nova leitura de gordura corporal do usuário é de 20% para a data de 10/03/2026:

Solicitação

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

Resposta

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

Atualizar os carimbos de data/hora do intervalo para dados atuais

Para atualizar o startTime ou endTime de um ponto de dados de intervalo, envie uma solicitação PATCH ao URI do recurso do ponto de dados. Somente o criador ou proprietário original de um registro pode modificar os campos dele. Os aplicativos não podem editar pontos de dados que não foram criados por eles.

Para saber mais sobre a mutabilidade do carimbo de data/hora, atualizações upstream da Conexão Saúde e implicações de armazenamento em cache, consulte o guia de gerenciamento de dados.

O exemplo a seguir demonstra um aplicativo proprietário atualizando os carimbos de data/hora de intervalo de um registro de hidratação usando o endpoint patch:

Solicitação

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

Resposta

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

Registrar um alimento

Para registrar um item alimentar, envie uma solicitação POST para o endpoint nutrition-log dataPoints. O corpo da solicitação contém um DataPoint com um objeto nutritionLog. Para mais informações, consulte o guia de nutrição.

Exemplo:

Solicitação

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

Resposta

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

Excluir dados de saúde do usuário

Use o método batchDelete para excluir uma matriz de dados do app Fitbit de um usuário.

Confira um exemplo em que um usuário registrou o percentual de gordura corporal em uma balança, mas quer excluir o registro. Usando user-id e data-point-id da ação de inserção original:

Solicitação

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

Resposta

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

Encontrar informações do dispositivo

Use o endpoint list para recuperar a lista de dispositivos pareados com a conta de um usuário. Isso inclui as informações do modelo do dispositivo (deviceVersion) e a última vez que ele foi sincronizado com o app Google Health para dispositivos móveis (lastSyncTime).

As informações de configuração e sincronização da lista são úteis para solucionar problemas de sincronização ou buscar dados históricos desde a última sincronização.

Exemplo:

Solicitação

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

Resposta

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

Consultar dados históricos

Um dos principais benefícios da API Google Health é a capacidade de acompanhar o desempenho de um usuário e monitorar os sinais vitais dele por longos períodos. Você pode consultar os dados de um usuário desde que eles foram registrados. A API não impõe limitações ou restrições à quantidade de dados históricos que seu aplicativo pode consumir.

No entanto, a consulta de dados históricos ainda é regida pelos limites de taxa padrão. Para gerenciar a estabilidade do sistema e evitar payloads excessivos, a API Google Health usa paginação automática com tamanhos de página específicos do endpoint. Observe os seguintes limites e comportamentos:

  • Paginação automática:se você consultar um período longo de dados, a API vai retornar apenas a primeira página de resultados até o limite de tamanho da página para esse endpoint, além de um nextPageToken. Use o nextPageToken para solicitar as páginas seguintes.
  • Tamanhos de página variáveis:os limites de capping dependem do endpoint e do tipo de dados. Para a maioria dos tipos de dados, os tamanhos de página são limitados a um máximo de 10.000. No entanto, para determinados tipos de dados, como exercise e sleep, o tamanho padrão e máximo da página é limitado a 25. Por exemplo, se um cliente solicitar todos os dados de sono dos últimos 10 anos, a API ainda vai retornar apenas 25 sessões de sono na primeira página.
  • Restrições de período de agregação:para endpoints de agregação e rollup de dados (como rollUp e dailyRollUp), os períodos de consulta são restritos com base no tipo de dados:
    • Um período máximo de 14 dias para calories-in-heart-rate-zone, heart-rate, active-minutes e total-calories.
    • Um período máximo de 90 dias para todos os outros tipos de dados de consolidação.

Dependendo do volume de dados históricos que seu aplicativo precisa, a recuperação de todo o conjunto de dados exigirá paginação sequencial. Tenha isso em mente ao projetar o processo de sincronização de dados do aplicativo.

Para garantir o desempenho ideal e evitar erros de API, siga estas diretrizes ao consultar dados históricos:

Sincronização de dados em fases (carga quente x carregamento a frio)

  • Carga "quente" inicial:busca e renderiza apenas os dados dos últimos 7 a 14 dias durante a sequência de carga principal. Isso garante que os usuários vejam os dados imediatamente, sem esperar por consultas de longa duração.
  • Carregamento "frio" em segundo plano:delegue a recuperação de dados históricos mais antigos a uma fila assíncrona de prioridade mais baixa ou a um processo em segundo plano depois que a interface principal for renderizada.

Divisão de consultas para agregação

  • Como os endpoints de rollup e rollup diário impõem um limite máximo de período (14 ou 90 dias, dependendo do tipo de dados), é necessário dividir consultas de agregação históricas grandes em intervalos menores e sequenciais dentro desses limites.
  • Faça em lote ou em sequência essas subconsultas com segurança para respeitar os limites de simultaneidade e manter indicadores de progresso da interface estáveis.

Aproveitar consolidações pré-agregadas

Reestruture os painéis de visão geral e os gráficos de tendências para usar endpoints pré-agregados e de resumo (como DailyRollUpDataPoints). Isso vai reduzir drasticamente a sobrecarga de computação no back-end e o tempo de transferência de rede para o cliente.

Tratamento de erros resiliente (novas tentativas inteligentes)

  • Implemente o tratamento estrito de espera exponencial ao encontrar limites de taxa (429 Too Many Requests) e tempos limite de gateway do servidor (504 Gateway Timeout). Nunca repita payloads grandes e com falha imediatamente. As novas tentativas instantâneas multiplicam o congestionamento do back-end e agravam a degradação do sistema.