En esta página, se proporciona una descripción general de las convenciones de la API de REST, junto con un índice de las tareas comunes de la API de Google Health y ejemplos de cada una.
Convenciones de la API de REST
La API de Google Health sigue los estándares de las Propuestas de mejora de las APIs de Google (AIP), específicamente AIP-127 (transcodificación de HTTP y gRPC) y AIP-131 a AIP-135 (métodos estándar). Estos estándares definen cómo se asignan los datos de un mensaje .proto a una solicitud HTTP.
Parámetros de consulta
Los parámetros de consulta se utilizan cuando los datos forman parte de la URL. Se usa principalmente para las solicitudes de GET (recuperación de un recurso) o de LIST (filtrado o paginación), pero también se usa para las operaciones de DELETE.
- Posición: Se agrega a la URL después de un
?. - Sintaxis: Pares clave-valor separados por
&. - Asignación: Cada campo del mensaje de solicitud que no forma parte de la plantilla de ruta de URL se asigna a un parámetro de consulta.
- Ideal para: Tipos simples (cadenas, números enteros, enumeraciones) y campos repetidos.
Ejemplo de sintaxis:
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"
Cuerpo de la solicitud
El cuerpo de la solicitud se usa cuando los datos modifican el estado de un recurso o son demasiado grandes para una URL. Por lo general, el cuerpo es una representación JSON del recurso en sí. Se suele usar para las operaciones POST, PATCH y PUT.
- Ubicación: Dentro de la carga útil de HTTP (no visible en la URL)
- Sintaxis: Se formatea como un objeto JSON.
- Asignación: Se define en la anotación
google.api.http.body: "*"significa que todo el mensaje es el cuerpo.body: "resource_name"significa que solo un campo específico en el archivo .proto es el cuerpo.
- Ideal para: Objetos complejos, mensajes anidados y datos sensibles.
Ejemplo de sintaxis:
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"
}El caso híbrido
En un método Update que cumple con AIP-134 o en una operación PATCH, se usan ambos.
La URL contiene el nombre del recurso, el cuerpo contiene los datos del recurso actualizado y un parámetro de consulta (por lo general, update_mask) especifica qué campos se deben cambiar.
PATCH https://health.googleapis.com/v4/projects/project-id/subscribers/subscriber-id
Content-Type: application/json
{
"endpointUri": "https://myapp.com/new-webhooks/health"
}
Diferencias clave en un vistazo
| Función | Parámetros de búsqueda | Cuerpo de la solicitud |
|---|---|---|
| Orientación sobre la AIP | Se usa para operaciones de búsqueda, filtrado y lectura. | Se usa para operaciones de escritura. |
| Visibilidad | Se puede ver en el historial del navegador y en los registros del servidor. | Está oculta en la URL. |
| Complejidad | Se limita a estructuras planas o repetidas. | Admite objetos JSON anidados de forma profunda. |
| Codificación | Debe estar codificado como URL (por ejemplo, los espacios se convierten en %20). |
Es la codificación JSON estándar. |
Fechas
Todas las fechas en la API de Google Health se muestran en el formato YYYY-MM-DD. La API de Nutrition admite el estándar ISO-8601 para los valores de fecha con las siguientes condiciones:
- Un año de 4 dígitos
YYYY - Valores de año dentro del rango de 0000 a 9999
- No se aplica ninguna restricción de fecha de inicio según el estándar ISO-8601 o cualquier otra época.
Encabezados
Para ejecutar los extremos de la API de Google Health, se deben usar los encabezados y el token de acceso adecuados. Se recomienda el siguiente encabezado para las solicitudes GET y POST:
Authorization: Bearer access-token Accept: application/json
Índice de tareas de la API
En esta sección, se proporciona un índice de las tareas comunes de la API de Google Health y ejemplos de cada una.
Obtén tu ID de usuario de Fitbit o Google.
Después de que un usuario otorga su consentimiento a través de Google OAuth 2.0, la respuesta del token no contiene el ID de usuario de Fitbit ni de Google. Para obtener el ID de usuario, llama al extremo getIdentity. getIdentity devuelve tanto el ID de usuario heredado de Fitbit como el ID de usuario de Google.
Te recomendamos que, en cuanto un usuario nuevo otorgue su consentimiento a través de OAuth, llames al extremo getIdentity y almacenes ambos IDs de usuario. Esto proporciona compatibilidad con versiones anteriores y posteriores en tu integración.
Por ejemplo:
Solicitud
GET https://health.googleapis.com/v4/users/me/identity Authorization: Bearer access-token Accept: application/json
Respuesta
{
"name": "users/me/identity",
"legacyUserId": "A1B2C3",
"healthUserId": "111111256096816351"
}Obtén datos detallados o intradía recopilados a lo largo del día
Utilice el punto final list para un tipo de datos específico para obtener datos intradiarios o detallados recopilados a lo largo del día en intervalos admitidos para ese tipo de datos.
Por ejemplo:
Solicitud
GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints Authorization: Bearer access-token Accept: application/json
Respuesta
{
"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"
}Filtra datos
Para recuperar subconjuntos específicos de registros de puntos de datos que coincidan con criterios como un intervalo, una fecha o una hora de observación, usa el extremo list o reconcile con un parámetro filter.
Para obtener lineamientos detallados, reglas de formato, errores de validación y ejemplos de consultas, consulta la guía de datos de filtro.
Filtrar por familia de fuentes de datos
Para aislar o agregar datos de tipos específicos de fuentes (por ejemplo, dispositivos físicos portátiles frente a entradas manuales), utilice el parámetro dataSourceFamily.
Para obtener instrucciones detalladas, familias admitidas y ejemplos de solicitudes y respuestas para reconcile, rollUp y dailyRollUp, consulta Cómo filtrar por familia de fuentes de datos en la guía de filtrado de datos.
Cómo filtrar datos por hora de inicio civil de un intervalo
Usa el extremo list con un parámetro filter para filtrar los datos por hora civil o por un intervalo.
Por ejemplo:
Solicitud
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
Respuesta
{
"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 datos por la hora física de una observación de muestra
Usa el endpoint list con un parámetro filter para filtrar los datos por hora física de la observación de la muestra.
Por ejemplo:
Solicitud
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
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": ""
}Filtra y agrega 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 en comparación con entradas manuales).
Todos los extremos reconcile, rollUp y dailyRollUp admiten el parámetro dataSourceFamily. El mecanismo de transferencia depende del endpoint:
| Extremo (método HTTP) | Mecanismos |
|---|---|
reconcile (GET) |
Pasa dataSourceFamily como un parámetro de búsqueda 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. Devuelve los datos conciliados en todas las fuentes de datos de origen (1P) y de terceros (3P) registradas. Con esta opción, se devolverán los datos de las 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 de sensores sin procesar registrada directamente por el hardware de 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). |
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 búsqueda 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 desde 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"
}
}
]
}Puntos de datos agregados durante un rango de tiempo
Usa el extremo rollUp para devolver el agregado de los datos según un período en segundos, en el rango datetime según la hora física de los usuarios (en UTC).
Cuando llames al extremo rollUp, debes proporcionar el cuerpo de la solicitud que representa el período requerido en la hora civil del usuario. Por ejemplo:
Solicitud
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": "30s"
}Respuesta
{
"rollupDataPoints": [
{
"startTime": "2026-02-17T17:55:00Z",
"endTime": "2026-02-17T17:55:30Z",
"steps": {
"countSum": "41"
}
},
{
"startTime": "2026-02-17T17:54:00Z",
"endTime": "2026-02-17T17:54:30Z",
"steps": {
"countSum": "31"
}
},
...
]
}Agrega datos en un solo día o en varios
El endpoint dailyRollUp se debe usar cuando deseas agregar datos de un solo día o de varios días, lo que se conoce como windowSize. Proporciona el intervalo de tiempo civil cerrado-abierto para el intervalo requerido en el cuerpo de la solicitud. Dependiendo del tipo de datos, recibirá la suma o el promedio del intervalo.
Por ejemplo:
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": 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
}Respuesta
{
"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"
}
}
]
}Agrupación cuando el rango no es un múltiplo del tamaño de la ventana.
Si el intervalo solicitado no es un múltiplo exacto de windowSize (o windowSizeDays), el último intervalo se truncará cronológicamente en el extremo superior del intervalo y abarcará una duración más corta que el tamaño de la ventana. La API acepta tu solicitud sin modificaciones y no realiza ningún redondeo, cambio de hora ni interpolación de datos.
Para abarcar todo el intervalo solicitado, la API usa la división por redondeo hacia arriba para calcular la cantidad total de períodos de agregación:
Number of windows = ceiling(Range duration / Window size)
Cada cubo comienza secuencialmente desde el principio de su gama. Si agregar otra ventana de tamaño completo se extendería más allá de la hora de finalización solicitada, la ventana final se trunca (se limita) en la hora de finalización del período.
Cómo funciona la división en buckets
Cuando solicitas resúmenes con rangos no divisibles, la API aplica las siguientes reglas:
- El discretización comienza al principio del rango solicitado (
range.startTimeorange.start) y avanza según el tamaño de la ventana (windowSizeowindowSizeDays). - El último bucket cronológico se fija al final del rango solicitado (
range.endTimeorange.end), lo que significa que abarca una duración más corta que el tamaño de la ventana solicitada. - Los objetos
RollupDataPointoDailyRollupDataPointdevueltos especifican explícitamente sus propias marcas de tiempo de inicio y finalización, que puedes usar para inspeccionar la duración real del bucket truncado. - Dado que la API devuelve los datos acumulados en orden cronológico inverso (los más recientes primero), el bucket cronológico final (que es el truncado) aparece como el primer elemento (
index 0) en la lista devuelta.
Situación: Intervalo de 12 minutos con una ventana de 5 minutos
Supongamos que un cliente solicita un resumen en un período de 12 minutos con un windowSize de 5 minutos:
range.startTime:10:00:00range.endTime:10:12:00(duración total: 12 minutos)windowSize:5 minutes
Dado que 12 minutos no es un múltiplo de 5 minutos (12 = 5 * 2 + 2), la API acepta la solicitud y calcula la cantidad de ventanas como ceiling(12 / 5) = 3.
Esto produce los siguientes tres segmentos cronológicos:
- Segmento 1:
[10:00:00, 10:05:00), duración: 5 minutos (ventana completa) - Segmento 2:
[10:05:00, 10:10:00), duración: 5 minutos (ventana completa) - Segmento 3 (truncado):
[10:10:00, 10:12:00): Duración: 2 minutos (truncado enrange.endTime)
Impacto en los valores agregados
Debido a que la ventana final tiene una duración más corta, las métricas aditivas (como la suma o el recuento de pasos) serán más bajas en el bucket truncado solo debido a la pista de tiempo más corta.
Si un usuario camina a un ritmo constante de 100 pasos por minuto durante todo este período de 12 minutos, ocurrirá lo siguiente:
- Segmento 1 (10:00 a 10:05): 500 pasos (5 minutos × 100 pasos/minuto)
- Segmento 2 (10:05 a 10:10): 500 pasos (5 minutos × 100 pasos/minuto)
- Segmento 3 (10:10 a 10:12): 200 pasos (2 minutos × 100 pasos/minuto)
Ejemplo de respuesta de la API que muestra el orden
Dado que la API devuelve los resultados en orden cronológico inverso, el bucket truncado aparece como el primer elemento de la lista devuelta:
{
"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"
}
}
]
}
Actualiza los datos de salud de un usuario
Usa el extremo patch para actualizar los datos de salud de un usuario.
El extremo patch actualiza un registro existente según el identificador especificado en la URL de la solicitud. Proporciona el identificador de un punto de datos insertado anteriormente. La API reemplaza el registro existente.
Cuándo usar el identificador de punto de datos
El identificador del punto de datos es fundamental en los siguientes casos:
- Actualizaciones segmentadas: Para actualizar una medición específica, proporciona su identificador en la solicitud
patch. - Borrado: Conservar el identificador permite que tu aplicación borre el registro más adelante con el extremo
batchDelete.
Este es un ejemplo en el que un usuario actualiza su lectura de grasa corporal en una báscula llamada "HumanScale" de la empresa "Scales R Us". El nuevo porcentaje de grasa corporal del usuario es del 20% para la fecha del 2026-03-10:
Solicitud
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
}
}Respuesta
{
"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
}
}
}Cómo registrar un alimento
Para registrar un alimento, envíe una solicitud POST al punto final nutrition-log dataPoints. El cuerpo de la solicitud contiene un objeto DataPoint con un objeto nutritionLog.
Para obtener más información, consulta la Guía de nutrición.
Por ejemplo:
Solicitud
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
}
}
}Respuesta
{
"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"
}
}
}Cómo borrar los datos de salud del usuario
Utilice el método batchDelete para eliminar una matriz de datos de la aplicación Fitbit de un usuario.
Aquí tenemos un ejemplo en el que un usuario registró previamente su porcentaje de grasa corporal en una báscula, pero quiere borrar ese registro. Utilizando user-id y data-point-id de la acción de inserción original:
Solicitud
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"
]
}Respuesta
{
"done": true,
"response": {
"@type": "type.googleapis.com/google.devicesandservices.health.v4main.BatchDeleteDataPointsResponse"
}
}Cómo encontrar información del dispositivo
Usa el extremo list para recuperar la lista de dispositivos vinculados a la cuenta de un usuario. Esto incluye la información del modelo del dispositivo (deviceVersion) y la última vez que se sincronizó con la app de Google Health para dispositivos móviles (lastSyncTime).
La información de configuración y sincronización de la lista es útil para solucionar problemas de sincronización o recuperar datos históricos desde la última hora de sincronización.
Por ejemplo:
Solicitud
GET https://health.googleapis.com/v4/users/me/pairedDevices Authorization: Bearer access-token Accept: application/json
Respuesta
{
"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"
]
}
]
}Consulta datos históricos
Uno de los principales beneficios de la API de Google Health es la capacidad de hacer un seguimiento del rendimiento de un usuario y supervisar sus signos vitales durante períodos prolongados. Puedes consultar los datos de un usuario desde que se registraron; la API no impone limitaciones ni restricciones en la cantidad de datos históricos que tu aplicación puede consumir.
Sin embargo, las consultas de datos históricos siguen sujetas a los límites de frecuencia estándar. Para administrar la estabilidad del sistema y evitar cargas útiles excesivas, la API de Google Health usa la paginación automática con tamaños de página específicos del extremo. Ten en cuenta los siguientes límites y comportamientos:
- Paginación automática: Si consultas un intervalo extenso de datos, la API solo devolverá la primera página de resultados hasta el límite de tamaño de página para ese endpoint, junto con un
nextPageToken. Debes usarnextPageTokenpara solicitar páginas posteriores. - Tamaños de página variables: Los límites de la función de límite dependen del extremo y el tipo de datos. En la mayoría de los tipos de datos, el tamaño de la página tiene un límite máximo de 10,000.
Sin embargo, para ciertos tipos de datos, como
exerciseysleep, el tamaño de página predeterminado y máximo se limita a 25. Por ejemplo, si un cliente solicita todos los datos de sueño de los últimos 10 años, la API solo devolverá 25 sesiones de sueño en la primera página. - Restricciones de períodos para el resumen de datos: Para los extremos de resumen y agregación de datos (como
rollUpydailyRollUp), los períodos de la consulta se restringen según el tipo de datos:- Un período máximo de 14 días para
calories-in-heart-rate-zone,heart-rate,active-minutesytotal-calories. - Un período máximo de 90 días para todos los demás tipos de datos acumulados
- Un período máximo de 14 días para
Dependiendo del volumen de datos históricos que necesite su aplicación, la recuperación del conjunto de datos completo requerirá paginar las páginas secuencialmente. Ten esto en cuenta cuando diseñes el proceso de sincronización de datos de tu aplicación.
Para garantizar un rendimiento óptimo y evitar errores de la API, sigue estos lineamientos cuando consultes datos históricos:
Sincronización de datos por fases (carga en caliente frente a carga en frío)
- Carga inicial "caliente": Obtenga y muestre solo los datos de los últimos 7 a 14 días durante la secuencia de carga primaria. Esto garantiza que los usuarios vean los datos de inmediato sin tener que esperar a que se ejecuten consultas de larga duración.
- Carga "en frío" en segundo plano: Delega la recuperación de datos históricos más antiguos a una cola asíncrona de menor prioridad o a un proceso en segundo plano después de que se renderice la IU principal.
Fragmentación de consultas para la agregación
- Dado que los extremos de resumen y resumen diario aplican un límite máximo de período (14 o 90 días, según el tipo de datos), debes dividir las consultas de agregación históricas grandes en intervalos más pequeños y secuenciales dentro de estos límites.
- Agrupe o secuencie estas subconsultas de forma segura para respetar los límites de simultaneidad y mantener indicadores de progreso de la interfaz de usuario estables.
Aprovecha los resúmenes agregados previamente
Reestructura los paneles generales y los gráficos de tendencias para usar extremos de resumen previamente agregados (como DailyRollUpDataPoints). Esto reducirá drásticamente la sobrecarga de procesamiento en el backend y el tiempo de transferencia de red al cliente.
Manejo de errores resiliente (reintentos inteligentes)
- Implementa un control estricto de la retirada exponencial cuando se alcancen los límites de frecuencia (
429 Too Many Requests) y los tiempos de espera de la puerta de enlace del servidor (504 Gateway Timeout). Nunca reintentes cargas útiles grandes que hayan fallado de inmediato. Los reintentos instantáneos multiplican la congestión del backend y agravan la degradación del sistema.