Suscripciones a webhooks

La API de Google Health permite que tu aplicación reciba notificaciones en tiempo real cuando cambian los datos de salud de un usuario. En lugar de sondear los cambios, tu servidor recibe una solicitud HTTPS POST (webhook){:target="_blank" class="external"} tan pronto como los datos están disponibles en la API de Google Health.

Tipos de datos admitidos

Se admiten las notificaciones de webhook para los siguientes tipos de datos:

  • Minutos en zona activa
  • Nivel de actividad
  • Altitud
  • Glucemia
  • Grasa corporal
  • Calorías en la zona de frecuencia cardíaca
  • 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 diarias de la temperatura durante el sueño
  • Distancia
  • Ejercicio
  • Pisos
  • Frecuencia cardíaca
  • Variabilidad del ritmo cardíaco
  • Altura
  • Registro de hidratación
  • Registro de nutrición
  • Resumen de sueño de la frecuencia respiratoria
  • VO2 máx. en carreras
  • Período sedentario
  • Sueño
  • Pasos
  • Tiempo en la zona de frecuencia cardíaca
  • Calorías totales
  • Peso

Las notificaciones se envían para estos tipos de datos solo cuando un usuario otorgó su consentimiento para uno de los siguientes permisos correspondientes:

  • Actividad, que abarca los tipos de datos de pasos, altitud, distancia y pisos:
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly
  • Métricas de salud, que abarca el tipo de datos de peso:
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.writeonly
  • Sueño, que abarca el tipo de datos de sueño:
    • https://www.googleapis.com/auth/googlehealth.sleep.readonly
    • https://www.googleapis.com/auth/googlehealth.sleep.writeonly

Cuentas de servicio de IAM

Si bien no es obligatorio, recomendamos usar una cuenta de servicio de IAM cuando configures suscriptores para la API de Google Health. Las cuentas de servicio proporcionan mejor seguridad para las cargas de trabajo de las aplicaciones en comparación con las cuentas de usuario estándar a través de las siguientes funciones:

  • Credenciales automatizadas de corta duración: Cuando se conectan a un entorno de ejecución de Google Cloud (como Compute Engine, Cloud Run o Google Kubernetes Engine), las cuentas de servicio obtienen y rotan automáticamente credenciales seguras de corta duración. Esto elimina los riesgos de administrar y almacenar claves estáticas persistentes.
  • Principio de privilegio mínimo: Las cuentas de servicio proporcionan identidades dedicadas para las cargas de trabajo. Puedes otorgarles solo los permisos específicos necesarios para administrar los extremos de suscriptores, lo que evita un acceso más amplio a tus recursos de Google Cloud.
  • Independencia del ciclo de vida: Las cuentas de servicio operan de forma independiente de la cuenta de cualquier usuario individual, lo que garantiza que los cambios de personal no afecten la estabilidad de la autenticación a largo plazo.

Configurar una cuenta de servicio

Para configurar tu aplicación de suscriptor para que se autentique con una cuenta de servicio, haz lo siguiente:

  1. Crea una cuenta de servicio: En la consola de Google Cloud, navega a la página IAM y administración de tu proyecto para crear una cuenta de servicio nueva administrada por el usuario.
  2. Otorga los roles de IAM necesarios: Asigna a la cuenta de servicio los roles adecuados necesarios para administrar suscriptores en tu proyecto de Google Cloud.
  3. Conecta la cuenta de servicio a tu carga de trabajo: Configura el entorno que aloja tu lógica de suscriptor para que se ejecute como la cuenta de servicio nueva. Esto permite que el código de la aplicación (como las bibliotecas cliente de la API de Google) detecte y use automáticamente las credenciales de corta duración de la cuenta de servicio cuando llame a la API de REST de projects.subscribers.

Roles de CPE

Para administrar los suscriptores o las suscripciones a las APIs de Google Health, debes otorgar el rol adecuado a la cuenta de servicio suplantada que realiza las llamadas a la API. Según el nivel de acceso necesario, asigna uno de los siguientes roles:

  • Lectura de la API de Google Health
  • Editor de la API de Google Health
  • Administrador de la API de Google Health

Obtén más información sobre los roles y permisos de IAM de las APIs de Google Health.

Cómo administrar los suscriptores

Antes de poder recibir notificaciones, debes registrar un suscriptor, que representa el extremo de notificaciones de tu aplicación. Puedes administrar suscriptores con la API de REST disponible en projects.subscribers.

Tu extremo de suscriptor debe usar HTTPS (TLSv1.2+) y ser de acceso público. Durante la creación y las actualizaciones de suscriptores, la API de Google Health realiza un desafío de verificación para garantizar que seas propietario del URI del extremo. Si falla la verificación, las operaciones de creación y actualización de suscriptores fallarán con un FailedPreconditionException.

Crea un suscriptor

Para registrar un suscriptor nuevo para tu proyecto, usa el extremo create. Debes proporcionar lo siguiente:

  • project-id: Es el número del proyecto en el que se creó la cuenta de servicio del webhook.
  • subscriberId: Es un identificador único que proporcionas para el suscriptor. Este ID debe tener entre 4 y 36 caracteres, y coincidir con la expresión regular ([a-z]([a-z0-9-]{2,34}[a-z0-9])).
  • endpointUri: Es la URL de destino para las notificaciones de webhook.
  • subscriberConfigs: Son los tipos de datos para los que deseas recibir notificaciones y la política de suscripción para cada uno.
  • endpointAuthorization: Es el mecanismo de autorización para tu extremo. Debe contener un secret que proporciones. El valor de secret se envía en el encabezado Authorization con cada mensaje de notificación. Puedes usar este token para verificar que las solicitudes entrantes provengan de la API de Google Health. Por ejemplo, puedes establecer secret en Bearer R4nd0m5tr1ng123 para la autenticación de portador o en Basic dXNlcjpwYXNzd29yZA== para la autenticación básica.

En subscriberConfigs, debes establecer subscriptionCreatePolicy para cada tipo de datos. Establécelo en AUTOMATIC para usar suscripciones automáticas o en MANUAL si planeas administrar las suscripciones de los usuarios por tu cuenta. Consulta las suscripciones automáticas y las suscripciones manuales para obtener más detalles sobre cada opción.

Solicitud

POST https://health.googleapis.com/v4/projects/project-id/subscribers?subscriberId=subscriber-id
{
  "endpointUri": "https://myapp.com/webhooks/health",
  "subscriberConfigs": [
    {
      "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
      "subscriptionCreatePolicy": "AUTOMATIC"
    },
    {
      "dataTypes": ["sleep"],
      "subscriptionCreatePolicy": "MANUAL"
    }
  ],
  "endpointAuthorization": {
    "secret": "Bearer example-secret-token"
  }
}

Respuesta

{
  "name": "projects/project-id/subscribers/subscriber-id",
  "endpointUri": "https://myapp.com/webhooks/health",
  "subscriberConfigs": [
    {
      "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
      "subscriptionCreatePolicy": "AUTOMATIC"
    },
    {
      "dataTypes": ["sleep"],
      "subscriptionCreatePolicy": "MANUAL"
    }
  ]
}

Enumera los suscriptores

Usa el extremo list para recuperar todos los suscriptores registrados en tu proyecto.

Solicitud

GET https://health.googleapis.com/v4/projects/project-id/subscribers

Respuesta

{
  "subscribers": [
    {
      "name": "projects/project-id/subscribers/subscriber-id",
      "endpointUri": "https://myapp.com/webhooks/health",
      "subscriberConfigs": [
        {
          "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
          "subscriptionCreatePolicy": "AUTOMATIC"
        },
        {
          "dataTypes": ["sleep"],
          "subscriptionCreatePolicy": "MANUAL"
        }
      ],
      "endpointAuthorization": {
        "authorizationTokenSet": true
      }
    }
  ],
  "totalSize": 1
}

Actualiza un suscriptor

Usa el extremo patch para actualizar un suscriptor en tu proyecto. Los campos que se pueden actualizar son endpointUri, subscriberConfigs y endpointAuthorization.

Para actualizar campos, proporciona un parámetro de consulta updateMask y un cuerpo de solicitud. El parámetro updateMask debe contener una lista separada por comas de los nombres de los campos que deseas actualizar, con el formato camel case para los nombres de los campos (por ejemplo, endpointUri). El cuerpo de la solicitud debe contener un objeto Subscriber parcial con los valores nuevos para los campos que deseas actualizar. Solo se actualizan los campos especificados en updateMask. Si proporcionas campos en el cuerpo de la solicitud que no están en updateMask, se ignorarán.

Si actualizas endpointUri o endpointAuthorization, se realiza la verificación de extremos. Consulta Verificación de extremos para obtener más detalles.

Cuando actualices subscriberConfigs, ten en cuenta que se trata de un reemplazo completo, no de una combinación. Si subscriberConfigs se incluye en updateMask, todas las configuraciones almacenadas para ese suscriptor se reemplazan por la lista proporcionada en el cuerpo de la solicitud. Para agregar o quitar una configuración, debes proporcionar el conjunto completo de configuraciones. Si actualizas otros campos y deseas conservar tus configuraciones actuales, omite subscriberConfigs de updateMask.

Solicitud

PATCH https://health.googleapis.com/v4/projects/project-id/subscribers/subscriber-id?updateMask=endpointUri
{
  "endpointUri": "https://myapp.com/new-webhooks/health"
}

Respuesta

{
  "name": "projects/project-id/subscribers/subscriber-id",
  "endpointUri": "https://myapp.com/new-webhooks/health",
  "subscriberConfigs": [
    {
      "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
      "subscriptionCreatePolicy": "AUTOMATIC"
    },
    {
      "dataTypes": ["sleep"],
      "subscriptionCreatePolicy": "MANUAL"
    }
  ]
}

Cómo borrar un suscriptor

Usa el extremo delete para quitar un suscriptor de tu proyecto. Una vez que se borre, el suscriptor ya no recibirá notificaciones.

Solicitud

DELETE https://health.googleapis.com/v4/projects/project-id/subscribers/subscriber-id

Respuesta

Si la eliminación se realiza correctamente, se devuelve un cuerpo de respuesta vacío con el estado HTTP "200 OK".
{}

Verificación de extremos

Para garantizar la seguridad y la confiabilidad de la entrega de notificaciones, la API de Google Health realiza un protocolo de enlace de verificación en dos pasos obligatoria cada vez que creas un suscriptor o actualizas la configuración de su extremo (endpointUri o endpointAuthorization). Este proceso se realiza de forma síncrona durante la llamada a la API. El servicio envía dos solicitudes POST automatizadas al URI de tu extremo, con el User-Agent Google-Health-API-Webhooks-Verifier y el cuerpo JSON {"type": "verification"}.

  • Apertura autorizada: La primera solicitud se envía con el encabezado Authorization configurado. Tu servidor debe responder con un estado 200 OK o 201 Created.
  • Desafío no autorizado: La segunda solicitud se envía sin credenciales. Tu servidor debe responder con un estado 401 Unauthorized o 403 Forbidden.

Este handshake confirma que tu extremo está activo y que aplica la seguridad correctamente. Si falla alguno de los pasos, la solicitud a la API fallará con un error FAILED_PRECONDITION. Solo después de que se complete este proceso, se guardará tu suscriptor y se activará para recibir notificaciones de datos de salud.

Rotación de claves

Si necesitas rotar las claves de endpointAuthorization, sigue estos pasos:

  1. Configura tu extremo para que acepte valores endpointAuthorization tanto antiguos como nuevos.
  2. Actualiza la configuración del suscriptor con el nuevo valor de endpointAuthorization usando una solicitud patch con ?updateMask=endpointAuthorization.
  3. Configura tu extremo para que solo acepte el nuevo valor de endpointAuthorization después de confirmar que el paso 2 se realizó correctamente.

Suscripciones de usuarios

La API de Google Health te ayuda a administrar las suscripciones de los usuarios de manera eficiente, lo que reduce la necesidad de realizar registros manuales durante la incorporación de usuarios.

Suscripciones automáticas

Recomendamos usar suscripciones automáticas. Para habilitar esta función, establece subscriptionCreatePolicy en AUTOMATIC en tu subscriberConfigs para los tipos de datos específicos. El dataTypes que especificas con una política de AUTOMATIC son los mismos tipos de datos para los que la API de Google Health envía notificaciones, siempre que también se otorgue el consentimiento del usuario para esos tipos de datos.

Cuando un usuario otorga consentimiento de la aplicación para los permisos que corresponden a tipos de datos con una política de AUTOMATIC, la API de Google Health automáticamente hace un seguimiento de los tipos de datos que resultan de la intersección entre los tipos de datos obtenidos con consentimiento del usuario y los tipos de datos de configuración del suscriptor automático para ese usuario, y envía notificaciones sobre ellos. Luego, se envían notificaciones a tu extremo cada vez que ese usuario genera datos nuevos para esos tipos. Esto funciona para los usuarios que otorgan el consentimiento antes o después de que crees el suscriptor. Las notificaciones no se reabastecen para los datos generados antes de que se creara el suscriptor.

Si un usuario revoca el consentimiento, se detendrán las notificaciones para los tipos de datos correspondientes. Google administra las suscripciones automáticas, por lo que no se pueden enumerar ni borrar de forma individual. Solo se quitan cuando se borra el suscriptor principal.

Suscripciones manuales

Si tu suscriptor está configurado con un subscription_create_policy MANUAL para tipos de datos específicos, debes crear y administrar suscripciones de forma explícita para cada usuario. Una suscripción vincula a un usuario específico con tu extremo de suscriptor para un conjunto definido de tipos de datos. Los desarrolladores pueden usar APIs específicas para realizar las siguientes acciones:

  • Create (manual) subscriptions per healthUserId: Crea una suscripción nueva para un usuario específico. Este método requiere que el suscriptor tenga un SubscriptionCreatePolicy establecido en MANUAL para los tipos de datos solicitados.
  • Actualización (manual) de la suscripción: Actualiza los tipos de datos de una suscripción de usuario existente.
  • Borrar suscripción (manual): Borra la suscripción de un usuario específico. Una vez que se borre, tu extremo de suscriptor ya no recibirá notificaciones para este usuario sobre los tipos de datos asociados.
  • Enumera las suscripciones (manuales): Enumera todas las suscripciones activas de un suscriptor determinado. Puedes filtrar los resultados por usuario o tipo de datos.

Notificaciones

Cuando cambian los datos de un usuario para un tipo de datos suscrito, la API de Google Health envía una solicitud POST de HTTPS a la URL del extremo del suscriptor.

Formato de las notificaciones

La carga útil de la notificación es un objeto JSON que contiene detalles sobre el cambio de datos. Esto incluye el ID de usuario, el tipo de datos y los intervalos de tiempo, que puedes usar para consultar los datos actualizados.

{
  "data": {
    "version": "1",
    "clientProvidedSubscriptionName": "subscription-name",
    "healthUserId": "health-user-id",
    "operation": "UPSERT",
    "dataType": "steps",
    "intervals": [
      {
        "physicalTimeInterval": {
          "startTime": "2026-03-08T01:29:00Z",
          "endTime": "2026-03-08T01:34:00Z"
        },
        "civilDateTimeInterval": {
          "startDateTime": {
            "date": {
              "year": 2026,
              "month": 3,
              "day": 7
            },
            "time": {
              "hours": 17,
              "minutes": 29
            }
          },
          "endDateTime": {
            "date": {
              "year": 2026,
              "month": 3,
              "day": 7
            },
            "time": {
              "hours": 17,
              "minutes": 34
            }
          }
        },
        "civilIso8601TimeInterval": {
          "startTime": "2026-03-07T17:29:00",
          "endTime": "2026-03-07T17:34:00"
        }
      }
    ]
  }
}

El campo operation indica el tipo de cambio que activó la notificación:

  • UPSERT: Se envía para cualquier modificación o adición de datos.
  • DELETE: Se envía cuando un usuario borra datos.

Te recomendamos que hagas que tu lógica de control de notificaciones sea idempotente, en especial para las operaciones de UPSERT, ya que los reintentos pueden provocar que se envíen notificaciones duplicadas.

El campo clientProvidedSubscriptionName es un identificador único. En el caso de las suscripciones con una política de MANUAL, este campo contiene el nombre persistente de la suscripción proporcionado por el desarrollador que se especificó cuando se creó la suscripción. Esto proporciona un ID estable para administrar suscripciones manuales. En el caso de las suscripciones creadas con una política de AUTOMATIC, la API de Google Health genera y asigna automáticamente un identificador único (un UUID aleatorio) a este campo para cada notificación. Incluir clientProvidedSubscriptionName para las políticas manuales y automáticas garantiza un formato de carga útil de notificación coherente en todos los tipos de suscripción.

El healthUserId es un identificador de la API de Google Health para el usuario cuyos datos cambiaron. Si tu aplicación admite varios usuarios, es posible que recibas notificaciones para cualquier usuario que haya otorgado su consentimiento a tu aplicación. Cuando recibas una notificación, usa healthUserId para identificar los datos del usuario que cambiaron, de modo que puedas usar sus credenciales de OAuth para consultar sus datos.

Para asignar las credenciales de OAuth de un usuario a su healthUserId, usa el extremo getIdentity. Llama a este extremo con las credenciales de un usuario durante la incorporación del usuario para recuperar su healthUserId y almacenar esta asignación. Esta asignación no cambia con el tiempo, por lo que se puede almacenar en caché de forma indefinida. Para ver un ejemplo, consulta Cómo obtener el ID de usuario. Esto te permite seleccionar las credenciales de usuario correctas cuando consultas datos según el healthUserId en una notificación.

Responde a una notificación

Tu servidor debe responder a las notificaciones con un código de estado HTTP 204 No Content de inmediato. Para evitar los tiempos de espera, procesa la carga útil de la notificación de forma asíncrona después de enviar la respuesta. Si la API de Google Health recibe cualquier otro código de estado o se agota el tiempo de espera de la solicitud, vuelve a intentar enviar la notificación más tarde.

Ejemplo de Node.js (Express):

app.post('/webhook-receiver', (req, res) => {
    // 1. Immediately acknowledge the notification
    res.status(204).send();

    // 2. Process the data asynchronously in the background
    const notification = req.body;
    setImmediate(() => {
        console.log(`Update for user ${notification.data.healthUserId} of type ${notification.data.dataType}`);
        // Trigger your data retrieval logic here
    });
});

Verificación de la firma

Para garantizar la autenticidad de las notificaciones de Webhooks, la carga útil JSON sin procesar de cada notificación de webhook saliente se firma con una clave privada usando PublicKeySign de Tink, lo que proporciona la firma codificada en Base64 en el encabezado HTTP GOOGLE-HEALTH-API-SIGNATURE de la solicitud. Estas claves de firma se rotan automáticamente cada 30 días, y el conjunto de claves públicas oficial correspondiente se distribuye como un archivo JSON en la URL permanente https://www.gstatic.com/googlehealthapi/webhooks/webhooks_public_keyset.json.

Cómo verificar la firma

Usa Tink (recomendado): Los desarrolladores pueden verificar la firma con la primitiva PublicKeyVerify de Tink. Recupera el conjunto de claves públicas de la URL permanente, crea una instancia del elemento primitivo PublicKeyVerify con el conjunto de claves y verifica el encabezado GOOGLE-HEALTH-API-SIGNATURE decodificado con la carga útil JSON sin procesar del webhook.

Verificación manual (sin Tink): Si los desarrolladores deciden no usar Tink, pueden verificar la firma de forma manual siguiendo estos pasos:

  1. Decodifica en Base64 el encabezado GOOGLE-HEALTH-API-SIGNATURE para separar el prefijo de 5 bytes de Tink (que contiene un prefijo de versión de 1 byte y un keyId de 4 bytes) de la firma real codificada en DER.
  2. Recupera el conjunto de claves JSON de https://www.gstatic.com/googlehealthapi/webhooks/webhooks_public_keyset.json.
  3. Busca la clave que coincida con el keyId analizado y decodifica en Base64 su campo de valor, que contiene un búfer de protocolo EcdsaPublicKey serializado.
  4. Extrae las coordenadas X e Y big-endian (etiquetas de Protobuf 3 y 4) de esta carga útil binaria.
  5. Crea una instancia de una clave pública ECDSA P-256 estándar en una biblioteca de criptografía integrada con las coordenadas X e Y extraídas.
  6. Verifica la carga útil JSON sin procesar del webhook con la firma DER extraída usando el algoritmo SHA-256.

Estado de suscriptor y recuperación

Si tu endpoint de suscriptor deja de estar disponible o muestra un código de estado de error (cualquier valor que no sea 204), la API de Google Health almacena las notificaciones pendientes durante un máximo de 7 días y vuelve a intentar la entrega con retirada exponencial.

Una vez que tu extremo vuelva a estar en línea y responda con 204, la API entregará automáticamente el backlog de mensajes almacenados. Las notificaciones con más de 7 días de antigüedad se descartan y no se pueden recuperar.

Errores comunes

Código de error Mensaje Descripción Recomendación
400 Bad Request Número de proyecto no válido en el nombre del recurso Cuando borras o actualizas un suscriptor con el ID del proyecto de Google Cloud en la URL de la solicitud en lugar del número del proyecto Esto se aplica a las suscripciones de webhook que usan el extremo projects.subscribers. Usa el número de tu proyecto de Google Cloud en la URL de la solicitud, no el ID del proyecto.
403 Forbidden El emisor no tiene permiso Cuando creas o enumeras suscriptores con el ID de tu proyecto de Google Cloud en la URL de la solicitud en lugar del número de proyecto Esto se aplica a las suscripciones de webhook que usan el extremo projects.subscribers. Usa el número de tu proyecto de Google Cloud en la URL de la solicitud, no el ID del proyecto.