{"openapi": "3.1.0", "info": {"title": "Fettle Public API", "version": "1.3.1", "description": "The Fettle public API lets you manage monitors, heartbeats and maintenance\nwindows programmatically, read incidents and status pages (and acknowledge\nan incident), using an API key instead of a user session.\n\n## Authentication\n\nCreate a key under **Settings \u2192 API Keys** in the dashboard. Send it on every\nrequest as:\n\n```\nAuthorization: Bearer fettle_...\n```\n\nA key is bound to one organization, and every operation below acts on that\norganization \u2014 there is nothing to select per request.\n\n## Scopes\n\nEach key is issued with one or both scopes:\n\n- **read** \u2014 every `GET` operation on this document.\n- **write** \u2014 every operation that creates, updates, deletes or otherwise\n  changes state (`POST`, `PATCH`, `DELETE`).\n\nA key without the scope an operation requires is rejected with `403`. Each\noperation's raw JSON also carries `x-fettle-public-api: read` or `write`,\nnaming exactly the scope it needs \u2014 the reference below does not render this\nfield, but it is there for anyone reading the document directly.\n\n## Rate limits\n\nRequests are rate-limited per organization, not per key: all keys belonging\nto the same organization share one bucket, sized by that organization's plan.\nA successful response, and a `429` from this bucket, carry the current\npacing:\n\n- `X-RateLimit-Limit` \u2014 requests allowed in the current window.\n- `X-RateLimit-Remaining` \u2014 requests left in the current window.\n- `X-RateLimit-Reset` \u2014 unix timestamp when the window resets.\n\nA `429` from this bucket also carries a `Retry-After` header (seconds to\nwait) and a JSON body of the form:\n\n```json\n{\"error\": \"Too Many Requests\", \"message\": \"API rate limit exceeded\", \"retry_after\": 12}\n```\n\nA `401` (missing, malformed or invalid key) carries none of the above: an\nauthentication failure is deliberately silent about rate-limit state and\nabout whether the presented key was even recognized.\n"}, "servers": [{"url": "https://api.fettle.sh"}], "tags": [{"name": "Monitors", "description": "Checks Fettle runs against your endpoints from several regions: create and configure them, read their status and uptime, pause or resume them, or force a check right now."}, {"name": "Tags", "description": "Flat labels such as env:prod, shared by monitors and heartbeats in one per-organization dictionary. List the tags in use with how many monitors and heartbeats carry each, rename a tag everywhere it appears (merging it into a tag an item already has), or remove it from every monitor and heartbeat at once."}, {"name": "Heartbeats", "description": "The inverse of a monitor: your job pings Fettle on a schedule, and Fettle alerts when a ping does not arrive in time. For cron jobs, backups and workers that nothing can reach from outside."}, {"name": "Plans", "description": "The organization's subscription tier, the limits it brings, and how much of them is used right now: read it before creating monitors in bulk instead of guessing at quotas."}, {"name": "Channels", "description": "Where alerts are delivered. Read-only: list the organization's channels with their ids so they can be bound to monitors and heartbeats. Delivery secrets are never returned; create and edit channels in the dashboard."}, {"name": "Maintenance Windows", "description": "Planned downtime. Alerts are suppressed for the monitors a window covers, on a one-off or recurring (iCal RRULE) schedule in the organization's own timezone."}, {"name": "Incidents", "description": "What Fettle opens when a monitor goes down and closes when it recovers. Read them, and acknowledge one to stop its re-notifications."}, {"name": "Status pages", "description": "The public page your users read during an outage. Pages are composed in the dashboard; here you read them and post, update or delete their manual incidents."}, {"name": "Regions", "description": "The regions checks can run from: the codes accepted in a monitor's regions, in display order."}], "paths": {"/v1/heartbeats/{heartbeat_id}/pause": {"post": {"tags": ["Heartbeats"], "summary": "Pause Heartbeat", "description": "Pause liveness tracking for the heartbeat.", "operationId": "pause_heartbeat", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "heartbeat_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Heartbeat Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HeartbeatRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/maintenance-windows/{window_id}": {"patch": {"tags": ["Maintenance Windows"], "summary": "Update Maintenance Window", "description": "Update fields on a maintenance window.", "operationId": "update_maintenance_window", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "window_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Window Id"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MaintenanceWindowUpdate"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MaintenanceWindowRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}, "delete": {"tags": ["Maintenance Windows"], "summary": "Delete Maintenance Window", "description": "Delete a maintenance window.", "operationId": "delete_maintenance_window", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "window_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Window Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SuccessResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}, "get": {"tags": ["Maintenance Windows"], "summary": "Get Maintenance Window", "description": "Return a single maintenance window by id, with its next occurrences.", "operationId": "get_maintenance_window", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "window_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Window Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MaintenanceWindowDetailRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/heartbeats/{heartbeat_id}": {"delete": {"tags": ["Heartbeats"], "summary": "Delete Heartbeat", "description": "Delete a heartbeat.", "operationId": "delete_heartbeat", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "heartbeat_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Heartbeat Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SuccessResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}, "patch": {"tags": ["Heartbeats"], "summary": "Update Heartbeat", "description": "Update fields on a heartbeat.", "operationId": "update_heartbeat", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "heartbeat_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Heartbeat Id"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HeartbeatUpdate"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HeartbeatRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}, "get": {"tags": ["Heartbeats"], "summary": "Get Heartbeat", "description": "Return a single heartbeat by id.", "operationId": "get_heartbeat", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "heartbeat_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Heartbeat Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HeartbeatRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/monitors/{monitor_id}/uptime-daily": {"get": {"tags": ["Monitors"], "summary": "Get Monitor Uptime Daily", "description": "Return the daily uptime series for a monitor over the last N days.\n\nDays with nothing observed (before the monitor was created, or any gap)\nare returned as explicit no-data points so the strip never shows uptime\nthe monitor did not record. Days are UTC calendar days.", "operationId": "get_monitor_uptime_daily", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Monitor Id"}}, {"name": "days", "in": "query", "required": false, "schema": {"type": "integer", "maximum": 365, "minimum": 1, "default": 30, "title": "Days"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorUptimeDailyResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/monitors/{monitor_id}/response-time-by-region": {"get": {"tags": ["Monitors"], "summary": "Get Monitor Response Time By Region", "description": "Return the per-region response-time series for a monitor.\n\nEach region is returned as its own dense, evenly-spaced series so the card\ncan plot one region at a time on an axis scaled to that region's baseline \u2014\na fast region and a slow region never share an axis. ``window`` selects the\nspan and point granularity (24h hourly, 7d six-hourly, 30d daily).", "operationId": "get_monitor_response_time_by_region", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Monitor Id"}}, {"name": "window", "in": "query", "required": false, "schema": {"enum": ["24h", "7d", "30d"], "type": "string", "default": "24h", "title": "Window"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorResponseTimeByRegionResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/heartbeats/{heartbeat_id}/resume": {"post": {"tags": ["Heartbeats"], "summary": "Resume Heartbeat", "description": "Resume a paused heartbeat.", "operationId": "resume_heartbeat", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "heartbeat_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Heartbeat Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HeartbeatRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/monitors/bulk": {"post": {"tags": ["Monitors"], "summary": "Bulk Create Monitors", "description": "Create up to 100 monitors in one request.\n\nAll of them are created or none is: an invalid monitor, or a batch that\nwould exceed your plan's monitor limits, rejects the whole request.\n\nA field that fails request validation is reported with its position, for\nexample `body.monitors.3.target`. Any other rejection of one monitor (its\nconfig, interval, regions or channels) keeps its usual status code, and\nthe message starts with `monitors[3] (\"<name>\"): ` so you can tell which\none failed.", "operationId": "bulk_create_monitors", "security": [{"ApiKeyBearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkMonitorCreateRequest"}}}}, "responses": {"201": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkMonitorCreateResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}, "patch": {"tags": ["Monitors"], "summary": "Bulk Update Monitors", "description": "Change the interval, timeout, regions, notification channels, confirmation\nthreshold or notification cooldown of up to 100 monitors at once.\n\nThe same values go to every listed monitor; omitted fields stay unchanged\nand `null` is refused. All of them change or none does: an unknown\nmonitor or channel, a value your plan does not allow, or a value one\nmonitor's type does not accept rejects the whole request. A problem with\none monitor names it, for example `monitors[3] (\"API\"): `.", "operationId": "bulk_update_monitors", "security": [{"ApiKeyBearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkMonitorUpdateRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkMonitorStateResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/monitors/presets/exposed-ports": {"get": {"tags": ["Monitors"], "summary": "Get Exposed Ports Preset", "description": "List ports that should not be reachable from the internet.\n\nWatch them with one TCP monitor on your server's host:\n`config: {\"ports\": [...], \"expected_state\": \"closed\"}`, one region, an\ninterval of at least 300 seconds. Any of them answering opens an incident.", "operationId": "get_exposed_ports_preset", "security": [{"ApiKeyBearer": []}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExposedPortsPresetResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/monitors/{monitor_id}": {"get": {"tags": ["Monitors"], "summary": "Get Monitor", "description": "Return a single monitor by id.", "operationId": "get_monitor", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Monitor Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}, "delete": {"tags": ["Monitors"], "summary": "Delete Monitor", "description": "Delete a monitor.", "operationId": "delete_monitor", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Monitor Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SuccessResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}, "patch": {"tags": ["Monitors"], "summary": "Update Monitor", "description": "Update fields on a monitor.\n\nPlan limits apply as on create; moving a monitor below 60 seconds counts\ntoward the plan's fast-interval quota.", "operationId": "update_monitor", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Monitor Id"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorUpdate"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/status-pages/{page_id}": {"get": {"tags": ["Status pages"], "summary": "Get Status Page", "description": "Return a single status page and its layout.", "operationId": "get_status_page", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "page_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Page Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/StatusPageRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/status-pages/{page_id}/incidents/{incident_id}/updates": {"post": {"tags": ["Status pages"], "summary": "Post Page Incident Update", "description": "Post a timeline update on a public incident.", "operationId": "post_page_incident_update", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "page_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Page Id"}}, {"name": "incident_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Incident Id"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PageIncidentUpdateCreate"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PageIncidentRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/monitors/summary": {"get": {"tags": ["Monitors"], "summary": "Get Monitors Summary", "description": "Return monitor counts by status and 30-day uptime for the active organization.", "operationId": "get_monitors_summary", "security": [{"ApiKeyBearer": []}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorsSummaryResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/monitors/bulk/resume": {"post": {"tags": ["Monitors"], "summary": "Bulk Resume Monitors", "description": "Resume up to 100 paused monitors at once.\n\nAll of them are resumed or none is: an unknown id, or more active monitors\nthan your plan allows, rejects the whole request. Resuming a monitor that\nis already running is not an error.", "operationId": "bulk_resume_monitors", "security": [{"ApiKeyBearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkMonitorIdsRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkMonitorStateResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/maintenance-windows/active": {"get": {"tags": ["Maintenance Windows"], "summary": "List Active Maintenance Windows", "description": "List the organization's maintenance windows that are currently active.", "operationId": "list_active_maintenance_windows", "security": [{"ApiKeyBearer": []}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"type": "array", "items": {"$ref": "#/components/schemas/MaintenanceWindowRead"}, "title": "Response List Active Maintenance Windows V1 Maintenance Windows Active Get"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/heartbeats/minimal": {"get": {"tags": ["Heartbeats"], "summary": "List Minimal Heartbeats", "description": "List compact heartbeat rows for selector controls.", "operationId": "list_minimal_heartbeats", "security": [{"ApiKeyBearer": []}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"type": "array", "items": {"$ref": "#/components/schemas/HeartbeatMinimalRead"}, "title": "Response List Minimal Heartbeats V1 Heartbeats Minimal Get"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/maintenance-windows/{window_id}/effective": {"get": {"tags": ["Maintenance Windows"], "summary": "Get Effective Maintenance Window", "description": "Return the window's schedule as it was effective at the given instant.", "operationId": "get_effective_maintenance_window", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "window_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Window Id"}}, {"name": "at", "in": "query", "required": true, "schema": {"type": "string", "format": "date-time", "title": "At"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MaintenanceWindowRevisionRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/monitors/tags": {"post": {"tags": ["Monitors"], "summary": "Bulk Update Monitor Tags", "description": "Add or remove tags across several monitors at once.\n\nEvery listed monitor must belong to your organization. The change is\napplied to all of them or to none: an unknown monitor, or a monitor that\nwould end up with more than 10 tags, rejects the whole request.", "operationId": "bulk_update_monitor_tags", "security": [{"ApiKeyBearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkMonitorTagsRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkMonitorTagsResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/incidents/{incident_id}": {"get": {"tags": ["Incidents"], "summary": "Get Incident", "description": "Return a single incident by id.", "operationId": "get_incident", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "incident_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Incident Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IncidentRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/heartbeats": {"get": {"tags": ["Heartbeats"], "summary": "List Heartbeats", "description": "List heartbeats for the active organization, optionally filtered by a\nsearch query and by tags: with `tag_match=all` (default) a heartbeat must\ncarry every tag given, with `tag_match=any` at least one. Ordered by the\ngiven sort option (problems-first by default).", "operationId": "list_heartbeats", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "q", "in": "query", "required": false, "schema": {"anyOf": [{"type": "string", "maxLength": 255}, {"type": "null"}], "title": "Q"}}, {"name": "sort", "in": "query", "required": false, "schema": {"$ref": "#/components/schemas/HeartbeatSortOption", "default": "status"}}, {"name": "tag", "in": "query", "required": false, "schema": {"anyOf": [{"type": "array", "items": {"type": "string", "maxLength": 50}, "maxItems": 10}, {"type": "null"}], "title": "Tag"}}, {"name": "tag_match", "in": "query", "required": false, "schema": {"$ref": "#/components/schemas/TagMatchMode", "default": "all"}}, {"name": "page", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 1, "default": 1, "title": "Page"}}, {"name": "size", "in": "query", "required": false, "schema": {"type": "integer", "maximum": 100, "minimum": 1, "default": 25, "title": "Size"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PaginatedResponse_HeartbeatRead_"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}, "post": {"tags": ["Heartbeats"], "summary": "Create Heartbeat", "description": "Create a new heartbeat for the active organization.", "operationId": "create_heartbeat", "security": [{"ApiKeyBearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HeartbeatCreate"}}}}, "responses": {"201": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HeartbeatRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/monitors/{monitor_id}/pause": {"post": {"tags": ["Monitors"], "summary": "Pause Monitor", "description": "Pause checks for the monitor.", "operationId": "pause_monitor", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Monitor Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/maintenance-windows/preview": {"post": {"tags": ["Maintenance Windows"], "summary": "Preview Maintenance Window", "description": "Preview the next occurrences of a draft maintenance schedule.", "operationId": "preview_maintenance_window", "security": [{"ApiKeyBearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MaintenanceWindowPreviewRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"type": "array", "items": {"$ref": "#/components/schemas/OccurrenceRead"}, "title": "Response Preview Maintenance Window V1 Maintenance Windows Preview Post"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/monitors/{monitor_id}/stats": {"get": {"tags": ["Monitors"], "summary": "Get Monitor Stats", "description": "Return uptime statistics for a monitor over the 24h, 7d, and 30d windows.", "operationId": "get_monitor_stats", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Monitor Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorStatsResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/tags": {"get": {"tags": ["Tags"], "summary": "List Tags", "description": "List the tags used in this organization, with how many monitors and\nheartbeats carry each one. Most-used first.", "operationId": "list_tags", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "kind", "in": "query", "required": false, "schema": {"$ref": "#/components/schemas/TagKind", "default": "all"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TagListResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}, "delete": {"tags": ["Tags"], "summary": "Delete Tag", "description": "Remove a tag from every monitor and heartbeat that carries it. The tag\nitself disappears from the organization once nothing uses it.", "operationId": "delete_tag", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "tag", "in": "query", "required": true, "schema": {"type": "string", "minLength": 1, "title": "Tag"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TagDeleteResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}, "patch": {"tags": ["Tags"], "summary": "Rename Tag", "description": "Rename a tag on every monitor and heartbeat that carries it. Renaming to\na tag an item already has merges the two rather than duplicating.", "operationId": "rename_tag", "security": [{"ApiKeyBearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TagRenameRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TagMutationResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/channels/directory": {"get": {"tags": ["Channels"], "summary": "List Channel Directory", "description": "List the organization's notification channels with their ids, so they can\nbe bound to monitors and heartbeats. Delivery URLs are shortened to their\nhost. Email is not listed: every alert also goes to the account email of the\nuser who created the monitor or heartbeat.", "operationId": "list_channel_directory", "security": [{"ApiKeyBearer": []}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"type": "array", "items": {"$ref": "#/components/schemas/NotificationChannelDirectoryRead"}, "title": "Response List Channel Directory V1 Channels Directory Get"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/incidents": {"get": {"tags": ["Incidents"], "summary": "List Incidents", "description": "List incidents across the active organization's monitors, filtered by status, cause, period.", "operationId": "list_incidents", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "query", "required": false, "schema": {"anyOf": [{"type": "string", "format": "uuid"}, {"type": "null"}], "title": "Monitor Id"}}, {"name": "status", "in": "query", "required": false, "schema": {"anyOf": [{"$ref": "#/components/schemas/IncidentStatusFilter"}, {"type": "null"}], "description": "Filter by open or resolved; omit for both.", "title": "Status"}, "description": "Filter by open or resolved; omit for both."}, {"name": "cause", "in": "query", "required": false, "schema": {"anyOf": [{"$ref": "#/components/schemas/IncidentCause"}, {"type": "null"}], "description": "Filter by structured failure cause.", "title": "Cause"}, "description": "Filter by structured failure cause."}, {"name": "period_days", "in": "query", "required": false, "schema": {"anyOf": [{"type": "integer", "maximum": 365, "minimum": 1}, {"type": "null"}], "description": "Only incidents that were active within the last N days. An incident still open is always included, whenever it started. Combined with status=open this makes period_days a no-op, since every open incident already satisfies that arm \u2014 use status=resolved or omit status to see the window take effect.", "title": "Period Days"}, "description": "Only incidents that were active within the last N days. An incident still open is always included, whenever it started. Combined with status=open this makes period_days a no-op, since every open incident already satisfies that arm \u2014 use status=resolved or omit status to see the window take effect."}, {"name": "page", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 1, "default": 1, "title": "Page"}}, {"name": "size", "in": "query", "required": false, "schema": {"type": "integer", "maximum": 100, "minimum": 1, "default": 25, "title": "Size"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PaginatedResponse_IncidentRead_"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/incidents/summary": {"get": {"tags": ["Incidents"], "summary": "Get Incident Summary", "description": "Return total, open, and resolved incident counts for the organization.", "operationId": "get_incident_summary", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "query", "required": false, "schema": {"anyOf": [{"type": "string", "format": "uuid"}, {"type": "null"}], "title": "Monitor Id"}}, {"name": "cause", "in": "query", "required": false, "schema": {"anyOf": [{"$ref": "#/components/schemas/IncidentCause"}, {"type": "null"}], "title": "Cause"}}, {"name": "period_days", "in": "query", "required": false, "schema": {"anyOf": [{"type": "integer", "maximum": 365, "minimum": 1}, {"type": "null"}], "title": "Period Days"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IncidentSummaryRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/monitors/{monitor_id}/check-now": {"post": {"tags": ["Monitors"], "summary": "Check Now Monitor", "description": "Run this monitor on the next scheduler tick instead of waiting for its interval.\n\nRepeat requests for the same monitor within 30 seconds return it unchanged.\nAcross monitors the endpoint is limited per user; over the limit it answers\n429 with a `Retry-After` header.", "operationId": "check_now_monitor", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Monitor Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/monitors/precheck": {"post": {"tags": ["Monitors"], "summary": "Precheck Monitor Target", "description": "Probe a target once before creating a monitor to flag if it looks down.", "operationId": "precheck_monitor_target", "security": [{"ApiKeyBearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorPrecheckRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorPrecheckResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/monitors": {"get": {"tags": ["Monitors"], "summary": "List Monitors", "description": "List monitors for the active organization.\n\nFilter by search text, by type and by status (repeat a parameter to allow\nseveral values), and by tags: with `tag_match=all` (default) a monitor must\ncarry every tag given, with `tag_match=any` at least one. Problems come\nfirst by default; `sort=ssl_expiry` puts the soonest-expiring certificates\nfirst. `view=compact` returns short rows without configuration or uptime\nhistory.", "operationId": "list_monitors", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "q", "in": "query", "required": false, "schema": {"anyOf": [{"type": "string", "maxLength": 255}, {"type": "null"}], "title": "Q"}}, {"name": "sort", "in": "query", "required": false, "schema": {"$ref": "#/components/schemas/MonitorSortOption", "default": "status"}}, {"name": "tag", "in": "query", "required": false, "schema": {"anyOf": [{"type": "array", "items": {"type": "string", "maxLength": 50}, "maxItems": 10}, {"type": "null"}], "title": "Tag"}}, {"name": "tag_match", "in": "query", "required": false, "schema": {"$ref": "#/components/schemas/TagMatchMode", "default": "all"}}, {"name": "type", "in": "query", "required": false, "schema": {"anyOf": [{"type": "array", "items": {"$ref": "#/components/schemas/CheckType"}}, {"type": "null"}], "title": "Type"}}, {"name": "status", "in": "query", "required": false, "schema": {"anyOf": [{"type": "array", "items": {"$ref": "#/components/schemas/MonitorStatus"}}, {"type": "null"}], "title": "Status"}}, {"name": "view", "in": "query", "required": false, "schema": {"$ref": "#/components/schemas/MonitorListView", "default": "full"}}, {"name": "page", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 1, "default": 1, "title": "Page"}}, {"name": "size", "in": "query", "required": false, "schema": {"type": "integer", "maximum": 100, "minimum": 1, "default": 25, "title": "Size"}}], "responses": {"200": {"description": "A page of monitors: full rows by default, compact rows for `view=compact`.", "content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/PaginatedResponse_MonitorListRead_"}, {"$ref": "#/components/schemas/PaginatedResponse_MonitorCompactRead_"}], "title": "Response 200 List Monitors V1 Monitors Get"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}, "post": {"tags": ["Monitors"], "summary": "Create Monitor", "description": "Create a new monitor for the active organization.\n\nPlan limits apply to the monitor count, the minimum interval, monitors\nchecked more often than every 60 seconds and the number of regions;\n`GET /v1/plans/usage` shows them and what is left. Send `is_active: false`\nto create it paused \u2014 no check runs until you resume it.", "operationId": "create_monitor", "security": [{"ApiKeyBearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorCreate"}}}}, "responses": {"201": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/maintenance-windows": {"post": {"tags": ["Maintenance Windows"], "summary": "Create Maintenance Window", "description": "Create a maintenance window for the active organization.", "operationId": "create_maintenance_window", "security": [{"ApiKeyBearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MaintenanceWindowCreate"}}}}, "responses": {"201": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MaintenanceWindowRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}, "get": {"tags": ["Maintenance Windows"], "summary": "List Maintenance Windows", "description": "List the active organization's maintenance windows, optionally filtered by name.", "operationId": "list_maintenance_windows", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "q", "in": "query", "required": false, "schema": {"anyOf": [{"type": "string", "maxLength": 255}, {"type": "null"}], "title": "Q"}}, {"name": "sort", "in": "query", "required": false, "schema": {"$ref": "#/components/schemas/MaintenanceSortOption", "default": "created_at"}}, {"name": "page", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 1, "default": 1, "title": "Page"}}, {"name": "size", "in": "query", "required": false, "schema": {"type": "integer", "maximum": 100, "minimum": 1, "default": 25, "title": "Size"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PaginatedResponse_MaintenanceWindowRead_"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/monitors/minimal": {"get": {"tags": ["Monitors"], "summary": "List Minimal Monitors", "description": "List compact monitor rows for selector controls.\n\nThe response carries an `ETag`; send it back in `If-None-Match` to get\n`304 Not Modified` while the catalog is unchanged.", "operationId": "list_minimal_monitors", "security": [{"ApiKeyBearer": []}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"type": "array", "items": {"$ref": "#/components/schemas/MonitorMinimalRead"}, "title": "Response List Minimal Monitors V1 Monitors Minimal Get"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/status-pages": {"get": {"tags": ["Status pages"], "summary": "List Status Pages", "description": "List the active organization's status pages.", "operationId": "list_status_pages", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "sort", "in": "query", "required": false, "schema": {"$ref": "#/components/schemas/StatusPageSortOption", "default": "created_at"}}, {"name": "page", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 1, "default": 1, "title": "Page"}}, {"name": "size", "in": "query", "required": false, "schema": {"type": "integer", "maximum": 100, "minimum": 1, "default": 25, "title": "Size"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PaginatedResponse_StatusPageRead_"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/status-pages/{page_id}/incidents": {"post": {"tags": ["Status pages"], "summary": "Create Page Incident", "description": "Publish a manual incident on a status page.", "operationId": "create_page_incident", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "page_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Page Id"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PageIncidentCreate"}}}}, "responses": {"201": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PageIncidentRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}, "get": {"tags": ["Status pages"], "summary": "List Page Incidents", "description": "List a status page's manual and automatic incidents.", "operationId": "list_page_incidents", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "page_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Page Id"}}, {"name": "page", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 1, "default": 1, "title": "Page"}}, {"name": "size", "in": "query", "required": false, "schema": {"type": "integer", "maximum": 100, "minimum": 1, "default": 25, "title": "Size"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PaginatedResponse_PageIncidentRead_"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/regions": {"get": {"tags": ["Regions"], "summary": "List Regions", "description": "Return the check regions available across the platform.", "operationId": "list_regions", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RegionsResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read", "security": [{"ApiKeyBearer": []}]}}, "/v1/monitors/{monitor_id}/check-results": {"get": {"tags": ["Monitors"], "summary": "List Check Results", "description": "List recent check results for a monitor.", "operationId": "list_check_results", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Monitor Id"}}, {"name": "region", "in": "query", "required": false, "schema": {"anyOf": [{"type": "string", "maxLength": 64}, {"type": "null"}], "title": "Region"}}, {"name": "status", "in": "query", "required": false, "schema": {"anyOf": [{"$ref": "#/components/schemas/CheckResultStatus"}, {"type": "null"}], "title": "Status"}}, {"name": "period_days", "in": "query", "required": false, "schema": {"anyOf": [{"type": "integer", "maximum": 365, "minimum": 1}, {"type": "null"}], "title": "Period Days"}}, {"name": "page", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 1, "default": 1, "title": "Page"}}, {"name": "size", "in": "query", "required": false, "schema": {"type": "integer", "maximum": 100, "minimum": 1, "default": 25, "title": "Size"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PaginatedResponse_CheckResultRead_"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/status-pages/{page_id}/incidents/{incident_id}": {"delete": {"tags": ["Status pages"], "summary": "Delete Page Incident", "description": "Delete a public incident from a status page.", "operationId": "delete_page_incident", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "page_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Page Id"}}, {"name": "incident_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Incident Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SuccessResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}, "patch": {"tags": ["Status pages"], "summary": "Update Page Incident", "description": "Rename a public incident.", "operationId": "update_page_incident", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "page_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Page Id"}}, {"name": "incident_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Incident Id"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PageIncidentPatch"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PageIncidentRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/plans/usage": {"get": {"tags": ["Plans"], "summary": "Get Plan Usage", "description": "Return your organization's plan, its limits, and how much of it you use.", "operationId": "get_plan_usage", "security": [{"ApiKeyBearer": []}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanUsageResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "read"}}, "/v1/monitors/{monitor_id}/resume": {"post": {"tags": ["Monitors"], "summary": "Resume Monitor", "description": "Resume a paused monitor.\n\nFails when the plan's monitor limit is already reached by active monitors.", "operationId": "resume_monitor", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "monitor_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Monitor Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MonitorRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/incidents/{incident_id}/acknowledge": {"post": {"tags": ["Incidents"], "summary": "Acknowledge Incident", "description": "Mark an incident as acknowledged.", "operationId": "acknowledge_incident", "security": [{"ApiKeyBearer": []}], "parameters": [{"name": "incident_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Incident Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IncidentRead"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}, "/v1/monitors/bulk/pause": {"post": {"tags": ["Monitors"], "summary": "Bulk Pause Monitors", "description": "Pause up to 100 monitors at once.\n\nEvery listed monitor must belong to your organization; one unknown id\nrejects the whole request. Pausing closes a monitor's open incident without\nan alert. Pausing an already paused monitor is not an error.", "operationId": "bulk_pause_monitors", "security": [{"ApiKeyBearer": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkMonitorIdsRequest"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkMonitorStateResponse"}}}, "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}, "429": {"$ref": "#/components/responses/RateLimited"}}, "x-fettle-public-api": "write"}}}, "components": {"responses": {"Unauthorized": {"description": "No key, a malformed `Authorization` header, or a key that is unknown, revoked, expired or calling from outside its allow-list. Deliberately identical in all of those cases: the response says nothing about whether the presented key exists.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}, "example": {"error": "Unauthorized", "message": "Invalid API key"}}}}, "Forbidden": {"description": "The key is valid but may not do this: its scope is `read` and the operation writes, or the endpoint is not part of the public surface at all.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}, "example": {"error": "Permission Denied", "message": "API key scope is not sufficient"}}}}, "NotFound": {"description": "No such resource in this key's organization. A resource that exists but belongs to another organization is also a 404 \u2014 existence is not leaked across organizations.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}, "example": {"error": "Instance not found", "message": "Monitor not found"}}}}, "RateLimited": {"description": "The organization's per-minute budget is spent. The budget is shared by every key the organization owns and sized by its plan; an MCP tool call spends from the same bucket.", "headers": {"X-RateLimit-Limit": {"$ref": "#/components/headers/X-RateLimit-Limit"}, "X-RateLimit-Remaining": {"$ref": "#/components/headers/X-RateLimit-Remaining"}, "X-RateLimit-Reset": {"$ref": "#/components/headers/X-RateLimit-Reset"}, "Retry-After": {"$ref": "#/components/headers/Retry-After"}}, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RateLimitErrorResponse"}, "example": {"error": "Too Many Requests", "message": "API rate limit exceeded", "retry_after": 12}}}}}, "schemas": {"BulkMonitorCreateRequest": {"properties": {"monitors": {"items": {"$ref": "#/components/schemas/MonitorCreate"}, "type": "array", "maxItems": 100, "minItems": 1, "title": "Monitors", "description": "Monitors to create, each shaped like a single create request."}}, "additionalProperties": false, "type": "object", "required": ["monitors"], "title": "BulkMonitorCreateRequest", "description": "Create several monitors in one all-or-nothing request."}, "BulkMonitorCreateResponse": {"properties": {"monitors": {"items": {"$ref": "#/components/schemas/MonitorCompactRead"}, "type": "array", "title": "Monitors"}}, "additionalProperties": false, "type": "object", "required": ["monitors"], "title": "BulkMonitorCreateResponse", "description": "The created monitors, in request order."}, "BulkMonitorIdsRequest": {"properties": {"monitor_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "maxItems": 100, "minItems": 1, "title": "Monitor Ids", "description": "Monitors to act on. Every id must belong to the active organization."}}, "additionalProperties": false, "type": "object", "required": ["monitor_ids"], "title": "BulkMonitorIdsRequest", "description": "A set of the organization's monitors to act on together."}, "BulkMonitorStateResponse": {"properties": {"monitors": {"items": {"$ref": "#/components/schemas/MonitorCompactRead"}, "type": "array", "title": "Monitors"}}, "additionalProperties": false, "type": "object", "required": ["monitors"], "title": "BulkMonitorStateResponse", "description": "The affected monitors after the change, in request order."}, "BulkMonitorTagsRequest": {"properties": {"monitor_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "maxItems": 300, "minItems": 1, "title": "Monitor Ids", "description": "Monitors to retag. Every id must belong to the active organization."}, "add": {"items": {"type": "string"}, "type": "array", "title": "Add", "description": "Tags to add to every listed monitor."}, "remove": {"items": {"type": "string"}, "type": "array", "title": "Remove", "description": "Tags to remove from every listed monitor."}}, "additionalProperties": false, "type": "object", "required": ["monitor_ids"], "title": "BulkMonitorTagsRequest", "description": "Add and/or remove tags across several monitors in one transaction.\n\n``MonitorUpdate.tags`` is a full replacement, so \"add one tag to twelve\nmonitors\" through PATCH means twelve reads, twelve client-side unions and\ntwelve writes, any of which can fail halfway. This request states the\nintent instead, and the server applies it atomically."}, "BulkMonitorTagsResponse": {"properties": {"monitors_updated": {"type": "integer", "minimum": 0.0, "title": "Monitors Updated"}}, "additionalProperties": false, "type": "object", "required": ["monitors_updated"], "title": "BulkMonitorTagsResponse", "description": "How many monitors the bulk tag write actually changed."}, "BulkMonitorUpdateRequest": {"properties": {"monitor_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "maxItems": 100, "minItems": 1, "title": "Monitor Ids", "description": "Monitors to act on. Every id must belong to the active organization."}, "changes": {"$ref": "#/components/schemas/MonitorBulkChanges"}}, "additionalProperties": false, "type": "object", "required": ["monitor_ids", "changes"], "title": "BulkMonitorUpdateRequest", "description": "Set the same fields on several monitors in one all-or-nothing request."}, "ChannelType": {"type": "string", "enum": ["EMAIL", "TELEGRAM", "WEBHOOK", "SLACK", "DISCORD"], "title": "ChannelType", "description": "Transport for a user notification channel."}, "CheckResultRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "monitor_id": {"type": "string", "format": "uuid", "title": "Monitor Id"}, "region": {"type": "string", "title": "Region"}, "checked_at": {"type": "string", "format": "date-time", "title": "Checked At"}, "status": {"$ref": "#/components/schemas/CheckResultStatus"}, "response_time_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Response Time Ms"}, "status_code": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Status Code"}, "error_message": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error Message"}, "details": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Details"}, "job_id": {"type": "string", "title": "Job Id"}, "maintenance_window_id": {"anyOf": [{"type": "string", "format": "uuid"}, {"type": "null"}], "title": "Maintenance Window Id"}}, "additionalProperties": false, "type": "object", "required": ["id", "monitor_id", "region", "checked_at", "status", "response_time_ms", "status_code", "error_message", "details", "job_id"], "title": "CheckResultRead", "description": "Response model for a single check probe outcome."}, "CheckResultStatus": {"type": "string", "enum": ["UP", "DEGRADED", "DOWN", "ERROR"], "title": "CheckResultStatus", "description": "Outcome of a single probe execution reported in a :class:`CheckResult`.\n\n``DEGRADED`` means the resource responded / is working but in a degraded\nstate (e.g. partial ping packet loss, a TLS cert expiring soon). It counts\nas up for uptime \u2014 it never penalises uptime% and never opens an incident \u2014\nbut is tracked separately so the UI can render it distinctly."}, "CheckType": {"type": "string", "enum": ["HTTP", "PING", "SSL", "TCP", "DNS"], "title": "CheckType", "description": "Type of probe a worker must run for a :class:`CheckJob`."}, "ComponentRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "monitor_id": {"type": "string", "format": "uuid", "title": "Monitor Id"}, "display_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Display Name"}, "position": {"type": "integer", "title": "Position"}}, "additionalProperties": false, "type": "object", "required": ["id", "monitor_id", "display_name", "position"], "title": "ComponentRead", "description": "Editor view of a component (carries the monitor id, unlike the public one)."}, "ExposedPortRead": {"properties": {"port": {"type": "integer", "title": "Port"}, "service": {"type": "string", "title": "Service"}}, "additionalProperties": false, "type": "object", "required": ["port", "service"], "title": "ExposedPortRead", "description": "One port of the exposed-ports preset."}, "ExposedPortsPresetResponse": {"properties": {"ports": {"items": {"$ref": "#/components/schemas/ExposedPortRead"}, "type": "array", "title": "Ports"}}, "additionalProperties": false, "type": "object", "required": ["ports"], "title": "ExposedPortsPresetResponse", "description": "Ports to check are closed on a server, with what usually listens there."}, "FailureKind": {"type": "string", "enum": ["TIMEOUT", "DNS_FAILURE", "CONNECTION_REFUSED", "TLS_INVALID", "HTTP_4XX", "HTTP_5XX", "HTTP_UNEXPECTED_STATUS", "KEYWORD_MISSING", "TOO_MANY_REDIRECTS", "TARGET_BLOCKED", "PORT_STATE_MISMATCH", "INVALID_TARGET", "UNKNOWN"], "title": "FailureKind", "description": "Structured classification of why a probe reported a non-UP result.\n\nSet by the worker on DOWN/ERROR outcomes so the core can store a typed\nincident cause (icons, grouping, filtering) while ``CheckResult.error`` /\nthe incident's ``cause_detail`` carry the raw human-readable reason.\nAbsent on UP results."}, "GroupRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "name": {"type": "string", "title": "Name"}, "position": {"type": "integer", "title": "Position"}, "components": {"items": {"$ref": "#/components/schemas/ComponentRead"}, "type": "array", "title": "Components"}}, "additionalProperties": false, "type": "object", "required": ["id", "name", "position", "components"], "title": "GroupRead", "description": "Editor view of a group."}, "HTTPValidationError": {"properties": {"detail": {"items": {"$ref": "#/components/schemas/ValidationError"}, "type": "array", "title": "Detail"}}, "type": "object", "title": "HTTPValidationError"}, "HeartbeatCreate": {"properties": {"name": {"type": "string", "maxLength": 255, "minLength": 1, "title": "Name"}, "period_seconds": {"type": "integer", "maximum": 2592000.0, "minimum": 60.0, "title": "Period Seconds"}, "grace_seconds": {"type": "integer", "maximum": 2592000.0, "minimum": 0.0, "title": "Grace Seconds"}, "notification_cooldown_seconds": {"anyOf": [{"type": "integer", "maximum": 86400.0, "minimum": 60.0}, {"type": "null"}], "title": "Notification Cooldown Seconds"}, "channel_ids": {"anyOf": [{"items": {"type": "string", "format": "uuid"}, "type": "array"}, {"type": "null"}], "title": "Channel Ids"}, "tags": {"items": {"type": "string"}, "type": "array", "title": "Tags"}}, "additionalProperties": false, "type": "object", "required": ["name", "period_seconds", "grace_seconds"], "title": "HeartbeatCreate", "description": "Create payload for a heartbeat."}, "HeartbeatMinimalRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "name": {"type": "string", "title": "Name"}, "state": {"$ref": "#/components/schemas/HeartbeatState"}}, "additionalProperties": false, "type": "object", "required": ["id", "name", "state"], "title": "HeartbeatMinimalRead", "description": "Compact heartbeat payload for organization-scoped selector controls."}, "HeartbeatRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "name": {"type": "string", "title": "Name"}, "state": {"$ref": "#/components/schemas/HeartbeatState"}, "period_seconds": {"type": "integer", "title": "Period Seconds"}, "grace_seconds": {"type": "integer", "title": "Grace Seconds"}, "ping_url": {"type": "string", "title": "Ping Url"}, "last_ping_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Last Ping At"}, "last_success_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Last Success At"}, "last_start_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Last Start At"}, "last_duration_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Last Duration Ms"}, "overdue_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Overdue At"}, "notification_cooldown_seconds": {"type": "integer", "title": "Notification Cooldown Seconds"}, "is_active": {"type": "boolean", "title": "Is Active"}, "channel_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "title": "Channel Ids"}, "tags": {"items": {"type": "string"}, "type": "array", "title": "Tags"}, "created_at": {"type": "string", "format": "date-time", "title": "Created At"}, "updated_at": {"type": "string", "format": "date-time", "title": "Updated At"}}, "additionalProperties": false, "type": "object", "required": ["id", "name", "state", "period_seconds", "grace_seconds", "ping_url", "last_ping_at", "last_success_at", "last_start_at", "last_duration_ms", "overdue_at", "notification_cooldown_seconds", "is_active", "created_at", "updated_at"], "title": "HeartbeatRead", "description": "Response model for a heartbeat, including the full ping-URL."}, "HeartbeatSortOption": {"type": "string", "enum": ["status", "name", "created_at"], "title": "HeartbeatSortOption", "description": "Ordering options for the heartbeat listing endpoint."}, "HeartbeatState": {"type": "string", "enum": ["PENDING", "UP", "DOWN", "PAUSED"], "title": "HeartbeatState", "description": "Lifecycle state of a heartbeat.\n\n``PENDING`` \u2014 created, never pinged; the sweep skips it (``overdue_at``\nis NULL) so a freshly created heartbeat does not false-alarm.\n``UP`` \u2014 pinged within ``period + grace``; the only state the sweep can\nflip to ``DOWN``.\n``DOWN`` \u2014 a ping was missed or the job sent ``/fail``; an incident is open.\n``PAUSED`` \u2014 owner-paused; inactive, never alerts."}, "HeartbeatUpdate": {"properties": {"name": {"anyOf": [{"type": "string", "maxLength": 255, "minLength": 1}, {"type": "null"}], "title": "Name"}, "period_seconds": {"anyOf": [{"type": "integer", "maximum": 2592000.0, "minimum": 60.0}, {"type": "null"}], "title": "Period Seconds"}, "grace_seconds": {"anyOf": [{"type": "integer", "maximum": 2592000.0, "minimum": 0.0}, {"type": "null"}], "title": "Grace Seconds"}, "notification_cooldown_seconds": {"anyOf": [{"type": "integer", "maximum": 86400.0, "minimum": 60.0}, {"type": "null"}], "title": "Notification Cooldown Seconds"}, "channel_ids": {"anyOf": [{"items": {"type": "string", "format": "uuid"}, "type": "array"}, {"type": "null"}], "title": "Channel Ids"}, "tags": {"items": {"type": "string"}, "type": "array", "title": "Tags"}}, "additionalProperties": false, "type": "object", "title": "HeartbeatUpdate", "description": "Partial update payload \u2014 every field optional."}, "IncidentCause": {"type": "string", "enum": ["TIMEOUT", "DNS_FAILURE", "CONNECTION_REFUSED", "TLS_INVALID", "HTTP_4XX", "HTTP_5XX", "HTTP_UNEXPECTED_STATUS", "KEYWORD_MISSING", "TOO_MANY_REDIRECTS", "TARGET_BLOCKED", "PORT_STATE_MISMATCH", "INVALID_TARGET", "HEARTBEAT_MISSED", "HEARTBEAT_FAILED", "UNKNOWN"], "title": "IncidentCause", "description": "Structured cause of an incident, across both incident sources.\n\nA superset of the worker's wire ``FailureKind``: every value the worker can\nreport is storable here, plus the causes only the core can observe (a\nheartbeat that never pinged, a client that reported its own failure). The\ntwo enums are declared separately so the worker contract does not grow\nvalues the worker never emits \u2014 ``test_enums.py`` guards the subset\nrelation, which is what keeps ``process_check_result`` able to store any\nincoming ``failure_kind``.\n\nThe raw human-readable reason lives in ``Incident.cause_detail``."}, "IncidentRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "monitor_id": {"anyOf": [{"type": "string", "format": "uuid"}, {"type": "null"}], "title": "Monitor Id"}, "heartbeat_id": {"anyOf": [{"type": "string", "format": "uuid"}, {"type": "null"}], "title": "Heartbeat Id"}, "started_at": {"type": "string", "format": "date-time", "title": "Started At"}, "resolved_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Resolved At"}, "cause": {"$ref": "#/components/schemas/IncidentCause"}, "cause_detail": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cause Detail"}, "last_notified_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Last Notified At"}, "acknowledged_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Acknowledged At"}, "acknowledged_by": {"anyOf": [{"type": "string", "format": "uuid"}, {"type": "null"}], "title": "Acknowledged By"}, "renotify_count": {"type": "integer", "title": "Renotify Count"}, "created_at": {"type": "string", "format": "date-time", "title": "Created At"}, "updated_at": {"type": "string", "format": "date-time", "title": "Updated At"}, "notification_logs": {"items": {"$ref": "#/components/schemas/NotificationLogRead"}, "type": "array", "title": "Notification Logs"}}, "additionalProperties": false, "type": "object", "required": ["id", "started_at", "resolved_at", "cause", "cause_detail", "last_notified_at", "acknowledged_at", "acknowledged_by", "renotify_count", "created_at", "updated_at"], "title": "IncidentRead", "description": "Response model for an open or resolved incident."}, "IncidentStatusFilter": {"type": "string", "enum": ["open", "resolved"], "title": "IncidentStatusFilter", "description": "Status filter accepted by the incidents listing endpoint.\n\n``OPEN`` keeps only ongoing incidents (``resolved_at IS NULL``);\n``RESOLVED`` keeps only closed ones. Omitting the filter returns both."}, "IncidentSummaryRead": {"properties": {"total": {"type": "integer", "minimum": 0.0, "title": "Total"}, "open": {"type": "integer", "minimum": 0.0, "title": "Open"}, "resolved": {"type": "integer", "minimum": 0.0, "title": "Resolved"}}, "additionalProperties": false, "type": "object", "required": ["total", "open", "resolved"], "title": "IncidentSummaryRead", "description": "Counts for the incident summary card.\n\nThe three fields come from one query's conditional aggregates, so\n``total == open + resolved`` holds by construction. The use case logs a\nwarning if it ever does not \u2014 a read model must not fail serialisation\nover slightly inconsistent counters."}, "IncidentUpdateRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "status": {"$ref": "#/components/schemas/StatusPageIncidentStatus"}, "body": {"type": "string", "title": "Body"}, "created_by": {"anyOf": [{"type": "string", "format": "uuid"}, {"type": "null"}], "title": "Created By"}, "created_at": {"type": "string", "format": "date-time", "title": "Created At"}}, "additionalProperties": false, "type": "object", "required": ["id", "status", "body", "created_by", "created_at"], "title": "IncidentUpdateRead", "description": "One timeline entry on a public incident. ``created_by=None`` = system."}, "MaintenanceScope": {"type": "string", "enum": ["MONITOR", "ORG"], "title": "MaintenanceScope", "description": "What a window targets. ``ORG`` covers every monitor in the org;\n``MONITOR`` covers the explicitly linked monitors only."}, "MaintenanceSortOption": {"type": "string", "enum": ["name", "created_at"], "title": "MaintenanceSortOption", "description": "Ordering for the windows listing endpoint."}, "MaintenanceWindowCreate": {"properties": {"name": {"type": "string", "maxLength": 255, "minLength": 1, "title": "Name"}, "enabled": {"type": "boolean", "title": "Enabled", "default": true}, "scope": {"$ref": "#/components/schemas/MaintenanceScope"}, "dtstart": {"type": "string", "format": "date-time", "title": "Dtstart"}, "duration_minutes": {"type": "integer", "maximum": 40320.0, "exclusiveMinimum": 0.0, "title": "Duration Minutes"}, "rrule": {"anyOf": [{"type": "string", "maxLength": 1024}, {"type": "null"}], "title": "Rrule"}, "timezone": {"anyOf": [{"type": "string", "maxLength": 64}, {"type": "null"}], "title": "Timezone"}, "monitor_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "title": "Monitor Ids"}}, "additionalProperties": false, "type": "object", "required": ["name", "scope", "dtstart", "duration_minutes"], "title": "MaintenanceWindowCreate", "description": "Create payload for a maintenance window."}, "MaintenanceWindowDetailRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "name": {"type": "string", "title": "Name"}, "enabled": {"type": "boolean", "title": "Enabled"}, "scope": {"$ref": "#/components/schemas/MaintenanceScope"}, "dtstart": {"type": "string", "format": "date-time", "title": "Dtstart"}, "duration_minutes": {"type": "integer", "title": "Duration Minutes"}, "rrule": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rrule"}, "timezone": {"type": "string", "title": "Timezone"}, "monitor_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "title": "Monitor Ids"}, "created_at": {"type": "string", "format": "date-time", "title": "Created At"}, "next_occurrences": {"items": {"$ref": "#/components/schemas/OccurrenceRead"}, "type": "array", "title": "Next Occurrences"}}, "additionalProperties": false, "type": "object", "required": ["id", "name", "enabled", "scope", "dtstart", "duration_minutes", "rrule", "timezone", "created_at"], "title": "MaintenanceWindowDetailRead", "description": "One window with its next occurrences.\n\nOnly the single read computes them, so the field lives here: on list and\nwrite responses it used to come back always empty."}, "MaintenanceWindowPreviewRequest": {"properties": {"dtstart": {"type": "string", "format": "date-time", "title": "Dtstart"}, "duration_minutes": {"type": "integer", "maximum": 40320.0, "exclusiveMinimum": 0.0, "title": "Duration Minutes"}, "rrule": {"anyOf": [{"type": "string", "maxLength": 1024}, {"type": "null"}], "title": "Rrule"}, "timezone": {"anyOf": [{"type": "string", "maxLength": 64}, {"type": "null"}], "title": "Timezone"}}, "additionalProperties": false, "type": "object", "required": ["dtstart", "duration_minutes"], "title": "MaintenanceWindowPreviewRequest", "description": "Draft schedule for the preview endpoint (no persistence)."}, "MaintenanceWindowRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "name": {"type": "string", "title": "Name"}, "enabled": {"type": "boolean", "title": "Enabled"}, "scope": {"$ref": "#/components/schemas/MaintenanceScope"}, "dtstart": {"type": "string", "format": "date-time", "title": "Dtstart"}, "duration_minutes": {"type": "integer", "title": "Duration Minutes"}, "rrule": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rrule"}, "timezone": {"type": "string", "title": "Timezone"}, "monitor_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "title": "Monitor Ids"}, "created_at": {"type": "string", "format": "date-time", "title": "Created At"}}, "additionalProperties": false, "type": "object", "required": ["id", "name", "enabled", "scope", "dtstart", "duration_minutes", "rrule", "timezone", "created_at"], "title": "MaintenanceWindowRead", "description": "Response model for a maintenance window."}, "MaintenanceWindowRevisionRead": {"properties": {"effective_from": {"type": "string", "format": "date-time", "title": "Effective From"}, "name": {"type": "string", "title": "Name"}, "scope": {"$ref": "#/components/schemas/MaintenanceScope"}, "dtstart": {"type": "string", "format": "date-time", "title": "Dtstart"}, "duration_minutes": {"type": "integer", "title": "Duration Minutes"}, "rrule": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rrule"}, "timezone": {"type": "string", "title": "Timezone"}, "monitor_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "title": "Monitor Ids"}, "edited_by": {"anyOf": [{"type": "string", "format": "uuid"}, {"type": "null"}], "title": "Edited By"}}, "additionalProperties": false, "type": "object", "required": ["effective_from", "name", "scope", "dtstart", "duration_minutes", "rrule", "timezone", "edited_by"], "title": "MaintenanceWindowRevisionRead", "description": "A historical snapshot of a window's schedule."}, "MaintenanceWindowUpdate": {"properties": {"name": {"anyOf": [{"type": "string", "maxLength": 255, "minLength": 1}, {"type": "null"}], "title": "Name"}, "enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Enabled"}, "scope": {"anyOf": [{"$ref": "#/components/schemas/MaintenanceScope"}, {"type": "null"}]}, "dtstart": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Dtstart"}, "duration_minutes": {"anyOf": [{"type": "integer", "maximum": 40320.0, "exclusiveMinimum": 0.0}, {"type": "null"}], "title": "Duration Minutes"}, "rrule": {"anyOf": [{"type": "string", "maxLength": 1024}, {"type": "null"}], "title": "Rrule"}, "timezone": {"anyOf": [{"type": "string", "maxLength": 64}, {"type": "null"}], "title": "Timezone"}, "monitor_ids": {"anyOf": [{"items": {"type": "string", "format": "uuid"}, "type": "array"}, {"type": "null"}], "title": "Monitor Ids"}}, "additionalProperties": false, "type": "object", "title": "MaintenanceWindowUpdate", "description": "Partial update payload \u2014 every field optional."}, "MonitorBulkChanges": {"properties": {"interval_seconds": {"type": "integer", "maximum": 86400.0, "minimum": 30.0, "title": "Interval Seconds"}, "timeout_seconds": {"type": "integer", "maximum": 120.0, "minimum": 1.0, "title": "Timeout Seconds"}, "regions": {"items": {"type": "string"}, "type": "array", "minItems": 1, "title": "Regions"}, "channel_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "title": "Channel Ids"}, "confirmation_threshold": {"type": "integer", "maximum": 10.0, "minimum": 1.0, "title": "Confirmation Threshold"}, "notification_cooldown_seconds": {"type": "integer", "maximum": 86400.0, "minimum": 60.0, "title": "Notification Cooldown Seconds"}}, "additionalProperties": false, "type": "object", "minProperties": 1, "title": "MonitorBulkChanges", "description": "The fields a bulk update may set; the same value goes to every monitor.\n\nOnly fields that mean the same thing for every monitor type. ``config``\nis type-specific, ``name`` is per monitor and ``tags`` has its own bulk\nendpoint. Omit a field to leave it unchanged; ``null`` is a 422."}, "MonitorCompactRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "name": {"type": "string", "title": "Name"}, "type": {"$ref": "#/components/schemas/CheckType"}, "target": {"type": "string", "title": "Target"}, "status": {"$ref": "#/components/schemas/MonitorStatus"}, "is_active": {"type": "boolean", "title": "Is Active"}, "tags": {"items": {"type": "string"}, "type": "array", "title": "Tags"}, "interval_seconds": {"type": "integer", "title": "Interval Seconds"}, "ssl_expires_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Ssl Expires At"}, "last_checked_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Last Checked At"}}, "additionalProperties": false, "type": "object", "required": ["id", "name", "type", "target", "status", "is_active", "interval_seconds", "ssl_expires_at", "last_checked_at"], "title": "MonitorCompactRead", "description": "One monitor as a list row: identity, state and the fields agents filter on.\n\nNo ``config``, no history and no region detail \u2014 those are what made a\n100-monitor page several hundred kilobytes. ``GET /v1/monitors/{id}``\nstill returns everything."}, "MonitorCreate": {"properties": {"name": {"type": "string", "maxLength": 255, "minLength": 1, "title": "Name"}, "type": {"$ref": "#/components/schemas/CheckType"}, "target": {"type": "string", "maxLength": 2048, "minLength": 1, "title": "Target"}, "interval_seconds": {"type": "integer", "maximum": 86400.0, "minimum": 30.0, "title": "Interval Seconds"}, "timeout_seconds": {"type": "integer", "maximum": 120.0, "minimum": 1.0, "title": "Timeout Seconds"}, "regions": {"items": {"type": "string"}, "type": "array", "minItems": 1, "title": "Regions"}, "config": {"additionalProperties": true, "type": "object", "title": "Config"}, "confirmation_threshold": {"anyOf": [{"type": "integer", "maximum": 10.0, "minimum": 1.0}, {"type": "null"}], "title": "Confirmation Threshold"}, "notification_cooldown_seconds": {"anyOf": [{"type": "integer", "maximum": 86400.0, "minimum": 60.0}, {"type": "null"}], "title": "Notification Cooldown Seconds"}, "channel_ids": {"anyOf": [{"items": {"type": "string", "format": "uuid"}, "type": "array"}, {"type": "null"}], "title": "Channel Ids"}, "tags": {"items": {"type": "string"}, "type": "array", "title": "Tags"}, "is_active": {"type": "boolean", "title": "Is Active", "default": true}}, "additionalProperties": false, "type": "object", "required": ["name", "type", "target", "interval_seconds", "timeout_seconds", "regions"], "title": "MonitorCreate", "description": "Request body for ``POST /v1/monitors``."}, "MonitorListRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "user_id": {"type": "string", "format": "uuid", "title": "User Id"}, "name": {"type": "string", "title": "Name"}, "type": {"$ref": "#/components/schemas/CheckType"}, "target": {"type": "string", "title": "Target"}, "interval_seconds": {"type": "integer", "title": "Interval Seconds"}, "timeout_seconds": {"type": "integer", "title": "Timeout Seconds"}, "regions": {"items": {"type": "string"}, "type": "array", "title": "Regions"}, "config": {"additionalProperties": true, "type": "object", "title": "Config"}, "status": {"$ref": "#/components/schemas/MonitorStatus"}, "last_checked_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Last Checked At"}, "next_run_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Next Run At"}, "confirmation_threshold": {"type": "integer", "title": "Confirmation Threshold"}, "notification_cooldown_seconds": {"type": "integer", "title": "Notification Cooldown Seconds"}, "ssl_expires_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Ssl Expires At"}, "ssl_cert_info": {"anyOf": [{"$ref": "#/components/schemas/SslCertInfo"}, {"type": "null"}]}, "is_active": {"type": "boolean", "title": "Is Active"}, "badge_enabled": {"type": "boolean", "title": "Badge Enabled", "default": false}, "tags": {"items": {"type": "string"}, "type": "array", "title": "Tags"}, "created_at": {"type": "string", "format": "date-time", "title": "Created At"}, "updated_at": {"type": "string", "format": "date-time", "title": "Updated At"}, "channel_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "title": "Channel Ids"}, "uptime_daily": {"items": {"$ref": "#/components/schemas/UptimeDayPoint"}, "type": "array", "title": "Uptime Daily"}, "region_statuses": {"items": {"$ref": "#/components/schemas/RegionStatusRead"}, "type": "array", "title": "Region Statuses", "description": "Per-region latest status, sorted by region name.\n\nBuilt from ``region_snapshots``; ``job_id`` is dropped (internal\ndedup key) and malformed/partial snapshot rows are skipped rather\nthan failing the read.", "readOnly": true}}, "additionalProperties": false, "type": "object", "required": ["id", "user_id", "name", "type", "target", "interval_seconds", "timeout_seconds", "regions", "config", "status", "last_checked_at", "next_run_at", "confirmation_threshold", "notification_cooldown_seconds", "ssl_expires_at", "is_active", "created_at", "updated_at", "region_statuses"], "title": "MonitorListRead", "description": "A full list row: the monitor plus its 30-day uptime strip.\n\nOnly the list fills the strip (one bulk aggregation for the page), so it\nlives here rather than on ``MonitorRead``: a single read used to carry it\nalways empty, which looked like \"no data\". One monitor's days come from\n``/uptime-daily``."}, "MonitorListView": {"type": "string", "enum": ["full", "compact"], "title": "MonitorListView", "description": "Shape of a monitors-list page: the full card or a compact row."}, "MonitorMinimalRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "name": {"type": "string", "title": "Name"}, "type": {"$ref": "#/components/schemas/CheckType"}, "status": {"$ref": "#/components/schemas/MonitorStatus"}, "created_at": {"type": "string", "format": "date-time", "title": "Created At"}}, "additionalProperties": false, "type": "object", "required": ["id", "name", "type", "status", "created_at"], "title": "MonitorMinimalRead", "description": "Compact monitor payload for organization-scoped selector controls."}, "MonitorPrecheckRequest": {"properties": {"type": {"$ref": "#/components/schemas/CheckType"}, "target": {"type": "string", "maxLength": 2048, "minLength": 1, "title": "Target"}, "config": {"additionalProperties": true, "type": "object", "title": "Config"}}, "additionalProperties": false, "type": "object", "required": ["type", "target"], "title": "MonitorPrecheckRequest", "description": "Request body for ``POST /v1/monitors/precheck``.\n\nThe pre-check probes a target once before a monitor is created. The same\ntype-aware normalization (and SSRF / non-global reject) as monitor creation\nruns here, so a target the API would reject on create fails fast with 422\nrather than being dispatched to the worker fleet."}, "MonitorPrecheckResponse": {"properties": {"status": {"$ref": "#/components/schemas/PrecheckOutcome"}, "region": {"type": "string", "title": "Region"}, "response_time_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Response Time Ms"}, "status_code": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Status Code"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error"}, "failure_kind": {"anyOf": [{"$ref": "#/components/schemas/FailureKind"}, {"type": "null"}]}}, "additionalProperties": false, "type": "object", "required": ["status", "region"], "title": "MonitorPrecheckResponse", "description": "Advisory result of a pre-check, returned to the create-monitor form.\n\n``status`` is ``up``/``down``/``error`` from the probing region, or\n``unknown`` when the core could not get a definite answer (no worker,\ntimeout, kill switch) \u2014 the form treats ``unknown`` as \"proceed without a\nwarning\". ``region`` names the single probing region so the UI can say\n\"seems down from <region>\"."}, "MonitorRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "user_id": {"type": "string", "format": "uuid", "title": "User Id"}, "name": {"type": "string", "title": "Name"}, "type": {"$ref": "#/components/schemas/CheckType"}, "target": {"type": "string", "title": "Target"}, "interval_seconds": {"type": "integer", "title": "Interval Seconds"}, "timeout_seconds": {"type": "integer", "title": "Timeout Seconds"}, "regions": {"items": {"type": "string"}, "type": "array", "title": "Regions"}, "config": {"additionalProperties": true, "type": "object", "title": "Config"}, "status": {"$ref": "#/components/schemas/MonitorStatus"}, "last_checked_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Last Checked At"}, "next_run_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Next Run At"}, "confirmation_threshold": {"type": "integer", "title": "Confirmation Threshold"}, "notification_cooldown_seconds": {"type": "integer", "title": "Notification Cooldown Seconds"}, "ssl_expires_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Ssl Expires At"}, "ssl_cert_info": {"anyOf": [{"$ref": "#/components/schemas/SslCertInfo"}, {"type": "null"}]}, "is_active": {"type": "boolean", "title": "Is Active"}, "badge_enabled": {"type": "boolean", "title": "Badge Enabled", "default": false}, "tags": {"items": {"type": "string"}, "type": "array", "title": "Tags"}, "created_at": {"type": "string", "format": "date-time", "title": "Created At"}, "updated_at": {"type": "string", "format": "date-time", "title": "Updated At"}, "channel_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "title": "Channel Ids"}, "region_statuses": {"items": {"$ref": "#/components/schemas/RegionStatusRead"}, "type": "array", "title": "Region Statuses", "description": "Per-region latest status, sorted by region name.\n\nBuilt from ``region_snapshots``; ``job_id`` is dropped (internal\ndedup key) and malformed/partial snapshot rows are skipped rather\nthan failing the read.", "readOnly": true}}, "additionalProperties": false, "type": "object", "required": ["id", "user_id", "name", "type", "target", "interval_seconds", "timeout_seconds", "regions", "config", "status", "last_checked_at", "next_run_at", "confirmation_threshold", "notification_cooldown_seconds", "ssl_expires_at", "is_active", "created_at", "updated_at", "region_statuses"], "title": "MonitorRead", "description": "Response model for monitor reads and creates."}, "MonitorResponseTimeByRegionResponse": {"properties": {"monitor_id": {"type": "string", "format": "uuid", "title": "Monitor Id"}, "window": {"type": "string", "title": "Window"}, "bucket_seconds": {"type": "integer", "title": "Bucket Seconds"}, "regions": {"items": {"$ref": "#/components/schemas/RegionResponseSeries"}, "type": "array", "title": "Regions"}}, "additionalProperties": false, "type": "object", "required": ["monitor_id", "window", "bucket_seconds", "regions"], "title": "MonitorResponseTimeByRegionResponse", "description": "Per-region response-time series for a monitor over one time window (\u04237).\n\nEach region is plotted on its own auto-scaled axis on the frontend, so a\nfast ``eu`` probe and a slow ``us`` probe each render readably instead of\nas one saw-tooth line on a shared axis. The per-region latest status the\ncard's switcher shows is joined client-side from the monitor's\n``region_statuses`` \u2014 this payload is purely the time series."}, "MonitorSortOption": {"type": "string", "enum": ["status", "up_first", "name", "newest", "oldest", "ssl_expiry"], "title": "MonitorSortOption", "description": "Ordering options for the monitors list endpoint.\n\n``STATUS`` is the default and surfaces actionable monitors first\n(PENDING \u2192 DOWN \u2192 DEGRADED \u2192 UP \u2192 PAUSED), then by name, then newest.\n``UP_FIRST`` inverts the severity so healthy monitors lead. ``NAME``,\n``NEWEST`` and ``OLDEST`` are plain orderings.\n\n``SSL_EXPIRY`` orders by certificate expiry, soonest first; monitors with\nno known expiry (non-SSL types, not yet probed) come last."}, "MonitorStatsResponse": {"properties": {"monitor_id": {"type": "string", "format": "uuid", "title": "Monitor Id"}, "windows": {"additionalProperties": {"$ref": "#/components/schemas/MonitorStatsWindow"}, "type": "object", "title": "Windows"}}, "additionalProperties": false, "type": "object", "required": ["monitor_id", "windows"], "title": "MonitorStatsResponse", "description": "Per-window uptime statistics for a monitor.\n\n``windows`` is keyed by the window label (``24h`` / ``7d`` / ``30d``); the\nkeys are JSON strings rather than model attributes because Pydantic field\nnames cannot begin with a digit."}, "MonitorStatsWindow": {"properties": {"uptime_percentage": {"anyOf": [{"type": "number", "maximum": 100.0, "minimum": 0.0}, {"type": "null"}], "title": "Uptime Percentage"}, "total_checks": {"type": "integer", "minimum": 0.0, "title": "Total Checks"}, "up_checks": {"type": "integer", "minimum": 0.0, "title": "Up Checks"}, "down_checks": {"type": "integer", "minimum": 0.0, "title": "Down Checks"}, "degraded_checks": {"type": "integer", "minimum": 0.0, "title": "Degraded Checks", "default": 0}, "incident_count": {"type": "integer", "minimum": 0.0, "title": "Incident Count"}, "avg_response_time_ms": {"anyOf": [{"type": "integer", "minimum": 0.0}, {"type": "null"}], "title": "Avg Response Time Ms"}, "downtime_seconds": {"type": "integer", "minimum": 0.0, "title": "Downtime Seconds", "description": "Seconds of confirmed downtime inside the window."}, "observed_seconds": {"type": "integer", "minimum": 0.0, "title": "Observed Seconds", "description": "Seconds inside the window the monitor was observed; uptime is measured over this time. Never less than downtime_seconds."}, "window_start": {"type": "string", "format": "date-time", "title": "Window Start", "description": "Start of the window: the window length before now, or when the monitor was created if that is later."}}, "additionalProperties": false, "type": "object", "required": ["uptime_percentage", "total_checks", "up_checks", "down_checks", "incident_count", "avg_response_time_ms", "downtime_seconds", "observed_seconds", "window_start"], "title": "MonitorStatsWindow", "description": "Aggregated uptime statistics for a single time window.\n\nThe window spans ``[window_start, now)``, where ``window_start`` is the\nlater of ``now - window length`` and the monitor's creation time.\n``uptime_percentage`` is ``1 - downtime_seconds / observed_seconds``:\ndowntime comes from the downtime periods of confirmed incidents, observed\ntime from the hours the monitor was actually probed. Unconfirmed DOWN\nchecks and DEGRADED checks do not lower it; ``None`` when nothing was\nobserved, exactly ``100.0`` only without downtime.\n\nThe check counters are informational. ``degraded_checks`` is reported\nseparately so the UI can render degradation distinctly while uptime stays\ngreen."}, "MonitorStatus": {"type": "string", "enum": ["PENDING", "UP", "DEGRADED", "DOWN", "PAUSED"], "title": "MonitorStatus", "description": "Aggregated state of a monitor as derived by the results state machine."}, "MonitorUpdate": {"properties": {"name": {"type": "string", "maxLength": 255, "minLength": 1, "title": "Name"}, "interval_seconds": {"type": "integer", "maximum": 86400.0, "minimum": 30.0, "title": "Interval Seconds"}, "timeout_seconds": {"type": "integer", "maximum": 120.0, "minimum": 1.0, "title": "Timeout Seconds"}, "regions": {"items": {"type": "string"}, "type": "array", "minItems": 1, "title": "Regions"}, "config": {"additionalProperties": true, "type": "object", "title": "Config"}, "confirmation_threshold": {"type": "integer", "maximum": 10.0, "minimum": 1.0, "title": "Confirmation Threshold"}, "notification_cooldown_seconds": {"type": "integer", "maximum": 86400.0, "minimum": 60.0, "title": "Notification Cooldown Seconds"}, "channel_ids": {"anyOf": [{"items": {"type": "string", "format": "uuid"}, "type": "array"}, {"type": "null"}], "title": "Channel Ids"}, "badge_enabled": {"type": "boolean", "title": "Badge Enabled"}, "tags": {"items": {"type": "string"}, "type": "array", "title": "Tags"}}, "additionalProperties": false, "type": "object", "title": "MonitorUpdate", "description": "Request body for ``PATCH /v1/monitors/{id}`` \u2014 all fields optional."}, "MonitorUptimeDailyResponse": {"properties": {"monitor_id": {"type": "string", "format": "uuid", "title": "Monitor Id"}, "days": {"items": {"$ref": "#/components/schemas/UptimeDayPoint"}, "type": "array", "title": "Days"}}, "additionalProperties": false, "type": "object", "required": ["monitor_id", "days"], "title": "MonitorUptimeDailyResponse", "description": "Dense per-day uptime series for a monitor over the last N UTC days.\n\n``days`` always holds exactly the requested number of points, ordered\noldest-first and ending on today (UTC); days without data are present as\nexplicit no-data points so the frontend never has to invent the axis."}, "MonitorsSummaryResponse": {"properties": {"total": {"type": "integer", "minimum": 0.0, "title": "Total"}, "status_counts": {"additionalProperties": {"type": "integer"}, "type": "object", "title": "Status Counts"}, "uptime_30d": {"anyOf": [{"type": "number", "maximum": 100.0, "minimum": 0.0}, {"type": "null"}], "title": "Uptime 30D"}}, "additionalProperties": false, "type": "object", "required": ["total", "status_counts"], "title": "MonitorsSummaryResponse", "description": "Account-wide monitor summary for the dashboard KPI cards.\n\n``status_counts`` is exhaustive over ``MonitorStatus`` (every status present,\nzero-filled). ``uptime_30d`` is the account-wide uptime percentage over the\ntrailing 30 days, ``1 - sum(downtime) / sum(observed)`` across monitors:\neach monitor counts from ``max(now - 30d, created_at)``, downtime comes\nfrom confirmed incident downtime periods, so a young monitor weighs only\nas much as it was observed. ``null`` without monitors or observations.\n``total`` is the count of the account's non-deleted monitors."}, "NotificationChannelDirectoryRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "type": {"$ref": "#/components/schemas/ChannelType"}, "label": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Label"}, "is_verified": {"type": "boolean", "title": "Is Verified"}, "is_active": {"type": "boolean", "title": "Is Active"}, "destination_hint": {"type": "string", "title": "Destination Hint"}}, "additionalProperties": false, "type": "object", "required": ["id", "type", "label", "is_verified", "is_active", "destination_hint"], "title": "NotificationChannelDirectoryRead", "description": "One stored channel as an API key sees it: enough to pick it, nothing secret.\n\n``destination_hint`` never carries a delivery secret: a WEBHOOK URL is cut to\nits scheme and host, SLACK/DISCORD already store a masked display string,\nTELEGRAM stores a chat id."}, "NotificationEvent": {"type": "string", "enum": ["TRIGGERED", "RESOLVED", "SSL_EXPIRY"], "title": "NotificationEvent", "description": "Lifecycle event that triggered an outgoing notification."}, "NotificationLogRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "channel_type": {"$ref": "#/components/schemas/ChannelType"}, "destination": {"type": "string", "title": "Destination"}, "event": {"$ref": "#/components/schemas/NotificationEvent"}, "sent_at": {"type": "string", "format": "date-time", "title": "Sent At"}, "status": {"$ref": "#/components/schemas/NotificationStatus"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error"}}, "additionalProperties": false, "type": "object", "required": ["id", "channel_type", "destination", "event", "sent_at", "status", "error"], "title": "NotificationLogRead", "description": "One delivery attempt in an incident's notification timeline."}, "NotificationStatus": {"type": "string", "enum": ["PENDING", "SENT", "FAILED"], "title": "NotificationStatus", "description": "Delivery outcome for an outgoing notification."}, "OccurrenceRead": {"properties": {"start": {"type": "string", "format": "date-time", "title": "Start"}, "end": {"type": "string", "format": "date-time", "title": "End"}}, "additionalProperties": false, "type": "object", "required": ["start", "end"], "title": "OccurrenceRead", "description": "A single materialized occurrence, tz-aware in the window timezone."}, "PageIncidentCreate": {"properties": {"title": {"type": "string", "maxLength": 255, "minLength": 1, "title": "Title"}, "status": {"$ref": "#/components/schemas/StatusPageIncidentStatus", "default": "INVESTIGATING"}, "body": {"type": "string", "maxLength": 5000, "minLength": 1, "title": "Body"}, "component_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "title": "Component Ids"}}, "additionalProperties": false, "type": "object", "required": ["title", "body"], "title": "PageIncidentCreate", "description": "Create payload for a manual public incident."}, "PageIncidentPatch": {"properties": {"title": {"type": "string", "maxLength": 255, "minLength": 1, "title": "Title"}}, "additionalProperties": false, "type": "object", "required": ["title"], "title": "PageIncidentPatch", "description": "Metadata-only patch \u2014 renaming a public incident triggers no email."}, "PageIncidentRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "title": {"type": "string", "title": "Title"}, "status": {"$ref": "#/components/schemas/StatusPageIncidentStatus"}, "is_auto": {"type": "boolean", "title": "Is Auto"}, "started_at": {"type": "string", "format": "date-time", "title": "Started At"}, "resolved_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Resolved At"}, "notified_at": {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}], "title": "Notified At"}, "component_ids": {"items": {"type": "string", "format": "uuid"}, "type": "array", "title": "Component Ids"}, "updates": {"items": {"$ref": "#/components/schemas/IncidentUpdateRead"}, "type": "array", "title": "Updates"}}, "additionalProperties": false, "type": "object", "required": ["id", "title", "status", "is_auto", "started_at", "resolved_at", "notified_at", "component_ids", "updates"], "title": "PageIncidentRead", "description": "Editor view of a public incident and its timeline."}, "PageIncidentUpdateCreate": {"properties": {"status": {"$ref": "#/components/schemas/StatusPageIncidentStatus"}, "body": {"type": "string", "maxLength": 5000, "minLength": 1, "title": "Body"}}, "additionalProperties": false, "type": "object", "required": ["status", "body"], "title": "PageIncidentUpdateCreate", "description": "Payload for a new timeline entry on an existing public incident."}, "PaginatedResponse_CheckResultRead_": {"properties": {"items": {"items": {"$ref": "#/components/schemas/CheckResultRead"}, "type": "array", "title": "Items"}, "total": {"type": "integer", "title": "Total"}, "page": {"type": "integer", "title": "Page"}, "size": {"type": "integer", "title": "Size"}, "pages": {"type": "integer", "title": "Pages"}}, "additionalProperties": false, "type": "object", "required": ["items", "total", "page", "size", "pages"], "title": "PaginatedResponse[CheckResultRead]"}, "PaginatedResponse_HeartbeatRead_": {"properties": {"items": {"items": {"$ref": "#/components/schemas/HeartbeatRead"}, "type": "array", "title": "Items"}, "total": {"type": "integer", "title": "Total"}, "page": {"type": "integer", "title": "Page"}, "size": {"type": "integer", "title": "Size"}, "pages": {"type": "integer", "title": "Pages"}}, "additionalProperties": false, "type": "object", "required": ["items", "total", "page", "size", "pages"], "title": "PaginatedResponse[HeartbeatRead]"}, "PaginatedResponse_IncidentRead_": {"properties": {"items": {"items": {"$ref": "#/components/schemas/IncidentRead"}, "type": "array", "title": "Items"}, "total": {"type": "integer", "title": "Total"}, "page": {"type": "integer", "title": "Page"}, "size": {"type": "integer", "title": "Size"}, "pages": {"type": "integer", "title": "Pages"}}, "additionalProperties": false, "type": "object", "required": ["items", "total", "page", "size", "pages"], "title": "PaginatedResponse[IncidentRead]"}, "PaginatedResponse_MaintenanceWindowRead_": {"properties": {"items": {"items": {"$ref": "#/components/schemas/MaintenanceWindowRead"}, "type": "array", "title": "Items"}, "total": {"type": "integer", "title": "Total"}, "page": {"type": "integer", "title": "Page"}, "size": {"type": "integer", "title": "Size"}, "pages": {"type": "integer", "title": "Pages"}}, "additionalProperties": false, "type": "object", "required": ["items", "total", "page", "size", "pages"], "title": "PaginatedResponse[MaintenanceWindowRead]"}, "PaginatedResponse_MonitorCompactRead_": {"properties": {"items": {"items": {"$ref": "#/components/schemas/MonitorCompactRead"}, "type": "array", "title": "Items"}, "total": {"type": "integer", "title": "Total"}, "page": {"type": "integer", "title": "Page"}, "size": {"type": "integer", "title": "Size"}, "pages": {"type": "integer", "title": "Pages"}}, "additionalProperties": false, "type": "object", "required": ["items", "total", "page", "size", "pages"], "title": "PaginatedResponse[MonitorCompactRead]"}, "PaginatedResponse_MonitorListRead_": {"properties": {"items": {"items": {"$ref": "#/components/schemas/MonitorListRead"}, "type": "array", "title": "Items"}, "total": {"type": "integer", "title": "Total"}, "page": {"type": "integer", "title": "Page"}, "size": {"type": "integer", "title": "Size"}, "pages": {"type": "integer", "title": "Pages"}}, "additionalProperties": false, "type": "object", "required": ["items", "total", "page", "size", "pages"], "title": "PaginatedResponse[MonitorListRead]"}, "PaginatedResponse_PageIncidentRead_": {"properties": {"items": {"items": {"$ref": "#/components/schemas/PageIncidentRead"}, "type": "array", "title": "Items"}, "total": {"type": "integer", "title": "Total"}, "page": {"type": "integer", "title": "Page"}, "size": {"type": "integer", "title": "Size"}, "pages": {"type": "integer", "title": "Pages"}}, "additionalProperties": false, "type": "object", "required": ["items", "total", "page", "size", "pages"], "title": "PaginatedResponse[PageIncidentRead]"}, "PaginatedResponse_StatusPageRead_": {"properties": {"items": {"items": {"$ref": "#/components/schemas/StatusPageRead"}, "type": "array", "title": "Items"}, "total": {"type": "integer", "title": "Total"}, "page": {"type": "integer", "title": "Page"}, "size": {"type": "integer", "title": "Size"}, "pages": {"type": "integer", "title": "Pages"}}, "additionalProperties": false, "type": "object", "required": ["items", "total", "page", "size", "pages"], "title": "PaginatedResponse[StatusPageRead]"}, "PlanLimitsRead": {"properties": {"tier": {"$ref": "#/components/schemas/PlanTier"}, "max_monitors": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Monitors"}, "min_interval_seconds": {"type": "integer", "title": "Min Interval Seconds"}, "max_fast_monitors": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Fast Monitors"}, "fast_interval_threshold_seconds": {"type": "integer", "title": "Fast Interval Threshold Seconds"}, "max_regions": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Regions"}, "history_retention_days": {"type": "integer", "title": "History Retention Days"}, "allowed_channel_types": {"items": {"$ref": "#/components/schemas/ChannelType"}, "type": "array", "title": "Allowed Channel Types"}, "max_channels": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Channels"}, "max_heartbeats": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Heartbeats"}, "max_maintenance_windows": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Maintenance Windows"}, "max_status_pages": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Status Pages"}, "max_status_page_subscribers": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Status Page Subscribers"}, "renotify_interval_seconds": {"type": "integer", "title": "Renotify Interval Seconds"}, "renotify_max_count": {"type": "integer", "title": "Renotify Max Count"}, "max_api_keys": {"type": "integer", "title": "Max Api Keys"}, "api_rate_limit_per_minute": {"type": "integer", "title": "Api Rate Limit Per Minute"}, "allowed_regions": {"items": {"type": "string"}, "type": "array", "title": "Allowed Regions"}}, "additionalProperties": false, "type": "object", "required": ["tier", "max_monitors", "min_interval_seconds", "max_fast_monitors", "fast_interval_threshold_seconds", "max_regions", "history_retention_days", "allowed_channel_types", "max_channels", "max_heartbeats", "max_maintenance_windows", "max_status_pages", "max_status_page_subscribers", "renotify_interval_seconds", "renotify_max_count", "max_api_keys", "api_rate_limit_per_minute", "allowed_regions"], "title": "PlanLimitsRead", "description": "Public view of a single plan's limits."}, "PlanTier": {"type": "string", "enum": ["FREE", "PLUS", "PRO", "MAX", "ENTERPRISE"], "title": "PlanTier", "description": "Subscription tier of an organization; gates feature/usage limits."}, "PlanUsageRead": {"properties": {"monitors": {"type": "integer", "minimum": 0.0, "title": "Monitors", "description": "Monitors, paused ones included."}, "fast_monitors": {"type": "integer", "minimum": 0.0, "title": "Fast Monitors", "description": "Monitors with an interval below the fast threshold."}, "heartbeats": {"type": "integer", "minimum": 0.0, "title": "Heartbeats"}}, "additionalProperties": false, "type": "object", "required": ["monitors", "fast_monitors", "heartbeats"], "title": "PlanUsageRead", "description": "How much of its plan an organization uses right now."}, "PlanUsageResponse": {"properties": {"plan": {"$ref": "#/components/schemas/PlanTier"}, "limits": {"$ref": "#/components/schemas/PlanLimitsRead"}, "usage": {"$ref": "#/components/schemas/PlanUsageRead"}}, "additionalProperties": false, "type": "object", "required": ["plan", "limits", "usage"], "title": "PlanUsageResponse", "description": "The organization's plan, its limits and its current usage."}, "PrecheckOutcome": {"type": "string", "enum": ["up", "down", "error", "unknown"], "title": "PrecheckOutcome", "description": "Advisory outcome of a \u04232 pre-check, returned to the create-monitor form.\n\n``UP``/``DOWN``/``ERROR`` map from the worker's ``CheckResultStatus``;\n``UNKNOWN`` is the fail-open value used whenever the core cannot get a\ndefinite reply (no worker in the region, request timeout, malformed reply,\nor the pre-check kill switch). Only ``DOWN``/``ERROR`` should gate the form\nwith a modal; ``UP``/``UNKNOWN`` proceed to create directly."}, "RegionRead": {"properties": {"code": {"type": "string", "title": "Code"}, "display_name": {"type": "string", "title": "Display Name"}, "city": {"type": "string", "title": "City"}, "country_code": {"type": "string", "title": "Country Code"}, "group": {"type": "string", "title": "Group"}, "group_display_name": {"type": "string", "title": "Group Display Name"}}, "additionalProperties": false, "type": "object", "required": ["code", "display_name", "city", "country_code", "group", "group_display_name"], "title": "RegionRead", "description": "A single active check region exposed by ``GET /v1/regions``.\n\n``code`` is the stable identifier (DB value, NATS subject, worker env);\neverything else is display text. The wave-2 transition shim ``name``,\nwhich duplicated ``code``, was removed on 2026-08-04 once the deployed\nfrontend stopped requiring it."}, "RegionResponsePoint": {"properties": {"bucket_start": {"type": "string", "format": "date-time", "title": "Bucket Start"}, "avg_response_time_ms": {"anyOf": [{"type": "integer", "minimum": 0.0}, {"type": "null"}], "title": "Avg Response Time Ms"}, "sample_count": {"type": "integer", "minimum": 0.0, "title": "Sample Count"}}, "additionalProperties": false, "type": "object", "required": ["bucket_start", "sample_count"], "title": "RegionResponsePoint", "description": "Average response time for one region in one fixed-width time bucket.\n\n``avg_response_time_ms`` is ``None`` for a bucket with no successful check\n(a gap, or only failed probes) \u2014 the frontend renders those as a break in\nthe line rather than a fabricated value, the same honest-data rule the\ndaily uptime strip follows."}, "RegionResponseSeries": {"properties": {"region": {"type": "string", "title": "Region"}, "display_name": {"type": "string", "title": "Display Name"}, "points": {"items": {"$ref": "#/components/schemas/RegionResponsePoint"}, "type": "array", "title": "Points"}}, "additionalProperties": false, "type": "object", "required": ["region", "display_name", "points"], "title": "RegionResponseSeries", "description": "One region's dense response-time series over the requested window.\n\n``points`` always holds exactly the window's bucket count, ordered\noldest-first and ending on the bucket the request fell in. Every region the\nmonitor is configured for gets a series, even one with no data yet (a full\nline of no-data points) so the card's region switcher lists them all."}, "RegionStatusRead": {"properties": {"region": {"type": "string", "title": "Region"}, "status": {"$ref": "#/components/schemas/CheckResultStatus"}, "checked_at": {"type": "string", "format": "date-time", "title": "Checked At"}, "display_name": {"type": "string", "title": "Display Name"}}, "additionalProperties": false, "type": "object", "required": ["region", "status", "checked_at", "display_name"], "title": "RegionStatusRead", "description": "Latest probe outcome for one region, derived from a monitor's snapshots.\n\nDrives the dashboard region grid and the per-region status dots. The\nstatus is a per-region :class:`CheckStatus` (``UP`` / ``DOWN`` / ``ERROR``);\nthe aggregate ``DEGRADED`` / ``PAUSED`` states live on the monitor itself,\nnot on a single region."}, "RegionsResponse": {"properties": {"regions": {"items": {"$ref": "#/components/schemas/RegionRead"}, "type": "array", "title": "Regions"}}, "additionalProperties": false, "type": "object", "required": ["regions"], "title": "RegionsResponse", "description": "Region listing response."}, "SslCertInfo": {"properties": {"issuer": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Issuer"}, "subject": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Subject"}, "not_before": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Not Before"}, "not_after": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Not After"}, "valid": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Valid"}}, "type": "object", "title": "SslCertInfo", "description": "Latest TLS certificate snapshot for an SSL monitor (\u04238).\n\nPromoted from an SSL probe's ``CheckResult.details`` onto the monitor row\nso the card/detail render \"what cert, valid until, issued by/when\" without\na per-check query. All fields are nullable \u2014 a partial worker blob or a\nnot-yet-probed monitor leaves them ``None``.\n\n``not_before`` / ``not_after`` are kept as the raw RFC3339 strings the\nworker reported (display echo). The canonical, typed expiry is the\nmonitor's top-level ``ssl_expires_at``; \"expires in N days\" is recomputed\nclient-side from it, never the worker's stale ``days_left``."}, "StatusPageIncidentStatus": {"type": "string", "enum": ["INVESTIGATING", "IDENTIFIED", "MONITORING", "RESOLVED"], "title": "StatusPageIncidentStatus", "description": "Lifecycle of a public incident on a status page. Persisted."}, "StatusPageRead": {"properties": {"id": {"type": "string", "format": "uuid", "title": "Id"}, "slug": {"type": "string", "title": "Slug"}, "name": {"type": "string", "title": "Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "is_published": {"type": "boolean", "title": "Is Published"}, "history_days": {"type": "integer", "title": "History Days"}, "created_at": {"type": "string", "format": "date-time", "title": "Created At"}, "groups": {"items": {"$ref": "#/components/schemas/GroupRead"}, "type": "array", "title": "Groups"}, "ungrouped_components": {"items": {"$ref": "#/components/schemas/ComponentRead"}, "type": "array", "title": "Ungrouped Components"}}, "additionalProperties": false, "type": "object", "required": ["id", "slug", "name", "description", "is_published", "history_days", "created_at", "groups", "ungrouped_components"], "title": "StatusPageRead", "description": "Editor view of a status page and its layout."}, "StatusPageSortOption": {"type": "string", "enum": ["name", "created_at"], "title": "StatusPageSortOption", "description": "Ordering for the status-pages listing endpoint."}, "SuccessResponse": {"properties": {"success": {"type": "boolean", "title": "Success"}}, "additionalProperties": false, "type": "object", "required": ["success"], "title": "SuccessResponse"}, "TagCountRead": {"properties": {"tag": {"type": "string", "title": "Tag"}, "monitor_count": {"type": "integer", "minimum": 0.0, "title": "Monitor Count"}, "heartbeat_count": {"type": "integer", "minimum": 0.0, "title": "Heartbeat Count"}}, "additionalProperties": false, "type": "object", "required": ["tag", "monitor_count", "heartbeat_count"], "title": "TagCountRead", "description": "One tag and how many monitors and heartbeats carry it."}, "TagDeleteResponse": {"properties": {"from": {"type": "string", "title": "From"}, "monitors_updated": {"type": "integer", "minimum": 0.0, "title": "Monitors Updated"}, "heartbeats_updated": {"type": "integer", "minimum": 0.0, "title": "Heartbeats Updated"}}, "additionalProperties": false, "type": "object", "required": ["from", "monitors_updated", "heartbeats_updated"], "title": "TagDeleteResponse", "description": "What a delete actually touched.\n\nWire contract is ``{\"from\": ..., \"monitors_updated\": ...,\n\"heartbeats_updated\": ...}`` \u2014 matching the rename request's own ``from``\nnaming. There is deliberately no ``to``: a delete has no destination tag, so\npublishing a nullable one would let a generated client permit a ``null``\nthat never occurs on this route."}, "TagKind": {"type": "string", "enum": ["monitor", "heartbeat", "all"], "title": "TagKind", "description": "Which aggregate's tags a listing should include.\n\nFilters which tags appear, not which counts are reported: every row always\ncarries both counts, so one cached response serves the monitor form's\nautocomplete, the heartbeat form's autocomplete and both filter dropdowns."}, "TagListResponse": {"properties": {"items": {"items": {"$ref": "#/components/schemas/TagCountRead"}, "type": "array", "title": "Items"}}, "additionalProperties": false, "type": "object", "required": ["items"], "title": "TagListResponse", "description": "The organization's tag dictionary, most-used first."}, "TagMatchMode": {"type": "string", "enum": ["all", "any"], "title": "TagMatchMode", "description": "How a multi-tag filter combines: every tag (``ALL``) or any of them."}, "TagMutationResponse": {"properties": {"from": {"type": "string", "title": "From"}, "to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "To"}, "monitors_updated": {"type": "integer", "minimum": 0.0, "title": "Monitors Updated"}, "heartbeats_updated": {"type": "integer", "minimum": 0.0, "title": "Heartbeats Updated"}}, "additionalProperties": false, "type": "object", "required": ["from", "monitors_updated", "heartbeats_updated"], "title": "TagMutationResponse", "description": "What a rename actually touched.\n\nWire contract is ``{\"from\": ..., \"to\": ..., \"monitors_updated\": ...,\n\"heartbeats_updated\": ...}`` \u2014 matching the request's own ``from``/``to``\nnaming."}, "TagRenameRequest": {"properties": {"from": {"type": "string", "minLength": 1, "title": "From"}, "to": {"type": "string", "minLength": 1, "title": "To"}}, "additionalProperties": false, "type": "object", "required": ["from", "to"], "title": "TagRenameRequest", "description": "Rename one tag across every taggable aggregate of the organization.\n\nThe tag travels in the body, never in the path: ``/`` is a legal tag\ncharacter, and a ``%2F`` path segment is normalized or rejected by nginx and\nthe k3s ingress before FastAPI sees it."}, "UptimeDayPoint": {"properties": {"date": {"type": "string", "format": "date", "title": "Date"}, "uptime_percentage": {"anyOf": [{"type": "number", "maximum": 100.0, "minimum": 0.0}, {"type": "null"}], "title": "Uptime Percentage"}, "total_checks": {"type": "integer", "minimum": 0.0, "title": "Total Checks"}, "up_checks": {"type": "integer", "minimum": 0.0, "title": "Up Checks"}, "down_checks": {"type": "integer", "minimum": 0.0, "title": "Down Checks"}, "degraded_checks": {"type": "integer", "minimum": 0.0, "title": "Degraded Checks", "default": 0}, "maintenance_checks": {"type": "integer", "minimum": 0.0, "title": "Maintenance Checks", "default": 0}, "downtime_seconds": {"type": "integer", "minimum": 0.0, "title": "Downtime Seconds", "description": "Seconds of confirmed downtime inside the day.", "default": 0}, "observed_seconds": {"type": "integer", "minimum": 0.0, "title": "Observed Seconds", "description": "Seconds of the day the monitor was observed; uptime is measured over this time. Never less than downtime_seconds; 0 means no data.", "default": 0}, "degraded_seconds": {"type": "integer", "minimum": 0.0, "title": "Degraded Seconds", "description": "Seconds of this UTC day the monitor spent in confirmed DEGRADED status (from the monitor's status history; an ongoing degradation counts up to now). Maintenance is not subtracted. Zero for days before this monitor's status history began (when the status ledger shipped).", "default": 0}}, "additionalProperties": false, "type": "object", "required": ["date", "uptime_percentage", "total_checks", "up_checks", "down_checks"], "title": "UptimeDayPoint", "description": "Uptime for a single UTC calendar day in the daily strip.\n\n``uptime_percentage`` is ``1 - downtime_seconds / observed_seconds`` over\nthe day (today: up to now; the creation day: from the monitor's creation):\ndowntime comes from the downtime periods of confirmed incidents; observed\ntime is the hours the monitor was actually probed plus those confirmed\ndowntime periods. Unconfirmed DOWN checks and DEGRADED checks do not\nlower it.\n\n``uptime_percentage`` is ``None`` for a day with nothing observed (before\nthe monitor existed, or any gap) \u2014 the frontend renders those as \"no\ndata\" rather than full uptime. Hours probed only during maintenance are\nobserved and count as uptime: a maintenance-only day is ``100.0``.\n\n``degraded_seconds`` is the day's confirmed DEGRADED time from the\nmonitor's status history; the strip colours a day as degraded (amber)\nwhen it is above zero, while its uptime stays green. It does not lower\n``uptime_percentage``.\n\nThe check counters are informational, for the day's tooltip:\n``degraded_checks`` counts raw DEGRADED checks (confirmed or not), and\n``maintenance_checks`` counts checks stamped ``in_maintenance`` and\nexcluded from up/down/degraded."}, "ValidationError": {"properties": {"loc": {"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, "type": "array", "title": "Location"}, "msg": {"type": "string", "title": "Message"}, "type": {"type": "string", "title": "Error Type"}, "input": {"title": "Input"}, "ctx": {"type": "object", "title": "Context"}}, "type": "object", "required": ["loc", "msg", "type"], "title": "ValidationError"}, "ErrorResponse": {"type": "object", "properties": {"error": {"type": "string", "description": "Short, stable classification of the failure."}, "message": {"type": "string", "description": "What went wrong, in a sentence."}}, "required": ["error", "message"]}, "RateLimitErrorResponse": {"type": "object", "properties": {"error": {"type": "string", "description": "Short, stable classification of the failure."}, "message": {"type": "string", "description": "What went wrong, in a sentence."}, "retry_after": {"type": "integer", "description": "Seconds until the bucket refills. Present whenever the limiter knows the reset time; mirrors the `Retry-After` header, which a browser cannot always read on a credentialed request."}}, "required": ["error", "message"]}}, "headers": {"X-RateLimit-Limit": {"description": "Requests allowed in the current window.", "schema": {"type": "integer"}, "example": 1000}, "X-RateLimit-Remaining": {"description": "Requests left in the current window.", "schema": {"type": "integer"}, "example": 987}, "X-RateLimit-Reset": {"description": "Unix timestamp at which the window resets.", "schema": {"type": "integer"}, "example": 1787310000}, "Retry-After": {"description": "Seconds to wait before retrying.", "schema": {"type": "integer"}, "example": 12}}, "securitySchemes": {"ApiKeyBearer": {"type": "http", "scheme": "bearer", "description": "An organization API key, sent as `Authorization: Bearer fettle_...`. Create one in Settings -> API Keys."}}}, "security": [{"ApiKeyBearer": []}]}