{"openapi":"3.1.0","info":{"title":"Chaukidar API","version":"0.1.0","description":"Chaukidar is uptime monitoring and status pages built for AI agents first. Every feature is\navailable through this JSON API.\n\n## Authentication\n- **Agents and scripts:** send `Authorization: Bearer chk_live_…` with an API key. A key\n  belongs to exactly one workspace and has the scope `read` or `read`+`write`. A person\n  creates keys with POST /v1/api-keys after signing in; agents cannot create keys.\n- **People:** sign in with POST /v1/auth/magic-link then POST /v1/auth/verify, which sets the\n  `chk_session` cookie.\n\n## Workspaces\nAll data lives in a workspace. API keys always act in their own workspace. A signed-in person\nwho belongs to several workspaces sends `x-workspace-id: ws_…` to choose one (optional when\nthey have only one). Resources in other workspaces answer 404, exactly like ids that do not exist.\n\n## Ids\nIds are prefixed strings: `ws_…` workspace, `mon_…` monitor, `key_…` API key, `usr_…` user,\n`inc_…` incident, `chn_…` alert channel, `rule_…` alert rule, `dlv_…` delivery, `evt_…` event,\n`pg_…` status page, `cmp_…` status page component.\n\n## Safe retries\nPOST /v1/monitors, /v1/alert-rules, /v1/status-pages and /v1/status-pages/{id}/components accept an `Idempotency-Key` header (any unique string up to 255\ncharacters, e.g. a UUID). Retrying with the same key and the same body within 24 hours returns\nthe original response (with `Idempotent-Replayed: true`) instead of creating a duplicate.\nThe same key with a different body answers 422 `idempotency_key_reused`. Failed requests are\nnot stored, so a corrected retry may reuse the key.\n\n## Errors\nEvery error is `application/problem+json` (RFC 9457) with:\n- `code`: stable machine-readable reason (e.g. `validation_failed`, `plan_limit`,\n  `monitor_not_found`, `insufficient_scope`). Branch on this, never on text.\n- `detail`: what went wrong, in plain English.\n- `hint`: how to fix it.\n- `errors`: for invalid input, one `{field, message}` per problem, with field like\n  `body.url` or `querystring.limit`.\n- `request_id`: quote it when reporting a problem (also in the `x-request-id` header).\n\n## Incidents\nA monitor's check fails a first time: it is re-checked about every 20 seconds. After\n`confirm_failures` failures in a row (default 3) an incident opens and the monitor's state is\n`down`; after `confirm_recoveries` successes in a row (default 2) it resolves automatically.\nGET /v1/incidents?open=true lists what is down now. People and agents add timeline updates with\nPOST /v1/incidents/{id}/updates; posting `resolved` closes an incident by hand.\n\n## Alerts\nWhen an incident opens or resolves, every enabled **alert rule** that matches (its monitor, or\nall monitors) sends the event to its **channel**: an email, or a webhook. A new workspace starts\nwith an email channel for its owner and an \"All monitors\" rule. Each alert to each channel is a\n**delivery** (GET /v1/deliveries), retried with backoff (30 s doubling, 8 attempts over about an\nhour) until it is `delivered`; then `dead` if every attempt failed, or `failed` at once for a\nproblem retrying cannot fix (e.g. the webhook host resolves to a private address).\nPOST /v1/channels/{id}/test sends a test event right away.\n\nWebhooks are `POST` with a JSON body `{id, type, created_at, workspace_id, message, incident,\nmonitor}` and headers `Chaukidar-Event-Id` (the event id; the same on retries, use it to drop\nduplicates) and `Chaukidar-Signature: t=<unix seconds>,v1=<hex>`. To verify, compute\nHMAC-SHA256 with the channel secret over `<t>.<raw body>`, compare it to `v1` in constant\ntime, and reject timestamps more than 5 minutes old. Any 2xx answer counts as delivered;\nredirects are not followed. Answer quickly (within 10 seconds) and do slow work afterwards.\n\n## Status pages\nA status page (POST /v1/status-pages) shows chosen monitors as public **components**, under\npublic names; monitor names, URLs and check details never appear on it. Read it without\nauthentication as JSON at `/s/{slug}/status.json` and `/s/{slug}/incidents.json`\n(versioned with `version: 1`; fields are only ever added; CORS allows any origin; cached for\nup to 30 s) or as HTML at `/s/{slug}`. Incident updates you post with\nPOST /v1/incidents/{id}/updates are shown on status pages as written, so write them for the\npublic; automatic updates appear as short generic sentences. Style a page with `theme`\n(colors, font, logo, links, light/dark) and optional `custom_css`, which may not load\nanything or run code.\n\n## Plan limits\nEach workspace has `limits.max_monitors` and `limits.min_interval_seconds`\n(GET /v1/workspaces/{id}), and at most 20 alert channels, 50 alert rules, 5 status pages\nand 50 components per page. Hiding \"Powered by Chaukidar\" needs `limits.hide_powered_by`. Going over a\nlimit answers 403 `plan_limit`.\n\n## Pagination\nList endpoints return `{ data, next_cursor }`. Pass `next_cursor` as `?cursor=` to get the\nnext page; it is null on the last page."},"paths":{"/healthz":{"get":{"operationId":"getHealth","summary":"Health check","tags":["System"],"description":"Answers 200 {\"status\":\"ok\"} when the API and its database are working, 503 otherwise. No authentication. Never cached.","responses":{"200":{"description":"Default Response"}}}},"/v1/auth/magic-link":{"post":{"operationId":"requestMagicLink","summary":"Email a sign-in link to a person","tags":["Auth"],"description":"Sends a one-time sign-in link (valid 15 minutes) to the address. Always answers 202, whether or not an account exists, so it cannot be used to discover accounts. At most 5 emails per address per hour and 10 requests per minute per IP. For people; agents use API keys instead.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Email address to sign in with."}},"required":["email"]}}}},"responses":{"200":{"description":"Default Response"}}}},"/v1/auth/verify":{"post":{"operationId":"verifyMagicLink","summary":"Exchange a sign-in token for a session","tags":["Auth"],"description":"Consumes the token from the emailed link (once) and sets the chk_session cookie. The first sign-in for an email creates the person and a workspace they own. Answers 401 invalid_login_token for unknown, used or expired tokens.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","minLength":1,"maxLength":200,"description":"The token query parameter from the emailed link."}},"required":["token"]}}}},"responses":{"200":{"description":"Default Response"}}}},"/v1/auth/logout":{"post":{"operationId":"logout","summary":"Sign out","tags":["Auth"],"description":"Ends the current session and clears the chk_session cookie. Answers 204. API keys are not affected; revoke them with DELETE /v1/api-keys/{id}.","security":[{"session":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/me":{"get":{"operationId":"getMe","summary":"Who am I and what may I do","tags":["Auth"],"description":"Returns the caller (a person or an API key), the workspace the request acts in, and the scopes there (read, write). Call this first to check a key works. For a person in several workspaces without x-workspace-id, workspace is null and workspaces lists them all.","security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/workspaces":{"get":{"operationId":"listWorkspaces","summary":"List workspaces","tags":["Workspaces"],"description":"For a person: every workspace they belong to, with their role (owner, admin or viewer). For an API key: only its own workspace. Each item includes the plan limits max_monitors and min_interval_seconds.","security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"Default Response"}}},"post":{"operationId":"createWorkspace","summary":"Create a workspace","tags":["Workspaces"],"description":"Creates another workspace owned by the signed-in person, on the free plan. Only people can do this; API keys get 403 session_required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Workspace name, 1 to 100 characters."}},"required":["name"]}}}},"security":[{"session":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/workspaces/{id}":{"get":{"operationId":"getWorkspace","summary":"Get a workspace and its plan limits","tags":["Workspaces"],"description":"Returns the workspace with its plan and limits: max_monitors (how many monitors may exist) and min_interval_seconds (the fastest allowed check interval). Workspaces you cannot access answer 404.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Workspace id, e.g. ws_0192f3a45b6c7d8e9f0123456789abcd."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"Default Response"}}},"patch":{"operationId":"updateWorkspace","summary":"Rename a workspace","tags":["Workspaces"],"description":"Changes the workspace name. Needs the write scope (owner or admin, or a read+write API key). Plan limits cannot be changed through the API.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"New workspace name, 1 to 100 characters."}},"required":["name"]}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Workspace id, e.g. ws_0192f3a45b6c7d8e9f0123456789abcd."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/api-keys":{"get":{"operationId":"listApiKeys","summary":"List API keys","tags":["API keys"],"description":"Lists the API keys of the workspace, newest first, including revoked ones (revoked_at set). Secret tokens are never returned; prefix identifies a key. Needs the read scope.","security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"Default Response"}}},"post":{"operationId":"createApiKey","summary":"Create an API key","tags":["API keys"],"description":"Creates a key for an agent or script. The secret token is in the response once and never again: store it. Only a signed-in owner or admin can do this (API keys get 403 session_required), so a person always decides which agents can act.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Label for the key, e.g. the agent that uses it."},"scopes":{"anyOf":[{"type":"array","prefixItems":[{"type":"string","enum":["read"]}],"items":false,"minItems":1,"maxItems":1},{"type":"array","prefixItems":[{"type":"string","enum":["read"]},{"type":"string","enum":["write"]}],"items":false,"minItems":2,"maxItems":2}],"description":"[\"read\"] to only read, or [\"read\",\"write\"] to also change things."},"actor_kind":{"default":"agent","description":"Who will use the key; shown in the audit log. Default agent.","type":"string","enum":["agent","human"]},"expires_at":{"description":"Optional expiry (ISO 8601, in the future). The key stops working after it.","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":["name","scopes"]}}}},"security":[{"session":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/api-keys/{id}":{"delete":{"operationId":"revokeApiKey","summary":"Revoke an API key","tags":["API keys"],"description":"Revokes the key immediately: requests with it answer 401 from now on. Revoking an already revoked key is a no-op. Only a signed-in owner or admin can do this.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"API key id, e.g. key_0192f3a45b6c7d8e9f0123456789abcd."}],"security":[{"session":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/monitors":{"post":{"operationId":"createMonitor","summary":"Create an HTTP monitor","tags":["Monitors"],"description":"Starts checking a URL on a schedule. Only `name` and `url` are required. The monitor starts in state `pending` and the first check is due immediately. Counts against the workspace limit `max_monitors`; `interval_seconds` must be at least `min_interval_seconds` (both answer 403 `plan_limit` otherwise). Send an `Idempotency-Key` header to make retries safe. Needs the `write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMonitorRequestInput"}}}},"parameters":[{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."},{"schema":{"type":"string"},"in":"header","name":"idempotency-key","required":false,"description":"Optional unique key (1 to 255 visible ASCII characters, e.g. a UUID) that makes this request safe to retry: the same key and body within 24 hours replay the first response instead of creating a duplicate."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"201":{"description":"The created monitor. Replays of an Idempotency-Key return the same body with `Idempotent-Replayed: true`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitor"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing `write` scope (`insufficient_scope`), or over a plan limit (`plan_limit`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The Idempotency-Key was already used with a different body (`idempotency_key_reused`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"operationId":"listMonitors","summary":"List monitors","tags":["Monitors"],"description":"Returns the monitors in the workspace, newest first, in pages of up to 100. Use `state=down` to find what is failing right now, and `tag` or `pinned` to narrow the list. Follow `next_cursor` until it is null to read every page. Deleted monitors are never listed. Needs the `read` scope.","parameters":[{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"in":"query","name":"limit","required":false,"description":"Page size, 1 to 100. Default 50."},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"The next_cursor value from the previous page. Omit for the first page."},{"schema":{"type":"string","enum":["pending","up","down","paused"]},"in":"query","name":"state","required":false,"description":"Only return monitors in this state: pending, up, down or paused."},{"schema":{"type":"string","minLength":1,"maxLength":40},"in":"query","name":"tag","required":false,"description":"Only return monitors that have this tag (exact match)."},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"pinned","required":false,"description":"Only return pinned (true) or unpinned (false) monitors."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"One page of monitors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorList"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/monitors/{id}":{"get":{"operationId":"getMonitor","summary":"Get a monitor","tags":["Monitors"],"description":"Returns one monitor with its settings and current state (`pending`, `up`, `down` or `paused`) and when it was last and will next be checked. Needs the `read` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Monitor id, e.g. mon_0192f3a45b6c7d8e9f0123456789abcd."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The monitor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitor"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No monitor with this id in the workspace (`monitor_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateMonitor","summary":"Change monitor settings","tags":["Monitors"],"description":"Changes only the fields you send; everything else stays as it is. Changing what is checked (url, method, request_headers, request_body, expected_status, keyword, keyword_mode or timeout_ms) restarts confirmation: state becomes `pending` (or stays `down` while an incident is open), the next check is due now, and checks already in flight no longer count. Send null to clear `request_body`, `keyword` or `keyword_mode`. The result must satisfy the same rules as create (e.g. no body with GET, timeout shorter than the interval). A new `interval_seconds` must respect the plan minimum. `tags` and `pinned` only organise monitors: changing them never restarts confirmation. Use the pause and resume endpoints to stop or restart checks. Needs the `write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMonitorRequestInput"}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Monitor id, e.g. mon_0192f3a45b6c7d8e9f0123456789abcd."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The updated monitor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitor"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing `write` scope (`insufficient_scope`), or interval below the plan minimum (`plan_limit`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No monitor with this id in the workspace (`monitor_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteMonitor","summary":"Delete a monitor","tags":["Monitors"],"description":"Stops checking and removes the monitor from the API: afterwards it answers 404 everywhere and no longer counts toward `max_monitors`. Alert rules for this monitor are deleted with it (rules for all monitors stay). This cannot be undone through the API; to stop checks temporarily, pause it instead. Needs the `write` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Monitor id, e.g. mon_0192f3a45b6c7d8e9f0123456789abcd."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"204":{"description":"Deleted. No body."},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No monitor with this id in the workspace (`monitor_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/monitors/{id}/pause":{"post":{"operationId":"pauseMonitor","summary":"Pause a monitor","tags":["Monitors"],"description":"Stops checks and alerts for this monitor until it is resumed; state becomes `paused` and `next_check_at` null. Settings and history are kept. Pausing a paused monitor changes nothing and still answers 200. No request body. Needs the `write` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Monitor id, e.g. mon_0192f3a45b6c7d8e9f0123456789abcd."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The monitor after the change.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitor"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No monitor with this id in the workspace (`monitor_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/monitors/{id}/resume":{"post":{"operationId":"resumeMonitor","summary":"Resume a paused monitor","tags":["Monitors"],"description":"Restarts checks for a paused monitor: state becomes `pending` and the next check is due immediately. Resuming a monitor that is not paused changes nothing and still answers 200. No request body. Needs the `write` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Monitor id, e.g. mon_0192f3a45b6c7d8e9f0123456789abcd."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The monitor after the change.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitor"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No monitor with this id in the workspace (`monitor_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/monitors/{id}/checks":{"get":{"operationId":"listMonitorChecks","summary":"List a monitor's check results","tags":["Monitors"],"description":"Returns the results of the monitor's checks, newest first: whether each passed, the HTTP status, response time and, for failures, an error_code with a plain-English error_message. Follow `next_cursor` for older results. Raw results are kept for 30 days. Needs the `read` scope.","parameters":[{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"in":"query","name":"limit","required":false,"description":"Page size, 1 to 100. Default 50."},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"The next_cursor from the previous page. Omit for the first page."},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Monitor id, e.g. mon_0192f3a45b6c7d8e9f0123456789abcd."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"One page of check results.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckResultList"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No monitor with this id in the workspace (`monitor_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/incidents":{"get":{"operationId":"listIncidents","summary":"List incidents","tags":["Incidents"],"description":"Returns the incidents of the workspace, newest first. Use `open=true` to see what is down right now, or `monitor_id` for one monitor's history. Follow `next_cursor` until it is null to read every page. Needs the `read` scope.","parameters":[{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"in":"query","name":"limit","required":false,"description":"Page size, 1 to 100. Default 50."},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"The next_cursor from the previous page. Omit for the first page."},{"schema":{"type":"string"},"in":"query","name":"monitor_id","required":false,"description":"Only incidents of this monitor (mon_…)."},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"open","required":false,"description":"\"true\": only incidents not yet resolved. \"false\": only resolved ones."},{"schema":{"type":"string","enum":["investigating","identified","monitoring","resolved"]},"in":"query","name":"status","required":false,"description":"Only incidents with this status."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"One page of incidents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentList"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/incidents/{id}":{"get":{"operationId":"getIncident","summary":"Get an incident with its timeline","tags":["Incidents"],"description":"Returns one incident with its full timeline of updates (oldest first) and the monitor's last 10 checks up to the end of the incident (newest first), which show what failed and how. Needs the `read` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Incident id, e.g. inc_0192f3a45b6c7d8e9f0123456789abcd."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The incident.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentDetail"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No incident with this id in the workspace (`incident_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/incidents/{id}/updates":{"post":{"operationId":"postIncidentUpdate","summary":"Post an update to an incident","tags":["Incidents"],"description":"Adds a plain-text update to the incident timeline and sets its status (investigating, identified, monitoring, resolved). Posting `resolved` closes an open incident by hand: it stays closed even if checks keep failing, and the next confirmed failure opens a new incident. A resolved incident accepts only further `resolved` updates (notes such as a postmortem); reopening answers 409 `incident_resolved`. Needs the `write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentUpdateRequestInput"}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Incident id, e.g. inc_0192f3a45b6c7d8e9f0123456789abcd."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"201":{"description":"The update was added.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentUpdateResponse"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No incident with this id in the workspace (`incident_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The incident is resolved and the update tried to change its status (`incident_resolved`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/channels":{"post":{"operationId":"createChannel","summary":"Create an alert channel (email or webhook)","tags":["Alerts"],"description":"Adds a place alerts can go. A channel receives nothing until an alert rule points at it (POST /v1/alert-rules). Email channels: an owner's own login email works at once; any other address is emailed a confirmation link and gets no alerts until the recipient confirms (`confirmed`); confirmation emails are limited (429 `rate_limited`). For webhooks, the response contains `secret` (whsec_…), used to sign every request: it is shown only here, so store it now. Not idempotent (the secret is never stored in plain text, so a replay could not return it): if unsure whether a create went through, list channels. At most 20 channels per workspace (403 `plan_limit`). Needs the `write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChannelRequestInput"}}}},"parameters":[{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"201":{"description":"The created channel; webhooks include their signing secret this one time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelWithSecret"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing `write` scope (`insufficient_scope`), or 20 channels already (`plan_limit`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many confirmation emails for this workspace or address today (`rate_limited`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"operationId":"listChannels","summary":"List alert channels","tags":["Alerts"],"description":"Returns the channels of the workspace, newest first. Secrets are never included. Needs the `read` scope.","parameters":[{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"in":"query","name":"limit","required":false,"description":"Page size, 1 to 100. Default 50."},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"next_cursor from the previous page."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"One page of channels.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelList"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/channels/{id}":{"get":{"operationId":"getChannel","summary":"Get an alert channel","tags":["Alerts"],"description":"Returns one channel. The webhook secret is never included. Needs the `read` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Channel id (chn_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The channel.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Channel"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No channel with this id in the workspace (`channel_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateChannel","summary":"Update an alert channel","tags":["Alerts"],"description":"Renames, enables or disables a channel, or changes its email address (email channels) or URL (webhooks). A new email address needs confirming again (unless it is an owner's login email), so alerts stop until then. The type and the webhook secret stay the same. Needs the `write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateChannelRequestInput"}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Channel id (chn_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The updated channel.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Channel"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No channel with this id in the workspace (`channel_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many confirmation emails for this workspace or address today (`rate_limited`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteChannel","summary":"Delete an alert channel","tags":["Alerts"],"description":"Deletes the channel and every alert rule that points at it. Deliveries still waiting for an attempt are marked failed (`channel_deleted`); delivery history is kept. Needs the `write` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Channel id (chn_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"204":{"description":"Deleted. No body."},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No channel with this id in the workspace (`channel_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/channels/{id}/resend-confirmation":{"post":{"operationId":"resendChannelConfirmation","summary":"Email a new confirmation link","tags":["Alerts"],"description":"For an email channel that is not confirmed yet: emails a new confirmation link, which replaces the old one. At most once a minute per channel, and within the daily limits per workspace and per address (429 `rate_limited`). Needs the `write` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Channel id (chn_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"202":{"description":"Sent. The channel stays unconfirmed until the recipient clicks the link.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Channel"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No channel with this id in the workspace (`channel_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Nothing to confirm: a webhook, or already confirmed (`channel_already_confirmed`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Sent less than a minute ago, or too many confirmation emails today (`rate_limited`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/channels/{id}/rotate-secret":{"post":{"operationId":"rotateChannelSecret","summary":"Replace a webhook signing secret","tags":["Alerts"],"description":"Generates a new signing secret for a webhook channel and returns it this one time. Every request from now on is signed with the new secret only, so update the receiver right away. Use it if the secret may have leaked. Needs the `write` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Channel id (chn_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The channel with its new secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelWithSecret"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No channel with this id in the workspace (`channel_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Email channels have no secret (`channel_has_no_secret`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/channels/{id}/test":{"post":{"operationId":"testChannel","summary":"Send a test alert to a channel now","tags":["Alerts"],"description":"Sends one test event (type \"test\") to the channel right away, exactly like a real alert (signed, through the same address checks), and answers with the tracked delivery: `status` is \"delivered\", \"dead\" (the receiver failed, see `last_error`) or \"failed\" (a permanent problem such as `blocked_address`). Test sends are tried once and never retried. At most 5 per minute per channel (429 `rate_limited`). Needs the `write` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Channel id (chn_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The delivery of the test event, after the attempt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Delivery"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No channel with this id in the workspace (`channel_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"More than 5 test sends to this channel in a minute (`rate_limited`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/channel-confirmations":{"post":{"operationId":"confirmChannel","summary":"Confirm an email channel (recipient)","tags":["Alerts"],"description":"Called with the token from a confirmation email; no API key needed. From then on the channel receives alerts. Tokens work once and expire after 7 days.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","maxLength":200,"description":"The token from the confirmation link."}},"required":["token"]}}}},"security":[],"responses":{"200":{"description":"Confirmed.","content":{"application/json":{"schema":{"type":"object","properties":{"channel_id":{"type":"string","description":"The channel (chn_…)."},"email":{"type":"string"},"confirmed":{"type":"boolean","enum":[true]}},"required":["channel_id","email","confirmed"],"additionalProperties":false}}}},"400":{"description":"Invalid, expired or already used token (`invalid_confirmation_token`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/alert-rules":{"post":{"operationId":"createAlertRule","summary":"Create an alert rule","tags":["Alerts"],"description":"Sends incident events of one monitor (`monitor_id`) or of every monitor (omit it) to a channel. `events` defaults to both \"incident.opened\" and \"incident.resolved\". At most 50 rules per workspace (403 `plan_limit`). Send an `Idempotency-Key` header to make retries safe. Needs the `write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAlertRuleRequestInput"}}}},"parameters":[{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."},{"schema":{"type":"string"},"in":"header","name":"idempotency-key","required":false,"description":"Optional unique key (1 to 255 visible ASCII characters, e.g. a UUID) that makes this request safe to retry: the same key and body within 24 hours replay the first response instead of creating a duplicate."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"201":{"description":"The created rule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertRule"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing `write` scope (`insufficient_scope`), or 50 rules already (`plan_limit`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"The channel or monitor does not exist in this workspace (`channel_not_found`, `monitor_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The Idempotency-Key was already used with a different body (`idempotency_key_reused`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"operationId":"listAlertRules","summary":"List alert rules","tags":["Alerts"],"description":"Returns the alert rules of the workspace, newest first. Filter by `channel_id` or `monitor_id` (rules for every monitor have monitor_id null and are not included in a monitor_id filter). Needs the `read` scope.","parameters":[{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"in":"query","name":"limit","required":false,"description":"Page size, 1 to 100. Default 50."},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"next_cursor from the previous page."},{"schema":{"type":"string"},"in":"query","name":"channel_id","required":false,"description":"Only rules for this channel (chn_…)."},{"schema":{"type":"string"},"in":"query","name":"monitor_id","required":false,"description":"Only rules for this monitor (mon_…); rules for every monitor are not included."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"One page of alert rules.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertRuleList"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/alert-rules/{id}":{"get":{"operationId":"getAlertRule","summary":"Get an alert rule","tags":["Alerts"],"description":"Returns one alert rule: which monitor (or all), which channel and which events. Needs the `read` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Alert rule id (rule_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The rule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertRule"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No alert rule with this id in the workspace (`alert_rule_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateAlertRule","summary":"Update an alert rule","tags":["Alerts"],"description":"Changes the name, channel, monitor (null: every monitor), events or enabled flag of a rule. Omitted fields keep their value. Needs the `write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAlertRuleRequestInput"}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Alert rule id (rule_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The updated rule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertRule"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such rule, channel or monitor in this workspace.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteAlertRule","summary":"Delete an alert rule","tags":["Alerts"],"description":"Stops sending the rule's events. Deliveries already made stay in the history. Needs the `write` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Alert rule id (rule_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"204":{"description":"Deleted. No body."},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No alert rule with this id in the workspace (`alert_rule_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/deliveries":{"get":{"operationId":"listDeliveries","summary":"List alert deliveries","tags":["Alerts"],"description":"Every alert sent to every channel, newest first, with its status and attempts. Use `status=dead` or `status=failed` to find alerts that never arrived and why (`last_error`). Needs the `read` scope.","parameters":[{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"in":"query","name":"limit","required":false,"description":"Page size, 1 to 100. Default 50."},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"next_cursor from the previous page."},{"schema":{"type":"string","enum":["pending","sending","delivered","failed","dead"]},"in":"query","name":"status","required":false,"description":"Only deliveries in this status, e.g. \"dead\" to find alerts that never arrived."},{"schema":{"type":"string"},"in":"query","name":"channel_id","required":false,"description":"Only deliveries to this channel (chn_…)."},{"schema":{"type":"string"},"in":"query","name":"incident_id","required":false,"description":"Only deliveries for this incident (inc_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"One page of deliveries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryList"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/deliveries/{id}":{"get":{"operationId":"getDelivery","summary":"Get an alert delivery","tags":["Alerts"],"description":"One delivery with its status, attempts and the exact JSON payload sent. Needs the `read` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Delivery id (dlv_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The delivery.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryDetail"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No delivery with this id in the workspace (`delivery_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/deliveries/{id}/retry":{"post":{"operationId":"retryDelivery","summary":"Retry a failed or dead delivery","tags":["Alerts"],"description":"Puts a \"failed\" or \"dead\" delivery back in line with a fresh set of attempts, starting now (the worker sends it within seconds). The payload is the original one. Fix the cause first (e.g. the receiver, or the channel URL), or it will fail again. Needs the `write` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Delivery id (dlv_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The delivery, now pending.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Delivery"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No delivery with this id in the workspace (`delivery_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Only failed and dead deliveries can be retried (`delivery_not_retryable`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/status-pages":{"post":{"operationId":"createStatusPage","summary":"Create a public status page","tags":["Status pages"],"description":"Creates a page at /s/{slug} (HTML) with /s/{slug}/status.json and /s/{slug}/incidents.json for agents and your own front end. Add components (POST /v1/status-pages/{id}/components) to show monitors on it. Style it with `theme` and optional `custom_css`. At most 5 pages per workspace. Send an `Idempotency-Key` header to make retries safe. Needs the `write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateStatusPageRequestInput"}}}},"parameters":[{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."},{"schema":{"type":"string"},"in":"header","name":"idempotency-key","required":false,"description":"Optional unique key (1 to 255 visible ASCII characters, e.g. a UUID) that makes this request safe to retry: the same key and body within 24 hours replay the first response instead of creating a duplicate."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"201":{"description":"The created page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusPage"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope (`insufficient_scope`), 5 pages already, or hiding \"Powered by\" outside the plan (`plan_limit`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The slug is taken (`slug_taken`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The Idempotency-Key was already used with a different body (`idempotency_key_reused`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"operationId":"listStatusPages","summary":"List status pages","tags":["Status pages"],"description":"Returns the status pages of the workspace, newest first, with their public URLs. Needs the `read` scope.","parameters":[{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"in":"query","name":"limit","required":false,"description":"Page size, 1 to 100. Default 50."},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"next_cursor from the previous page."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"One page of status pages.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusPageList"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/status-pages/{id}":{"get":{"operationId":"getStatusPage","summary":"Get a status page","tags":["Status pages"],"description":"Returns one status page with its theme, custom CSS and public URLs. Needs the `read` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Status page id (pg_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusPage"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No status page with this id in the workspace (`status_page_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateStatusPage","summary":"Update a status page (content, theme, CSS, visibility)","tags":["Status pages"],"description":"Changes the slug, title, description, visibility (`is_public`), theme (replaced as a whole), custom CSS (`null` removes it) or embedding (`allow_embedding`, `embed_domains`). Changes show on the public page within 30 seconds (cache). Needs the `write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStatusPageRequestInput"}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Status page id (pg_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The updated page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusPage"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or hiding \"Powered by\" outside the plan (`plan_limit`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No status page with this id in the workspace (`status_page_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The slug is taken (`slug_taken`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteStatusPage","summary":"Delete a status page","tags":["Status pages"],"description":"Deletes the page and its components; /s/{slug} answers 404 from then on (within 30 seconds, cache) and the slug becomes free. Monitors are not touched. Needs the `write` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Status page id (pg_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"204":{"description":"Deleted. No body."},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No status page with this id in the workspace (`status_page_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/status-pages/{id}/components":{"post":{"operationId":"createStatusPageComponent","summary":"Add a component to a status page","tags":["Status pages"],"description":"A component is a public line on the page, usually showing one monitor's state under a public name (the monitor's own name and URL are never shown). Without `monitor_id` its status is \"unknown\". At most 50 per page. Send an `Idempotency-Key` header to make retries safe. Needs the `write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateStatusPageComponentRequestInput"}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Status page id (pg_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."},{"schema":{"type":"string"},"in":"header","name":"idempotency-key","required":false,"description":"Optional unique key (1 to 255 visible ASCII characters, e.g. a UUID) that makes this request safe to retry: the same key and body within 24 hours replay the first response instead of creating a duplicate."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"201":{"description":"The component.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusPageComponent"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or 50 components already (`plan_limit`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such page or monitor in the workspace (`status_page_not_found`, `monitor_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"operationId":"listStatusPageComponents","summary":"List the components of a status page","tags":["Status pages"],"description":"All components of the page in display order (position, then creation). Needs the `read` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Status page id (pg_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The components.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusPageComponentList"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No status page with this id in the workspace (`status_page_not_found`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/status-pages/{id}/components/{componentId}":{"patch":{"operationId":"updateStatusPageComponent","summary":"Update a status page component","tags":["Status pages"],"description":"Changes the name, description, position or monitor (null: no monitor) of a component. Needs the `write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStatusPageComponentRequestInput"}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Status page id (pg_…)."},{"schema":{"type":"string"},"in":"path","name":"componentId","required":true,"description":"Component id (cmp_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"The component.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusPageComponent"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such page, component or monitor.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteStatusPageComponent","summary":"Remove a component from a status page","tags":["Status pages"],"description":"Removes the component from the page. The monitor keeps running. Needs the `write` scope.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Status page id (pg_…)."},{"schema":{"type":"string"},"in":"path","name":"componentId","required":true,"description":"Component id (cmp_…)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"204":{"description":"Removed. No body."},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such page or component.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/s/{slug}/status.json":{"get":{"operationId":"getPublicStatus","summary":"Current status of a public status page (JSON, v1)","tags":["Public status pages"],"description":"No authentication. The whole page as data: overall state, each component's status, open and recent incidents with their public timelines, and 90 days of daily uptime. Versioned (`version: 1`): fields may be added, never removed. CORS allows any origin, so a website or an agent can read it directly. Cached for up to 30 seconds.","parameters":[{"schema":{"type":"string","maxLength":64},"in":"path","name":"slug","required":true,"description":"The page slug."}],"security":[],"responses":{"200":{"description":"The status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicStatusV1"}}}},"404":{"description":"No public status page with this slug (`status_page_not_found`). Private pages answer the same.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/s/{slug}/incidents.json":{"get":{"operationId":"getPublicIncidents","summary":"Incident history of a public status page (JSON, v1)","tags":["Public status pages"],"description":"No authentication. Open incidents and those of the last 90 days, each with its public timeline. Versioned (`version: 1`). CORS allows any origin. Cached for up to 30 seconds.","parameters":[{"schema":{"type":"string","maxLength":64},"in":"path","name":"slug","required":true,"description":"The page slug."}],"security":[],"responses":{"200":{"description":"The incidents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicIncidentsV1"}}}},"404":{"description":"No public status page with this slug (`status_page_not_found`). Private pages answer the same.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/s/{slug}":{"get":{"operationId":"getPublicStatusPage","summary":"Public status page (HTML)","tags":["Public status pages"],"description":"No authentication. The status page for people, rendered from the same data as status.json with the page theme. No JavaScript; served with a strict Content-Security-Policy. Cached for up to 30 seconds.","parameters":[{"schema":{"type":"string","maxLength":64},"in":"path","name":"slug","required":true,"description":"The page slug."}],"security":[],"responses":{"200":{"description":"Default Response"}}}},"/v1/overview/stats":{"get":{"operationId":"getOverviewStats","summary":"Get workspace health and telemetry stats","tags":["Overview"],"description":"Returns real aggregated 24h metrics: uptime percentage, average probe latency, check counts, and recent incident status.","parameters":[{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"Workspace overview stats.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OverviewStats"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/exports/monitors.csv":{"get":{"operationId":"exportMonitorsCsv","summary":"Export monitors inventory to RFC 4180 CSV","tags":["Exports"],"description":"Streams a complete CSV spreadsheet of workspace monitors with configuration and status.","parameters":[{"schema":{"type":"string","enum":["up","down","paused","pending"]},"in":"query","name":"state","required":false,"description":"Filter by monitor state."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/exports/incidents.csv":{"get":{"operationId":"exportIncidentsCsv","summary":"Export incidents log to RFC 4180 CSV","tags":["Exports"],"description":"Streams a chronological audit log of outages with MTTR durations, cause codes, and resolution stats.","parameters":[{"schema":{"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))$"},"in":"query","name":"from","required":false,"description":"Filter incidents starting after this ISO date."},{"schema":{"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))$"},"in":"query","name":"to","required":false,"description":"Filter incidents starting before this ISO date."},{"schema":{"type":"string"},"in":"query","name":"monitor_id","required":false,"description":"Filter incidents for a specific monitor (mon_...)."},{"schema":{"type":"string","enum":["open","resolved","investigating","identified","monitoring"]},"in":"query","name":"status","required":false,"description":"Filter by incident status."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/exports/checks.csv":{"get":{"operationId":"exportChecksCsv","summary":"Stream probe execution checks to RFC 4180 CSV","tags":["Exports"],"description":"Streams raw synthetic probe execution results with chunked encoding in constant O(1) memory.","parameters":[{"schema":{"type":"string"},"in":"query","name":"monitor_id","required":false,"description":"Filter checks for a specific monitor (mon_...)."},{"schema":{"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))$"},"in":"query","name":"from","required":false,"description":"Earliest check scheduled_at timestamp."},{"schema":{"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))$"},"in":"query","name":"to","required":false,"description":"Latest check scheduled_at timestamp."},{"schema":{"type":"boolean"},"in":"query","name":"ok","required":false,"description":"Filter by success or failure."},{"schema":{"type":"string","maxLength":32},"in":"query","name":"region","required":false,"description":"Filter by edge probe region code (fra, iad, sin, etc.)."},{"schema":{"default":50000,"type":"number","minimum":1,"maximum":100000},"in":"query","name":"limit","required":false,"description":"Max records to stream."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/exports/deliveries.csv":{"get":{"operationId":"exportDeliveriesCsv","summary":"Export notification deliveries audit trail to CSV","tags":["Exports"],"description":"Streams a SOC2-compliant log of all email and webhook dispatches.","parameters":[{"schema":{"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))$"},"in":"query","name":"from","required":false,"description":"Filter deliveries after this ISO date."},{"schema":{"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))$"},"in":"query","name":"to","required":false,"description":"Filter deliveries before this ISO date."},{"schema":{"type":"string"},"in":"query","name":"channel_id","required":false,"description":"Filter deliveries for a channel (chn_...)."},{"schema":{"type":"string","enum":["delivered","failed","dead","pending","sending"]},"in":"query","name":"status","required":false,"description":"Filter by delivery status."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"Default Response"}}}},"/v1/reports/sla":{"get":{"operationId":"getSlaReport","summary":"Generate server-side SLA compliance and reliability report","tags":["Reports"],"description":"Computes mathematically exact uptime, MTTR, MTBF, error budget, and daily reliability breakdown.","parameters":[{"schema":{"default":"30d","type":"string","enum":["7d","30d","90d","custom"]},"in":"query","name":"period","required":false,"description":"Predefined time window or custom range."},{"schema":{"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))$"},"in":"query","name":"from","required":false,"description":"Start of time window if period=custom."},{"schema":{"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))$"},"in":"query","name":"to","required":false,"description":"End of time window if period=custom."},{"schema":{"type":"string"},"in":"query","name":"monitor_id","required":false,"description":"Optional specific monitor ID (mon_...)."},{"schema":{"default":99.9,"type":"number","minimum":50,"maximum":100},"in":"query","name":"target_sla","required":false,"description":"Target SLA percentage (default 99.9)."},{"schema":{"type":"string"},"in":"header","name":"x-workspace-id","required":false,"description":"Workspace to act in (ws_…). Only for signed-in people who belong to several workspaces; API keys always use their own workspace and must not point elsewhere."}],"security":[{"apiKey":[]},{"session":[]}],"responses":{"200":{"description":"SLA report and reliability statistics.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SlaReport"}}}},"400":{"description":"Invalid input (`validation_failed`, with `errors` naming each field) or a malformed id (`invalid_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, revoked or expired credentials (`authentication_required`, `invalid_api_key`, `invalid_session`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key or role lacks the needed scope (`insufficient_scope`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"tags":[{"name":"Overview","description":"Workspace health aggregates, 24-hour telemetry, and live probe latencies."},{"name":"Monitors","description":"HTTP uptime checks: create, configure, pause, resume, delete, and read check results."},{"name":"Incidents","description":"Outages detected by checks (3 failures in a row open one, 2 successes resolve it), with a timeline of updates."},{"name":"Alerts","description":"Where incident alerts go (email and signed webhook channels), which incidents go where (alert rules), and every delivery with its retries."},{"name":"Status pages","description":"Manage public status pages: content, components (which monitors show, under which public names), theme and custom CSS."},{"name":"Public status pages","description":"Unauthenticated, cacheable, CORS-enabled: /s/{slug} (HTML), /s/{slug}/status.json and /s/{slug}/incidents.json (versioned JSON, the main way to read a status page from code or an agent)."},{"name":"Auth","description":"Sign-in for people (magic link) and the current identity."},{"name":"Workspaces","description":"Workspaces hold all data, members and plan limits."},{"name":"API keys","description":"Scoped keys for agents and scripts."},{"name":"System","description":"Health checks."}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"API key: `Authorization: Bearer chk_live_…`. Bound to one workspace; scope read or read+write."},"session":{"type":"apiKey","in":"cookie","name":"chk_session","description":"Session cookie set by POST /v1/auth/verify for signed-in people."}},"schemas":{"CreateChannelRequestInput":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"email"},"name":{"type":"string","minLength":1,"maxLength":100,"description":"Label, 1 to 100 characters."},"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"The address alerts are sent to."}},"required":["type","name","email"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"webhook"},"name":{"type":"string","minLength":1,"maxLength":100,"description":"Label, 1 to 100 characters."},"url":{"type":"string","description":"Where to POST alerts. Same rules as monitor URLs: http:// or https://, no credentials, port 80, 443, 8080 or 8443, and a public host. Private and internal addresses are refused here and again at send time (after DNS), so a public name that resolves inside a private network fails with blocked_address."}},"required":["type","name","url"],"additionalProperties":false}],"description":"An email channel ({type:\"email\", name, email}) or a webhook channel ({type:\"webhook\", name, url}).","examples":[{"type":"webhook","name":"Ops webhook","url":"https://hooks.example.com/chaukidar"}]},"UpdateChannelRequestInput":{"type":"object","properties":{"name":{"description":"New label.","type":"string","minLength":1,"maxLength":100},"enabled":{"description":"false stops new alerts to this channel.","type":"boolean"},"email":{"description":"Email channels only: the new recipient.","type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"url":{"description":"Webhook channels only: the new URL. The signing secret stays the same.","type":"string"}},"additionalProperties":false,"description":"Fields to change; omitted fields keep their value. The type cannot change."},"CreateAlertRuleRequestInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Label, 1 to 100 characters."},"channel_id":{"type":"string","description":"Channel to alert (chn_…)."},"monitor_id":{"description":"Monitor to watch (mon_…). Omit or null: every monitor.","type":["string","null"]},"events":{"minItems":1,"type":"array","items":{"type":"string","enum":["incident.opened","incident.resolved"]},"description":"Which events to send: \"incident.opened\", \"incident.resolved\" or both. Default both."},"enabled":{"description":"Default true.","type":"boolean"}},"required":["name","channel_id"],"additionalProperties":false,"examples":[{"name":"Checkout API to Ops","channel_id":"chn_0192f3a45b6c7d8e9f0123456789abcd","monitor_id":"mon_0192f3a45b6c7d8e9f0123456789abcd","events":["incident.opened","incident.resolved"]}]},"UpdateAlertRuleRequestInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"channel_id":{"description":"New channel (chn_…).","type":"string"},"monitor_id":{"description":"New monitor (mon_…), or null for every monitor.","type":["string","null"]},"events":{"minItems":1,"type":"array","items":{"type":"string","enum":["incident.opened","incident.resolved"]},"description":"Which events to send: \"incident.opened\", \"incident.resolved\" or both. Default both."},"enabled":{"type":"boolean"}},"additionalProperties":false,"description":"Fields to change; omitted fields keep their value."},"CreateIncidentUpdateRequestInput":{"type":"object","properties":{"status":{"type":"string","enum":["investigating","identified","monitoring","resolved"],"description":"The incident status after this update. Sending \"resolved\" closes an open incident by hand: it stays closed even if checks still fail, and the next confirmed failure opens a new incident. On an already resolved incident only \"resolved\" is accepted (a note, e.g. a postmortem)."},"message":{"type":"string","minLength":1,"maxLength":5000,"description":"What happened or what is being done, in plain text. 1 to 5000 characters."}},"required":["status","message"],"additionalProperties":false,"description":"A timeline update for an incident.","examples":[{"status":"identified","message":"The primary database failed over; writes are recovering."}]},"StatusPageThemeInput":{"type":"object","properties":{"layout":{"default":"default","description":"Page layout. Only \"default\" for now; more layouts come later.","type":"string","enum":["default"]},"mode":{"default":"auto","description":"\"auto\" follows the visitor's system setting.","type":"string","enum":["light","dark","auto"]},"brand_color":{"default":"#1f6feb","description":"Header color, hex like #1f6feb. Text on it is black or white, whichever reads better.","type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent_color":{"default":"#1f6feb","description":"Link color, hex.","type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"font":{"default":"system","description":"Font: system, serif, mono, rounded, humanist (system fonts; nothing is downloaded).","type":"string","enum":["system","serif","mono","rounded","humanist"]},"logo_url":{"default":null,"description":"Logo image (https), shown in the header instead of the title text.","anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"show_title_with_logo":{"default":true,"description":"Whether to display the title text next to the logo in the header.","type":"boolean"},"favicon_url":{"default":null,"description":"Favicon (https).","anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"header_links":{"default":[],"description":"Up to 5 links in the header, e.g. your website.","maxItems":5,"type":"array","items":{"type":"object","properties":{"label":{"type":"string","pattern":"^[^<>\\x00-\\x1f\\x7f]{1,40}$","description":"Link text."},"url":{"type":"string","maxLength":500,"description":"https:// or mailto: URL."}},"required":["label","url"],"additionalProperties":false}},"footer_links":{"default":[],"description":"Up to 10 links in the footer, e.g. support or privacy.","maxItems":10,"type":"array","items":{"type":"object","properties":{"label":{"type":"string","pattern":"^[^<>\\x00-\\x1f\\x7f]{1,40}$","description":"Link text."},"url":{"type":"string","maxLength":500,"description":"https:// or mailto: URL."}},"required":["label","url"],"additionalProperties":false}}},"additionalProperties":false,"description":"How the public page looks. Omitted fields take their default."},"CreateStatusPageRequestInput":{"type":"object","properties":{"slug":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$","description":"The public address: /s/{slug}. Unique across all of Chaukidar. 3 to 40 lowercase letters, digits and hyphens."},"title":{"type":"string","minLength":1,"maxLength":100,"description":"Page title, shown as the heading and in the browser tab."},"description":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"description":"One or two sentences under the title, also the meta description."},"is_public":{"description":"Default true.","type":"boolean"},"show_powered_by":{"description":"Default true. false needs the workspace limit hide_powered_by (paid plans).","type":"boolean"},"theme":{"$ref":"#/components/schemas/StatusPageThemeInput"},"custom_css":{"description":"Optional extra CSS (max 20,000 characters) to restyle the page. It may not load anything or run code: no url(), @import, image functions, expression(), behavior, -moz-binding, javascript:, backslash escapes, \"<\", or at-rules other than @media, @supports, @keyframes, @container and @layer. The page is served with a Content-Security-Policy that allows no scripts and no remote styles.","type":["string","null"]},"allow_embedding":{"type":"boolean","description":"true lets other sites show the HTML page in an iframe (CSP frame-ancestors). Default false: no site may embed it."},"embed_domains":{"maxItems":20,"type":"array","items":{"type":"string","pattern":"^(\\*\\.)?([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,63}$"},"description":"With allow_embedding: the sites that may embed the page (https only), up to 20, e.g. [\"example.com\", \"*.example.com\"]. Empty: any https site."}},"required":["slug","title"],"additionalProperties":false,"examples":[{"slug":"acme","title":"Acme status","theme":{"brand_color":"#ff6600","mode":"auto"}}]},"UpdateStatusPageRequestInput":{"type":"object","properties":{"slug":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$","description":"The public address: /s/{slug}. Unique across all of Chaukidar. 3 to 40 lowercase letters, digits and hyphens."},"title":{"type":"string","minLength":1,"maxLength":100,"description":"Page title, shown as the heading and in the browser tab."},"description":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"description":"One or two sentences under the title, also the meta description."},"is_public":{"type":"boolean"},"show_powered_by":{"type":"boolean"},"theme":{"description":"Replaces the whole theme; omitted theme fields go back to their defaults.","$ref":"#/components/schemas/StatusPageThemeInput"},"custom_css":{"description":"New custom CSS, or null to remove it.","type":["string","null"]},"allow_embedding":{"type":"boolean","description":"true lets other sites show the HTML page in an iframe (CSP frame-ancestors). Default false: no site may embed it."},"embed_domains":{"description":"Replaces the list.","maxItems":20,"type":"array","items":{"type":"string","pattern":"^(\\*\\.)?([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,63}$"}}},"additionalProperties":false,"description":"Fields to change; omitted fields keep their value."},"CreateStatusPageComponentRequestInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Public name, e.g. \"Checkout\"."},"description":{"description":"Optional one-line description.","anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"monitor_id":{"description":"Monitor (mon_…) whose state the component shows.","type":["string","null"]},"position":{"description":"Order on the page. Default 0.","type":"integer","minimum":0,"maximum":1000}},"required":["name"],"additionalProperties":false,"examples":[{"name":"Checkout","monitor_id":"mon_0192f3a45b6c7d8e9f0123456789abcd","position":1}]},"UpdateStatusPageComponentRequestInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Public name, e.g. \"Checkout\"."},"description":{"description":"Optional one-line description.","anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"monitor_id":{"description":"Monitor (mon_…) whose state the component shows.","type":["string","null"]},"position":{"description":"Order on the page. Default 0.","type":"integer","minimum":0,"maximum":1000}},"additionalProperties":false},"CreateMonitorRequestInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Human-readable label shown in alerts and on status pages. 1 to 100 characters."},"url":{"type":"string","description":"The http:// or https:// URL to check. Rules: no username or password in the URL; port must be one of 80, 443, 8080, 8443 (default ports when omitted); the host must be a public domain name or a public IP address. Private, loopback, link-local and other internal addresses (e.g. 10.x, 192.168.x, 127.x, 169.254.169.254, ::1, localhost) are rejected. Max 2048 characters. Stored in normalised form."},"method":{"type":"string","enum":["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"],"description":"HTTP method used for the check. Default GET. GET and HEAD cannot have a request_body."},"request_headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":1024},"description":"Extra request headers sent with every check, as {\"name\": \"value\"}, e.g. {\"Authorization\": \"Bearer …\"}. Write-only: values are encrypted at rest (AES-256-GCM) and never returned by the API; responses list only request_header_names. On update, the object you send replaces all existing headers; send {} to remove them, or omit the field to keep them. Names are stored in lowercase. Up to 20 headers, values up to 1024 characters. Host, Content-Length, Transfer-Encoding, Connection and other hop-by-hop headers are not allowed. Default {}."},"request_body":{"type":"string","maxLength":10000,"description":"Raw request body sent with every check (for POST, PUT, PATCH, DELETE, OPTIONS). Up to 10000 characters. Default none."},"expected_status":{"type":"string","maxLength":100,"description":"Which HTTP status codes count as \"up\": a comma-separated list of codes and inclusive ranges, e.g. \"200-299,301\". Any other status is a failure. Default \"200-399\"."},"keyword":{"type":"string","minLength":1,"maxLength":200,"description":"Optional text to look for in the response body (case-sensitive, first 1 MB). Use with keyword_mode. Default none."},"keyword_mode":{"type":"string","enum":["present","absent"],"description":"\"present\": the check fails unless the body contains keyword. \"absent\": the check fails if the body contains keyword. Only allowed together with keyword; defaults to \"present\" when keyword is set."},"timeout_ms":{"type":"integer","minimum":1000,"maximum":30000,"description":"How long to wait for the full response before the check fails, in milliseconds. 1000 to 30000, and shorter than the interval. Default 10000."},"interval_seconds":{"type":"integer","minimum":30,"maximum":86400,"description":"Seconds between checks, 30 to 86400. Must also be at least the workspace's limits.min_interval_seconds (see GET /v1/workspaces/{id}); a smaller value is rejected with 403 plan_limit. Default: the workspace minimum."},"confirm_failures":{"type":"integer","minimum":1,"maximum":10,"description":"Consecutive failed checks needed before an incident opens and alerts are sent. 1 to 10. Default 3. While confirming, the monitor is re-checked every 20 seconds."},"confirm_recoveries":{"type":"integer","minimum":1,"maximum":10,"description":"Consecutive successful checks needed before an open incident is resolved. 1 to 10. Default 2."},"tags":{"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":40},"description":"Labels for grouping and filtering monitors, e.g. [\"production\", \"api\"]. Shared by everyone in the workspace. Up to 20 tags of 1 to 40 characters; duplicates are dropped. On update, the list you send replaces the existing one; send [] to remove all tags. Tags do not affect checks. Default []."},"pinned":{"type":"boolean","description":"Pins the monitor to the top of the dashboard for everyone in the workspace. Does not affect checks. Default false."}},"required":["name","url"],"additionalProperties":false,"description":"A new HTTP monitor. Only name and url are required; everything else has a default. Unknown fields are rejected.","examples":[{"name":"Checkout API","url":"https://api.example.com/health","method":"GET","expected_status":"200-299","keyword":"\"status\":\"ok\"","timeout_ms":10000,"interval_seconds":300,"confirm_failures":3}]},"UpdateMonitorRequestInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Human-readable label shown in alerts and on status pages. 1 to 100 characters."},"url":{"type":"string","description":"The http:// or https:// URL to check. Rules: no username or password in the URL; port must be one of 80, 443, 8080, 8443 (default ports when omitted); the host must be a public domain name or a public IP address. Private, loopback, link-local and other internal addresses (e.g. 10.x, 192.168.x, 127.x, 169.254.169.254, ::1, localhost) are rejected. Max 2048 characters. Stored in normalised form."},"method":{"type":"string","enum":["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"],"description":"HTTP method used for the check. Default GET. GET and HEAD cannot have a request_body."},"request_headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":1024},"description":"Extra request headers sent with every check, as {\"name\": \"value\"}, e.g. {\"Authorization\": \"Bearer …\"}. Write-only: values are encrypted at rest (AES-256-GCM) and never returned by the API; responses list only request_header_names. On update, the object you send replaces all existing headers; send {} to remove them, or omit the field to keep them. Names are stored in lowercase. Up to 20 headers, values up to 1024 characters. Host, Content-Length, Transfer-Encoding, Connection and other hop-by-hop headers are not allowed. Default {}."},"request_body":{"anyOf":[{"type":"string","maxLength":10000,"description":"Raw request body sent with every check (for POST, PUT, PATCH, DELETE, OPTIONS). Up to 10000 characters. Default none."},{"type":"null"}],"description":"Raw request body sent with every check (for POST, PUT, PATCH, DELETE, OPTIONS). Up to 10000 characters. Default none. Send null to remove it."},"expected_status":{"type":"string","maxLength":100,"description":"Which HTTP status codes count as \"up\": a comma-separated list of codes and inclusive ranges, e.g. \"200-299,301\". Any other status is a failure. Default \"200-399\"."},"keyword":{"anyOf":[{"type":"string","minLength":1,"maxLength":200,"description":"Optional text to look for in the response body (case-sensitive, first 1 MB). Use with keyword_mode. Default none."},{"type":"null"}],"description":"Optional text to look for in the response body (case-sensitive, first 1 MB). Use with keyword_mode. Default none. Send null to stop keyword checking."},"keyword_mode":{"anyOf":[{"type":"string","enum":["present","absent"],"description":"\"present\": the check fails unless the body contains keyword. \"absent\": the check fails if the body contains keyword. Only allowed together with keyword; defaults to \"present\" when keyword is set."},{"type":"null"}],"description":"\"present\": the check fails unless the body contains keyword. \"absent\": the check fails if the body contains keyword. Only allowed together with keyword; defaults to \"present\" when keyword is set."},"timeout_ms":{"type":"integer","minimum":1000,"maximum":30000,"description":"How long to wait for the full response before the check fails, in milliseconds. 1000 to 30000, and shorter than the interval. Default 10000."},"interval_seconds":{"type":"integer","minimum":30,"maximum":86400,"description":"Seconds between checks, 30 to 86400. Must also be at least the workspace's limits.min_interval_seconds (see GET /v1/workspaces/{id}); a smaller value is rejected with 403 plan_limit. Default: the workspace minimum."},"confirm_failures":{"type":"integer","minimum":1,"maximum":10,"description":"Consecutive failed checks needed before an incident opens and alerts are sent. 1 to 10. Default 3. While confirming, the monitor is re-checked every 20 seconds."},"confirm_recoveries":{"type":"integer","minimum":1,"maximum":10,"description":"Consecutive successful checks needed before an open incident is resolved. 1 to 10. Default 2."},"tags":{"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":40},"description":"Labels for grouping and filtering monitors, e.g. [\"production\", \"api\"]. Shared by everyone in the workspace. Up to 20 tags of 1 to 40 characters; duplicates are dropped. On update, the list you send replaces the existing one; send [] to remove all tags. Tags do not affect checks. Default []."},"pinned":{"type":"boolean","description":"Pins the monitor to the top of the dashboard for everyone in the workspace. Does not affect checks. Default false."}},"additionalProperties":false,"description":"Fields to change; omitted fields keep their value. Send null for request_body, keyword or keyword_mode to clear them. The same rules as on create apply to the resulting monitor.","examples":[{"name":"Checkout API (EU)","interval_seconds":600}]},"Problem":{"type":"object","properties":{"type":{"type":"string","description":"URI for this error type: urn:chaukidar:error:{code}."},"title":{"type":"string","description":"HTTP status text, e.g. \"Not Found\"."},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"HTTP status code."},"code":{"type":"string","description":"Stable machine-readable error code. Branch on this."},"detail":{"type":"string","description":"What went wrong, in plain English."},"hint":{"description":"How to fix it.","type":"string"},"errors":{"description":"One entry per invalid field, for validation_failed and some plan_limit errors.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"Where the problem is, e.g. body.url or querystring.limit."},"message":{"type":"string","description":"What is wrong with that field."}},"required":["field","message"],"additionalProperties":false}},"request_id":{"type":"string","description":"Id of this request; also in the x-request-id response header."}},"required":["type","title","status","code","detail","request_id"],"additionalProperties":false,"description":"RFC 9457 problem document."},"Channel":{"type":"object","properties":{"id":{"type":"string","description":"Channel id: \"chn_\" followed by 32 hex characters."},"type":{"type":"string","enum":["email","webhook"],"description":"\"email\": a plain-text email per alert. \"webhook\": a signed JSON POST per alert."},"name":{"type":"string","description":"Label, e.g. \"On-call email\"."},"email":{"description":"Email channels: the recipient. null for webhooks.","type":["string","null"]},"url_masked":{"description":"Webhook channels: the URL alerts are POSTed to, masked to scheme, host and its last 4 characters (e.g. \"https://hooks.slack.com/…x9Qz\"). The full URL is stored encrypted and never returned, because webhook URLs often contain a token. null for email.","type":["string","null"]},"confirmed":{"type":"boolean","description":"Email channels: true once the recipient confirmed the address (an owner's own login email is confirmed at once). Unconfirmed channels get no alerts. Always true for webhooks."},"enabled":{"type":"boolean","description":"Disabled channels get no new alerts; pending deliveries to them fail with channel_disabled."},"created_at":{"type":"string","description":"When the channel was created. ISO 8601 UTC timestamp."},"updated_at":{"type":"string","description":"When the channel last changed. ISO 8601 UTC timestamp."}},"required":["id","type","name","email","url_masked","confirmed","enabled","created_at","updated_at"],"additionalProperties":false,"description":"Where alerts go. A new workspace starts with an email channel for its owner.","examples":[{"id":"chn_0192f3a45b6c7d8e9f0123456789abcd","type":"webhook","name":"Ops webhook","email":null,"url_masked":"https://hooks.example.com/…idar","confirmed":true,"enabled":true,"created_at":"2026-10-11T12:00:00.000Z","updated_at":"2026-10-11T12:00:00.000Z"}]},"ChannelWithSecret":{"type":"object","properties":{"id":{"type":"string","description":"Channel id: \"chn_\" followed by 32 hex characters."},"type":{"type":"string","enum":["email","webhook"],"description":"\"email\": a plain-text email per alert. \"webhook\": a signed JSON POST per alert."},"name":{"type":"string","description":"Label, e.g. \"On-call email\"."},"email":{"description":"Email channels: the recipient. null for webhooks.","type":["string","null"]},"url_masked":{"description":"Webhook channels: the URL alerts are POSTed to, masked to scheme, host and its last 4 characters (e.g. \"https://hooks.slack.com/…x9Qz\"). The full URL is stored encrypted and never returned, because webhook URLs often contain a token. null for email.","type":["string","null"]},"confirmed":{"type":"boolean","description":"Email channels: true once the recipient confirmed the address (an owner's own login email is confirmed at once). Unconfirmed channels get no alerts. Always true for webhooks."},"enabled":{"type":"boolean","description":"Disabled channels get no new alerts; pending deliveries to them fail with channel_disabled."},"created_at":{"type":"string","description":"When the channel was created. ISO 8601 UTC timestamp."},"updated_at":{"type":"string","description":"When the channel last changed. ISO 8601 UTC timestamp."},"secret":{"description":"Webhook channels only, and only in this response: the signing secret (whsec_…). Store it now; it is never shown again (rotate it with POST /v1/channels/{id}/rotate-secret to get a new one).","type":"string"}},"required":["id","type","name","email","url_masked","confirmed","enabled","created_at","updated_at"],"additionalProperties":false,"description":"A channel, plus its webhook signing secret this one time."},"ChannelList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Channel"}},"next_cursor":{"description":"Pass as ?cursor= for the next page; null on the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"AlertRule":{"type":"object","properties":{"id":{"type":"string","description":"Alert rule id: \"rule_\" followed by 32 hex characters."},"name":{"type":"string","description":"Label."},"monitor_id":{"description":"The monitor this rule watches (mon_…), or null for every monitor in the workspace.","type":["string","null"]},"channel_id":{"type":"string","description":"Where matching events go (chn_…)."},"events":{"type":"array","items":{"type":"string","enum":["incident.opened","incident.resolved"]},"description":"Events this rule sends."},"enabled":{"type":"boolean","description":"Disabled rules match nothing."},"created_at":{"type":"string","description":"When the rule was created. ISO 8601 UTC timestamp."},"updated_at":{"type":"string","description":"When the rule last changed. ISO 8601 UTC timestamp."}},"required":["id","name","monitor_id","channel_id","events","enabled","created_at","updated_at"],"additionalProperties":false,"description":"Sends a monitor's (or every monitor's) incident events to a channel. When several rules match one event and one channel, the channel still gets the alert once.","examples":[{"id":"rule_0192f3a45b6c7d8e9f0123456789abcd","name":"All monitors","monitor_id":null,"channel_id":"chn_0192f3a45b6c7d8e9f0123456789abcd","events":["incident.opened","incident.resolved"],"enabled":true,"created_at":"2026-10-11T12:00:00.000Z","updated_at":"2026-10-11T12:00:00.000Z"}]},"AlertRuleList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AlertRule"}},"next_cursor":{"description":"Pass as ?cursor= for the next page; null on the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"Delivery":{"type":"object","properties":{"id":{"type":"string","description":"Delivery id: \"dlv_\" followed by 32 hex characters."},"channel_id":{"description":"The channel (chn_…), or null if it was deleted since.","type":["string","null"]},"channel_type":{"type":"string","enum":["email","webhook"]},"alert_rule_id":{"description":"The rule that matched (rule_…); null for test sends or if the rule was deleted.","type":["string","null"]},"incident_id":{"description":"The incident (inc_…); null for test sends.","type":["string","null"]},"event_id":{"type":"string","description":"The event (evt_…), the same for every channel; webhooks get it as Chaukidar-Event-Id."},"event_type":{"type":"string","enum":["incident.opened","incident.resolved","test"]},"status":{"type":"string","enum":["pending","sending","delivered","failed","dead"],"description":"\"pending\": waiting for its next attempt (next_attempt_at), also after a failed attempt. \"sending\": an attempt is in progress. \"delivered\": the receiver accepted it (2xx, or the email provider took it). \"failed\": a permanent problem, not retried (e.g. blocked_address, channel_deleted, channel_disabled). \"dead\": all max_attempts attempts failed. Failed and dead deliveries can be retried with POST /v1/deliveries/{id}/retry."},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Attempts made so far."},"max_attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Attempts allowed before the delivery is dead (8 for alerts, 1 for test sends)."},"next_attempt_at":{"description":"When the next attempt is due (pending only). ISO 8601 UTC timestamp, or null.","type":["string","null"]},"last_attempt_at":{"description":"When the last attempt started. ISO 8601 UTC timestamp, or null.","type":["string","null"]},"last_error":{"description":"Plain-English reason the last attempt failed, e.g. \"expected status 200-299, got 500\".","type":["string","null"]},"last_error_code":{"description":"Machine-readable reason: a probe error code for webhooks (status_mismatch, timeout, dns_failure, connection_refused, connection_error, tls_error, blocked_address, blocked_port, invalid_url) or email_failed, channel_deleted, channel_disabled, secret_unreadable, interrupted, internal_error.","type":["string","null"]},"last_response_code":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"HTTP status the webhook receiver answered on the last attempt."},"delivered_at":{"description":"When it was delivered. ISO 8601 UTC timestamp, or null.","type":["string","null"]},"created_at":{"type":"string","description":"When the delivery was created (when the event fanned out). ISO 8601 UTC timestamp."},"updated_at":{"type":"string","description":"When the delivery last changed. ISO 8601 UTC timestamp."}},"required":["id","channel_id","channel_type","alert_rule_id","incident_id","event_id","event_type","status","attempts","max_attempts","next_attempt_at","last_attempt_at","last_error","last_error_code","last_response_code","delivered_at","created_at","updated_at"],"additionalProperties":false,"description":"One alert to one channel, tracked through every retry."},"DeliveryDetail":{"type":"object","properties":{"id":{"type":"string","description":"Delivery id: \"dlv_\" followed by 32 hex characters."},"channel_id":{"description":"The channel (chn_…), or null if it was deleted since.","type":["string","null"]},"channel_type":{"type":"string","enum":["email","webhook"]},"alert_rule_id":{"description":"The rule that matched (rule_…); null for test sends or if the rule was deleted.","type":["string","null"]},"incident_id":{"description":"The incident (inc_…); null for test sends.","type":["string","null"]},"event_id":{"type":"string","description":"The event (evt_…), the same for every channel; webhooks get it as Chaukidar-Event-Id."},"event_type":{"type":"string","enum":["incident.opened","incident.resolved","test"]},"status":{"type":"string","enum":["pending","sending","delivered","failed","dead"],"description":"\"pending\": waiting for its next attempt (next_attempt_at), also after a failed attempt. \"sending\": an attempt is in progress. \"delivered\": the receiver accepted it (2xx, or the email provider took it). \"failed\": a permanent problem, not retried (e.g. blocked_address, channel_deleted, channel_disabled). \"dead\": all max_attempts attempts failed. Failed and dead deliveries can be retried with POST /v1/deliveries/{id}/retry."},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Attempts made so far."},"max_attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Attempts allowed before the delivery is dead (8 for alerts, 1 for test sends)."},"next_attempt_at":{"description":"When the next attempt is due (pending only). ISO 8601 UTC timestamp, or null.","type":["string","null"]},"last_attempt_at":{"description":"When the last attempt started. ISO 8601 UTC timestamp, or null.","type":["string","null"]},"last_error":{"description":"Plain-English reason the last attempt failed, e.g. \"expected status 200-299, got 500\".","type":["string","null"]},"last_error_code":{"description":"Machine-readable reason: a probe error code for webhooks (status_mismatch, timeout, dns_failure, connection_refused, connection_error, tls_error, blocked_address, blocked_port, invalid_url) or email_failed, channel_deleted, channel_disabled, secret_unreadable, interrupted, internal_error.","type":["string","null"]},"last_response_code":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"HTTP status the webhook receiver answered on the last attempt."},"delivered_at":{"description":"When it was delivered. ISO 8601 UTC timestamp, or null.","type":["string","null"]},"created_at":{"type":"string","description":"When the delivery was created (when the event fanned out). ISO 8601 UTC timestamp."},"updated_at":{"type":"string","description":"When the delivery last changed. ISO 8601 UTC timestamp."},"payload":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The JSON body that is POSTed to webhooks (and that emails are written from): {id, type, created_at, workspace_id, message, incident, monitor}."}},"required":["id","channel_id","channel_type","alert_rule_id","incident_id","event_id","event_type","status","attempts","max_attempts","next_attempt_at","last_attempt_at","last_error","last_error_code","last_response_code","delivered_at","created_at","updated_at","payload"],"additionalProperties":false},"DeliveryList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Delivery"}},"next_cursor":{"description":"Pass as ?cursor= for the next page; null on the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"Incident":{"type":"object","properties":{"id":{"type":"string","description":"Incident id: \"inc_\" followed by 32 hex characters."},"monitor_id":{"description":"The monitor this incident is about (mon_…), or null for a manual incident.","type":["string","null"]},"source":{"type":"string","enum":["auto","manual"],"description":"\"auto\": opened by failed checks. \"manual\": created by a person or agent."},"title":{"type":"string","description":"Short headline, e.g. \"Checkout API is down\"."},"summary":{"type":"string","description":"One or two plain-English sentences: what failed, since when, and the last error. Safe to show to users."},"status":{"type":"string","enum":["investigating","identified","monitoring","resolved"],"description":"Where the incident stands: \"investigating\" (detected, cause unknown), \"identified\" (cause known), \"monitoring\" (fix applied, watching), \"resolved\" (over)."},"cause_code":{"description":"error_code of the check that confirmed the outage: status_mismatch, keyword_mismatch, timeout, dns_failure, connection_refused, connection_error, tls_error, blocked_address, blocked_port, too_many_redirects, invalid_redirect or invalid_url.","type":["string","null"]},"cause_message":{"description":"Plain-English error of that check, e.g. \"expected status 200-399, got 503\".","type":["string","null"]},"failed_regions":{"type":"array","items":{"type":"string"},"description":"Probe regions whose checks failed."},"started_at":{"type":"string","description":"When the outage started: the first failed check of the confirming streak. ISO 8601 UTC timestamp."},"resolved_at":{"description":"When it ended: the first successful check of the recovery (automatic), or when someone resolved it by hand. ISO 8601 UTC timestamp, or null.","type":["string","null"]},"resolved_by":{"anyOf":[{"type":"string","enum":["auto","manual"]},{"type":"null"}],"description":"\"auto\": checks recovered. \"manual\": a person or agent resolved it (it stays resolved even if checks still fail). null while open."},"duration_seconds":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"resolved_at minus started_at in seconds; null while open."},"created_at":{"type":"string","description":"When the incident record was created (when the outage was confirmed). ISO 8601 UTC timestamp."},"updated_at":{"type":"string","description":"When the incident last changed. ISO 8601 UTC timestamp."}},"required":["id","monitor_id","source","title","summary","status","cause_code","cause_message","failed_regions","started_at","resolved_at","resolved_by","duration_seconds","created_at","updated_at"],"additionalProperties":false,"description":"An outage of a monitor, from first failure to recovery.","examples":[{"id":"inc_0192f3a45b6c7d8e9f0123456789abcd","monitor_id":"mon_0192f3a45b6c7d8e9f0123456789abcd","source":"auto","title":"Checkout API is down","summary":"Checkout API (https://api.example.com/health) failed 3 checks in a row since 2026-10-11T12:00:00.000Z. Last error: expected status 200-399, got 503 (status_mismatch).","status":"investigating","cause_code":"status_mismatch","cause_message":"expected status 200-399, got 503","failed_regions":["default"],"started_at":"2026-10-11T12:00:00.000Z","resolved_at":null,"resolved_by":null,"duration_seconds":null,"created_at":"2026-10-11T12:00:41.000Z","updated_at":"2026-10-11T12:00:41.000Z"}]},"IncidentUpdate":{"type":"object","properties":{"id":{"type":"string","description":"Update id: \"upd_\" followed by 32 hex characters."},"status":{"type":"string","enum":["investigating","identified","monitoring","resolved"],"description":"Where the incident stands: \"investigating\" (detected, cause unknown), \"identified\" (cause known), \"monitoring\" (fix applied, watching), \"resolved\" (over)."},"message":{"type":"string","description":"What happened or what is being done, in plain text."},"author":{"type":"object","properties":{"type":{"type":"string","enum":["system","user","api_key"],"description":"\"system\": written by Chaukidar; \"user\": a person; \"api_key\": an agent or script."},"id":{"description":"usr_… or key_… id of the author; null for system.","type":["string","null"]}},"required":["type","id"],"additionalProperties":false,"description":"Who wrote the update."},"created_at":{"type":"string","description":"When the update was posted. ISO 8601 UTC timestamp."}},"required":["id","status","message","author","created_at"],"additionalProperties":false,"description":"One entry in an incident timeline."},"CheckResult":{"type":"object","properties":{"id":{"type":"string","description":"Check result id (a number, as a string)."},"region":{"type":"string","description":"Probe region that ran the check."},"scheduled_at":{"type":"string","description":"The time slot this check was scheduled for. ISO 8601 UTC timestamp."},"checked_at":{"type":"string","description":"When the probe started the check. ISO 8601 UTC timestamp."},"ok":{"type":"boolean","description":"True when the check passed (status, keyword and connection all fine)."},"status_code":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"HTTP status of the final response; null if none arrived."},"response_time_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Milliseconds until the final response headers arrived; null if none did."},"error_code":{"description":"Why the check failed (see Incident.cause_code for the values); null when ok.","type":["string","null"]},"error_message":{"description":"Plain-English reason for the failure; null when ok.","type":["string","null"]},"resolved_ip":{"description":"IP address the probe connected to; null if it never connected.","type":["string","null"]},"redirects":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Redirects followed (at most 5)."}},"required":["id","region","scheduled_at","checked_at","ok","status_code","response_time_ms","error_code","error_message","resolved_ip","redirects"],"additionalProperties":false,"description":"The outcome of one check of a monitor."},"IncidentDetail":{"type":"object","properties":{"id":{"type":"string","description":"Incident id: \"inc_\" followed by 32 hex characters."},"monitor_id":{"description":"The monitor this incident is about (mon_…), or null for a manual incident.","type":["string","null"]},"source":{"type":"string","enum":["auto","manual"],"description":"\"auto\": opened by failed checks. \"manual\": created by a person or agent."},"title":{"type":"string","description":"Short headline, e.g. \"Checkout API is down\"."},"summary":{"type":"string","description":"One or two plain-English sentences: what failed, since when, and the last error. Safe to show to users."},"status":{"type":"string","enum":["investigating","identified","monitoring","resolved"],"description":"Where the incident stands: \"investigating\" (detected, cause unknown), \"identified\" (cause known), \"monitoring\" (fix applied, watching), \"resolved\" (over)."},"cause_code":{"description":"error_code of the check that confirmed the outage: status_mismatch, keyword_mismatch, timeout, dns_failure, connection_refused, connection_error, tls_error, blocked_address, blocked_port, too_many_redirects, invalid_redirect or invalid_url.","type":["string","null"]},"cause_message":{"description":"Plain-English error of that check, e.g. \"expected status 200-399, got 503\".","type":["string","null"]},"failed_regions":{"type":"array","items":{"type":"string"},"description":"Probe regions whose checks failed."},"started_at":{"type":"string","description":"When the outage started: the first failed check of the confirming streak. ISO 8601 UTC timestamp."},"resolved_at":{"description":"When it ended: the first successful check of the recovery (automatic), or when someone resolved it by hand. ISO 8601 UTC timestamp, or null.","type":["string","null"]},"resolved_by":{"anyOf":[{"type":"string","enum":["auto","manual"]},{"type":"null"}],"description":"\"auto\": checks recovered. \"manual\": a person or agent resolved it (it stays resolved even if checks still fail). null while open."},"duration_seconds":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"resolved_at minus started_at in seconds; null while open."},"created_at":{"type":"string","description":"When the incident record was created (when the outage was confirmed). ISO 8601 UTC timestamp."},"updated_at":{"type":"string","description":"When the incident last changed. ISO 8601 UTC timestamp."},"updates":{"type":"array","items":{"$ref":"#/components/schemas/IncidentUpdate"},"description":"The incident timeline, oldest first."},"recent_checks":{"type":"array","items":{"$ref":"#/components/schemas/CheckResult"},"description":"The monitor's last 10 checks up to the end of the incident (or now), newest first."}},"required":["id","monitor_id","source","title","summary","status","cause_code","cause_message","failed_regions","started_at","resolved_at","resolved_by","duration_seconds","created_at","updated_at","updates","recent_checks"],"additionalProperties":false,"description":"An incident with its timeline and the checks around it.","examples":[{"id":"inc_0192f3a45b6c7d8e9f0123456789abcd","monitor_id":"mon_0192f3a45b6c7d8e9f0123456789abcd","source":"auto","title":"Checkout API is down","summary":"Checkout API (https://api.example.com/health) failed 3 checks in a row since 2026-10-11T12:00:00.000Z. Last error: expected status 200-399, got 503 (status_mismatch).","status":"investigating","cause_code":"status_mismatch","cause_message":"expected status 200-399, got 503","failed_regions":["default"],"started_at":"2026-10-11T12:00:00.000Z","resolved_at":null,"resolved_by":null,"duration_seconds":null,"created_at":"2026-10-11T12:00:41.000Z","updated_at":"2026-10-11T12:00:41.000Z","updates":[],"recent_checks":[]}]},"CreateIncidentUpdateResponse":{"type":"object","properties":{"update":{"description":"The update that was added.","$ref":"#/components/schemas/IncidentUpdate"},"incident":{"description":"The incident after the update.","$ref":"#/components/schemas/Incident"}},"required":["update","incident"],"additionalProperties":false,"description":"The new update and the incident as it is now.","examples":[{"update":{"id":"upd_0192f3a45b6c7d8e9f0123456789abce","status":"identified","message":"The primary database failed over; writes are recovering.","author":{"type":"api_key","id":"key_0192f3a45b6c7d8e9f0123456789abcf"},"created_at":"2026-10-11T12:05:00.000Z"},"incident":{"id":"inc_0192f3a45b6c7d8e9f0123456789abcd","monitor_id":"mon_0192f3a45b6c7d8e9f0123456789abcd","source":"auto","title":"Checkout API is down","summary":"Checkout API (https://api.example.com/health) failed 3 checks in a row since 2026-10-11T12:00:00.000Z. Last error: expected status 200-399, got 503 (status_mismatch).","status":"identified","cause_code":"status_mismatch","cause_message":"expected status 200-399, got 503","failed_regions":["default"],"started_at":"2026-10-11T12:00:00.000Z","resolved_at":null,"resolved_by":null,"duration_seconds":null,"created_at":"2026-10-11T12:00:41.000Z","updated_at":"2026-10-11T12:00:41.000Z"}}]},"IncidentList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Incident"},"description":"Incidents on this page, newest first."},"next_cursor":{"description":"Pass as ?cursor= for the next page; null on the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false,"description":"A page of incidents."},"CheckResultList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CheckResult"},"description":"Check results on this page, newest first."},"next_cursor":{"description":"Pass as ?cursor= for the next page; null on the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false,"description":"A page of check results."},"OverviewStats":{"type":"object","properties":{"monitors":{"type":"object","properties":{"total":{"type":"number","description":"Total active monitors in the workspace."},"up":{"type":"number","description":"Monitors currently operational and passing checks."},"down":{"type":"number","description":"Monitors currently experiencing an active outage."},"pending":{"type":"number","description":"Monitors awaiting their initial probe check."},"paused":{"type":"number","description":"Monitors currently paused by the team."}},"required":["total","up","down","pending","paused"],"additionalProperties":false,"description":"Monitor count breakdown by current lifecycle state."},"uptime_24h_percent":{"type":"number","description":"24-hour aggregate uptime percentage across all monitors (0 to 100)."},"avg_latency_ms":{"type":"number","description":"24-hour aggregate average probe latency in milliseconds."},"total_checks_24h":{"type":"number","description":"Total probe check executions recorded in the past 24 hours."},"open_incidents_count":{"type":"number","description":"Count of ongoing, unresolved incidents in this workspace."},"recent_incidents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Incident public id (inc_...)."},"title":{"type":"string","description":"Incident headline summary."},"status":{"type":"string","description":"Current status: investigating, identified, monitoring, or resolved."},"started_at":{"type":"string","description":"ISO timestamp when the outage was first confirmed."},"resolved_at":{"description":"ISO timestamp when the incident resolved, or null if open.","type":["string","null"]}},"required":["id","title","status","started_at","resolved_at"],"additionalProperties":false},"description":"Up to 5 latest incidents detected in the workspace."},"monitor_latencies":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":["number","null"]},"description":"Latest probe response time in milliseconds keyed by monitor public id (mon_...)."}},"required":["monitors","uptime_24h_percent","avg_latency_ms","total_checks_24h","open_incidents_count","recent_incidents","monitor_latencies"],"additionalProperties":false,"description":"Workspace health aggregates, 24-hour telemetry, and live probe latencies."},"StatusPageTheme":{"type":"object","properties":{"layout":{"default":"default","description":"Page layout. Only \"default\" for now; more layouts come later.","type":"string","enum":["default"]},"mode":{"default":"auto","description":"\"auto\" follows the visitor's system setting.","type":"string","enum":["light","dark","auto"]},"brand_color":{"default":"#1f6feb","description":"Header color, hex like #1f6feb. Text on it is black or white, whichever reads better.","type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accent_color":{"default":"#1f6feb","description":"Link color, hex.","type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"font":{"default":"system","description":"Font: system, serif, mono, rounded, humanist (system fonts; nothing is downloaded).","type":"string","enum":["system","serif","mono","rounded","humanist"]},"logo_url":{"default":null,"description":"Logo image (https), shown in the header instead of the title text.","anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"show_title_with_logo":{"default":true,"description":"Whether to display the title text next to the logo in the header.","type":"boolean"},"favicon_url":{"default":null,"description":"Favicon (https).","anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"header_links":{"default":[],"description":"Up to 5 links in the header, e.g. your website.","maxItems":5,"type":"array","items":{"type":"object","properties":{"label":{"type":"string","pattern":"^[^<>\\x00-\\x1f\\x7f]{1,40}$","description":"Link text."},"url":{"type":"string","maxLength":500,"description":"https:// or mailto: URL."}},"required":["label","url"],"additionalProperties":false}},"footer_links":{"default":[],"description":"Up to 10 links in the footer, e.g. support or privacy.","maxItems":10,"type":"array","items":{"type":"object","properties":{"label":{"type":"string","pattern":"^[^<>\\x00-\\x1f\\x7f]{1,40}$","description":"Link text."},"url":{"type":"string","maxLength":500,"description":"https:// or mailto: URL."}},"required":["label","url"],"additionalProperties":false}}},"required":["layout","mode","brand_color","accent_color","font","logo_url","show_title_with_logo","favicon_url","header_links","footer_links"],"additionalProperties":false,"description":"How the public page looks. Omitted fields take their default."},"PublicComponentV1":{"type":"object","properties":{"id":{"type":"string","description":"Component id: \"cmp_\" followed by 32 hex characters. Stable."},"name":{"type":"string","description":"Public name, e.g. \"Checkout\"."},"description":{"description":"Optional one-line description.","type":["string","null"]},"status":{"type":"string","enum":["up","down","unknown"],"description":"\"up\": working. \"down\": an open incident. \"unknown\": no data (no monitor, paused, or not checked yet)."},"since":{"description":"Since when the component has had this status. ISO 8601 UTC timestamp, or null.","type":["string","null"]}},"required":["id","name","description","status","since"],"additionalProperties":false},"PublicIncidentV1":{"type":"object","properties":{"id":{"type":"string","description":"Incident id: \"inc_\" followed by 32 hex characters. Stable."},"title":{"type":"string","description":"Public headline, e.g. \"Checkout outage\"."},"status":{"type":"string","enum":["investigating","identified","monitoring","resolved"],"description":"Where the incident stands."},"started_at":{"type":"string","description":"When it started. ISO 8601 UTC timestamp."},"resolved_at":{"description":"When it ended; null while open. ISO 8601 UTC timestamp, or null.","type":["string","null"]},"duration_seconds":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Length of the outage in seconds; null while open."},"affected_components":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"cmp_… id."},"name":{"type":"string","description":"Component name."}},"required":["id","name"],"additionalProperties":false},"description":"Components of this page affected by the incident."},"updates":{"type":"array","items":{"type":"object","properties":{"status":{"type":"string","description":"Status at the time of the update."},"message":{"type":"string","description":"What the team said (automatic updates are short generic sentences)."},"created_at":{"type":"string","description":"When it was posted. ISO 8601 UTC timestamp."}},"required":["status","message","created_at"],"additionalProperties":false},"description":"Timeline, oldest first."}},"required":["id","title","status","started_at","resolved_at","duration_seconds","affected_components","updates"],"additionalProperties":false},"PublicStatusV1":{"type":"object","properties":{"version":{"type":"number","const":1,"description":"Shape version. Fields may be added within version 1, never removed or changed."},"page":{"type":"object","properties":{"slug":{"type":"string","description":"The page address: /s/{slug}."},"title":{"type":"string","description":"Page title."},"description":{"description":"Page description.","type":["string","null"]},"url":{"type":"string","description":"The HTML page."},"theme":{"description":"The page theme, for rendering your own page in the same look.","$ref":"#/components/schemas/StatusPageTheme"}},"required":["slug","title","description","url","theme"],"additionalProperties":false},"overall":{"type":"string","enum":["up","degraded","down"],"description":"\"up\": nothing is down. \"degraded\": some components are down. \"down\": every component with a known status is down."},"components":{"type":"array","items":{"$ref":"#/components/schemas/PublicComponentV1"},"description":"In page order."},"active_incidents":{"type":"array","items":{"$ref":"#/components/schemas/PublicIncidentV1"},"description":"Open incidents, newest first."},"recent_incidents":{"type":"array","items":{"$ref":"#/components/schemas/PublicIncidentV1"},"description":"Resolved incidents of the last 90 days, newest first."},"uptime_90d":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","description":"UTC day, YYYY-MM-DD."},"pct":{"description":"Share of successful checks that day across the page's components, 0 to 100 (2 decimals); null without checks.","type":["number","null"]}},"required":["date","pct"],"additionalProperties":false},"description":"One entry per day, oldest first, the last one is today (90 entries)."},"generated_at":{"type":"string","description":"When this snapshot was made (responses are cached for up to 30 seconds). ISO 8601 UTC timestamp."}},"required":["version","page","overall","components","active_incidents","recent_incidents","uptime_90d","generated_at"],"additionalProperties":false,"description":"Current status of a public status page: overall, components, incidents and 90 days of uptime."},"PublicIncidentsV1":{"type":"object","properties":{"version":{"type":"number","const":1,"description":"Shape version."},"page":{"type":"object","properties":{"slug":{"type":"string","description":"The page address: /s/{slug}."},"title":{"type":"string","description":"Page title."},"description":{"description":"Page description.","type":["string","null"]},"url":{"type":"string","description":"The HTML page."}},"required":["slug","title","description","url"],"additionalProperties":false},"incidents":{"type":"array","items":{"$ref":"#/components/schemas/PublicIncidentV1"},"description":"Open incidents first, then those resolved in the last 90 days; newest first in each group."},"generated_at":{"type":"string","description":"When this snapshot was made. ISO 8601 UTC timestamp."}},"required":["version","page","incidents","generated_at"],"additionalProperties":false,"description":"Incident history of a public status page."},"StatusPage":{"type":"object","properties":{"id":{"type":"string","description":"Status page id: \"pg_\" followed by 32 hex characters."},"slug":{"type":"string","description":"Public address /s/{slug}."},"title":{"type":"string"},"description":{"type":["string","null"]},"is_public":{"type":"boolean","description":"false: the page and its JSON answer 404 to everyone."},"show_powered_by":{"type":"boolean","description":"Shows \"Powered by Chaukidar\" in the footer. Can be false only when the workspace limit hide_powered_by is true (paid plans)."},"theme":{"$ref":"#/components/schemas/StatusPageTheme"},"custom_css":{"description":"The custom CSS, or null.","type":["string","null"]},"allow_embedding":{"type":"boolean","description":"true lets other sites show the HTML page in an iframe (CSP frame-ancestors). Default false: no site may embed it."},"embed_domains":{"type":"array","items":{"type":"string"},"description":"Sites allowed to embed the page when allow_embedding is true; empty means any https site."},"public_url":{"type":"string","description":"The HTML page."},"status_json_url":{"type":"string","description":"The JSON status (for agents and your own front end)."},"created_at":{"type":"string","description":"When the page was created. ISO 8601 UTC timestamp."},"updated_at":{"type":"string","description":"When the page last changed. ISO 8601 UTC timestamp."}},"required":["id","slug","title","description","is_public","show_powered_by","theme","custom_css","allow_embedding","embed_domains","public_url","status_json_url","created_at","updated_at"],"additionalProperties":false,"description":"A public status page."},"StatusPageList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/StatusPage"}},"next_cursor":{"description":"Pass as ?cursor= for the next page; null on the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"StatusPageComponent":{"type":"object","properties":{"id":{"type":"string","description":"Component id: \"cmp_\" followed by 32 hex characters."},"status_page_id":{"type":"string","description":"The page (pg_…)."},"monitor_id":{"description":"The monitor whose state this component shows (mon_…), or null (status \"unknown\").","type":["string","null"]},"name":{"type":"string","description":"Public name. The monitor's own name and URL are never shown on the page."},"description":{"type":["string","null"]},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Order on the page, smallest first."},"created_at":{"type":"string","description":"When the component was added. ISO 8601 UTC timestamp."},"updated_at":{"type":"string","description":"When the component last changed. ISO 8601 UTC timestamp."}},"required":["id","status_page_id","monitor_id","name","description","position","created_at","updated_at"],"additionalProperties":false},"StatusPageComponentList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/StatusPageComponent"}}},"required":["data"],"additionalProperties":false},"Monitor":{"type":"object","properties":{"id":{"type":"string","description":"Monitor id: \"mon_\" followed by 32 hex characters. Use it in /v1/monitors/{id}."},"name":{"type":"string","description":"Human-readable label shown in alerts and on status pages. 1 to 100 characters."},"type":{"type":"string","enum":["http"],"description":"Kind of check. Only \"http\" exists today (covers http and https)."},"url":{"type":"string","description":"The URL being checked, normalised."},"method":{"type":"string","enum":["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"],"description":"HTTP method used for the check."},"request_header_names":{"type":"array","items":{"type":"string"},"description":"Names (lowercase, sorted) of the extra request headers sent with every check. Header values are secret: they are encrypted at rest and never returned. Set or replace them with request_headers on create or update."},"request_body":{"description":"Request body sent with every check, or null.","type":["string","null"]},"expected_status":{"type":"string","description":"Status codes and ranges that count as up, e.g. \"200-399\"."},"keyword":{"description":"Text looked for in the response body, or null.","type":["string","null"]},"keyword_mode":{"anyOf":[{"type":"string","enum":["present","absent"]},{"type":"null"}],"description":"Whether keyword must be present or absent; null when keyword is null."},"timeout_ms":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Response timeout in milliseconds."},"interval_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Seconds between checks."},"confirm_failures":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Consecutive failures needed to open an incident."},"confirm_recoveries":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Consecutive successes needed to resolve an incident."},"tags":{"type":"array","items":{"type":"string"},"description":"Labels for grouping and filtering monitors, shared by the workspace. Set them with tags on create or update."},"pinned":{"type":"boolean","description":"True when the monitor is pinned to the top of the dashboard for the workspace."},"regions":{"type":"array","items":{"type":"string"},"description":"Probe regions that run this check. Currently always [\"default\"]; multi-region arrives later."},"paused":{"type":"boolean","description":"True when checks are stopped. Change it with POST /v1/monitors/{id}/pause and /resume."},"state":{"type":"string","enum":["pending","up","down","paused"],"description":"\"pending\": no confirmed result yet (new, edited or just resumed). \"up\": last confirmed result was healthy. \"down\": failures confirmed and an incident is open. \"paused\": not being checked."},"last_checked_at":{"description":"When the last check ran; null if it never ran. ISO 8601 UTC timestamp, or null.","type":["string","null"]},"next_check_at":{"description":"When the next check is due; null while paused. ISO 8601 UTC timestamp, or null.","type":["string","null"]},"created_at":{"type":"string","description":"When the monitor was created. ISO 8601 UTC timestamp."},"updated_at":{"type":"string","description":"When the monitor settings last changed. ISO 8601 UTC timestamp."}},"required":["id","name","type","url","method","request_header_names","request_body","expected_status","keyword","keyword_mode","timeout_ms","interval_seconds","confirm_failures","confirm_recoveries","tags","pinned","regions","paused","state","last_checked_at","next_check_at","created_at","updated_at"],"additionalProperties":false,"description":"An HTTP uptime monitor.","examples":[{"id":"mon_0192f3a45b6c7d8e9f0123456789abcd","name":"Checkout API","type":"http","url":"https://api.example.com/health","method":"GET","request_header_names":["authorization"],"request_body":null,"expected_status":"200-299","keyword":"\"status\":\"ok\"","keyword_mode":"present","timeout_ms":10000,"interval_seconds":300,"confirm_failures":3,"confirm_recoveries":2,"tags":["production","api"],"pinned":false,"regions":["default"],"paused":false,"state":"pending","last_checked_at":null,"next_check_at":"2026-10-11T12:00:00.000Z","created_at":"2026-10-11T12:00:00.000Z","updated_at":"2026-10-11T12:00:00.000Z"}]},"MonitorList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Monitor"},"description":"Monitors on this page, newest first."},"next_cursor":{"description":"Pass as ?cursor= to get the next page. null when this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false,"description":"A page of monitors."},"SlaReport":{"type":"object","properties":{"period":{"type":"string","description":"Reporting period identifier."},"from":{"type":"string","description":"Window start timestamp (ISO)."},"to":{"type":"string","description":"Window end timestamp (ISO)."},"target_sla_percent":{"type":"number","description":"Target SLA percentage."},"total_monitors":{"type":"number","description":"Total active monitors in scope."},"summary":{"type":"object","properties":{"availability_percent":{"type":"number","description":"Calculated aggregate uptime percentage (0-100)."},"target_sla_percent":{"type":"number","description":"Configured target SLA."},"status":{"description":"Compliance status against target SLA.","type":"string","enum":["compliant","breached"]},"sla_status":{"type":"string","enum":["met","breached"],"description":"Whether current availability meets or breaches target SLA."},"total_downtime_seconds":{"type":"number","description":"Cumulative outage duration across all monitors in seconds."},"total_downtime_formatted":{"type":"string","description":"Human-readable total downtime."},"allowed_downtime_seconds":{"type":"number","description":"Permissible downtime before breaching target SLA."},"allowed_downtime_formatted":{"description":"Human-readable allowed downtime.","type":"string"},"error_budget_remaining_seconds":{"type":"number","description":"Remaining error budget in seconds (can be negative if breached)."},"error_budget_remaining_formatted":{"description":"Human-readable error budget remaining.","type":"string"},"error_budget_used_percent":{"type":"number","description":"Percentage of error budget consumed."},"error_budget_burn_percent":{"description":"Error budget consumption percentage.","type":"number"},"total_incidents":{"type":"number","description":"Total confirmed outages in reporting window."},"mttr_seconds":{"description":"Mean Time to Resolution in seconds.","type":["number","null"]},"mttr_formatted":{"type":"string","description":"Human-readable MTTR."},"mtbf_seconds":{"description":"Mean Time Between Failures in seconds.","type":["number","null"]},"mtbf_formatted":{"type":"string","description":"Human-readable MTBF."}},"required":["availability_percent","target_sla_percent","sla_status","total_downtime_seconds","total_downtime_formatted","allowed_downtime_seconds","error_budget_remaining_seconds","error_budget_used_percent","total_incidents","mttr_seconds","mttr_formatted","mtbf_seconds","mtbf_formatted"],"additionalProperties":false},"monitors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"monitor_id":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"state":{"type":"string"},"status":{"type":"string","enum":["compliant","breached"]},"uptime_percent":{"type":"number"},"total_downtime_seconds":{"type":"number"},"downtime_formatted":{"type":"string"},"incidents_count":{"type":"number"},"resolved_count":{"type":"number"},"mttr_seconds":{"type":["number","null"]},"mttr_formatted":{"type":"string"}},"required":["id","name","url","state","uptime_percent","total_downtime_seconds","downtime_formatted","incidents_count","mttr_seconds","mttr_formatted"],"additionalProperties":false}},"daily_timeline":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"uptime_percent":{"type":"number"},"downtime_seconds":{"type":"number"},"incidents_count":{"type":"number"}},"required":["date","uptime_percent","downtime_seconds","incidents_count"],"additionalProperties":false}}},"required":["period","from","to","target_sla_percent","total_monitors","summary","monitors","daily_timeline"],"additionalProperties":false,"description":"Enterprise SLA compliance and reliability analytics."}}}}