{"openapi":"3.1.0","info":{"title":"StillOnline API","version":"1.0.0","description":"REST API for StillOnline — public status reads and private project/check/incident management (Pro and Ultimate). Human-readable docs: https://stillonline.tech/en/docs/api"},"servers":[{"url":"https://api.stillonline.tech/v1"}],"paths":{"/public/status/{slug}":{"get":{"summary":"Public status JSON","description":"Read the current status of a public status page — no API key. Use the page slug or project id from the dashboard URL.","responses":{"200":{"description":"Overall status, components, 7-day uptime, optional open incident.","content":{"application/json":{"schema":{"type":"object"},"example":{"slug":"demo","status":"operational","updated_at":"2026-05-27T12:00:00.000Z","components":[{"name":"Website","url":"https://example.com","status":"operational","uptime_7d":99.9}],"active_incident":null}}}},"404":{"description":"Page not found or visibility is private."},"429":{"description":"Rate limit: 60 requests per minute per IP (Retry-After header)."}},"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Status page slug or project id (cuid)."}]}},"/health":{"get":{"summary":"API health","description":"Lightweight liveness check for monitors and deploy smoke tests.","responses":{"200":{"description":"Service is up.","content":{"application/json":{"schema":{"type":"object"},"example":{"status":"ok","service":"stillonline-api","version":"v1"}}}}}}},"/projects":{"get":{"summary":"List projects","description":"Returns all non-deleted projects for the API key owner, newest first.","responses":{"200":{"description":"Array of projects with status_page_id.","content":{"application/json":{"schema":{"type":"object"},"example":{"projects":[{"id":"clx…","name":"Acme","description":null,"slug":"acme","timezone":"UTC","status_page_id":"clx…","created_at":"2026-05-27T10:00:00.000Z"}]}}}},"401":{"description":"Missing or invalid Bearer key."}},"security":[{"bearerAuth":[]}]},"post":{"summary":"Create project","description":"Creates a project, status page, and the first HTTP check in one request.","responses":{"201":{"description":"Created project object."},"400":{"description":"Invalid JSON or missing name/url."},"401":{"description":"Unauthorized."},"403":{"description":"Plan limit (code PLAN_LIMIT_PROJECTS) or Free tier without API access."}},"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"},"example":{"name":"Acme API","url":"https://api.example.com/health","description":"Optional note"}}}}}},"/projects/{id}/checks":{"get":{"summary":"List checks","description":"All uptime checks for a project you own.","responses":{"200":{"description":"Array of checks.","content":{"application/json":{"schema":{"type":"object"},"example":{"checks":[{"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-27T12:00:00.000Z"}]}}}},"401":{"description":"Unauthorized."},"404":{"description":"Project not found."}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Project id."}]},"post":{"summary":"Create check","description":"Adds an HTTP check to a project. interval_seconds must match your plan (Pro/Ultimate).","responses":{"201":{"description":"Created check."},"401":{"description":"Unauthorized."},"403":{"description":"PLAN_LIMIT_CHECKS or PLAN_LIMIT_INTERVAL."},"404":{"description":"Project not found."}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Project id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"},"example":{"name":"API","url":"https://api.example.com/health","interval_seconds":300}}}}}},"/checks/{id}":{"patch":{"summary":"Update check","description":"Partial update: name, enabled, or interval_seconds.","responses":{"200":{"description":"Updated check."},"401":{"description":"Unauthorized."},"403":{"description":"PLAN_LIMIT_INTERVAL."},"404":{"description":"Check not found."}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Check id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"},"example":{"enabled":false,"interval_seconds":300}}}}},"delete":{"summary":"Delete check","description":"Permanently removes a check you own.","responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object"},"example":{"deleted":true}}}},"401":{"description":"Unauthorized."},"404":{"description":"Check not found."}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Check id."}]}},"/status-pages/{id}":{"get":{"summary":"Get status page","description":"Metadata for a status page: slug, visibility (public/private), linked project.","responses":{"200":{"description":"Status page object.","content":{"application/json":{"schema":{"type":"object"},"example":{"status_page":{"id":"clx…","project_id":"clx…","slug":"acme","visibility":"public","project_name":"Acme"}}}}},"401":{"description":"Unauthorized."},"404":{"description":"Not found."}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Status page id."}]}},"/status-pages/{id}/incidents":{"post":{"summary":"Create incident","description":"Opens a manual incident on a status page (shown on the public page while open).","responses":{"201":{"description":"Created incident."},"401":{"description":"Unauthorized."},"404":{"description":"Status page not found."}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Status page id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"},"example":{"title":"Investigating API errors"}}}}}},"/incidents/{id}":{"get":{"summary":"Get incident","description":"Fetch one incident by id (open or resolved).","responses":{"200":{"description":"Incident object.","content":{"application/json":{"schema":{"type":"object"},"example":{"incident":{"id":"clx…","status_page_id":"clx…","title":"Investigating API errors","status":"open","started_at":"2026-05-27T12:00:00.000Z","resolved_at":null}}}}},"401":{"description":"Unauthorized."},"404":{"description":"Not found."}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Incident id."}]}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key sk_live_… from /app/settings/api (Pro or Ultimate)"}}}}