CloudLine
Reference

Webhook payloads

What CloudLine sends to your Discord webhook on each alert type — the embed shape, field names, severity colors, and timestamps.

When CloudLine fires an alert (your bot went offline, latency spiked, gateway zombied, etc.), it POSTs a Discord webhook message to your configured URL. This page documents the exact embed structure so you know what to expect — and what to build against if you're routing the webhook through a custom receiver before forwarding to Discord.

Alert types

TypeFires when...
offlineBot missed too many heartbeats. Opens an incident.
recoveryBot came back from offline. Closes the incident.
degradedBot is heartbeating but slowly (opt-in).
testYou clicked Send test on the Alerts tab.
latency_highGateway ping above threshold for the sustained window.
latency_recoveryGateway ping back below threshold.
zombieBot's gateway has been stale for the sustained window.
zombie_recoveryGateway recovered.
shard_downSharded bot has fewer shards connected than expected.
shard_recoveryAll shards back.
cpu_high / cpu_recoveryCPU sustained above / back below threshold.
mem_high / mem_recoveryRAM sustained above / back below.
lag_high / lag_recoveryEvent-loop lag sustained above / back below.
err_high / err_recoveryErrors-per-minute sustained above / back below.

Every threshold-based alert has a paired _recovery event when the metric returns to normal.

Discord embed shape

CloudLine sends a single embeds entry, with username: "CloudLine" on the message. The shape:

{
  "username": "CloudLine",
  "embeds": [
    {
      "title":       "<emoji> <Alert title> · CL-<short ref>",
      "url":         "<appUrl>/dashboard/bots/<botId>",
      "description": "<one-line summary>",
      "color":       4474437,
      "fields": [
        { "name": "Bot",      "value": "`MyBot`",                          "inline": true },
        { "name": "Status",   "value": "CRITICAL",                         "inline": true },
        { "name": "Detected", "value": "`2026-06-03 14:23`\n2 min ago",    "inline": true }
        // … type-specific fields here
      ],
      "footer": {
        "text": "CloudLine Monitoring · BOT-<short ref>"
      },
      "timestamp": "2026-06-03T14:23:45.123Z"
    }
  ]
}

Notes:

  • The color field is the decimal form of the hex below (e.g. #ED42454474437).
  • The footer is a plain text line — there is no footer.icon_url. Business users with a custom footer get <your footer> · BOT-<ref> instead of the default CloudLine Monitoring · BOT-<ref>.
  • A Business custom logo is attached at the message level as avatar_url, not inside the footer.

The embed colour follows the alert type / severity and is not customisable for real incidents. A Business customBrandColor only re-colours the test alert — live incident colours stay semantic (red / yellow / green) so an outage always looks like an outage:

Severity (Status field)Alert typesColor
CRITICALoffline, zombiered #ED4245
WARNINGdegraded, latency_high, shard_down, cpu_high, mem_high, lag_high, err_highdegraded is yellow #FEE75C; all other warnings are orange #FF8800
RECOVERYrecovery, *_recoverygreen #57F287
TESTtestblurple #5865F2

Title format

Each alert type has a specific title with a leading emoji. The short incident reference (CL-A1B2C3D) follows on the same line so you can quote it when paging up colleagues:

TypeTitle
offline🔴 Bot Offline · CL-…
recovery🟢 Bot Recovered · CL-…
degraded🟡 Bot Degraded · CL-…
test🔔 Test Alert · CL-…
latency_high⚡ High Latency · CL-…
latency_recovery✅ Latency Recovered · CL-…
zombie🧟 Bot Zombie · CL-…
zombie_recovery✅ Gateway Recovered · CL-…
shard_down🧩 Shard Down · CL-…
shard_recovery✅ Shards Recovered · CL-…
cpu_high🔥 High CPU · CL-…
mem_high🧠 High Memory · CL-…
lag_high⏱ Event-loop Stalling · CL-…
err_high🚨 Error Burst · CL-…

The recovery variants for CPU / memory / lag / error all use the emoji with their "… Recovered / Subsided" title.

Fields by alert type

All alerts share three header fields: Bot, Status, Detected. Per-type fields:

offline, degraded

FieldValue
TriggerMulti-line code block with the cause (e.g. "no heartbeat since 2 min ago").

recovery

FieldValue
Downtime1m 32s style string.
LatencyFirst heartbeat's gateway ping after recovery (when reported).

latency_high

FieldValue
Current350 ms
Threshold200 ms
Sustained1m 0s style string.

cpu_high, mem_high, lag_high, err_high

Same shape as latency_high — Current / Threshold / Sustained, with the units appropriate to the metric (%, MB, ms, /min).

*_recovery (latency / cpu / mem / lag / err)

A single field echoing the current value (Latency, CPU, Memory, Event-loop lag, Error rate).

zombie

FieldValue
Gateway stale1m 0s — how long the gateway has been unhealthy.

shard_down, shard_recovery

FieldValue
Shards3/5 connected

test

FieldValue
Note"Test dispatch — no real incident. Templates render identically for live alerts."

Severity labels

The Status field of the embed carries a fixed per-type severity label — it's the alert's category, not an outage-duration tier:

  • CRITICALoffline, zombie. The bot is having a real problem.
  • WARNINGdegraded and all threshold alerts (latency_high, cpu_high, mem_high, lag_high, err_high, shard_down). Notable, often self-resolving.
  • RECOVERY — every *_recovery event.
  • TEST — the manual test dispatch.

If the alert was dispatched from a context that knows the dashboard's app URL, the embed url (which makes the title clickable in Discord) is:

<appUrl>/dashboard/bots/<botId>

Clicking it opens the bot detail in your CloudLine dashboard.

Timestamps

The timestamp field on the embed is an ISO-8601 UTC string. Discord renders this in the client's local timezone. The text in the Detected field is a copy of the same instant rendered in the bot owner's configured timezone (set in your account settings) so the embed reads correctly even when forwarded to a server in a different timezone.

What gets retried

The webhook delivery makes up to 3 attempts:

  1. Initial send.
  2. Retry after 1 s.
  3. Retry after 2 s.

Discord's 429 Retry-After header is honored — if Discord asks us to wait, we wait (and that wait doesn't consume a normal backoff step). 4xx errors other than 429 (e.g. 404 — webhook deleted) are not retried; they're recorded as a delivery failure in the Alerts tab with a "delivery failed" badge.

Each attempt has a 10-second timeout so a hung connection can't wedge the dispatcher.

Email shape

Alert emails (Pro+) use the same field set as Discord embeds, rendered as HTML. Subject format:

<emoji> CloudLine — <Alert title>: <bot name>

For example: 🔴 CloudLine — Bot Offline: MyBot. The HTML body uses CloudLine's default theme; Business users with custom branding get their hex color on the header bar and their logo above the title.

Routing to a custom endpoint

A common pattern: send the Discord webhook to a custom receiver you control (Cloudflare Worker, your own backend), let it modify or forward the payload, then send to Discord.

In your CloudLine config, paste your receiver's URL instead of Discord's URL. Your receiver gets the exact JSON described above; do what you want with it, then POST onward to Discord.

Note: your receiver must accept application/json POST and return a 2xx within 10 seconds, or CloudLine treats the alert as a delivery failure. Keep your receiver fast and synchronous.