Assinaturas de webhook

Com a API Google Health, seu aplicativo recebe notificações em tempo real quando os dados de saúde de um usuário mudam. Em vez de fazer polling para mudanças, seu servidor recebe uma solicitação HTTPS POST (webhook){:target="_blank" class="external"} assim que os dados ficam disponíveis na API Google Health.

Tipos de dados compatíveis

As notificações de webhook são compatíveis com os seguintes tipos de dados:

  • Minutos na faixa ativa
  • Nível de atividade
  • Altitude
  • Glicemia
  • Gordura corporal
  • Calorias na faixa de frequência cardíaca
  • Variabilidade da frequência cardíaca diária
  • Zonas de frequência cardíaca diárias
  • Saturação de oxigênio diária
  • Ritmo respiratório diário
  • Frequência cardíaca em repouso diária
  • Derivações diárias da temperatura do sono
  • Distância
  • Exercício
  • Andares
  • Frequência cardíaca
  • Variabilidade da frequência cardíaca
  • Altura
  • Registro de hidratação
  • Registro de alimentação
  • Resumo do sono com ritmo respiratório
  • VO₂ máx. da corrida
  • Período sedentário
  • Sono
  • Etapas
  • Tempo na faixa de frequência cardíaca
  • Total de calorias
  • Peso

As notificações são enviadas para esses tipos de dados somente quando um usuário dá consentimento para um dos escopos correspondentes:

  • Atividade, que abrange tipos de dados de passos, altitude, distância e andares:
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly
  • Métricas de saúde, que abrangem o tipo de dados de peso:
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.writeonly
  • Sono, que abrange o tipo de dados de sono:
    • https://www.googleapis.com/auth/googlehealth.sleep.readonly
    • https://www.googleapis.com/auth/googlehealth.sleep.writeonly

Contas de serviço do IAM

Embora não seja obrigatório, recomendamos usar uma conta de serviço do IAM ao configurar assinantes para a API Google Health. As contas de serviço oferecem mais segurança para cargas de trabalho de aplicativos em comparação com as contas de usuário padrão pelos seguintes recursos:

  • Credenciais automatizadas de curta duração:quando anexadas a um ambiente de execução do Google Cloud (como Compute Engine, Cloud Run ou Google Kubernetes Engine), as contas de serviço recebem e alternam automaticamente credenciais seguras de curta duração. Isso elimina os riscos de gerenciar e armazenar chaves estáticas permanentes.
  • Princípio de privilégio mínimo:as contas de serviço fornecem identidades dedicadas para cargas de trabalho. É possível conceder apenas as permissões específicas necessárias para gerenciar endpoints de assinante, evitando um acesso mais amplo aos seus recursos do Google Cloud.
  • Independência do ciclo de vida:as contas de serviço operam de forma independente da conta de qualquer usuário individual, garantindo que as mudanças de pessoal não afetem a estabilidade da autenticação a longo prazo.

Configurar uma conta de serviço

Para configurar o aplicativo de assinante para autenticar usando uma conta de serviço:

  1. Crie uma conta de serviço:no console do Google Cloud, acesse a página Administrador de IAM e administrador do projeto para criar uma conta de serviço gerenciada pelo usuário.
  2. Conceda os papéis necessários do IAM:atribua à conta de serviço os papéis adequados necessários para gerenciar assinantes no seu projeto na nuvem do Google Cloud.
  3. Anexe a conta de serviço à sua carga de trabalho:configure o ambiente que hospeda sua lógica de assinante para ser executado como a nova conta de serviço. Isso permite que o código do aplicativo (como as bibliotecas de cliente da API do Google) detecte e use automaticamente as credenciais de curta duração da conta de serviço ao chamar a API REST projects.subscribers.

Funções de CPE

Para gerenciar assinantes ou assinaturas da API Google Health, conceda a função apropriada à conta de serviço representada que faz as chamadas de API. Dependendo do nível de acesso necessário, atribua um dos seguintes papéis:

  • Leitura da API Google Health
  • Editor da API Google Health
  • Administrador da API Google Health

Saiba mais sobre os papéis e permissões do IAM da API Google Health.

Gerenciar inscritos

Antes de receber notificações, é necessário registrar um assinante, que representa o endpoint de notificação do seu aplicativo. É possível gerenciar assinantes usando a API REST disponível em projects.subscribers.

O endpoint do assinante precisa usar HTTPS (TLSv1.2+) e estar acessível ao público. Durante a criação e as atualizações de assinantes, a API Google Health realiza um desafio de verificação para garantir que você é o proprietário do URI do endpoint. Se a verificação falhar, as operações de criação e atualização de assinantes vão falhar com um FailedPreconditionException.

Criar um assinante

Para registrar um novo assinante no seu projeto, use o endpoint create. Você precisa informar:

  • project-id: o número do projeto em que a conta de serviço do webhook foi criada.
  • subscriberId: um identificador exclusivo fornecido por você para o assinante. Ele precisa ter entre 4 e 36 caracteres e corresponder à expressão regular ([a-z]([a-z0-9-]{2,34}[a-z0-9])).
  • endpointUri: o URL de destino das notificações de webhook.
  • subscriberConfigs: os tipos de dados para os quais você quer receber notificações e a política de assinatura de cada um.
  • endpointAuthorization: o mecanismo de autorização do endpoint. Ele precisa conter um secret que você fornece. O valor de secret é enviado no cabeçalho Authorization com cada mensagem de notificação. Você pode usar esse token para verificar se as solicitações recebidas são da API Google Health. Por exemplo, você pode definir secret como Bearer R4nd0m5tr1ng123 para autenticação de portador ou Basic dXNlcjpwYXNzd29yZA== para autenticação básica.

Em subscriberConfigs, defina subscriptionCreatePolicy para cada tipo de dados. Defina como AUTOMATIC para usar assinaturas automáticas ou MANUAL se você pretende gerenciar as assinaturas dos usuários por conta própria. Consulte assinaturas automáticas e assinaturas manuais para mais detalhes sobre cada opção.

Solicitação

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"
  }
}

Resposta

{
  "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"
    }
  ]
}

Listar inscritos

Use o endpoint list para recuperar todos os assinantes registrados no seu projeto.

Solicitação

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

Resposta

{
  "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
}

Atualizar um assinante

Use o endpoint patch para atualizar um assinante no seu projeto. Os campos que podem ser atualizados são endpointUri, subscriberConfigs e endpointAuthorization.

Para atualizar campos, forneça um parâmetro de consulta updateMask e um corpo da solicitação. O updateMask precisa conter uma lista separada por vírgulas de nomes de campos que você quer atualizar, usando camel case para nomes de campos (por exemplo, endpointUri). O corpo da solicitação precisa conter um objeto Subscriber parcial com os novos valores dos campos que você quer atualizar. Somente os campos especificados em updateMask são atualizados. Se você fornecer campos no corpo da solicitação que não estão em updateMask, eles serão ignorados.

Se você atualizar endpointUri ou endpointAuthorization, a verificação de endpoints será realizada. Consulte Verificação de endpoints para mais detalhes.

Ao atualizar subscriberConfigs, observe que é uma substituição completa, não uma fusão. Se subscriberConfigs estiver incluído em updateMask, todas as configurações armazenadas para esse assinante serão substituídas pela lista fornecida no corpo da solicitação. Para adicionar ou remover uma configuração, forneça o conjunto completo de configurações. Se você estiver atualizando outros campos e quiser manter as configurações atuais, omita subscriberConfigs de updateMask.

Solicitação

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

Resposta

{
  "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"
    }
  ]
}

Excluir um assinante

Use o endpoint delete para remover um assinante do seu projeto. Depois de excluído, o assinante não vai mais receber notificações.

Solicitação

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

Resposta

Um corpo de resposta vazio com o status HTTP "200 OK" será retornado se a exclusão for bem-sucedida.
{}

Verificação de endpoints

Para garantir a segurança e a confiabilidade da entrega de notificações, a API Google Health realiza um handshake obrigatório de verificação em duas etapas sempre que você cria um assinante ou atualiza a configuração do endpoint (endpointUri ou endpointAuthorization). Esse processo é realizado de forma síncrona durante a chamada de API. O serviço envia duas solicitações POST automatizadas para o URI do endpoint, usando o User-Agent Google-Health-API-Webhooks-Verifier, com o corpo JSON {"type": "verification"}.

  • Handshake autorizado: a primeira solicitação é enviada com o cabeçalho Authorization configurado. O servidor precisa responder com um status 200 OK ou 201 Created.
  • Desafio não autorizado: a segunda solicitação é enviada sem credenciais. O servidor precisa responder com um status 401 Unauthorized ou 403 Forbidden.

Esse handshake confirma que seu endpoint está ativo e aplicando a segurança corretamente. Se qualquer uma das etapas falhar, a solicitação de API vai falhar com um erro FAILED_PRECONDITION. Somente depois que esse handshake for concluído, seu assinante será salvo e ativado para receber notificações de dados de saúde.

Rotação de chaves

Se você precisar girar as chaves do endpointAuthorization, siga estas etapas:

  1. Configure seu endpoint para aceitar valores endpointAuthorization antigos e novos.
  2. Atualize a configuração do assinante com o novo valor endpointAuthorization usando uma solicitação patch com ?updateMask=endpointAuthorization.
  3. Configure seu endpoint para aceitar apenas o novo valor endpointAuthorization depois de confirmar que a etapa 2 foi concluída.

Assinaturas de usuários

A API Google Health ajuda você a gerenciar as assinaturas dos usuários de maneira eficiente, reduzindo a necessidade de registro manual durante a integração de usuários.

Assinaturas automáticas

Recomendamos usar assinaturas automáticas. Para ativar esse recurso, defina subscriptionCreatePolicy como AUTOMATIC no seu subscriberConfigs para os tipos de dados específicos. O dataTypes especificado com uma política AUTOMATIC são os mesmos tipos de dados para os quais a API Google Health envia notificações, desde que o consentimento do usuário também seja concedido para esses tipos de dados.

Quando um usuário concede consentimento do aplicativo para escopos que correspondem a tipos de dados com uma política AUTOMATIC, a API Google Health rastreia e envia automaticamente notificações para os tipos de dados resultantes da interseção entre os tipos de dados consentidos pelo usuário e os tipos de dados de configuração automática do assinante para esse usuário. As notificações são enviadas ao seu endpoint sempre que o usuário gera novos dados para esses tipos. Isso funciona para usuários que concedem consentimento antes ou depois da criação do assinante. As notificações não são preenchidas com dados gerados antes da criação do assinante.

Se um usuário revogar o consentimento, as notificações para os tipos de dados correspondentes serão interrompidas. As assinaturas automáticas são gerenciadas pelo Google e não podem ser listadas ou excluídas individualmente. Elas só são removidas quando o assinante principal é excluído.

Assinaturas manuais

Se o assinante estiver configurado com um subscription_create_policy MANUAL para tipos de dados específicos, você precisará criar e gerenciar explicitamente as assinaturas de cada usuário. Uma assinatura vincula um usuário específico ao seu endpoint de assinante para um conjunto definido de tipos de dados. Os desenvolvedores podem usar APIs específicas para:

  • Criar assinaturas (manuais) por healthUserId: cria uma nova assinatura para um usuário específico. Esse método exige que o assinante tenha um SubscriptionCreatePolicy definido como MANUAL para os tipos de dados solicitados.
  • Atualizar (manual) assinatura: atualiza os tipos de dados de uma assinatura de usuário existente.
  • Excluir assinatura (manual): exclui a assinatura de um usuário específico. Depois da exclusão, o endpoint do assinante não vai mais receber notificações para esse usuário nos tipos de dados associados.
  • Listar assinaturas (manuais): lista todas as assinaturas ativas de um determinado assinante. É possível filtrar os resultados por usuário ou tipo de dados.

Notificações

Quando os dados de um usuário mudam para um tipo de dados inscrito, a API Google Health envia uma solicitação POST HTTPS para o URL do endpoint do assinante.

Formato da notificação

O payload da notificação é um objeto JSON que contém detalhes sobre a mudança nos dados. Isso inclui o ID do usuário, o tipo de dados e os intervalos de tempo, que podem ser usados para consultar os dados atualizados.

{
  "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"
        }
      }
    ]
  }
}

O campo operation indica o tipo de mudança que acionou a notificação:

  • UPSERT: enviado para qualquer adição ou modificação de dados.
  • DELETE: enviado quando um usuário exclui dados.

Recomendamos que você torne a lógica de processamento de notificações idempotente, principalmente para operações UPSERT, já que as novas tentativas podem causar o envio de notificações duplicadas.

O campo clientProvidedSubscriptionName é um identificador exclusivo. Para assinaturas com uma política MANUAL, esse campo contém o nome persistente fornecido pelo desenvolvedor especificado quando a assinatura é criada. Isso fornece um ID estável para gerenciar assinaturas manuais. Para assinaturas criadas com uma política AUTOMATIC, a API Google Health gera e atribui automaticamente um identificador exclusivo (um UUID aleatório) a esse campo para cada notificação. Incluir clientProvidedSubscriptionName em políticas manuais e automáticas garante um formato de payload de notificação consistente em todos os tipos de assinatura.

O healthUserId é um identificador da API Google Health para o usuário cujos dados foram alterados. Se o aplicativo for compatível com vários usuários, você poderá receber notificações de qualquer usuário que tenha concedido consentimento ao aplicativo. Quando você receber uma notificação, use healthUserId para identificar os dados de qual usuário foram alterados. Assim, você pode usar as credenciais OAuth dele para consultar os dados.

Para mapear as credenciais OAuth de um usuário para o healthUserId dele, use o endpoint getIdentity. Chame esse endpoint com as credenciais de um usuário durante a integração para recuperar o healthUserId dele e armazene esse mapeamento. Esse mapeamento não muda com o tempo, então pode ser armazenado em cache indefinidamente. Para um exemplo, consulte Receber o User ID. Isso permite selecionar as credenciais de usuário corretas ao consultar dados com base no healthUserId em uma notificação.

Responder a uma notificação

Seu servidor precisa responder às notificações imediatamente com um código de status HTTP 204 No Content. Para evitar tempos limite, processe o payload da notificação de forma assíncrona após enviar a resposta. Se a API Google Health receber qualquer outro código de status ou se a solicitação expirar, ela tentará enviar a notificação novamente mais tarde.

Exemplo 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
    });
});

Verificação de assinatura

Para garantir a autenticidade das notificações de webhook, o payload JSON bruto de cada notificação de webhook de saída é assinado com uma chave privada usando PublicKeySign do Tink, fornecendo a assinatura codificada em Base64 no cabeçalho GOOGLE-HEALTH-API-SIGNATURE HTTP na solicitação. Essas chaves de assinatura são trocadas automaticamente a cada 30 dias, e o conjunto de chaves públicas oficial correspondente é distribuído como um arquivo JSON no URL permanente https://www.gstatic.com/googlehealthapi/webhooks/webhooks_public_keyset.json.

Como verificar a assinatura

Usando o Tink (recomendado): os desenvolvedores podem verificar a assinatura usando a primitiva PublicKeyVerify do Tink. Busque o conjunto de chaves públicas no URL permanente, crie uma instância da primitiva PublicKeyVerify com o conjunto de chaves e verifique o cabeçalho GOOGLE-HEALTH-API-SIGNATURE decodificado em relação ao payload JSON bruto do webhook.

Verificação manual (sem o Tink): se os desenvolvedores não quiserem usar o Tink, eles poderão verificar a assinatura manualmente seguindo estas etapas:

  1. Decodifica em Base64 o cabeçalho GOOGLE-HEALTH-API-SIGNATURE para separar o prefixo de 5 bytes do Tink (que contém um prefixo de versão de 1 byte e um keyId de 4 bytes) da assinatura codificada em DER real.
  2. Extraia o conjunto de chaves JSON de https://www.gstatic.com/googlehealthapi/webhooks/webhooks_public_keyset.json.
  3. Localize a chave que corresponde ao keyId analisado e decodifique o campo de valor em Base64, que contém um buffer de protocolo EcdsaPublicKey serializado.
  4. Extraia as coordenadas x e y big-endian (tags do Protobuf 3 e 4) deste payload binário.
  5. Instancie uma chave pública ECDSA P-256 padrão em uma biblioteca de criptografia integrada usando as coordenadas x e y extraídas.
  6. Verifique o payload JSON bruto do webhook com a assinatura DER extraída usando o algoritmo SHA-256.

Status e recuperação de inscritos

Se o endpoint do assinante ficar indisponível ou retornar um código de status de erro (qualquer coisa diferente de 204), a API Google Health vai armazenar notificações pendentes por até sete dias e tentar entregar de novo com espera exponencial.

Quando o endpoint volta a ficar on-line e responde com 204, a API entrega automaticamente o backlog de mensagens armazenadas. As notificações com mais de sete dias são descartadas e não podem ser recuperadas.

Erros comuns

Código do erro Mensagem Descrição Recomendação
400 Solicitação inválida Número de projeto inválido no nome do recurso Ao excluir ou atualizar um assinante usando o ID do projeto do Google Cloud no URL da solicitação em vez do número do projeto. Isso se aplica a assinaturas de webhook usando o endpoint projects.subscribers. Use o número do projeto na nuvem do Google no URL da solicitação, não o ID do projeto.
403 Proibido O autor da chamada não tem permissão Ao criar ou listar assinantes usando o ID do projeto do Google Cloud no URL da solicitação em vez do número do projeto. Isso se aplica a assinaturas de webhook usando o endpoint projects.subscribers. Use o número do projeto na nuvem do Google no URL da solicitação, não o ID do projeto.