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:
- Public —
GET /v1/public/status/{slug}— no API key, customer-safe JSON. - Private —
GET /v1/projects/{id}/checks— owner view withlast_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.
Quick answer
StillOnline REST API v1 lets scripts read uptime without opening the dashboard: public GET /v1/public/status/{slug} needs no key; private GET /v1/projects/{id}/checks needs Bearer sk_live_… (Pro/Ultimate). Responses reflect stored probe results—StillOnline workers HTTP-get your health URL on a schedule. Owner down/recovery alerts stay in the UI (Telegram, Slack), not via these GET endpoints.
Choose the right endpoint
StillOnline splits customer-safe reads from owner reads on purpose: public JSON needs no secret; private lists need your API key and a Pro plan. Start from the row that matches who will consume the response.
| Need | Endpoint | Auth | Best for |
|---|---|---|---|
| Status page / widget / public bot | GET /public/status/{slug} | None | Stakeholders, status embeds, open monitoring |
| Your checks + probe timestamps | GET /projects/{id}/checks | Bearer sk_live_… | Deploy scripts, on-call tools, private dashboards |
| API itself is up | GET /health | None | Smoke test of StillOnline API |
Private endpoints need Pro ($9/mo) or Ultimate and a key from API settings. On Free there is no API key—use the web UI, or the public JSON when the status 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_statusmay still showOPERATIONAL— 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
Scripts should backoff on 429 using Retry-After. The buckets below are per IP (public) or per API key (private)—they are independent, so a heavy public poll does not consume your private write quota.
| Bucket | Limit | Applies to |
|---|---|---|
| Public status | 60/min per IP | GET /public/status/* |
| Private read | 120/min per API key | GET /projects, checks, incidents, … |
| Private write | 30/min per API key | POST, 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 callPOST /projects/{id}/checks— add URLPOST /status-pages/{id}/incidents— open comms incident (active_incidentin 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.
Owner alerts (not in the API)
The REST API reads probe results and status JSON. Down / recovery / 24h notifications to humans go through email, Telegram, or Slack in the dashboard — configure in account settings. Guides: Telegram · Slack. On Free, pick one owner channel; on Pro / Ultimate, enable all three.
Related guides
- Health check URL quickstart.
- MCP for AI agents.
- Telegram owner alerts · Slack alerts.
- Best uptime monitoring for indie SaaS 2026.
FAQ
When should I use StillOnline public vs private REST endpoints?
Use GET /public/status/{slug} for customer widgets, CI smoke tests, and anything that must not hold secrets—it mirrors your public status page. Use GET /projects/{id}/checks with Bearer auth when you need last_probed_at, pause state, and per-URL last_status (Pro/Ultimate only).
Does the StillOnline REST API ping my server on each GET?
No. These GET endpoints read stored probe results from StillOnline workers that HTTP-check your registered URL on an interval (for example 5 minutes on Free). Add a health URL before expecting meaningful JSON.
Can I fetch a private StillOnline status page without an API key?
No. GET /public/status/{slug} returns 404 when visibility is private. Use the private checks API with sk_live_… from API settings, or manage incidents in the StillOnline app.
Does StillOnline Free include REST API access?
How is StillOnline REST different from stillonline-mcp?
Can I close StillOnline incidents via REST API?
You can create incidents with POST …/incidents (they appear in public JSON as active_incident). Closing an incident is UI-only in API v1—a documented current limitation, not a roadmap promise.