{"openapi":"3.1.0","info":{"title":"CronObserver API","version":"1.0.0","description":"Public API v1 (`/v1/*`): authenticate with `Authorization: Bearer co_live_...`, an API key created by an organization owner or admin in Settings > API keys. Scopes: `read` (GET), `write` (create, change, pause, mute, ack) and `checkin` (report runs). Each key only sees its own organization. The legacy admin endpoints (`x-api-key`) are listed for reference.","license":{"name":"Proprietary","identifier":"LicenseRef-CronObserver"}},"servers":[{"url":"https://cronobserver.com/api"}],"tags":[{"name":"Monitors","description":"Scheduled jobs and AI agents being watched."},{"name":"Incidents","description":"Monitors that are overdue or degraded."}],"paths":{"/v1/monitors":{"get":{"operationId":"listMonitors","summary":"List monitors","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"skip","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"state","in":"query","description":"Only monitors in these states (comma-separated), e.g. `overdue,failed`. Unknown state → 400.","schema":{"type":"string"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"responses":{"200":{"description":"Monitors of the key's organization, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorList"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `read` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"createMonitor","summary":"Create a monitor","description":"Plan limits apply (number of monitors, alert channels).","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"write","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorCreate"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitor"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `write` scope, or: Plan limit reached or feature not in plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/monitors/{id}":{"get":{"operationId":"getMonitor","summary":"Get a monitor","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"responses":{"200":{"description":"The monitor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitor"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `read` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"operationId":"updateMonitor","summary":"Update a monitor","description":"Changes only the fields sent, including the schedule (`interval`, cron in UTC).","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"write","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorUpdate"}}}},"responses":{"200":{"description":"Updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitor"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `write` scope, or: Feature not in plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"operationId":"deleteMonitor","summary":"Delete a monitor","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"write","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"responses":{"204":{"description":"Deleted."},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `write` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/monitors/{id}/events":{"get":{"operationId":"listMonitorEvents","summary":"List runs and events of a monitor","description":"Check-ins, overdue/recovery transitions and alerts, newest first, within the plan's retention.","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"before","in":"query","description":"Cursor from `pagination.nextCursor`.","schema":{"type":"string"}},{"name":"type","in":"query","description":"Filter by event type.","schema":{"type":"string"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"responses":{"200":{"description":"A page of events.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorEventList"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `read` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/monitors/{id}/explain":{"get":{"operationId":"explainMonitor","summary":"Explain the monitor's current status","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"responses":{"200":{"description":"Diagnosis.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorExplanation"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `read` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/monitors/{id}/pause":{"post":{"operationId":"pauseMonitor","summary":"Pause a monitor","description":"No overdue detection and no alerts while paused.","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"write","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"responses":{"200":{"description":"Paused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleResult"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `write` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/monitors/{id}/resume":{"post":{"operationId":"resumeMonitor","summary":"Resume a paused monitor","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"write","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"responses":{"200":{"description":"Resumed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleResult"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `write` scope, or: Paused by the plan limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Not paused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/monitors/{id}/mute":{"post":{"operationId":"muteMonitor","summary":"Mute alerts of a monitor","description":"Suppresses alerts until `until` (or until unmuted). Does not change the monitor state: a paused monitor stays paused, and overdue detection keeps running for active ones.","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"write","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MuteRequest"}}}},"responses":{"200":{"description":"Muted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleResult"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `write` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/monitors/{id}/unmute":{"post":{"operationId":"unmuteMonitor","summary":"Unmute a monitor","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"write","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"responses":{"200":{"description":"Unmuted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleResult"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `write` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Not muted (neither muted state nor a future mutedUntil).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/monitors/{id}/checkin":{"post":{"operationId":"checkinMonitor","summary":"Report a successful run","description":"Same effect as POST /checkin/{token}, addressed by monitor id. Requires the `checkin` scope. Send `runId` to close the run opened by /checkin/start (the duration is recorded). A payload with `status: \"failed\"` counts as /checkin/fail.","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"checkin","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckinPayload"}}}},"responses":{"204":{"description":"Recorded."},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `checkin` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/monitors/{id}/checkin/start":{"post":{"operationId":"checkinMonitorStart","summary":"Report that a run started","description":"Opens a run (optional `runId`). Does not change the monitor state. If `maxRuntimeSeconds` is set and no success or failure arrives in time, the run is alerted as stuck. Same as POST /checkin/{token}/start.","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"checkin","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckinPayload"}}}},"responses":{"204":{"description":"Recorded."},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `checkin` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/monitors/{id}/checkin/fail":{"post":{"operationId":"checkinMonitorFail","summary":"Report a failed run","description":"Marks the run failed (optional `runId`, `exitCode`, `message`) and alerts right away, without waiting for the interval and grace. Same as POST /checkin/{token}/fail.","tags":["Monitors"],"security":[{"BearerApiKey":[]}],"x-required-scope":"checkin","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckinPayload"}}}},"responses":{"204":{"description":"Recorded."},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `checkin` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/incidents":{"get":{"operationId":"listIncidents","summary":"List open incidents","description":"Monitors currently overdue, degraded or whose last run failed.","tags":["Incidents"],"security":[{"BearerApiKey":[]}],"x-required-scope":"read","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"responses":{"200":{"description":"Open incidents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentList"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `read` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/incidents/{id}/ack":{"post":{"operationId":"ackIncident","summary":"Acknowledge the open incident of a monitor","description":"Records who acknowledged it. A new check-in closes the incident and clears the ack. To silence alerts, use mute.","tags":["Incidents"],"security":[{"BearerApiKey":[]}],"x-required-scope":"write","parameters":[{"name":"id","in":"path","required":true,"description":"Monitor id.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$"}},{"$ref":"#/components/parameters/RequestIdHeader"}],"responses":{"200":{"description":"Acknowledged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Incident"}}}},"400":{"description":"Invalid request (`invalidRequest` with `issues`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"API key lacks the `write` scope (`insufficientScope`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Monitor not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"The monitor has no open incident.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit per API key exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/healthz":{"get":{"summary":"Liveness probe","tags":["System"],"responses":{"200":{"description":"OK"}},"operationId":"legacyGetHealthz","security":[]}},"/readyz":{"get":{"summary":"Readiness probe","tags":["System"],"responses":{"200":{"description":"Ready"},"503":{"description":"Not ready"}},"operationId":"legacyGetReadyz","security":[]}},"/checkin/{token}":{"post":{"summary":"Check-in (public)","tags":["Check-in"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckinPayload"}}}},"responses":{"204":{"description":"No Content"},"400":{"description":"Invalid payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"legacyPostCheckinToken","security":[]}},"/admin/cronObservers":{"get":{"summary":"List CronObservers (admin)","tags":["Admin - CronObservers"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"minimum":1,"maximum":100}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0,"minimum":0}},{"name":"includePayload","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"When true, includes lastCheckInPayload in each item (may be large)."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CronObserverListResponse"}}}},"401":{"description":"Unauthorized"}},"operationId":"legacyGetAdminCronObservers"},"post":{"summary":"Create CronObserver (admin)","tags":["Admin - CronObservers"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["orgId","name","intervalMinutes"],"properties":{"orgId":{"type":"string"},"name":{"type":"string"},"intervalMinutes":{"type":"integer","minimum":1},"graceMinutes":{"type":"integer","minimum":0,"default":0},"webhookUrl":{"type":["string","null"]},"alertEmails":{"type":"array","items":{"type":"string"}},"alertCooldownMinutes":{"type":"integer","minimum":1,"default":60},"thresholds":{"$ref":"#/components/schemas/CronObserver/properties/thresholds"},"escalationSteps":{"type":"array","items":{"$ref":"#/components/schemas/EscalationStep"},"description":"Optional escalation policy. If provided, alerts follow escalation steps instead of legacy behavior."}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CronObserver"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"}},"operationId":"legacyPostAdminCronObservers"}},"/admin/cronObservers/{id}":{"get":{"summary":"Get CronObserver (admin)","tags":["Admin - CronObservers"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"includePayload","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"When true, includes lastCheckInPayload (may be large)."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CronObserver"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not Found"}},"operationId":"legacyGetAdminCronObserversId"},"patch":{"summary":"Update CronObserver (admin)","tags":["Admin - CronObservers"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"intervalMinutes":{"type":"integer","minimum":1},"graceMinutes":{"type":"integer","minimum":0},"webhookUrl":{"type":["string","null"]},"alertEmails":{"type":"array","items":{"type":"string"}},"alertCooldownMinutes":{"type":"integer","minimum":1},"thresholds":{"$ref":"#/components/schemas/CronObserver/properties/thresholds"},"escalationSteps":{"type":"array","items":{"$ref":"#/components/schemas/EscalationStep"},"description":"Update escalation policy. Setting this resets escalationState."},"state":{"type":"string","enum":["new","ok","overdue","paused","muted","maintenance","degraded"],"description":"Update observer state. State transitions are validated (Feature 4)."},"mutedUntil":{"type":["string","null"],"format":"date-time","description":"Set timestamp until which alerts are suppressed. Set to null to unmute (Feature 4)."},"maintenanceWindows":{"type":"array","items":{"$ref":"#/components/schemas/MaintenanceWindow"},"description":"Replace all maintenance windows. Use POST /admin/cronObservers/{id}/maintenance to add windows (Feature 4)."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CronObserver"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not Found"}},"operationId":"legacyPatchAdminCronObserversId"},"delete":{"summary":"Delete CronObserver (admin)","tags":["Admin - CronObservers"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"401":{"description":"Unauthorized"},"404":{"description":"Not Found"}},"operationId":"legacyDeleteAdminCronObserversId"}},"/admin/cronObservers/{id}/escalationPreview":{"get":{"summary":"Preview escalation steps (admin)","description":"Preview which escalation steps would trigger for a given overdue duration. Useful for testing and debugging escalation policies.","tags":["Admin - CronObservers"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"CronObserver ID"},{"name":"overdueMinutes","in":"query","required":true,"schema":{"type":"number","minimum":0},"description":"Simulated minutes overdue to preview."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EscalationPreviewResponse"}}}},"400":{"description":"Bad Request (invalid overdueMinutes)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not Found"}},"operationId":"legacyGetAdminCronObserversIdEscalationPreview"}},"/admin/cronObservers/{id}/maintenance":{"post":{"summary":"Add maintenance window (admin)","description":"Add a new maintenance window to the observer. During active windows, overdue detection and alerts are suppressed. Optionally transition the observer to maintenance state (Feature 4).","tags":["Admin - CronObservers"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"CronObserver ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["startAt","endAt"],"properties":{"startAt":{"type":"string","format":"date-time","description":"When the maintenance window starts."},"endAt":{"type":"string","format":"date-time","description":"When the maintenance window ends (must be after startAt)."},"reason":{"type":"string","description":"Optional human-readable reason for the maintenance."},"setMaintenanceState":{"type":"boolean","default":false,"description":"If true, transition the observer to maintenance state."}}}}}},"responses":{"201":{"description":"Maintenance window added","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"window":{"$ref":"#/components/schemas/MaintenanceWindow"},"state":{"type":"string"},"maintenanceWindows":{"type":"array","items":{"$ref":"#/components/schemas/MaintenanceWindow"}}}}}}},"400":{"description":"Bad Request (invalid window or state transition)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not Found"}},"operationId":"legacyPostAdminCronObserversIdMaintenance"},"delete":{"summary":"Remove maintenance windows (admin)","description":"Remove expired maintenance windows (cleanup). If clearAll=true, removes all windows including future ones (Feature 4).","tags":["Admin - CronObservers"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"CronObserver ID"},{"name":"clearAll","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"If true, removes all maintenance windows (including future ones)."}],"responses":{"200":{"description":"Maintenance windows removed","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"removedCount":{"type":"integer"},"remainingWindows":{"type":"array","items":{"$ref":"#/components/schemas/MaintenanceWindow"}}}}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not Found"}},"operationId":"legacyDeleteAdminCronObserversIdMaintenance"}},"/admin/cronObservers/{id}/events":{"get":{"summary":"Get timeline events for an observer (admin, Feature 7)","description":"Retrieve paginated timeline/history events for an observer. Supports cursor-based pagination and type filtering.","tags":["Admin - CronObservers","Feature 7 - Timeline"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"CronObserver ID"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"minimum":1,"maximum":100},"description":"Number of events to return"},{"name":"before","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"Cursor for pagination (ISO timestamp). Returns events before this time."},{"name":"type","in":"query","required":false,"schema":{"type":"string","enum":["checkin","overdue","recovered","failed","alertSent","alertFailed","configChanged"]},"description":"Filter by event type"}],"responses":{"200":{"description":"List of timeline events","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventListResponse"}}},"headers":{"x-request-id":{"schema":{"type":"string"},"description":"Request correlation ID"}}},"400":{"description":"Bad Request (invalid parameters)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Observer not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"legacyGetAdminCronObserversIdEvents"}},"/admin/cronObservers/{id}/timelineSummary":{"get":{"summary":"Get timeline statistics for an observer (admin, Feature 7)","description":"Retrieve aggregated event counts and latest event timestamps for quick overview.","tags":["Admin - CronObservers","Feature 7 - Timeline"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"CronObserver ID"}],"responses":{"200":{"description":"Timeline statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimelineSummaryResponse"}}},"headers":{"x-request-id":{"schema":{"type":"string"},"description":"Request correlation ID"}}},"401":{"description":"Unauthorized"},"404":{"description":"Observer not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"legacyGetAdminCronObserversIdTimelineSummary"}},"/admin/cronObservers/{id}/explain":{"get":{"summary":"Get human-readable state explanation (admin, Feature 7)","description":"Provides a human-readable explanation of why an observer is in its current state, with timing calculations and actionable guidance. Useful for 'Why am I overdue?' debugging.","tags":["Admin - CronObservers","Feature 7 - Explanations"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"CronObserver ID"}],"responses":{"200":{"description":"State explanation with timing details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExplainResponse"},"example":{"observerId":"507f1f77bcf86cd799439011","observerName":"Daily Backup Job","currentState":"overdue","expectedIntervalMinutes":1440,"graceMinutes":60,"totalToleranceMinutes":1500,"lastCheckInAt":"2026-01-28T10:00:00Z","nextExpectedAt":"2026-01-29T10:00:00Z","isOverdue":true,"overdueByMinutes":180,"overdueBySeconds":10800,"explanation":{"summary":"Overdue by 3 hours","reason":"Last check-in was 27 hours ago. Expected interval is 24 hours with 1 hour grace period. Check-in is 3 hours overdue.","nextAction":"Send a check-in immediately to recover"},"lifecycle":{"isPaused":false,"isMuted":false,"isInMaintenance":false,"mutedUntil":null,"activeMaintenanceWindow":null}}}},"headers":{"x-request-id":{"schema":{"type":"string"},"description":"Request correlation ID"}}},"401":{"description":"Unauthorized"},"404":{"description":"Observer not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"legacyGetAdminCronObserversIdExplain"}},"/admin/cronObservers/{id}/integrationSnippets":{"get":{"summary":"Generate integration code snippet (admin, Feature 8)","description":"Generate a ready-to-use code snippet for integrating TaskObserver with various platforms. The snippet includes the observer's check-in URL pre-filled and is ready to copy/paste into your CI/CD or scheduling platform.","tags":["Admin - CronObservers","Feature 8 - Integrations"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"CronObserver ID"},{"name":"type","in":"query","required":true,"schema":{"type":"string","enum":["githubActions","gitlabCi","k8sCronJob","awsLambda","dockerCompose"]},"description":"Integration platform type"}],"responses":{"200":{"description":"Integration snippet generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationSnippetResponse"},"examples":{"githubActions":{"summary":"GitHub Actions snippet","value":{"snippet":"# GitHub Actions Workflow with TaskObserver\nname: Daily Job with Monitoring\n\non:\n  schedule:\n    - cron: '0 2 * * *'\n  workflow_dispatch:\n\njobs:\n  monitored-job:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Run your job\n        run: |\n          echo \"Running job...\"\n          # Your job logic here\n\n      - name: Report success to TaskObserver\n        if: success()\n        run: |\n          curl -X POST \"https://cronobserver.com/checkin/abc123...\" \\\n            -H \"Content-Type: application/json\" \\\n            -d '{\n              \"status\": \"success\",\n              \"message\": \"Job completed\",\n              \"metadata\": {\n                \"workflow\": \"${{ github.workflow }}\",\n                \"run_id\": \"${{ github.run_id }}\",\n                \"run_number\": ${{ github.run_number }}\n              }\n            }'\n\n      - name: Report failure to TaskObserver\n        if: failure()\n        run: |\n          curl -X POST \"https://cronobserver.com/checkin/abc123...\" \\\n            -H \"Content-Type: application/json\" \\\n            -d '{\n              \"status\": \"failure\",\n              \"error\": \"Job failed\"\n            }'","type":"githubActions","observerId":"507f1f77bcf86cd799439011","observerName":"Daily Backup Job","checkinUrl":"https://cronobserver.com/checkin/abc123..."}},"k8sCronJob":{"summary":"Kubernetes CronJob snippet","value":{"snippet":"# Kubernetes CronJob with TaskObserver\napiVersion: v1\nkind: Secret\nmetadata:\n  name: taskobserver-secret\ntype: Opaque\nstringData:\n  checkinUrl: \"https://cronobserver.com/checkin/abc123...\"\n---\napiVersion: batch/v1\nkind: CronJob\nmetadata:\n  name: monitored-cronjob\nspec:\n  schedule: \"0 2 * * *\"\n  jobTemplate:\n    spec:\n      template:\n        spec:\n          containers:\n          - name: job\n            image: alpine:latest\n            env:\n            - name: TASKOBSERVER_CHECKIN_URL\n              valueFrom:\n                secretKeyRef:\n                  name: taskobserver-secret\n                  key: checkinUrl\n            command:\n            - /bin/sh\n            - -c\n            - |\n              # Your job logic\n              if YOUR_COMMAND; then\n                STATUS=\"success\"\n                MESSAGE=\"Job completed\"\n              else\n                STATUS=\"failure\"\n                MESSAGE=\"Job failed\"\n              fi\n              \n              # Report to TaskObserver\n              curl -X POST \"$TASKOBSERVER_CHECKIN_URL\" \\\n                -H \"Content-Type: application/json\" \\\n                -d \"{\\\"status\\\": \\\"$STATUS\\\", \\\"message\\\": \\\"$MESSAGE\\\"}\"\n          restartPolicy: OnFailure","type":"k8sCronJob","observerId":"507f1f77bcf86cd799439011","observerName":"Daily Backup Job","checkinUrl":"https://cronobserver.com/checkin/abc123..."}}}}},"headers":{"x-request-id":{"schema":{"type":"string"},"description":"Request correlation ID"}}},"400":{"description":"Bad Request - Missing or invalid type parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missingType":{"summary":"Missing type parameter","value":{"error":"bad_request","message":"Integration type is required. Valid types: githubActions, gitlabCi, k8sCronJob, awsLambda, dockerCompose","requestId":"req-abc123"}},"invalidType":{"summary":"Invalid type value","value":{"error":"bad_request","message":"Invalid integration type: jenkins. Valid types: githubActions, gitlabCi, k8sCronJob, awsLambda, dockerCompose","requestId":"req-abc123"}}}}}},"401":{"description":"Unauthorized - Missing or invalid API key"},"404":{"description":"Observer not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"legacyGetAdminCronObserversIdIntegrationSnippets"}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"},"BearerApiKey":{"type":"http","scheme":"bearer","bearerFormat":"co_live_<id>_<secret>","description":"Organization API key."}},"parameters":{"RequestIdHeader":{"name":"x-request-id","in":"header","required":false,"schema":{"type":"string"},"description":"Optional client-provided request correlation ID. Server generates one if not provided. (Feature 7)"}},"schemas":{"Error":{"type":"object","required":["error","requestId"],"properties":{"error":{"type":"string","description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error message"},"details":{"type":"object","description":"Additional error context (field-level validation, etc.)","additionalProperties":true},"requestId":{"type":"string","description":"Unique request correlation ID for debugging"}},"description":"Standardized error response format (Feature 7)."},"CheckinPayload":{"description":"Optional JSON payload stored with the check-in. Recognized keys: `runId` (links start and end), `exitCode` and `message` (failure details), `status: \"failed\"` (same as /fail), and for AI agents `tokens_in`, `tokens_out`, `cost_usd`, `model`, `items_processed`, `eval_score`.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"CronObserverCheckinMeta":{"type":["object","null"],"properties":{"receivedAt":{"type":"string","format":"date-time"},"ip":{"type":"string"},"userAgent":{"type":"string"},"payloadBytes":{"type":"integer","minimum":0}}},"EscalationStep":{"type":"object","properties":{"afterMinutesOverdue":{"description":"Minutes after the monitor became overdue.","type":"number","minimum":0},"channels":{"minItems":1,"type":"array","items":{"type":"string","enum":["email","webhook","slack","teams","telegram"]}},"emails":{"description":"Recipients for this step's email; empty uses the monitor's alertEmails. Counted in the per-monitor recipient limit.","type":"array","items":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}}},"required":["afterMinutesOverdue","channels"],"additionalProperties":false},"EscalationState":{"type":["object","null"],"description":"Current state of an ongoing escalation incident. Null when not in an overdue state.","properties":{"incidentStartedAt":{"type":"string","format":"date-time","description":"When the current overdue incident started."},"lastStepIndex":{"type":"integer","description":"Index of the last escalation step that was triggered (-1 if none)."},"lastStepSentAt":{"type":["string","null"],"format":"date-time","description":"When the last escalation step was sent."},"stepCooldowns":{"type":"object","additionalProperties":{"type":"string","format":"date-time"},"description":"Map of step:channel to last sent timestamp for cooldown tracking."}}},"MaintenanceWindow":{"description":"Alerts are suppressed while a window is active.","type":"object","properties":{"startAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"endAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"reason":{"type":"string","maxLength":500}},"required":["startAt","endAt"],"additionalProperties":false},"CronObserver":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"name":{"type":"string"},"token":{"type":"string"},"checkinUrl":{"type":"string"},"intervalMinutes":{"type":"integer"},"graceMinutes":{"type":"integer"},"webhookUrl":{"type":["string","null"]},"webhookSecret":{"type":["string","null"]},"alertEmails":{"type":"array","items":{"type":"string"}},"alertCooldownMinutes":{"type":"integer"},"lastCheckInAt":{"type":["string","null"],"format":"date-time"},"lastCheckInMeta":{"$ref":"#/components/schemas/CronObserverCheckinMeta"},"lastCheckInPayload":{"type":["object","null"],"description":"Only included when requested via includePayload=true on admin read/list endpoints.","additionalProperties":true},"thresholds":{"type":"object","description":"Expected thresholds for payload-aware semantic health checks.","properties":{"expected":{"type":"object","properties":{"processedMin":{"type":"number","minimum":0},"durationMsMax":{"type":"number","minimum":0}},"additionalProperties":false},"validationMode":{"type":"string","enum":["none","warn","alert"]}}},"lastThresholdAlertAt":{"type":["string","null"],"format":"date-time"},"escalationSteps":{"type":"array","items":{"$ref":"#/components/schemas/EscalationStep"},"description":"Escalation policy steps. Empty array means no escalation policy (legacy alert behavior)."},"escalationState":{"$ref":"#/components/schemas/EscalationState"},"state":{"type":"string","enum":["new","ok","overdue","paused","muted","maintenance","degraded"],"description":"Observer lifecycle state. New states: paused (no overdue detection), muted (overdue detection but alerts suppressed), maintenance (scheduled maintenance window), degraded (soft failure state)."},"pausedAt":{"type":["string","null"],"format":"date-time","description":"When the observer was last paused (Feature 4)."},"resumedAt":{"type":["string","null"],"format":"date-time","description":"When the observer was last resumed from paused state (Feature 4)."},"mutedUntil":{"type":["string","null"],"format":"date-time","description":"Timestamp until which alerts are suppressed. Null means not muted (Feature 4)."},"maintenanceWindows":{"type":"array","items":{"$ref":"#/components/schemas/MaintenanceWindow"},"description":"Scheduled maintenance windows. Overdue detection and alerts are suppressed during active windows (Feature 4)."},"lastAlertAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CronObserverListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CronObserver"}},"total":{"type":"integer"},"limit":{"type":"integer"},"skip":{"type":"integer"}}},"EscalationPreviewStep":{"type":"object","properties":{"stepIndex":{"type":"integer","description":"Index of the escalation step."},"afterMinutesOverdue":{"type":"number","description":"Threshold in minutes."},"channels":{"type":"array","items":{"type":"string","enum":["webhook","email"]}},"wouldTrigger":{"type":"boolean","description":"Whether this step would trigger at the given overdue duration."}}},"EscalationPreviewResponse":{"type":"object","properties":{"observerId":{"type":"string"},"observerName":{"type":"string"},"overdueMinutes":{"type":"number"},"totalSteps":{"type":"integer"},"stepsTriggered":{"type":"integer"},"steps":{"type":"array","items":{"$ref":"#/components/schemas/EscalationPreviewStep"}}}},"TaskEvent":{"type":"object","description":"Timeline event for observer history tracking (Feature 7).","required":["_id","observerId","type","occurredAt","createdAt"],"properties":{"_id":{"type":"string","description":"Event ID"},"observerId":{"type":"string","description":"Observer this event belongs to"},"type":{"type":"string","enum":["checkin","overdue","recovered","failed","alertSent","alertFailed","configChanged"],"description":"Event type"},"occurredAt":{"type":"string","format":"date-time","description":"When the event occurred"},"meta":{"type":["object","null"],"description":"Event-specific metadata (limited to 2KB)","additionalProperties":true},"createdAt":{"type":"string","format":"date-time","description":"When the event was created"}}},"EventListResponse":{"type":"object","description":"Paginated list of timeline events (Feature 7).","required":["events","pagination"],"properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/TaskEvent"}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean","description":"Whether more events exist"},"nextCursor":{"type":["string","null"],"format":"date-time","description":"ISO timestamp cursor for next page"}}}}},"TimelineSummaryResponse":{"type":"object","description":"Aggregated timeline statistics (Feature 7).","required":["observerId","observerName","eventCounts","totalEvents"],"properties":{"observerId":{"type":"string"},"observerName":{"type":"string"},"eventCounts":{"type":"object","description":"Event counts by type","properties":{"checkin":{"type":"integer"},"overdue":{"type":"integer"},"recovered":{"type":"integer"},"alertSent":{"type":"integer"},"alertFailed":{"type":"integer"},"configChanged":{"type":"integer"}}},"latestEvents":{"type":"object","description":"Latest occurrence timestamp for key event types","properties":{"lastCheckin":{"type":["string","null"],"format":"date-time"},"lastOverdue":{"type":["string","null"],"format":"date-time"},"lastRecovered":{"type":["string","null"],"format":"date-time"}}},"totalEvents":{"type":"integer","description":"Total events for this observer"}}},"ExplainResponse":{"type":"object","description":"Human-readable explanation of observer state with timing details (Feature 7).","required":["observerId","observerName","currentState","expectedIntervalMinutes","graceMinutes","totalToleranceMinutes","isOverdue","explanation","lifecycle"],"properties":{"observerId":{"type":"string"},"observerName":{"type":"string"},"currentState":{"type":"string","enum":["new","ok","overdue","paused","muted","maintenance","degraded"]},"expectedIntervalMinutes":{"type":"integer","description":"Expected check-in interval"},"graceMinutes":{"type":"integer","description":"Grace period before overdue"},"totalToleranceMinutes":{"type":"integer","description":"interval + grace"},"lastCheckInAt":{"type":["string","null"],"format":"date-time","description":"When last check-in was received"},"nextExpectedAt":{"type":["string","null"],"format":"date-time","description":"When next check-in is expected (lastCheckInAt + interval)"},"isOverdue":{"type":"boolean","description":"Whether observer is currently overdue"},"overdueByMinutes":{"type":["integer","null"],"description":"How many minutes overdue (null if not overdue)"},"overdueBySeconds":{"type":["integer","null"],"description":"How many seconds overdue (null if not overdue)"},"explanation":{"type":"object","description":"Human-readable explanation with actionable guidance","required":["summary","reason"],"properties":{"summary":{"type":"string","description":"One-line summary (e.g., 'Overdue by 3 minutes')"},"reason":{"type":"string","description":"Detailed explanation of current state"},"nextAction":{"type":["string","null"],"description":"Suggested next action for user"}}},"lifecycle":{"type":"object","description":"Lifecycle context (paused, muted, maintenance)","required":["isPaused","isMuted","isInMaintenance"],"properties":{"isPaused":{"type":"boolean"},"isMuted":{"type":"boolean"},"isInMaintenance":{"type":"boolean"},"mutedUntil":{"type":["string","null"],"format":"date-time","description":"When mute expires"},"activeMaintenanceWindow":{"type":["object","null"],"description":"Currently active maintenance window (if any)","properties":{"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"reason":{"type":["string","null"]}}}}}}},"IntegrationSnippetResponse":{"type":"object","description":"Generated code snippet for platform integration (Feature 8).","required":["snippet","type","observerId","observerName","checkinUrl"],"properties":{"snippet":{"type":"string","description":"Ready-to-copy code snippet with pre-filled check-in URL. Format depends on integration type (YAML for GitHub Actions/GitLab CI/K8s, JavaScript for Lambda, Docker Compose for docker-compose)."},"type":{"type":"string","enum":["githubActions","gitlabCi","k8sCronJob","awsLambda","dockerCompose"],"description":"Integration platform type"},"observerId":{"type":"string","description":"Observer ID"},"observerName":{"type":"string","description":"Observer name for reference"},"checkinUrl":{"type":"string","format":"uri","description":"Public check-in URL (already embedded in the snippet)"}}},"Interval":{"description":"Expected cadence. `cron` uses AWS cron syntax, evaluated in `timezone` (UTC by default).","type":"object","properties":{"type":{"type":"string","enum":["minutes","hours","days","cron"]},"value":{"type":"integer","minimum":1,"maximum":9007199254740991},"cronExpression":{"type":"string","minLength":1,"maxLength":200},"timezone":{"description":"IANA time zone for `cron` (default UTC). Example: America/Sao_Paulo.","type":"string","minLength":1,"maxLength":64}},"required":["type"],"additionalProperties":false},"SyntheticCheck":{"description":"Active HTTP probe from CronObserver (Orbital).","type":"object","properties":{"enabled":{"type":"boolean"},"type":{"type":"string","enum":["httpGet","httpPost"]},"url":{"type":"string","format":"uri"},"timeoutMs":{"type":"integer","minimum":1000,"maximum":60000},"expectedStatus":{"type":"integer","minimum":100,"maximum":599},"intervalMinutes":{"description":"Plan minimum applies (Orbital: 5).","type":"integer","minimum":1,"maximum":1440},"alertOnFailure":{"type":"boolean"}},"required":["enabled","type","url","timeoutMs","expectedStatus","intervalMinutes","alertOnFailure"],"additionalProperties":false},"Thresholds":{"description":"Payload rules checked on each check-in (Orbital).","type":"object","properties":{"expected":{"type":"object","properties":{"processedMin":{"type":"number","minimum":0},"durationMsMax":{"type":"number","minimum":0}},"additionalProperties":false},"validationMode":{"type":"string","enum":["none","warn","alert"]}},"required":["expected","validationMode"],"additionalProperties":false},"MonitorCreate":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"interval":{"$ref":"#/components/schemas/Interval"},"intervalMinutes":{"description":"Legacy shorthand for interval {type: minutes}.","type":"integer","minimum":1,"maximum":10080},"graceMinutes":{"type":"integer","minimum":0,"maximum":9007199254740991},"maxRuntimeSeconds":{"description":"A run opened with /start and not finished within this many seconds alerts as stuck. Null disables it.","anyOf":[{"type":"integer","minimum":1,"maximum":604800},{"type":"null"}]},"startsOn":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"webhookUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"string","const":""},{"type":"null"}]},"slackWebhookUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"string","const":""},{"type":"null"}]},"teamsWebhookUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"string","const":""},{"type":"null"}]},"telegramChatId":{"description":"Telegram chat id (or @channel) the CronObserver bot posts to. Orbital plan only.","anyOf":[{"type":"string","pattern":"^(-?\\d{1,20}|@[A-Za-z][A-Za-z0-9_]{4,31})$"},{"type":"string","const":""},{"type":"null"}]},"alertEmails":{"maxItems":50,"type":"array","items":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"alertCooldownMinutes":{"type":"integer","minimum":1,"maximum":9007199254740991},"runbook":{"description":"What to do when this monitor alerts (plain text or Markdown). Returned by explain, for humans and AI agents.","anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"escalationSteps":{"description":"Escalation policy (Orbital). Replaces the whole list; [] removes it.","type":"array","items":{"$ref":"#/components/schemas/EscalationStep"}},"syntheticCheck":{"description":"Synthetic HTTP check (Orbital). Fields not sent keep their value; null removes it. Enabling a new check needs every field.","anyOf":[{"type":"object","properties":{"enabled":{"type":"boolean"},"type":{"type":"string","enum":["httpGet","httpPost"]},"url":{"type":"string","format":"uri"},"timeoutMs":{"type":"integer","minimum":1000,"maximum":60000},"expectedStatus":{"type":"integer","minimum":100,"maximum":599},"intervalMinutes":{"description":"Plan minimum applies (Orbital: 5).","type":"integer","minimum":1,"maximum":1440},"alertOnFailure":{"type":"boolean"}},"additionalProperties":false},{"type":"null"}]},"maintenanceWindows":{"description":"Maintenance windows. Replaces the whole list; [] removes them.","type":"array","items":{"$ref":"#/components/schemas/MaintenanceWindow"}},"thresholds":{"$ref":"#/components/schemas/Thresholds"}},"required":["name"],"additionalProperties":false},"MonitorUpdate":{"description":"Only the fields sent are changed.","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"interval":{"$ref":"#/components/schemas/Interval"},"intervalMinutes":{"description":"Legacy shorthand for interval {type: minutes}.","type":"integer","minimum":1,"maximum":10080},"graceMinutes":{"type":"integer","minimum":0,"maximum":9007199254740991},"maxRuntimeSeconds":{"description":"A run opened with /start and not finished within this many seconds alerts as stuck. Null disables it.","anyOf":[{"type":"integer","minimum":1,"maximum":604800},{"type":"null"}]},"startsOn":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"webhookUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"string","const":""},{"type":"null"}]},"slackWebhookUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"string","const":""},{"type":"null"}]},"teamsWebhookUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"string","const":""},{"type":"null"}]},"telegramChatId":{"description":"Telegram chat id (or @channel) the CronObserver bot posts to. Orbital plan only.","anyOf":[{"type":"string","pattern":"^(-?\\d{1,20}|@[A-Za-z][A-Za-z0-9_]{4,31})$"},{"type":"string","const":""},{"type":"null"}]},"alertEmails":{"maxItems":50,"type":"array","items":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"alertCooldownMinutes":{"type":"integer","minimum":1,"maximum":9007199254740991},"runbook":{"description":"What to do when this monitor alerts (plain text or Markdown). Returned by explain, for humans and AI agents.","anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"escalationSteps":{"description":"Escalation policy (Orbital). Replaces the whole list; [] removes it.","type":"array","items":{"$ref":"#/components/schemas/EscalationStep"}},"syntheticCheck":{"description":"Synthetic HTTP check (Orbital). Fields not sent keep their value; null removes it. Enabling a new check needs every field.","anyOf":[{"type":"object","properties":{"enabled":{"type":"boolean"},"type":{"type":"string","enum":["httpGet","httpPost"]},"url":{"type":"string","format":"uri"},"timeoutMs":{"type":"integer","minimum":1000,"maximum":60000},"expectedStatus":{"type":"integer","minimum":100,"maximum":599},"intervalMinutes":{"description":"Plan minimum applies (Orbital: 5).","type":"integer","minimum":1,"maximum":1440},"alertOnFailure":{"type":"boolean"}},"additionalProperties":false},{"type":"null"}]},"maintenanceWindows":{"description":"Maintenance windows. Replaces the whole list; [] removes them.","type":"array","items":{"$ref":"#/components/schemas/MaintenanceWindow"}},"thresholds":{"$ref":"#/components/schemas/Thresholds"}},"additionalProperties":false},"MonitorState":{"type":"string","enum":["new","ok","overdue","paused","muted","maintenance","degraded","failed"]},"Monitor":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"token":{"description":"Check-in token (secret). Returned only to keys with the `checkin` scope.","type":"string"},"checkinUrl":{"description":"Returned only to keys with the `checkin` scope.","type":"string"},"slug":{"description":"Name in the org ping URL /ping/<pingKey>/<slug>; null when the monitor was not created by a ping.","anyOf":[{"type":"string"},{"type":"null"}]},"autoProvisioned":{"description":"Created automatically by the first ping to an unknown slug.","type":"boolean"},"interval":{"anyOf":[{"$ref":"#/components/schemas/Interval"},{"type":"null"}]},"intervalMinutes":{"anyOf":[{"type":"number"},{"type":"null"}]},"graceMinutes":{"type":"number"},"maxRuntimeSeconds":{"anyOf":[{"type":"number"},{"type":"null"}]},"lastRun":{"description":"Latest execution reported by /start, /checkin or /fail.","anyOf":[{"type":"object","properties":{"runId":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["running","success","failed","timeout"]},"startedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"finishedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"durationMs":{"anyOf":[{"type":"number"},{"type":"null"}]},"exitCode":{"anyOf":[{"type":"number"},{"type":"null"}]},"message":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["runId","status","startedAt","finishedAt","durationMs","exitCode","message"],"additionalProperties":false},{"type":"null"}]},"nextExpectedAt":{"description":"When the next check-in is due (before the grace period). Null when there is nothing to expect yet.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"startsOn":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"webhookUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"slackWebhookUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"teamsWebhookUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"telegramChatId":{"anyOf":[{"type":"string"},{"type":"null"}]},"alertEmails":{"type":"array","items":{"type":"string"}},"alertCooldownMinutes":{"type":"number"},"runbook":{"anyOf":[{"type":"string"},{"type":"null"}]},"thresholds":{"$ref":"#/components/schemas/Thresholds"},"escalationSteps":{"type":"array","items":{"$ref":"#/components/schemas/EscalationStep"}},"syntheticCheck":{"anyOf":[{"$ref":"#/components/schemas/SyntheticCheck"},{"type":"null"}]},"maintenanceWindows":{"type":"array","items":{"$ref":"#/components/schemas/MaintenanceWindow"}},"lastThresholdAlertAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"integrations":{"description":"Observability integrations (Orbital).","type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"enabled":{"type":"boolean"},"config":{"description":"Non-secret settings; secrets are never returned.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["type","enabled","config"],"additionalProperties":false}},"state":{"$ref":"#/components/schemas/MonitorState"},"mutedUntil":{"description":"Alerts suppressed until this instant. 9999-12-31T23:59:59.999Z means muted with no deadline.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"pausedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"lastCheckInAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"lastAlertAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","name","slug","autoProvisioned","interval","intervalMinutes","graceMinutes","maxRuntimeSeconds","lastRun","nextExpectedAt","startsOn","webhookUrl","slackWebhookUrl","teamsWebhookUrl","telegramChatId","alertEmails","alertCooldownMinutes","runbook","thresholds","escalationSteps","syntheticCheck","maintenanceWindows","lastThresholdAlertAt","integrations","state","mutedUntil","pausedAt","lastCheckInAt","lastAlertAt","createdAt","updatedAt"],"additionalProperties":false},"MonitorList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Monitor"}},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"skip":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["items","total","limit","skip"],"additionalProperties":false},"LifecycleResult":{"type":"object","properties":{"id":{"type":"string"},"state":{"$ref":"#/components/schemas/MonitorState"},"muted":{"description":"Alerts are suppressed (muted state or mutedUntil in the future).","type":"boolean"},"mutedUntil":{"description":"9999-12-31T23:59:59.999Z means muted until unmuted.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["id","state","muted","mutedUntil"],"additionalProperties":false},"MuteRequest":{"type":"object","properties":{"until":{"description":"Omit or null to mute until unmuted.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"additionalProperties":false},"MonitorEvent":{"type":"object","properties":{"id":{"type":"string"},"type":{"description":"checkin, overdue, recovered, alert_sent, state_change, ...","type":"string"},"occurredAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"meta":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","type","occurredAt","meta"],"additionalProperties":false},"MonitorEventList":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/MonitorEvent"}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"description":"Opaque cursor; pass it as `before` to fetch the next page.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"],"additionalProperties":false}},"required":["events","pagination"],"additionalProperties":false},"MonitorExplanation":{"description":"Human-readable diagnosis of the monitor's current status.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"Incident":{"description":"A monitor that is overdue, degraded or whose last run failed.","type":"object","properties":{"monitorId":{"type":"string"},"name":{"type":"string"},"state":{"$ref":"#/components/schemas/MonitorState"},"lastCheckInAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"lastAlertAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"acknowledged":{"type":"boolean"},"acknowledgedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"acknowledgedBy":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["monitorId","name","state","lastCheckInAt","lastAlertAt","acknowledged","acknowledgedAt","acknowledgedBy"],"additionalProperties":false},"IncidentList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Incident"}}},"required":["items"],"additionalProperties":false},"ApiError":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":{}}}}}