Pular para o conteúdo

Alertas por webhook

Como receber os alertas no seu sistema por um POST assinado, com o formato do corpo, a verificação da assinatura e as retentativas.

Atualizado em

Neste artigo

Um canal de webhook envia cada alerta como um POST com corpo JSON para uma URL sua. Cada requisição é assinada com um segredo do canal, o Secret do webhook, para que o seu sistema confira que ela veio do Notifex.

Os alertas saem quando um incidente abre e quando é resolvido, e também nos avisos de expiração de certificado SSL e de domínio. Quais monitores usam o canal é explicado em Canal padrão e canais do monitor.

Criar um canal de webhook#

  1. Abra Canais de alerta e clique em Novo canal.
  2. Em Tipo, escolha Webhook.
  3. Preencha o Nome e a URL do webhook, com http:// ou https://.
  4. Ligue Canal padrão se for o caso e deixe Ativo ligado.
  5. Clique em Criar canal.

A URL precisa ser pública. Endereços de rede interna e portas de e-mail são recusados com a mensagem Endereço não aceito: use uma URL pública (sem rede interna nem portas de e-mail). A URL é verificada de novo a cada envio.

O Secret do webhook#

Logo depois de criar o canal, o detalhe mostra o Secret do webhook, com o aviso Copie e guarde este valor agora. Use Mostrar para ver o valor e Copiar para copiá-lo.

O valor da imagem é só um exemplo: cada canal tem o seu.

Atenção

O secret aparece uma única vez, na criação do canal e a cada rotação. Ao sair da tela ou recarregar a página, ele não é mostrado de novo. Se você não guardou, a saída é rotacionar.

Rotacionar o secret#

  1. Abra o canal e, em Ações, clique em Rotacionar secret.
  2. Confirme em Rotacionar.
  3. Copie o novo valor, que aparece uma única vez, e atualize o seu sistema.

O secret anterior deixa de valer imediatamente. Alertas enviados entre a rotação e a atualização do seu sistema vão falhar na verificação.

A requisição#

  • Método POST, corpo JSON.
  • Qualquer resposta 2xx conta como entregue. Qualquer outra conta como falha.
  • Redirecionamentos não são seguidos: uma resposta 3xx é falha.
  • O tempo limite é de 10 segundos.

Cabeçalhos enviados:

CabeçalhoValor
Content-Typeapplication/json
User-AgentNotifex-Webhook/1.0
X-Notifex-EventO evento: incident.opened, incident.resolved, ssl.expiring, domain.expiring ou channel.test
X-Notifex-DeliveryO id da entrega, um por canal e por evento. Igual em todas as tentativas
X-Notifex-TimestampO instante do envio, em segundos (Unix). Muda a cada tentativa
X-Notifex-Signaturesha256=<hex>, o HMAC-SHA256 descrito abaixo

O corpo#

O corpo é um JSON numa linha só, sem espaços extras. Formatado para leitura, um incident.opened fica assim:

JSON
{
  "id": "6f1d2c3b-8a4e-4f5b-9c7d-1e2f3a4b5c6d-incident_opened",
  "event": "incident.opened",
  "version": 1,
  "createdAt": "2026-11-14T15:34:21.000Z",
  "organization": {
    "id": "0b7e5a1c-2d3f-4e5a-8b9c-0d1e2f3a4b5c",
    "name": "Loja Exemplo"
  },
  "monitor": {
    "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
    "name": "Página de pagamento",
    "type": "http",
    "target": "https://example.com/pagamento"
  },
  "incident": {
    "id": "6f1d2c3b-8a4e-4f5b-9c7d-1e2f3a4b5c6d",
    "kind": "downtime",
    "status": "open",
    "startedAt": "2026-11-14T15:34:10.000Z",
    "resolvedAt": null,
    "durationSeconds": null,
    "cause": { "code": "http_status", "message": "unexpected status 404" }
  }
}
CampoO que é
idIdentificador do evento. É o mesmo em todos os canais que recebem o evento
eventO mesmo valor de X-Notifex-Event
versionVersão do formato. Hoje, 1
createdAtInstante do evento (ISO 8601, UTC). Na abertura, é a confirmação da falha, alguns segundos depois de incident.startedAt
organizationid e name da organização
monitor.typehttp, tcp, ping, heartbeat, ssl ou domain
monitor.targetO alvo do monitor (URL sem query nem credenciais, host:porta, host ou domínio). null em heartbeat e em monitor já excluído
incident.kinddowntime, ssl_expiring ou domain_expiring
incident.statusopen ou resolved
incident.resolvedAt, incident.durationSecondsPreenchidos em incident.resolved
incident.causecode e message da causa, em inglês. Pode ser null
expirySó em ssl.expiring e domain.expiring: kind, threshold, daysRemaining e expiresAt

Verificar a assinatura#

A assinatura é o HMAC-SHA256, com o secret do canal como chave, sobre o texto <timestamp>.<corpo>: o valor de X-Notifex-Timestamp, um ponto e o corpo exatamente como chegou. O resultado em hexadecimal vai no cabeçalho com o prefixo sha256=.

Exemplo em Node.js. rawBody é o corpo bruto, exatamente como recebido, e headers é o objeto de cabeçalhos do Node (req.headers), com os nomes em minúsculas:

JavaScript
import { createHmac, timingSafeEqual } from "node:crypto";

// rawBody: o corpo exatamente como chegou (texto ou Buffer), sem re-serializar o JSON
export function isValidNotifexSignature(rawBody, headers, secret) {
  const timestamp = headers["x-notifex-timestamp"];
  const received = headers["x-notifex-signature"] ?? "";
  const expected =
    "sha256=" +
    createHmac("sha256", secret)
      .update(`${timestamp}.${rawBody}`)
      .digest("hex");
  const a = Buffer.from(received);
  const b = Buffer.from(expected);
  return a.length === b.length && timingSafeEqual(a, b);
}

Atenção

Calcule sobre o corpo cru. Se o seu framework já converteu o JSON em objeto, serializar de novo pode mudar espaços ou a ordem dos campos, e a assinatura não confere.

O mesmo exemplo aparece no detalhe de cada canal de webhook, na seção Como validar a assinatura, visível só para quem pode editar canais.

Retentativas#

Um alerta que falha é tentado até 5 vezes. A espera dobra a cada falha: 2, 4, 8 e 16 minutos depois da tentativa anterior, cerca de 30 minutos no total. Depois da quinta falha, a notificação fica como Falhou.

  • Todas as tentativas levam o mesmo X-Notifex-Delivery. Use esse valor para ignorar entregas repetidas.
  • Cada tentativa tem um X-Notifex-Timestamp novo e é assinada de novo.
  • Um canal excluído ou desativado antes do envio não recebe a requisição.

O resultado de cada envio fica no incidente, em Notificações enviadas, com as colunas Tentativas e Erro. Veja Incidentes. Erros comuns:

ErroSignificado
webhook responded 500O seu sistema respondeu com um status fora de 2xx (o número muda)
webhook timed outNão houve resposta em 10 segundos
webhook connection failedNão foi possível conectar à URL
webhook target not allowedA URL passou a apontar para um endereço não aceito

O texto do erro pode vir seguido de um código entre parênteses, por exemplo webhook connection failed (ECONNREFUSED).

Enviar teste#

Em Ações, Enviar teste manda um evento channel.test na hora. O teste é tentado uma vez só, sem retentativas, e o resultado aparece na tela: Teste entregue ou A entrega do teste falhou, com o motivo. Cada canal aceita até 5 testes por minuto.

O corpo do teste usa um monitor fictício e não traz incidente:

JSON
{
  "id": "11111111-1111-4111-8111-111111111111",
  "event": "channel.test",
  "version": 1,
  "createdAt": "2026-11-14T12:00:00.000Z",
  "organization": {
    "id": "0b7e5a1c-2d3f-4e5a-8b9c-0d1e2f3a4b5c",
    "name": "Loja Exemplo"
  },
  "monitor": {
    "id": "00000000-0000-0000-0000-000000000000",
    "name": "Notifex — teste de canal",
    "type": "http",
    "target": null
  },
  "incident": null
}

Não encontrou o que procurava?

Escreva para a gente pelo formulário de contato do site.

Falar com o Notifex