A API Google Health usa expressões de filtro para restringir os pontos de dados retornados ao chamar métodos de recuperação padrão. Especificamente, os filtros são usados com:
- Endpoints
list: consulta de pontos de dados brutos. reconcileendpoints: consulta de pontos de dados de fluxo conciliados.
Este guia explica como a filtragem é implementada, a sintaxe e as convenções, e tem exemplos para cada tipo de registro.
Convenções de filtro
A API Google Health implementa filtros seguindo o padrão das Propostas de melhoria da API do Google (AIP-160).
Parâmetros de consulta
Os filtros são transmitidos usando a string de consulta do URL no parâmetro filter.
Como os filtros contêm caracteres especiais (como <, >= e aspas), eles precisam ser codificados para uso em URL quando transmitidos na solicitação HTTP.
Por exemplo, uma solicitação com o filtro
steps.interval.civil_start_time >= "2026-03-04T00:00:00"
precisa ser codificada como:
GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints ?filter=steps.interval.civil_start_time%20%3E%3D%20%222026-03-04T00%3A00%3A00%22
Formato de nomenclatura
Se um tipo de dados tiver mais de uma palavra, o formato do identificador será diferente entre o caminho do recurso e o filtro:
- Caminho do endpoint: use hífens (por exemplo,
/dataTypes/body-fat). - String de filtro: use sublinhados (por exemplo,
body_fat).
Se você usar hífens no identificador do filtro, a API vai retornar um 400 Bad Request
com o motivo do erro INVALID_DATA_POINT_FILTER.
Tipos e campos de filtro
Os campos usados em um filtro dependem do tipo de registro do tipo de dados que você está consultando. A tabela a seguir descreve os campos compatíveis com cada tipo de registro:
| Tipo de registro | Descrição | Campos de filtro compatíveis |
|---|---|---|
| Interval | Pontos de dados registrados durante um período (por exemplo, steps, distance, calories). |
{dataType}.interval.start_time{dataType}.interval.civil_start_time
Exemplo: steps.interval.civil_start_time
|
| Sample | Observações instantâneas ou medições curtas (por exemplo, weight, body-fat, blood-glucose). |
{dataType}.sample_time.physical_time{dataType}.sample_time.civil_time
Exemplo: body_fat.sample_time.physical_time
|
| Diariamente | Métricas e resumos diários (por exemplo, daily-heart-rate-variability). |
{dataType}.date
Exemplo: daily_heart_rate_variability.date
|
| Sessão | Sessões de usuário estendidas com regras de tempo especializadas. |
Exercício:{dataType}.interval.civil_start_timeSono: sleep.interval.end_time, sleep.interval.civil_end_timeECG: electrocardiogram.interval.start_time
Exemplo: sleep.interval.civil_end_time
|
Operadores e regras de formato compatíveis
As expressões de filtro precisam obedecer às seguintes regras de formatação:
Operadores de comparação
Apenas dois operadores de comparação são aceitos:
| Operador | Descrição |
|---|---|
>= |
Limite inferior (inclusive). |
< |
Limite superior (exclusivo). |
Usar outros operadores de comparação (como >, <= ou =) retorna um 400 Bad Request com INVALID_DATA_POINT_FILTER_RESTRICTION_COMPARATOR.
Operadores lógicos
| Operador | Suporte |
|---|---|
AND |
Operador padrão e único compatível. Usado para combinar limites de início e fim. |
OR |
Incompatível. Usar OR retorna um 400 Bad Request com o motivo do erro INVALID_DATA_POINT_FILTER_EXPRESSION_STRUCTURE ("O filtro precisa ser uma conjunção ou sequência de restrições. Encontrado: DISJUNCTION"). |
Literais de hora
Os literais de tempo em expressões de filtro precisam usar estes formatos:
| Tipo hora | Requisitos | Exemplos |
|---|---|---|
| Tempo físico | Formato RFC 3339, terminando em Z ou um ajuste de UTC. Representa eventos do mundo real em UTC. |
Correto: "2026-03-01T00:00:00Z", "2026-03-01T00:00:00-08:00"Incorreto: "2026-03-01" |
| Horário civil | Formato ISO 8601: YYYY-MM-DD[THH:mm:ss]. Representa a hora no relógio de um usuário, independente da localização ou dos ajustes de fuso horário. |
Correto: "2026-03-01", "2026-03-01T08:30:00" |
Filtrar regras de validação
Os filtros seguem estas regras:
| Regra | Descrição | Exemplos |
|---|---|---|
| Sem tipos de tempo mistos | Não misture limites de tempo físicos e civis. | Inválido: steps.interval.start_time >= "2026-03-01T00:00:00Z" AND steps.interval.civil_start_time < "2026-03-02"Erro: INVALID_DATA_POINT_FILTER_MIXED_TIME_RESTRICTIONS ("O filtro não pode conter intervalos de tempo físico e civil") |
| Sem tipos de dados mistos | Use campos pertencentes ao tipo de dados no caminho da solicitação. | Inválido: caminho /users/.../dataTypes/steps/... com filtro distance.interval.start_time >= "..."Erro: INVALID_DATA_POINT_FILTER_COLLECTION_MISMATCH ("O tipo de dados no filtro não corresponde à coleção de tipo de dados principal") |
| Lógica de ordem cronológica | O limite superior precisa ser maior que o limite inferior. | Inválido: steps.interval.start_time >= "2026-03-02T00:00:00Z" AND steps.interval.start_time < "2026-03-01T00:00:00Z"Erro: INVALID_TIME_RANGE ("O horário de término da consulta precisa ser maior que o horário de início") |
| Formato do estojo | Use o formato snake case correspondente ao nome do tipo de dados. | Inválido: body-fat.sample_time.physical_time >= "..."Erro: INVALID_DATA_POINT_FILTER ("Filtro inválido") |
A API retorna HTTP 400 Bad Request para filtros inválidos. Confira error.details[].metadata.detailedReasons para ver o código do motivo do erro.
Escopos OAuth obrigatórios
Para consultar pontos de dados usando filtros, o usuário autorizado precisa conceder o escopo OAuth relevante para esse tipo de dado. Se o escopo necessário estiver faltando, a API
vai retornar um status 403 Forbidden com MISSING_OAUTH_SCOPE.
A tabela a seguir mapeia os escopos do OAuth para os tipos de dados a que concedem acesso de leitura. A tabela mostra os escopos no formato relativo. Por exemplo, .activity_and_fitness.readonly representa https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly:
| Escopo OAuth obrigatório | Tipos de dados |
|---|---|
.activity_and_fitness.readonly |
active-energy-burned, active-minutes, active-zone-minutes, activity-level, altitude, calories-in-heart-rate-zone, daily-vo2-max, distance, exercise, floors, run-vo2-max, sedentary-period, steps, swim-lengths-data, time-in-heart-rate-zone, total-calories, vo2-max |
.ecg.readonly |
eletrocardiograma |
.health_metrics_and_measurements.readonly |
blood-glucose, body-fat, core-body-temperature, daily-heart-rate-variability, daily-heart-rate-zones, daily-oxygen-saturation, daily-respiratory-rate, daily-resting-heart-rate, daily-sleep-temperature-derivations, heart-rate, heart-rate-variability, height, oxygen-saturation, respiratory-rate-sleep-summary, skin-temperature-sensors, weight |
.irn.readonly |
irregular-rhythm-notification |
.nutrition.readonly |
food, food-measurement-unit, hydration-log, nutrition-log |
.sleep.readonly |
sono |
Se o cliente receber apenas um escopo de gravação (como
.activity_and_fitness.writeonly) para um tipo de dados solicitado, ainda será possível
consultar pontos de dados gravados pelo seu próprio cliente. Nesse caso, as solicitações são restritas implicitamente à família de fontes de dados self-sources. Para detalhes e limitações de tipo de dados, consulte Filtrar por família de fonte de dados.
Casos de uso e exemplos
Os exemplos a seguir mostram como criar filtros para cenários comuns:
Consultar etapas por intervalo de tempo físico
Etapas de consulta registradas entre 2026-03-01T00:00:00Z (inclusive) e 2026-03-02T00:00:00Z (exclusive):
GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints ?filter=steps.interval.start_time >= "2026-03-01T00:00:00Z" AND steps.interval.start_time < "2026-03-02T00:00:00Z"
Consultar etapas por intervalo de tempo civil
Consultar etapas de um dia inteiro em 4 de março de 2026, em relação ao relógio local do usuário:
GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints ?filter=steps.interval.civil_start_time >= "2026-03-04" AND steps.interval.civil_start_time < "2026-03-05"
Consultar a gordura corporal por hora da amostra física
Consultar as medições de gordura corporal registradas a partir de março de 2026 (em UTC):
GET https://health.googleapis.com/v4/users/me/dataTypes/body-fat/dataPoints ?filter=body_fat.sample_time.physical_time >= "2026-03-01T00:00:00Z"
Peso da consulta por tempo de amostra civil
Registros de ponderação de consultas gravados após um horário local específico:
GET https://health.googleapis.com/v4/users/me/dataTypes/weight/dataPoints ?filter=weight.sample_time.civil_time >= "2026-03-01T08:00:00"
Consultar resumos diários da variabilidade da frequência cardíaca
Consultar resumos diários da variabilidade da frequência cardíaca (VFC) gravados antes de uma data específica:
GET https://health.googleapis.com/v4/users/me/dataTypes/daily-heart-rate-variability/dataPoints ?filter=daily_heart_rate_variability.date < "2026-08-15"
Consultar sessões de exercícios por horário civil de início
Consultar sessões de exercícios que ocorreram durante uma semana específica no fuso horário local do usuário:
GET https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints ?filter=exercise.interval.civil_start_time >= "2026-03-01" AND exercise.interval.civil_start_time < "2026-03-08"
Consultar sessões de sono por horário civil de término
Consultar registros de sono pelo horário de término da sessão:
GET https://health.googleapis.com/v4/users/me/dataTypes/sleep/dataPoints ?filter=sleep.interval.civil_end_time >= "2026-03-04T05:00:00" AND sleep.interval.civil_end_time < "2026-03-04T12:00:00"
Consultar eletrocardiogramas por horário de início
Consulta gravações de ECG a partir de um ponto físico no tempo em UTC. As consultas de ECG só são compatíveis com uma comparação >= em start_time:
GET https://health.googleapis.com/v4/users/me/dataTypes/electrocardiogram/dataPoints ?filter=electrocardiogram.interval.start_time >= "2026-03-10T12:00:00Z"
Filtrar 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). Ele permite isolar ou agregar dados de tipos específicos de fontes (por exemplo, dispositivos wearable físicos, entradas manuais ou dados gravados pelo seu próprio cliente).
Os endpoints list, 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 |
|---|---|
list (GET) |
Transmita dataSourceFamily como um parâmetro de consulta do URL. |
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 (quando um escopo de leitura é concedido). Inclui pontos de dados de todas as fontes de dados próprias (1P) e de terceiros (3P) disponíveis. Os dados de apps de terceiros sã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). |
users/me/dataSourceFamilies/self-sources |
Inclui apenas os dados que o cliente de chamada gravou pela API Google Health (pontos de dados cuja fonte de dados foi registrada pela API com o mesmo ID do cliente OAuth do chamador). |
Se nenhum ponto de dados corresponder à família de fontes de dados solicitada, a resposta será uma lista vazia em vez de um erro.
Escopos somente gravação e origens próprias
Os chamadores que recebem apenas escopos de gravação (como
.activity_and_fitness.writeonly) para os tipos de dados solicitados podem ler os
dados que eles mesmos gravaram, e apenas esses dados.
- As solicitações sem um parâmetro
dataSourceFamilyexplícito ou comdataSourceFamilydefinido comousers/me/dataSourceFamilies/self-sourcessão implicitamente restritas aself-sources. - Solicitar qualquer outra família de fontes de dados (como
all-sources,google-wearablesougoogle-sources) com apenas um escopo de gravação falha com um erro403 Forbidden(PERMISSION_DENIED).
Limitações de tipo de dados no endpoint de lista
No endpoint list (users.dataTypes.dataPoints.list), não é possível filtrar por dataSourceFamily para os tipos de dados sleep, food e food-measurement-unit:
- Definir explicitamente
dataSourceFamilyemlistparasleep,foodoufood-measurement-unitfalha com um erro400 Bad Request(INVALID_ARGUMENT). - Chamar
listpara esses tipos de dados quando apenas um escopo de gravação é concedido (em que a restrição aself-sourcesé implícita pelos escopos do chamador) falha com um erro403 Forbidden(PERMISSION_DENIED). - Para filtrar pontos de dados de
sleeppordataSourceFamily, use o endpointreconcileem vez disso.
Exemplos de família de fontes de dados
Para listar pontos de dados brutos que seu próprio cliente escreveu para um usuário, chame o endpoint list
com o parâmetro de consulta dataSourceFamily definido como
users/me/dataSourceFamilies/self-sources.
Por exemplo, a solicitação GET a seguir lista as medições brutas de body-fat
gravadas pelo cliente de chamada a partir de 01/03/2026:
Solicitação
GET https://health.googleapis.com/v4/users/me/dataTypes/body-fat/dataPoints ?dataSourceFamily=users/me/dataSourceFamilies/self-sources &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": ""
}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 tamanho de janela específico restrito a uma família de fontes de dados específica, chame o endpoint rollUp e transmita o campo dataSourceFamily no corpo da solicitação JSON.
A solicitação POST a seguir consulta as contagens de passos de caminhada intradiária 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"
}
}
]
}