← Blog

Read service uptime status with the StillOnline REST API

Dashboards are fine for humans. Scripts, CI gates, internal bots, and runbooks need a stable HTTP contract: is the API green, when was the last probe, is there an open incident?

StillOnline REST API v1 exposes two read paths for liveness / uptime:

  1. PublicGET /v1/public/status/{slug} — no API key, customer-safe JSON.
  2. PrivateGET /v1/projects/{id}/checks — owner view with last_status, last_probed_at, pause state.

Base URL: https://api.stillonline.tech/v1. Interactive reference: /en/docs/api. For Cursor/Windsurf agents, see MCP setup.

Choose the right endpoint

NeedEndpointAuthBest for
Status page / widget / public botGET /public/status/{slug}NoneStakeholders, status embeds, open monitoring
Your checks + probe timestampsGET /projects/{id}/checksBearer sk_live_…Deploy scripts, on-call tools, private dashboards
API itself is upGET /healthNoneSmoke test of StillOnline API

Private endpoints require Pro ($9/mo) or Ultimate and a key from API settings. Free tier has no API access — use the web UI or the public JSON if the page is public.

Public status (no API key)

Read the same JSON that powers your hosted status page.

curl -sS "https://api.stillonline.tech/v1/public/status/my-saas"

Replace my-saas with your status page slug or project id (cuid from the dashboard URL).

Example response (200):

{
  "slug": "my-saas",
  "status": "operational",
  "updated_at": "2026-05-29T10:00:00.000Z",
  "components": [
    {
      "name": "API",
      "url": "https://api.example.com/health",
      "status": "operational",
      "uptime_7d": 99.9,
      "ssl_valid_until": null
    }
  ],
  "active_incident": null
}

Status values: operational, degraded, down, unknown (overall and per component).

Limits: 60 requests/minute per IP → 429 with Retry-After. Response cached ~60s (Cache-Control).

404 if the slug does not exist or visibility is private.

Use this in:

  • A release checklist curl before announcing deploy done
  • A simple uptime badge script
  • Any integration that must not hold secrets

Need a health URL first? 5-minute health check quickstart.

Private: list checks with last probe result

For your projects, authenticate with the API key:

curl -sS \
  -H "Authorization: Bearer sk_live_..." \
  "https://api.stillonline.tech/v1/projects/PROJECT_ID/checks"

Find PROJECT_ID via:

curl -sS \
  -H "Authorization: Bearer sk_live_..." \
  "https://api.stillonline.tech/v1/projects"

Example check object:

{
  "id": "clx…",
  "project_id": "clx…",
  "name": "API",
  "url": "https://api.example.com/health",
  "method": "GET",
  "interval_seconds": 300,
  "enabled": true,
  "last_status": "OPERATIONAL",
  "last_probed_at": "2026-05-29T09:57:10.362Z"
}

last_status reflects the latest external HTTP probe StillOnline ran against your URL — not your app’s inline /health handler unless that is what you monitor.

Common values: OPERATIONAL, DOWN, DEGRADED, UNKNOWN (internal enum; public JSON uses lowercase).

Paused checks

PATCH /checks/{id} with {"enabled": false} pauses one URL. After pause:

  • Probes stop
  • last_status may still show OPERATIONAL — last result before pause, not live health
  • Dashboard shows a Paused badge

Resume with {"enabled": true}. Project-wide pause uses dashboard Play/Pause (all checks).

Rate limits and errors

BucketLimitApplies to
Public status60/min per IPGET /public/status/*
Private read120/min per API keyGET /projects, checks, incidents, …
Private write30/min per API keyPOST, PATCH, DELETE

On limit: HTTP 429, body includes RATE_LIMIT, header Retry-After (seconds).

Other codes:

  • 401 — missing or invalid Bearer key
  • 404 — wrong project/check id or soft-deleted project
  • 403 — plan limit (PLAN_LIMIT_*) or Free tier without API

Example: fail CI if production is down

#!/usr/bin/env bash
set -euo pipefail
SLUG="my-saas"
json=$(curl -sf "https://api.stillonline.tech/v1/public/status/${SLUG}")
status=$(echo "$json" | jq -r '.status')
if [[ "$status" != "operational" ]]; then
  echo "StillOnline reports: $status"
  exit 1
fi
echo "Status OK: $status"

For owner-only logic (e.g. skip if check is paused), use the private checks list and inspect enabled + last_status.

Write endpoints (brief)

Status reading is GET-only. When you also need to create monitors from code:

  • POST /projects — project + first check in one call
  • POST /projects/{id}/checks — add URL
  • POST /status-pages/{id}/incidents — open comms incident (active_incident in public JSON)

Full catalog: /en/docs/api. MCP wraps the same API: /en/docs/mcp.

Windows PowerShell note

Avoid curl -d '{"enabled":false}' with tricky quoting — use curl.exe with escaped quotes or send UTF-8 JSON bytes. Cyrillic in JSON bodies needs Content-Type: application/json; charset=utf-8. Details on the docs page under Windows PowerShell.

FAQ

Public vs private endpoint?

Public JSON is safe to embed and needs no key. Private checks expose probe metadata and require Pro/Ultimate.

Does the API ping my server directly?

No on these GET endpoints — they read stored probe results. StillOnline workers HTTP-probe your registered URLs on an interval.

Can I read a private status page without a key?

No. GET /public/status/{slug} returns 404 for private visibility. Use private API + your key, or sign in via the app.

Free plan and API?

Free has no API key. One URL and 24h history via the UI only; public JSON works if the status page is public.

How is this different from MCP?

Same data model. REST is for scripts and services; MCP is for AI agents in the IDE.

Close incidents via API?

Create with POST …/incidents; close is UI-only in v1.