{"openapi":"3.1.0","info":{"title":"Uptime Kuma API","description":"Uptime monitoring and alert management API for Haiven infrastructure status pages and monitoring","version":"1.0","contact":{"name":"Haiven Infrastructure","url":"https://status.haiven.site"},"license":{"name":"AGPL-3.0","url":"https://github.com/louislam/uptime-kuma/blob/master/LICENSE"}},"servers":[{"url":"https://status.haiven.site","description":"Production status page (via Traefik)"},{"url":"http://uptime-kuma:3001","description":"Internal Docker service endpoint"}],"tags":[{"name":"Status Pages","description":"Public status page endpoints"},{"name":"Monitors","description":"Monitor status and badge endpoints"},{"name":"Heartbeat","description":"Heartbeat and push monitoring"},{"name":"Incidents","description":"Incident and maintenance window management"}],"paths":{"/api/status-page/{slug}":{"get":{"tags":["Status Pages"],"summary":"Get status page configuration","description":"Retrieve status page configuration including monitors and current status","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"example":"haiven","description":"Status page slug identifier"}],"responses":{"200":{"description":"Status page configuration retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer","example":1,"description":"Status page ID"},"slug":{"type":"string","example":"haiven","description":"Status page slug"},"title":{"type":"string","example":"Haiven Infrastructure Status","description":"Status page title"},"description":{"type":"string","example":"Real-time status of Haiven services","description":"Status page description"},"icon":{"type":"string","description":"Status page icon URL"},"theme":{"type":"string","enum":["light","dark"],"example":"dark"},"published":{"type":"boolean","example":true},"showContacts":{"type":"boolean","example":true},"showPoweredBy":{"type":"boolean","example":true},"monitors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"status":{"type":"string","enum":["up","down","paused","maintenance"]},"uptime":{"type":"number","description":"Uptime percentage (0-100)"}}}}}}}}},"404":{"description":"Status page not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"Status page not found"}}}}}}}}},"/api/status-page/heartbeat/{slug}":{"get":{"tags":["Heartbeat"],"summary":"Get status page heartbeat data","description":"Retrieve real-time heartbeat and incident data for status page","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"example":"haiven","description":"Status page slug identifier"}],"responses":{"200":{"description":"Heartbeat data retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true,"description":"Overall status page health"},"monitors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"llama-swap"},"status":{"type":"string","enum":["up","down","paused","maintenance"],"example":"up"},"uptime":{"type":"number","example":99.95,"description":"Uptime percentage"},"certExpiryDays":{"type":"integer","nullable":true,"description":"Days until SSL certificate expiry"},"message":{"type":"string","nullable":true,"description":"Status message or error"}}}},"incidents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"title":{"type":"string"},"content":{"type":"string"},"style":{"type":"string","enum":["danger","warning","info"]},"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time","nullable":true}}}}}}}}},"404":{"description":"Status page not found"}}}},"/api/monitors":{"get":{"tags":["Monitors"],"summary":"List all monitors","description":"Get list of all configured monitors","responses":{"200":{"description":"List of monitors retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","example":1},"name":{"type":"string","example":"llama-swap"},"description":{"type":"string"},"type":{"type":"string","enum":["http","ping","tcp","dns","keyword","json-query","grpc-keyword"],"example":"http"},"url":{"type":"string","example":"https://llm.haiven.site/health"},"method":{"type":"string","enum":["GET","POST","PUT","DELETE","HEAD","PATCH"],"example":"GET"},"status":{"type":"string","enum":["up","down","paused","maintenance"],"example":"up"},"uptime":{"type":"number","example":99.95},"certExpiryDays":{"type":"integer","nullable":true},"maxRetries":{"type":"integer","example":0},"retryInterval":{"type":"integer","example":60},"interval":{"type":"integer","description":"Check interval in seconds","example":60},"createdAt":{"type":"string","format":"date-time"},"lastCheck":{"type":"string","format":"date-time","nullable":true}}}}}}}}}},"/api/monitors/{id}":{"get":{"tags":["Monitors"],"summary":"Get monitor details","description":"Retrieve detailed information for a specific monitor","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"example":1,"description":"Monitor ID"}],"responses":{"200":{"description":"Monitor details retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"description":{"type":"string"},"type":{"type":"string"},"url":{"type":"string"},"method":{"type":"string"},"status":{"type":"string"},"uptime":{"type":"number"},"expectedValue":{"type":"string","description":"Expected response value for keyword matching"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"}}}},"notifications":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"}}}}}}}}},"404":{"description":"Monitor not found"}}}},"/api/badge/{id}/status":{"get":{"tags":["Monitors"],"summary":"Get monitor status badge","description":"Retrieve SVG status badge for a monitor (for embedding in docs/dashboards)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"example":1,"description":"Monitor ID"},{"name":"style","in":"query","schema":{"type":"string","enum":["flat","flat-square","plastic","default"]},"description":"Badge style"}],"responses":{"200":{"description":"Status badge SVG","content":{"image/svg+xml":{"schema":{"type":"string"},"example":"<svg xmlns=\"http://www.w3.org/2000/svg\"><text>llama-swap: UP</text></svg>"}}},"404":{"description":"Monitor not found"}}}},"/api/badge/{id}/uptime/{duration}":{"get":{"tags":["Monitors"],"summary":"Get monitor uptime badge","description":"Retrieve SVG uptime percentage badge","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"example":1},{"name":"duration","in":"path","required":true,"schema":{"type":"string","enum":["24h","7d","30d","1y"]},"example":"30d","description":"Time duration for uptime calculation"}],"responses":{"200":{"description":"Uptime badge SVG","content":{"image/svg+xml":{}}},"404":{"description":"Monitor not found"}}}},"/api/push/{token}":{"get":{"tags":["Heartbeat"],"summary":"Push monitor heartbeat","description":"Record a heartbeat ping for push-type monitors","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"},"description":"Push monitor token (UUID format)"},{"name":"status","in":"query","schema":{"type":"string","enum":["up","down"]},"example":"up","description":"Status of monitored service"},{"name":"msg","in":"query","schema":{"type":"string"},"description":"Optional status message"},{"name":"ping","in":"query","schema":{"type":"integer"},"description":"Response time in milliseconds"}],"responses":{"200":{"description":"Heartbeat recorded successfully","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"msg":{"type":"string","example":"Heartbeat recorded"}}}}}},"404":{"description":"Push monitor token not found"},"400":{"description":"Invalid status value"}}}},"/api/heartbeat/{id}":{"get":{"tags":["Heartbeat"],"summary":"Get heartbeat history","description":"Retrieve heartbeat history for a specific monitor","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"example":1,"description":"Monitor ID"},{"name":"limit","in":"query","schema":{"type":"integer","default":100},"description":"Maximum number of heartbeats to return"}],"responses":{"200":{"description":"Heartbeat history retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"monitorID":{"type":"integer"},"status":{"type":"integer","description":"1 = up, 0 = down"},"duration":{"type":"integer","description":"Response time in milliseconds"},"ping":{"type":"integer","nullable":true},"time":{"type":"string","format":"date-time"},"message":{"type":"string","nullable":true}}}}}}}}}},"/api/incidents":{"get":{"tags":["Incidents"],"summary":"List all incidents","description":"Get list of all incidents and maintenance windows","parameters":[{"name":"statusPageID","in":"query","schema":{"type":"integer"},"description":"Filter by status page ID"}],"responses":{"200":{"description":"Incidents retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"title":{"type":"string","example":"LLM Service Maintenance"},"content":{"type":"string","example":"Scheduled maintenance on llama-swap"},"style":{"type":"string","enum":["danger","warning","info"],"example":"warning"},"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}}},"/api/incidents/{id}":{"get":{"tags":["Incidents"],"summary":"Get incident details","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"example":1}],"responses":{"200":{"description":"Incident details retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"},"title":{"type":"string"},"content":{"type":"string"},"style":{"type":"string"},"statusPages":{"type":"array","items":{"type":"integer","description":"Status page IDs affected"}}}}}}},"404":{"description":"Incident not found"}}}},"/api/settings/uptime":{"get":{"tags":["Status Pages"],"summary":"Get uptime settings","description":"Retrieve uptime calculation settings","responses":{"200":{"description":"Uptime settings retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"lookBackMonths":{"type":"integer","example":3,"description":"Months to include in uptime calculation"}}}}}}}}},"/api/health":{"get":{"tags":["Status Pages"],"summary":"API health check","description":"Check if API is operational","responses":{"200":{"description":"API is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"503":{"description":"API is unavailable"}}}}},"components":{"schemas":{"Monitor":{"type":"object","required":["id","name","type"],"properties":{"id":{"type":"integer"},"name":{"type":"string"},"description":{"type":"string"},"type":{"type":"string","enum":["http","ping","tcp","dns","keyword","json-query","grpc-keyword"]},"url":{"type":"string","format":"uri"},"method":{"type":"string","enum":["GET","POST","PUT","DELETE","HEAD","PATCH"]},"status":{"type":"string","enum":["up","down","paused","maintenance"]},"uptime":{"type":"number","minimum":0,"maximum":100},"interval":{"type":"integer","minimum":10,"description":"Check interval in seconds"}}},"StatusPage":{"type":"object","required":["slug","title"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"theme":{"type":"string","enum":["light","dark"]},"published":{"type":"boolean"},"monitors":{"type":"array","items":{"$ref":"#/components/schemas/Monitor"}}}},"Incident":{"type":"object","required":["title","startDate"],"properties":{"id":{"type":"integer"},"title":{"type":"string"},"content":{"type":"string"},"style":{"type":"string","enum":["danger","warning","info"]},"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time","nullable":true}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API token authentication (optional for authenticated endpoints)"}}}}