Skip to main content

Status Page

Your kuploy-cloud deployment ships with a public status page at /status (e.g. https://console.example.com/status). It shows real-time component health and lets you publish incidents to your customers.

It works alongside the central platform status page at kuploy.app/status (or whatever your LICENSE_HUB_URL points to), which covers the upstream platform you depend on (licensing hub, billing, central registry).

What Customers See​

The page is public, no sign-in. Three sections, top to bottom:

SectionContent
Status banner"All systems operational" / "Degraded" / "Major outage"
Active incidentsAny incident you've posted that isn't resolved yet
ComponentsOne row per component with the last 90 days of uptime
Past incidentsResolved incidents from the last 14 days

The page refreshes every 30 seconds. Customers don't need an account to view it.

Components Tracked​

Out of the box:

ComponentProbe
DashboardHTTP GET /api/health on this deployment
DatabaseSELECT 1 against the primary Postgres
Email HostingStalwart management API ping (only if configured)
Container RegistryRegistry /v2/ ping (only if configured)
Build RunnerQueue-health probe — flags when >50 deployments have been running for >1h
Custom Domain DNSResolves one registered custom domain (only if any are registered)

Email Hosting, Container Registry, and Custom Domain DNS are hidden when not configured — they only appear on the public page once there is something to probe. Dashboard, Database, and Build Runner always show.

How the Probes Run​

kuploy-cloud runs the probe in-process, on an internal scheduler (the same mechanism used by the license sync and stuck-build detector). There is no cron to configure, no Vercel, no Kubernetes CronJob. Once the tenant pod is up, probes start firing every 5 minutes automatically.

Cadence is controlled by the STATUS_PROBE_INTERVAL_SECONDS env var (clamped 60..3600; default 300 = 5 min). Change it and redeploy.

Manual probe endpoint

There's still a /api/cron/status-probe HTTP route gated by CRON_SECRET — kept for manual ops use. You don't need to schedule it; the in-process loop is authoritative.

Publishing Incidents​

When something is wrong and you want to communicate it to customers proactively:

  1. Sign in as a platform admin
  2. Admin → Status — Incidents
  3. New incident: title, severity, optional component, and the public-facing description
  4. As the situation evolves, post updates from the same row to advance through Investigating → Identified → Monitoring → Resolved
  5. Posting an update with status Resolved moves the incident to "Past incidents (14 days)"

Incidents you post show up immediately on the public /status page; no deploy needed.

Component states stay automatic

You don't toggle "operational" or "down" by hand — those come from the probes. Incidents add the human story on top: what happened, what you're doing about it, when it's resolved.

Severities​

SeverityUse for
MinorSingle non-critical component degraded, with workarounds
MajorCustomer-visible disruption affecting normal use
CriticalSignificant downtime or data risk
MaintenancePlanned maintenance windows you've announced in advance

The Upstream Platform Row​

Your status page shows an Upstream platform row at the top whenever the licensing hub's /api/status is reachable. The URL is resolved in this order:

  1. PLATFORM_STATUS_URL — explicit override
  2. LICENSE_HUB_URL + /api/status — same hub you license against
  3. https://kuploy.app/api/status — default

This lets customers see "the upstream is fine, the issue is local" — or the opposite — without leaving your status page.

To hide the row entirely (e.g. air-gapped deployments), set PLATFORM_STATUS_URL="" (empty).

A practical flow that works well with this system:

  1. Discover an issue (alert, customer report, log).
  2. Acknowledge publicly within minutes by posting a Minor/Major incident with status Investigating. Customers stop guessing.
  3. Update at least every 30 minutes while active, even if the only update is "still investigating, no new info" — silence is worse than no updates.
  4. Resolve with a one-line root-cause summary so customers can read it later in the 14-day past-incidents list.

Notifying Your Team on Incidents​

Incidents you publish can also fan out to your configured notification channels — Slack, Discord, Email, Telegram, etc. — using the same pipeline that handles usage and support-ticket events.

Three events are available:

  • Status: Incident Created — fires when you publish a new incident
  • Status: Incident Updated — fires on each update (investigating / identified / monitoring)
  • Status: Incident Resolved — fires when you resolve an incident

All three default OFF (unlike support-ticket events) so existing channels don't suddenly receive a new class of notifications. Opt in per channel from Account → Billing → Notification Channels.

See Billing Notifications for channel setup.

Upstream Platform Status Alerts​

Your deployment automatically monitors the upstream licensing hub's overall status (via LICENSE_HUB_URL). When the hub's state transitions — e.g. operational → major outage, or outage → operational — a Platform Status Changed notification fires through your configured channels.

This event is on by default for every channel, so operators are alerted immediately when the upstream they depend on goes down or recovers. Disable per channel if you'd rather check the /status page manually.

JSON API for Third-Party Monitoring​

Your deployment also exposes a public JSON endpoint at /api/status (no authentication). It returns the same data the /status page renders — overall state, per-component health, active and recent incidents — in a machine-readable format.

Use it with services like UptimeRobot, BetterStack, Pingdom, or any tool that polls a URL and alerts on non-"operational" values. Example:

curl -s https://your-tenant.example.com/api/status | jq .overall
# "operational"

The link is deliberately not shown on the public /status page to keep the customer-facing surface clean. It's documented here for operators who need it.

Customizing the Page​

The status page picks up your tenant branding automatically from Admin → Theme & Branding:

Theme fieldWhere it appears on /status
Site nameHeader title and browser tab (<Tenant> — Status)
LogoHeader, next to the site name
FaviconBrowser tab icon
Theme colors (HSL)Page chrome (background, borders, links, accents)
Footer copyrightFooter line above "Status snapshot refreshes…"
Custom CSSInjected globally; can override anything on the page

Component state colors (green/yellow/orange/red for operational/degraded/partial/major) are deliberately not themed — those are universal conventions and customizing them would confuse customers reading the page.

Custom Domain​

The status page is served from /status on whichever hostname your kuploy-cloud instance answers. If you've configured a custom domain for your tenant deployment (e.g. cloud.example.com), the page is automatically reachable at https://cloud.example.com/status with no extra setup — the route isn't special.

Want a dedicated status.example.com hostname instead? Point an A or CNAME record at your tenant deployment and the /status route will answer on that host too. No code change needed.