La API de Google Health se basa en expresiones de filtro para restringir los puntos de datos que se muestran cuando se llaman a métodos de recuperación estándar. Específicamente, los filtros se usan con lo siguiente:
- Extremos de
list: Consultar puntos de datos sin procesar reconcileextremos: Consultar los datos de transmisión conciliados.
En esta guía, se explica cómo se implementa el filtrado, la sintaxis y las convenciones, y se incluyen ejemplos para cada tipo de registro.
Convenciones de filtros
La API de Google Health implementa filtros según el estándar de las Propuestas de mejora de las APIs de Google (AIP-160).
Parámetros de consulta
Los filtros se pasan a través de la cadena de consulta de la URL en el parámetro filter.
Dado que los filtros contienen caracteres especiales (como <, >= y comillas), deben codificarse como URL cuando se transmiten en la solicitud HTTP.
Por ejemplo, una solicitud con el filtro steps.interval.civil_start_time >= "2026-03-04T00:00:00" se debe codificar de la siguiente manera:
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
Si un tipo de datos tiene más de una palabra, el formato del identificador difiere entre la ruta del recurso y el filtro:
- Ruta de acceso del extremo: Usa guiones (por ejemplo,
/dataTypes/body-fat). - Cadena de filtro: Usa guiones bajos (por ejemplo,
body_fat).
Si usas guiones en el identificador del filtro, la API devuelve un 400 Bad Request con el motivo del error INVALID_DATA_POINT_FILTER.
Tipos y campos de filtros
Los campos que usas en un filtro dependen del tipo de registro del tipo de datos sobre el que realizas la consulta. En la siguiente tabla, se describen los campos admitidos para cada tipo de registro:
| Tipo de registro | Descripción | Campos de filtro admitidos |
|---|---|---|
| Interval | Son los puntos de datos registrados durante un período (por ejemplo, steps, distance, calories). |
{dataType}.interval.start_time{dataType}.interval.civil_start_time
Ejemplo: steps.interval.civil_start_time
|
| Muestra | Observaciones instantáneas o mediciones breves (por ejemplo, weight, body-fat, blood-glucose) |
{dataType}.sample_time.physical_time{dataType}.sample_time.civil_time
Ejemplo: body_fat.sample_time.physical_time
|
| A diario | Métricas y resúmenes diarios (por ejemplo, daily-heart-rate-variability) |
{dataType}.date
Ejemplo: daily_heart_rate_variability.date
|
| Sesión | Sesiones de usuario extendidas con reglas de sincronización especializadas |
Ejercicio: {dataType}.interval.civil_start_timeSueño: sleep.interval.end_time, sleep.interval.civil_end_timeECG: electrocardiogram.interval.start_time
Ejemplo: sleep.interval.civil_end_time
|
Operadores y reglas de formato admitidos
Las expresiones de filtro deben cumplir con las siguientes reglas de formato:
Operadores de comparación
Solo se admiten dos operadores de comparación:
| Operador | Descripción |
|---|---|
>= |
Límite inferior (inclusive). |
< |
Límite superior (exclusivo). |
Si se usan otros operadores de comparación (como >, <= o =), se devuelve un 400 Bad Request con INVALID_DATA_POINT_FILTER_RESTRICTION_COMPARATOR.
Operadores lógicos
| Operador | Asistencia |
|---|---|
AND |
Es el operador predeterminado y el único compatible. Se usa para combinar los límites de inicio y finalización. |
OR |
No compatible. El uso de OR devuelve un 400 Bad Request con el motivo de error INVALID_DATA_POINT_FILTER_EXPRESSION_STRUCTURE ("El filtro debe ser una conjunción o secuencia de restricciones. Se encontró: DISJUNCTION"). |
Literales de hora
Los literales de tiempo en las expresiones de filtro deben usar estos formatos:
| Tipo hora | Requisitos | Ejemplos |
|---|---|---|
| Tiempo físico | Formato RFC 3339, que termina en Z o en un desplazamiento de UTC. Representa eventos del mundo real en UTC. |
Correcto: "2026-03-01T00:00:00Z", "2026-03-01T00:00:00-08:00"Incorrecto: "2026-03-01" |
| Hora civil | Formato ISO 8601: YYYY-MM-DD[THH:mm:ss]. Representa la hora en el reloj de un usuario, independientemente de la ubicación o las compensaciones de zona horaria. |
Correcto: "2026-03-01", "2026-03-01T08:30:00" |
Reglas de validación de filtros
Los filtros siguen estas reglas:
| Regla | Descripción | Ejemplos |
|---|---|---|
| No se admiten tipos de tiempo mixtos | No mezcles límites de tiempo físicos y civiles. | No válido: steps.interval.start_time >= "2026-03-01T00:00:00Z" AND steps.interval.civil_start_time < "2026-03-02"Error: INVALID_DATA_POINT_FILTER_MIXED_TIME_RESTRICTIONS ("El filtro no puede contener períodos tanto físicos como civiles") |
| No hay tipos de datos mixtos | Usa los campos que pertenecen al tipo de datos en la ruta de acceso de la solicitud. | No válido: Ruta de acceso /users/.../dataTypes/steps/... con filtro distance.interval.start_time >= "..."Error: INVALID_DATA_POINT_FILTER_COLLECTION_MISMATCH ("El tipo de datos del filtro no coincide con la colección de tipos de datos principal") |
| Lógica de ordenamiento por tiempo | El límite superior debe ser mayor que el límite inferior. | No válido: steps.interval.start_time >= "2026-03-02T00:00:00Z" AND steps.interval.start_time < "2026-03-01T00:00:00Z"Error: INVALID_TIME_RANGE ("La hora de finalización de la búsqueda debe ser estrictamente posterior a la hora de inicio") |
| Formato de la caja | Usa snake case que coincida con el nombre del tipo de datos. | No válido: body-fat.sample_time.physical_time >= "..."Error: INVALID_DATA_POINT_FILTER ("Invalid filter") |
La API devuelve HTTP 400 Bad Request para los filtros no válidos. Verifica error.details[].metadata.detailedReasons para conocer el código del motivo del error.
Permisos de OAuth obligatorios
Para consultar puntos de datos con filtros, el usuario autorizado debe otorgar el alcance de OAuth pertinente para ese tipo de datos. Si falta el alcance requerido, la API devuelve un estado 403 Forbidden con MISSING_OAUTH_SCOPE.
En la siguiente tabla, se asignan los permisos de OAuth a los tipos de datos a los que otorgan acceso de lectura. En la tabla, se muestran los permisos en su formato relativo (por ejemplo, .activity_and_fitness.readonly representa https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly):
| Permiso de OAuth obligatorio | Tipos de datos |
|---|---|
.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 |
Electrocardiograma |
.health_metrics_and_measurements.readonly |
glucemia, grasa corporal, temperatura corporal central, variabilidad de la frecuencia cardíaca diaria, zonas de frecuencia cardíaca diarias, saturación de oxígeno diaria, frecuencia respiratoria diaria, frecuencia cardíaca en reposo diaria, derivaciones de temperatura del sueño diarias, frecuencia cardíaca, variabilidad de la frecuencia cardíaca, altura, saturación de oxígeno, resumen del sueño de la frecuencia respiratoria, sensores de temperatura cutánea, peso |
.irn.readonly |
irregular-rhythm-notification |
.nutrition.readonly |
food, food-measurement-unit, hydration-log, nutrition-log |
.sleep.readonly |
sleep |
Si a tu cliente solo se le otorga un alcance de escritura (como .activity_and_fitness.writeonly) para un tipo de datos solicitado, aún puedes consultar los puntos de datos que escribió tu propio cliente. En este caso, las solicitudes se restringen de forma implícita a la familia de fuentes de datos self-sources. Para obtener detalles y conocer las limitaciones de los tipos de datos, consulta Cómo filtrar por familia de fuentes de datos.
Casos de uso y ejemplos
En los siguientes ejemplos, se muestra cómo construir filtros para situaciones comunes:
Pasos de la consulta por rango de tiempo físico
Pasos de la búsqueda registrados entre 2026-03-01T00:00:00Z (inclusive) y 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"
Pasos de la consulta por rango de tiempo civil
Pasos de la búsqueda para un día completo, el 4 de marzo de 2026, en relación con el reloj local del usuario:
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"
Consulta la grasa corporal por hora de la muestra física
Consulta las mediciones de grasa corporal registradas a partir de marzo de 2026 (en 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 de la búsqueda por hora de la muestra civil
Registros de peso de la búsqueda grabados después de una hora local específica:
GET https://health.googleapis.com/v4/users/me/dataTypes/weight/dataPoints ?filter=weight.sample_time.civil_time >= "2026-03-01T08:00:00"
Consultar resúmenes diarios de la variabilidad de la frecuencia cardíaca
Consultar los resúmenes diarios de la variabilidad de la frecuencia cardíaca (VFC) registrados antes de una fecha 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 sesiones de ejercicio por hora de inicio civil
Consultar las sesiones de ejercicio que ocurrieron durante una semana específica en la zona horaria local del usuario:
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"
Consulta las sesiones de sueño por hora civil de finalización
Consultar registros de sueño por hora de finalización de la sesión:
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"
Cómo consultar electrocardiogramas por hora de inicio
Consultar los registros de ECG a partir de un punto físico en el tiempo en UTC Ten en cuenta que las búsquedas de ECG solo admiten una comparación de >= en 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 familia de fuentes de datos
Una familia de fuentes de datos es una agrupación lógica de fuentes de datos (como relojes inteligentes, apps para dispositivos móviles o entradas manuales). Te permite aislar o agregar datos de tipos específicos de fuentes (por ejemplo, dispositivos wearables físicos, entradas manuales o datos escritos por tu propio cliente).
Todos los extremos list, reconcile, rollUp y dailyRollUp admiten el parámetro dataSourceFamily. El mecanismo de aprobación depende del extremo:
| Extremo (método HTTP) | Mecanismos |
|---|---|
list (GET) |
Pasa dataSourceFamily como un parámetro de consulta de URL. |
reconcile (GET) |
Pasa dataSourceFamily como un parámetro de consulta de URL. |
rollUp (POST) |
Pasa dataSourceFamily como un campo en el cuerpo de la solicitud JSON. |
dailyRollUp (POST) |
Pasa dataSourceFamily como un campo en el cuerpo de la solicitud JSON. |
Familias de fuentes de datos compatibles
En la siguiente tabla, se describen los valores de dataSourceFamily admitidos:
| Opción | Descripción |
|---|---|
users/me/dataSourceFamilies/all-sources |
Valor predeterminado (cuando se otorga un alcance de lectura). Incluye puntos de datos de todas las fuentes de datos de origen (1P) y de terceros (3P) disponibles. Con esta opción, se devuelven los datos de apps de terceros (como los pasos del reloj inteligente, los pasos de la app de terceros, los pasos del teléfono celular y los pasos manuales). |
users/me/dataSourceFamilies/google-wearables |
Incluye los datos registrados por los dispositivos de monitoreo de Google y Fitbit (como los monitores wearables de Fitbit y el Pixel Watch). Excluye los datos registrados manualmente y los datos estimados por el teléfono. Usa esta opción cuando tu integración requiera telemetría sin procesar del sensor registrada directamente por el hardware del wearable. |
users/me/dataSourceFamilies/google-sources |
Incluye fuentes de origen de Google y Fitbit. Esto incluye los registros de dispositivos de monitoreo de actividad física, los datos de Health Connect y las entradas manuales registradas a través de apps propias (como la app de Fitbit o Google Fit). |
users/me/dataSourceFamilies/self-sources |
Incluye solo los datos que el cliente que llama escribió a través de la API de Google Health (puntos de datos cuya fuente de datos se registró a través de la API con el mismo ID de cliente OAuth que el llamador). |
Si ningún punto de datos coincide con la familia de fuentes de datos solicitada, la respuesta será una lista vacía en lugar de un error.
Permisos de solo escritura y fuentes propias
Los llamadores a los que solo se otorgan permisos de escritura (como .activity_and_fitness.writeonly) para los tipos de datos solicitados pueden leer los datos que escribieron ellos mismos y solo esos datos.
- Las solicitudes sin un parámetro
dataSourceFamilyexplícito o condataSourceFamilyestablecido enusers/me/dataSourceFamilies/self-sourcesse restringen de forma implícita aself-sources. - Si solicitas cualquier otra familia de fuentes de datos (como
all-sources,google-wearablesogoogle-sources) solo con un permiso de escritura, se producirá un error403 Forbidden(PERMISSION_DENIED).
Limitaciones del tipo de datos en el endpoint de la lista
En el extremo list (users.dataTypes.dataPoints.list), no se admite el filtrado por dataSourceFamily para los tipos de datos sleep, food y food-measurement-unit:
- Si se configura
dataSourceFamilyde forma explícita enlistparasleep,foodofood-measurement-unit, se produce un error400 Bad Request(INVALID_ARGUMENT). - Si se llama a
listpara estos tipos de datos cuando solo se otorga un alcance de escritura (en el que las restricciones paraself-sourcesestán implícitas en los alcances de la persona que llama), se produce un error403 Forbidden(PERMISSION_DENIED). - Para filtrar los datos de
sleeppordataSourceFamily, usa el endpointreconcile.
Ejemplos de familias de fuentes de datos
Para enumerar los puntos de datos sin procesar que tu propio cliente escribió para un usuario, llama al extremo list con el parámetro de consulta dataSourceFamily establecido en users/me/dataSourceFamilies/self-sources.
Por ejemplo, la siguiente solicitud GET enumera las mediciones sin procesar de body-fat que escribió el cliente que llama a partir del 2026-03-01:
Solicitud
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
Respuesta
{
"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 obtener un flujo de datos conciliado de una familia de fuentes de datos específica, llama al extremo reconcile con el parámetro de consulta dataSourceFamily.
Por ejemplo, la siguiente solicitud GET recupera el sueño registrado por el dispositivo de monitoreo para el día posterior al 2026-03-03:
Solicitud
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
Respuesta
{
"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 puntos de datos en un período específico restringido a una familia de fuentes de datos en particular, llama al extremo rollUp y pasa el campo dataSourceFamily en el cuerpo de la solicitud JSON.
La siguiente solicitud POST consulta los recuentos de pasos de caminata intradía en intervalos horarios (3600s), agregados exclusivamente a partir de dispositivos wearables:
Solicitud
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"
}Respuesta
{
"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 puntos de datos diarios de una familia de fuentes específica, llama al extremo dailyRollUp y pasa el campo dataSourceFamily en el cuerpo de la solicitud.
Por ejemplo, la siguiente solicitud calcula los resúmenes diarios de los pasos del usuario, incluidas todas las fuentes propias de Google y Fitbit (dispositivos wearables y entradas manuales):
Solicitud
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"
}Respuesta
{
"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"
}
}
]
}