Skip to main content
GreenSlope

Webhook payloads

Reference for every payload GreenSlope POSTs to an outbound webhook. All payloads share a common envelope; each kind adds its own body.

Envelope

Every request body looks like:

{
  "event": {
    "id": "evt_01HJ1…",
    "kind": "alert.opened",
    "created_at": "2026-04-21T14:02:18Z",
    "tenant_id": "ten_01H…"
  },
  "alert": { "…": "see per-kind sections below" }
}

Signing

If you configured a signing secret when adding the webhook destination, every request includes:

x-greenslope-signature: <hex-encoded HMAC-SHA256 of the raw body>
x-greenslope-timestamp: <unix epoch seconds>

Reject requests whose timestamp is more than 5 minutes from now — this is the replay-attack mitigation.

alert.opened

Fired when a new alert transitions from idle to open.

{
  "event": { "id": "…", "kind": "alert.opened", "…": "…" },
  "alert": {
    "id": "alr_01HJ…",
    "url": "https://app.greenslope.io/alerts/alr_01HJ…",
    "title": "Burn rate 14.4x on web:availability",
    "severity": "sev1",
    "kind": "burn_rate",
    "service": "web",
    "environment": "production",
    "slo": {
      "id": "slo_01H…",
      "name": "availability",
      "burn_rate": 14.4,
      "window_short": "5m",
      "window_long": "1h"
    },
    "suspected_release": {
      "id": "7fa9c21a…",
      "pr": 842,
      "pr_url": "https://github.com/…/pull/842",
      "deployed_at": "2026-04-21T14:00:02Z"
    }
  }
}

suspected_release is only present when release attribution has a candidate. Absent otherwise.

alert.acknowledged

{
  "event": { "id": "…", "kind": "alert.acknowledged", "…": "…" },
  "alert": {
    "id": "alr_01HJ…",
    "acknowledged_by": {
      "user_id": "usr_01H…",
      "email": "ada@example.com"
    },
    "acknowledged_at": "2026-04-21T14:05:41Z"
  }
}

alert.resolved

{
  "event": { "id": "…", "kind": "alert.resolved", "…": "…" },
  "alert": {
    "id": "alr_01HJ…",
    "resolved_at": "2026-04-21T14:12:09Z",
    "resolution": "auto" // or "manual"
  }
}

alert.escalated

Fired when a sev-1 alert hasn't been acknowledged within the escalation window and progresses to the next destination (e.g. SMS → voice).

{
  "event": { "id": "…", "kind": "alert.escalated", "…": "…" },
  "alert": {
    "id": "alr_01HJ…",
    "from_channel": "sms",
    "to_channel": "voice",
    "escalated_at": "2026-04-21T14:05:00Z"
  }
}

change_event.created

Fired when a new change event is recorded (from the REST API, Vercel webhook, or dashboard).

{
  "event": { "id": "…", "kind": "change_event.created", "…": "…" },
  "change": {
    "id": "chg_01HJ…",
    "kind": "deploy",
    "service": "web",
    "environment": "production",
    "release_id": "7fa9c21a…",
    "actor": "ada",
    "pr": 842,
    "pr_url": "https://github.com/…/pull/842",
    "at": "2026-04-21T14:00:02Z"
  }
}

Retry semantics

Per-destination delivery state is visible in the dashboard at Settings → Alerts → Webhook destinations → Activity.

Related