Triggers
Automatizações por monitor que chamam sistemas externos em transições de estado ou correspondências de payload. As chamadas de saída são validadas e limitadas para evitar alvos inseguros e ciclos descontrolados.
TIPOS DE TRIGGER
- Webhook: esquema JSON fixo com cabeçalhos de assinatura HMAC-SHA256. Escolhe isto quando o recetor espera o formato KEEPitALIVE.
- HTTP Request: método, cabeçalhos e modelo de corpo totalmente personalizados com variáveis de marcador. Escolhe isto para integrações à medida.
- Notify: envia uma notificação através dos teus canais de alerta configurados (Email, Discord, Slack, etc.) com um modelo de título/corpo personalizado.
- Incident: abre um incidente de indisponibilidade/degradação quando uma condição de payload corresponde e resolve-o automaticamente quando um evento posterior limpa a condição (ou quando desativa/elimina o trigger). Uma origem totalmente silenciosa não se resolve automaticamente - consulta Condições.

EVENTOS
Nove eventos: down, recovered, degraded, flapping_start, flapping_stop, maintenance_start, maintenance_end, signal e payload. signal dispara para batimentos de heartbeat do Recetor de eventos. payload dispara para verificações que capturaram um payload de resposta, especialmente monitores API.

VARIÁVEIS DE MODELO
Usa estes nos modelos de corpo/cabeçalhos/URL de HTTP Request e de título de Notify:
{{monitor.id}} {{monitor.ref}} {{monitor.name}} {{monitor.url}} {{monitor.type}}
{{event.id}} - stable per-fire id (same value across the retry; use it to dedupe)
{{event.type}} {{event.status}} {{event.latency_ms}}
{{event.status_code}} {{event.error}} {{event.timestamp}}
{{check.id}} - id of the originating check (omitted for synthetic events)
{{payload}} - full check payload as raw string
{{payload.KEY}} - dot-path into the JSON payload (e.g. {{payload.status}})Nota: monitor.id e monitor.ref resolvem ambos para a referência pública do monitor - nunca para um id de base de dados interno. Baseia os teus sistemas a jusante nela.
{
"source": "keepitalive",
"monitor": "{{monitor.name}}",
"event": "{{event.type}}",
"status": "{{event.status}}",
"latency_ms": "{{event.latency_ms}}",
"error": "{{event.error}}",
"at": "{{event.timestamp}}"
}CONDIÇÕES
Os triggers podem condicionar o disparo com uma expressão contra o payload de verificação armazenado. Gramática: ==, !=, >, <, >=, <=, contains, exists, and, or, not, parênteses, caminhos com ponto. Exemplo: payload.failed_jobs > 0 and payload.status == "error". Os triggers de incidente exigem uma condição. Abrem o incidente enquanto a expressão corresponde e resolvem-no quando a expressão deixa de corresponder. Como funciona a resolução: o incidente resolve-se automaticamente quando uma verificação ou payload posterior reavalia o mesmo trigger e a expressão passa a ser falsa. Também fecha imediatamente se desativar ou eliminar o trigger. Importante: o silêncio não é recuperação. Se a origem parar completamente de enviar payloads/heartbeats, não há evento para limpar a condição, pelo que o incidente permanece aberto até chegar um novo evento ou o resolver manualmente. Isto é intencional - nunca tratamos "sem dados" como "recuperado", porque para uma origem de payload/signal o silêncio podes ser a verdadeira indisponibilidade.

Heartbeat / event receiver - your posted JSON stays at the top:
payload.failed_jobs, payload.status
What we observed sits under beat, so it cannot shadow yours:
payload.beat.received_at, payload.beat.exit_code,
payload.beat.duration_ms
(those three are also copied flat when you do not use the name)
API monitor - the response is wrapped:
payload.body.<what the server returned>
payload.status_code, payload.headers, payload.assertions
So an API check of a status endpoint reads
payload.body.status.indicator - not payload.status.indicator.Open degraded incident when:
payload.failed_jobs > 0 or payload.status == "error"
Auto-resolves when a later event makes that expression false,
or when you disable/delete the trigger.
A source that goes fully silent will NOT auto-resolve.FORMATO DO PAYLOAD DO WEBHOOK
Os triggers de webhook fazem POST deste corpo JSON fixo. Baseia o teu manipulador em event_id (deduplicação) e monitor.ref (identidade):
{
"event_id": "9f2c1ab4e5d6...", // stable per fire, repeats on retry
"event": "down",
"monitor": {
"id": "mon_abc123", "ref": "mon_abc123",
"name": "API", "url": "https://api.example.com", "type": "http"
},
"check": {
"id": 84213, "status": "down",
"latency_ms": 234, "status_code": 503, "error": "...",
"payload": { }
},
"timestamp": "2026-06-27T12:00:00Z"
}VERIFICAÇÃO DE ASSINATURA (WEBHOOK)
Quando um trigger de webhook tem um segredo, cada entrega transporta X-Timestamp e X-Signature-256. Recalcula e compara para rejeitar chamadas forjadas:
signed = X-Timestamp + "." + raw_request_body
expected = "sha256=" + hex(hmac_sha256(secret, signed))
reject unless constant_time_equals(expected, X-Signature-256)
// optional: reject if X-Timestamp is older than a few minutesSEMÂNTICA DE ENTREGA
- Idempotência: X-KEEPitALIVE-Event-ID (também event_id no corpo / {{event.id}}) é gerado uma vez por disparo e reutilizado nas repetições. Deduplica com base nele para que uma repetição que chega após uma primeira tentativa lenta não seja processada duas vezes.
- Política de repetição: os triggers de rede podem repetir 0-3 vezes com um atraso de 5-600 segundos. Os triggers Notify não repetem para evitar notificações duplicadas visíveis para o utilizador.
- Os redirecionamentos NÃO são seguidos: uma resposta 3xx conta como falha de entrega. Aponta o URL para o destino final.
- Quebrador de ciclo: as entregas de saída transportam X-KEEPitALIVE-Depth. Um batimento reenviado para um recetor de eventos propaga depth+1, e os triggers de rede param de disparar na profundidade 3 - assim as cadeias trigger -> recetor de eventos são limitadas a 3 saltos.
RECEITAS DE INTEGRAÇÃO
n8n / Make / Zapier: cria um Webhook (n8n) ou um catch hook Custom Webhook (Make/Zapier), cola o teu URL num trigger HTTP Request ou Webhook. Para triggers Webhook, verifica X-Signature-256 num passo Function/Code antes de agir; ramifica com base em {{event.type}} e deduplica com event_id.
Method: POST
URL: https://api.cloudflare.com/client/v4/zones/<ZONE_ID>/purge_cache
Headers: Authorization: Bearer <API_TOKEN>
Content-Type: application/json
Body: { "purge_everything": true }
// Tip: gate on {{event.type}} == recovered to purge after a deploy recovers.Method: POST
URL: https://<HA_HOST>/api/webhook/<WEBHOOK_ID>
Body: { "monitor": "{{monitor.name}}", "status": "{{event.status}}",
"event": "{{event.type}}", "event_id": "{{event.id}}" }Method: POST
URL: https://ops.example.com/hooks/restart
Headers: X-Auth-Token: <TOKEN>
Body: { "service": "{{monitor.name}}", "reason": "{{event.error}}",
"ref": "{{monitor.ref}}", "event_id": "{{event.id}}" }
// Make the receiver idempotent on event_id so a retry never double-restarts.SEGURANÇA
- O disjuntor desativa um trigger após 10 falhas consecutivas (o proprietário recebe uma notificação na app).
- Política de oscilação: a mesma regra de 4-em-10-min aplica-se por trigger.
- Os triggers Notify registam um resultado de entrega por canal (entregue / parcial / falhou) no registo de execução.
- O segredo do webhook é mostrado uma vez ao criar/rodar; é ocultado em todas as respostas subsequentes.