Skip to main content

Help

Webhooks

Webhooks let TowerOps POST signed, real-time notifications to your own endpoint whenever an event fires in your organization. Create an endpoint under Settings → Webhooks, choose which events to receive, and verify each delivery with the shared signing secret.

Delivered events

  • alert.triggered - An alert is created
  • alert.resolved - An alert is resolved
  • alert.acknowledged - An alert is acknowledged
  • alert.escalated - An alert escalates to a more severe state or on-call level
  • alert.snoozed - An alert is snoozed until a later time
  • device.created - A device is added to the organization
  • device.removed - A device is deleted from the organization
  • device.updated - A device's attributes change
  • device.status_changed - A device transitions up/down
  • site.created - A site is added to the organization
  • site.updated - A site's attributes change
  • site.deleted - A site is deleted from the organization
  • agent.offline - An agent goes silent past the liveness threshold
  • agent.online - An agent reports in after being offline
  • integration.sync_completed - A vendor integration sync finishes
  • integration.sync_failed - A vendor integration sync fails
  • status_page.incident.opened - An incident is opened on a status page
  • status_page.incident.updated - A status-page incident changes
  • status_page.incident.resolved - A status-page incident is resolved
  • report.ready - A scheduled report run finishes
  • coverage.completed - A coverage propagation compute finishes
  • config.changed - A config backup diff is recorded
  • subscriber_impact.detected - Subscriber impact computed for a down device
  • maintenance.started - A maintenance window becomes active
  • maintenance.ended - A maintenance window ends
  • maintenance.updated - A maintenance window's attributes change
  • maintenance.cancelled - A maintenance window is deleted

Each event's trigger and an example payload are listed by the API at GET /api/v1/webhook_events.

Verifying signatures

Every delivery carries a timestamp and an HMAC-SHA256 signature of the raw body:

signature = "sha256=" <> hex( HMAC-SHA256(secret, "<timestamp>.<raw_body>") )
# headers:
#   X-TowerOps-Signature: sha256=<hex>   ("sha256=" is part of the value)
#   X-TowerOps-Timestamp: <unix seconds>
#   X-TowerOps-Event:     <event type, e.g. alert.triggered>
#   X-TowerOps-Delivery:  <delivery id, stable across retries>
# Elixir (Plug)
def verify(conn, secret) do
  [sig] = Plug.Conn.get_req_header(conn, "x-towerops-signature")
  [ts]  = Plug.Conn.get_req_header(conn, "x-towerops-timestamp")
  {:ok, body, _} = Plug.Conn.read_body(conn)

  expected = :crypto.mac(:hmac, :sha256, secret, ts <> "." <> body)
             |> Base.encode16(case: :lower)

  Plug.Crypto.secure_compare("sha256=" <> expected, sig)
end

Failures retry automatically with exponential backoff. If an endpoint keeps failing it is disabled until you re-enable it, and every attempt is visible, and replayable, in the delivery log.