트리거
상태 전환이나 페이로드 일치 시 외부 시스템을 호출하는 모니터별 자동화. 아웃바운드 호출은 안전하지 않은 대상과 폭주 루프를 방지하기 위해 검증되고 제한됩니다.
트리거 유형
- Webhook: HMAC-SHA256 서명 헤더를 갖춘 고정 JSON 스키마. 수신자가 KEEPitALIVE 형식을 기대할 때 선택하세요.
- HTTP Request: 플레이스홀더 변수를 갖춘 완전히 사용자 지정 가능한 메서드, 헤더, 본문 템플릿. 맞춤 통합에 선택하세요.
- Notify: 구성된 알림 채널(Email, Discord, Slack 등)을 통해 사용자 지정 제목/본문 템플릿으로 알림을 보냅니다.
- Incident: 페이로드 조건이 일치하면 outage/degraded 인시던트를 열고, 이후 이벤트가 조건을 해제하면(또는 트리거를 비활성화/삭제하면) 자동으로 해결합니다. 완전히 침묵하는 소스는 자동 해결되지 않습니다 - 조건 참조.

이벤트
아홉 가지 이벤트: down, recovered, degraded, flapping_start, flapping_stop, maintenance_start, maintenance_end, signal, payload. signal은 Event-Receiver 하트비트 비트에 발동합니다. payload는 응답 페이로드를 캡처한 점검, 특히 API 모니터에 발동합니다.

템플릿 변수
HTTP Request 본문/헤더/URL과 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}})참고: monitor.id와 monitor.ref는 모두 공개 모니터 참조로 해석됩니다 - 절대 내부 데이터베이스 id가 아닙니다. 다운스트림 시스템은 이를 키로 사용하세요.
{
"source": "keepitalive",
"monitor": "{{monitor.name}}",
"event": "{{event.type}}",
"status": "{{event.status}}",
"latency_ms": "{{event.latency_ms}}",
"error": "{{event.error}}",
"at": "{{event.timestamp}}"
}조건
트리거는 저장된 점검 페이로드에 대한 표현식으로 발동을 제한할 수 있습니다. 문법: ==, !=, >, <, >=, <=, contains, exists, and, or, not, 괄호, 점 경로. 예: payload.failed_jobs > 0 and payload.status == "error". Incident 트리거에는 조건이 필요합니다. 표현식이 일치하는 동안 인시던트를 열고, 표현식이 더 이상 일치하지 않으면 해결합니다. 해결 작동 방식: 이후 점검이나 페이로드가 동일한 트리거를 재평가하고 표현식이 이제 false이면 인시던트가 자동으로 해결됩니다. 또한 트리거를 비활성화하거나 삭제하면 즉시 닫힙니다. 중요: 침묵은 복구가 아닙니다. 소스가 페이로드/하트비트 전송을 완전히 멈추면 조건을 해제할 이벤트가 없으므로, 새 이벤트가 도착하거나 수동으로 해결할 때까지 인시던트가 열린 채로 유지됩니다. 이는 의도적입니다 - 페이로드/신호 소스의 경우 침묵이 실제 장애일 수 있기 때문에 "데이터 없음"을 "복구됨"으로 절대 처리하지 않습니다.

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.WEBHOOK 페이로드 형태
Webhook 트리거는 이 고정 JSON 본문을 POST합니다. 핸들러는 event_id(중복 제거)와 monitor.ref(신원)를 키로 사용하세요:
{
"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"
}서명 검증 (WEBHOOK)
Webhook 트리거에 시크릿이 있으면 각 전달은 X-Timestamp와 X-Signature-256을 전달합니다. 위조된 호출을 거부하려면 다시 계산하여 비교하세요:
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 minutes전달 의미론
- 멱등성: X-KEEPitALIVE-Event-ID(본문의 event_id / '{{event.id}}'도 포함)는 발동당 한 번 생성되어 재시도 전반에 재사용됩니다. 느린 첫 시도 후 도착한 재시도가 두 번 처리되지 않도록 이를 기준으로 중복 제거하세요.
- 재시도 정책: 네트워크 트리거는 5-600초 지연으로 0-3회 재시도할 수 있습니다. Notify 트리거는 사용자에게 보이는 중복 알림을 피하기 위해 재시도하지 않습니다.
- 리다이렉트를 따르지 않습니다: 3xx 응답은 전달 실패로 계산됩니다. URL을 최종 대상으로 가리키세요.
- 루프 차단기: 아웃바운드 전달은 X-KEEPitALIVE-Depth를 전달합니다. 이벤트 수신기로 다시 게시된 비트는 depth+1을 전파하고, 네트워크 트리거는 depth 3에서 발동을 멈춥니다 - 따라서 트리거 -> 이벤트 수신기 체인은 3홉으로 제한됩니다.
통합 레시피
n8n / Make / Zapier: Webhook(n8n) 또는 Custom Webhook catch hook(Make/Zapier)을 만들고, 그 URL을 HTTP Request 또는 Webhook 트리거에 붙여넣으세요. Webhook 트리거의 경우, 동작하기 전에 Function/Code 단계에서 X-Signature-256을 검증하고, '{{event.type}}'으로 분기하며 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.안전
- 회로 차단기는 10회 연속 실패 후 트리거를 비활성화합니다(소유자는 앱 내 알림을 받습니다).
- 플래핑 정책: 동일한 10분 내 4회 규칙이 트리거별로 적용됩니다.
- Notify 트리거는 실행 로그에 채널별 전달 결과(delivered / partial / failed)를 기록합니다.
- Webhook 시크릿은 생성/교체 시 한 번 표시됩니다. 이후 모든 응답에서는 가려집니다.