Receber eventos com confiabilidade
As regras que todo endpoint de webhook deve seguir, sobre autenticidade, verificação da organização, duplicatas, confirmação rápida e busca de dados na API.
Esta página descreve como construir um endpoint que recebe os webhooks do BreezeAuth com segurança, sem perder eventos e sem processá-los em dobro. Ela foi escrita para desenvolvedores, mas o resumo abaixo é útil para qualquer pessoa responsável por uma integração.
Resumo
Para cada requisição recebida, o seu endpoint deve:
- Verificar a assinatura. Rejeitar a requisição se ela estiver ausente ou for inválida.
- Conferir a organização. Rejeitar a mensagem se
organizationsUuidnão for a organização esperada. - Ignorar duplicatas. Se esse
webhook-idjá foi recebido, responder2xxe parar. - Guardar a mensagem e responder
2xximediatamente, bem antes dos 15 segundos. - Processar a mensagem em segundo plano: buscar os dados atuais na API e atualizar o seu sistema.
POST /webhooks/breezeauth
├─ assinatura inválida? → 401, parar
├─ organizationsUuid inesperado? → 403, parar
├─ webhook-id já recebido? → 204, parar
├─ guardar mensagem + webhook-id (uma única transação)
└─ 204 → um processo em segundo plano trata a mensagem guardada
Verificar a assinatura
A assinatura é a única prova de que uma mensagem foi enviada pelo BreezeAuth. Confira-a antes de ler qualquer outra
coisa da mensagem e rejeite a requisição com um status 4xx se a verificação falhar. Todos os detalhes, com exemplos de
código, estão em Verificar assinaturas.
Conferir a organização
Uma assinatura válida prova que a mensagem vem do BreezeAuth, mas o BreezeAuth atende muitas organizações, e todas assinam com as mesmas chaves. O seu endpoint também precisa garantir que a mensagem é sobre a sua organização.
Compare o campo organizationsUuid do corpo com o identificador da organização que o seu sistema espera e rejeite a
mensagem se forem diferentes. Isso protege você, por exemplo, caso a URL do seu endpoint seja cadastrada por engano, ou
de propósito, como webhook em outra organização.
Se um mesmo endpoint atende várias organizações, por exemplo em um produto multi-tenant, mantenha a lista de identificadores de organização que ele aceita e procure cada mensagem nessa lista.
Observação: o identificador da sua organização é o valor de organizationsUuid. Ele é exibido abaixo do nome da
organização na página Gerenciar Organização, com um botão para copiá-lo.
Ignorar duplicatas
O BreezeAuth entrega cada evento pelo menos uma vez. Em algumas situações, a mesma mensagem pode chegar mais de uma vez, por exemplo:
- o seu endpoint processou a mensagem, mas a resposta demorou mais de 15 segundos ou se perdeu na rede, então o BreezeAuth considerou a tentativa como falha e tentou novamente;
- uma falha temporária na infraestrutura do BreezeAuth fez com que uma mensagem já entregue fosse enviada de novo;
- dois webhooks da sua organização apontam para a mesma URL e assinam o mesmo evento.
Por isso, a detecção de duplicatas do seu lado é obrigatória. Cada mensagem tem um identificador único, enviado no
cabeçalho webhook-id e repetido como uuid no corpo. Ele é o mesmo em todas as entregas do mesmo evento.
Uma abordagem simples e robusta é uma tabela com restrição de unicidade no identificador:
CREATE TABLE breezeauth_webhook_messages (
webhook_id VARCHAR(64) PRIMARY KEY,
received_at TIMESTAMP NOT NULL,
payload TEXT NOT NULL,
processed_at TIMESTAMP NULL
);
Quando uma mensagem chegar, insira o identificador e o conteúdo em uma única transação. Se a inserção falhar porque o
identificador já existe, a mensagem é uma duplicata: responda 2xx sem fazer mais nada. Guarde os identificadores por
pelo menos alguns dias; guardá-los por mais tempo custa pouco e deixa a sua trilha de auditoria mais completa.
Dica: responda 2xx às duplicatas, não um erro. Um erro faria o BreezeAuth tentar reenviar uma mensagem que você
já recebeu.
Confirmar rápido, processar depois
O BreezeAuth espera no máximo 15 segundos por uma resposta. O seu endpoint deve responder assim que a mensagem estiver guardada com segurança e deixar o trabalho de fato (chamar a API, atualizar bancos de dados, enviar e-mails) para um processo em segundo plano, como uma fila de jobs, um worker ou uma tarefa agendada.
- Responda com qualquer status
2xx, como200 OKou204 No Content. O corpo da resposta é ignorado. - Não chame a API do BreezeAuth nem outros serviços lentos antes de responder.
- Se o seu endpoint não conseguir guardar a mensagem (por exemplo, o banco de dados está fora do ar), responda com um
status
5xxpara que o BreezeAuth tente novamente.
Fazer trabalho pesado de forma síncrona é a causa mais comum de tempo esgotado e, portanto, de novas tentativas e duplicatas.
Buscar os detalhes na API
As mensagens trazem apenas identificadores. Quando o seu
processo em segundo plano precisa de mais informações, ele lê o estado atual na API do BreezeAuth, em
https://api.breezeauth.com.
-
No console de administração, crie um usuário de serviço em Usuários › Usuários de Serviço e gere uma credencial para ele. Você recebe um client ID e um client secret. Dê ao usuário de serviço apenas o acesso de que a sua integração precisa, por exemplo o papel Auditor para acesso somente leitura. Veja Usuários de serviço.
-
Troque a credencial por um token de acesso:
curl -X POST https://api.breezeauth.com/oauth/token \ -H 'Content-Type: application/json' \ -d '{"grant_type": "client_credentials", "client_id": "<client ID>", "client_secret": "<client secret>"}'A resposta contém um
access_tokene a sua validade em segundos,expires_in. Reutilize o token até ele expirar e depois solicite um novo. Veja Tokens de acesso para detalhes e exemplos de código. -
Chame a API com o token no cabeçalho
Authorization:curl https://api.breezeauth.com/organizations/<organizationsUuid>/memberships/<membershipsUuid> \ -H 'Authorization: Bearer <token de acesso>'
Onde ler cada recurso:
| Eventos | Requisição na API |
|---|---|
membership.* |
GET /organizations/{organizationsUuid}/memberships/{membershipsUuid} |
group.* |
GET /organizations/{organizationsUuid}/groups/{groupsUuid} |
group_assignment.* |
GET /organizations/{organizationsUuid}/groups/{groupsUuid}/assignments/{groupAssignmentsUuid} |
application.* |
GET /organizations/{organizationsUuid}/applications/{applicationsUuid} |
application_assignment.* |
GET /organizations/{organizationsUuid}/applications/{applicationsUuid}/assignments/{applicationAssignmentsUuid} |
domain.* |
GET /organizations/{organizationsUuid}/domains/{domainsUuid} |
Pontos de atenção:
- Recursos excluídos. Depois de um evento
*.deleted, o recurso normalmente não está mais disponível e a API responde404 Not Found. Trate isso como confirmação da exclusão. - A ordem não é garantida. As mensagens podem chegar em ordem diferente da dos eventos, por exemplo um
membership.updatedantes domembership.createdcorrespondente. Como você sempre lê o estado atual na API, a ordem não importa: trate cada mensagem como “algo mudou neste recurso, vou olhar agora”. - Várias mensagens, uma leitura. Quando muitos eventos sobre o mesmo recurso chegam juntos, o seu processo em segundo plano pode ler o recurso uma única vez e tratar todos eles.
Reconciliar periodicamente
Os webhooks mantêm o seu sistema atualizado quase em tempo real, mas não são um mecanismo de sincronização completo. Se o seu endpoint ficar indisponível por mais tempo do que a janela de novas tentativas, ou se um webhook ficar desativado por um tempo, alguns eventos não serão entregues. No momento, o BreezeAuth não oferece uma forma de reenviá-los.
Para integrações em que perder uma mudança é grave, como remover o acesso de quem saiu da empresa, adicione uma reconciliação periódica: por exemplo, uma vez por dia, liste os recursos relevantes pela API e corrija qualquer diferença com o seu sistema. Os webhooks cuidam das mudanças do dia a dia, e a reconciliação pega o que escapou.
Checklist
- O endpoint usa
https://e a URL cadastrada no BreezeAuth é o endereço final (sem redirecionamentos). - Opcionalmente, o firewall só aceita requisições dos endereços IP do BreezeAuth.
- A assinatura é verificada sobre o corpo bruto, antes de qualquer outra coisa.
- Mensagens com um
organizationsUuidinesperado são rejeitadas. - O
webhook-idé guardado com restrição de unicidade, e duplicatas recebem2xx. - O endpoint responde em poucos segundos e processa as mensagens em segundo plano.
- Tipos de evento desconhecidos recebem
2xxe são ignorados. - Os detalhes são buscados na API, e o
404após uma exclusão é tratado. - Existe uma reconciliação periódica para os dados críticos.
- Alguém confere o histórico de eventos quando as entregas falham.
Última atualização: 13 de outubro de 2026