Filtrar dados

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:

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_time
Sono:sleep.interval.end_time, sleep.interval.civil_end_time
ECG: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 dataSourceFamily explícito ou com dataSourceFamily definido como users/me/dataSourceFamilies/self-sources são implicitamente restritas a self-sources.
  • Solicitar qualquer outra família de fontes de dados (como all-sources, google-wearables ou google-sources) com apenas um escopo de gravação falha com um erro 403 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 dataSourceFamily em list para sleep, food ou food-measurement-unit falha com um erro 400 Bad Request (INVALID_ARGUMENT).
  • Chamar list para esses tipos de dados quando apenas um escopo de gravação é concedido (em que a restrição a self-sources é implícita pelos escopos do chamador) falha com um erro 403 Forbidden (PERMISSION_DENIED).
  • Para filtrar pontos de dados de sleep por dataSourceFamily, use o endpoint reconcile em 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"
      }
    }
  ]
}