From f0b5a9186e9adfac7934c69ae0a57499beea9dc7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 27 Aug 2026 12:07:42 +0000 Subject: [PATCH] chore: update generated API types from latest spec --- docs/openapi/monitoring-api.json | 8663 +++++++++++++++++++----------- src/devhelm/_generated.py | 597 +- 2 files changed, 6054 insertions(+), 3206 deletions(-) diff --git a/docs/openapi/monitoring-api.json b/docs/openapi/monitoring-api.json index 146f30f..2ba9e14 100644 --- a/docs/openapi/monitoring-api.json +++ b/docs/openapi/monitoring-api.json @@ -102,6 +102,14 @@ "name": "Monitor Auth", "description": "Manage authentication configuration for a monitor" }, + { + "name": "Monitor secret requests", + "description": "Secret keys a monitor requires and how they are fulfilled" + }, + { + "name": "Monitor session", + "description": "Cached sign-in session for a monitor" + }, { "name": "Monitors", "description": "Monitor CRUD and lifecycle management" @@ -2129,7 +2137,7 @@ "Audit Log" ], "summary": "List audit events for the current organization", - "operationId": "list_20", + "operationId": "list_21", "parameters": [ { "name": "action", @@ -5637,7 +5645,7 @@ ], "summary": "List all supported integration types", "description": "Returns the full static catalog of supported alert channel integration types with their metadata and config field schemas. Used by the frontend to dynamically render the 'Add Alert Channel' form.", - "operationId": "list_19", + "operationId": "list_20", "responses": { "200": { "description": "OK", @@ -6835,7 +6843,7 @@ "Members" ], "summary": "List organization members", - "operationId": "list_18", + "operationId": "list_19", "parameters": [ { "name": "pageable", @@ -7921,13 +7929,13 @@ } } }, - "/api/v1/monitors/{id}/pause": { + "/api/v1/monitors/{id}/mute": { "post": { "tags": [ "Monitors" ], - "summary": "Pause a monitor (set enabled=false)", - "operationId": "pause", + "summary": "Mute alert delivery without flipping enabled", + "operationId": "mute", "parameters": [ { "name": "id", @@ -7939,6 +7947,15 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MonitorOverlayRequest" + } + } + } + }, "responses": { "200": { "description": "OK", @@ -8033,14 +8050,13 @@ } } }, - "/api/v1/monitors/{id}/results": { - "get": { + "/api/v1/monitors/{id}/pause": { + "post": { "tags": [ - "Check Results" + "Monitors" ], - "summary": "List raw check results", - "description": "Returns check results for the given monitor with optional time-range, region, and pass/fail filtering. Uses cursor-based pagination — pass the returned `cursor` value on subsequent requests to retrieve the next page. The cursor encodes the original time bounds, so `from`/`to` are ignored when a cursor is present.", - "operationId": "getResults", + "summary": "Pause a monitor", + "operationId": "pause", "parameters": [ { "name": "id", @@ -8050,84 +8066,34 @@ "type": "string", "format": "uuid" } - }, - { - "name": "from", - "in": "query", - "description": "Start of time range (ISO 8601, inclusive); defaults to 24 hours ago", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "End of time range (ISO 8601, inclusive); defaults to now", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "cursor", - "in": "query", - "description": "Opaque cursor from a previous response for pagination", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "Maximum results per page (1–200)", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 50 - }, - "example": 50 - }, - { - "name": "region", - "in": "query", - "description": "Filter by region (e.g. us-east)", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "passed", - "in": "query", - "description": "Filter by pass/fail status", - "required": false, - "schema": { - "type": "boolean" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MonitorOverlayRequest" + } + } + } + }, "responses": { "200": { - "description": "Paginated check results", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/CursorPageCheckResultDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } }, "400": { - "description": "Invalid query parameters", + "description": "Bad request — the payload failed validation", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/CursorPageCheckResultDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -8143,21 +8109,21 @@ } }, "403": { - "description": "Monitor does not belong to the caller's org", + "description": "Forbidden — the actor lacks permission for this resource", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/CursorPageCheckResultDto" + "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { - "description": "Monitor not found", + "description": "Not found — the requested resource does not exist", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/CursorPageCheckResultDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -8205,14 +8171,13 @@ } } }, - "/api/v1/monitors/{id}/results/summary": { - "get": { + "/api/v1/monitors/{id}/quarantine": { + "post": { "tags": [ - "Check Results" + "Monitors" ], - "summary": "Get results summary", - "description": "Returns a dashboard summary for the monitor: current status derived from the latest result per region, time-bucketed chart data, the 24-hour uptime percentage, and the selected window's uptime percentage.", - "operationId": "getSummary", + "summary": "Quarantine a monitor", + "operationId": "quarantine", "parameters": [ { "name": "id", @@ -8222,40 +8187,35 @@ "type": "string", "format": "uuid" } - }, - { - "name": "chartWindow", - "in": "query", - "description": "Chart window: 24h returns hourly buckets, 7d/30d/90d return daily buckets", - "required": false, - "schema": { - "type": "string", - "enum": [ - "24h", - "7d", - "30d", - "90d" - ] - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QuarantineMonitorRequest" + } + } + }, + "required": true + }, "responses": { "200": { - "description": "Results summary", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/ResultSummaryDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } }, "400": { - "description": "Invalid chartWindow parameter", + "description": "Bad request — the payload failed validation", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -8271,21 +8231,21 @@ } }, "403": { - "description": "Monitor does not belong to the caller's org", + "description": "Forbidden — the actor lacks permission for this resource", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" + "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { - "description": "Monitor not found", + "description": "Not found — the requested resource does not exist", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -8333,13 +8293,13 @@ } } }, - "/api/v1/monitors/{id}/resume": { + "/api/v1/monitors/{id}/release-quarantine": { "post": { "tags": [ "Monitors" ], - "summary": "Resume a monitor (set enabled=true)", - "operationId": "resume", + "summary": "Release quarantine", + "operationId": "releaseQuarantine", "parameters": [ { "name": "id", @@ -8445,14 +8405,14 @@ } } }, - "/api/v1/monitors/{id}/rotate-token": { - "post": { + "/api/v1/monitors/{id}/results": { + "get": { "tags": [ - "Monitors" + "Check Results" ], - "summary": "Rotate the ping token for a heartbeat monitor", - "description": "Generates a new ping token. The old token remains valid for 24 hours to allow cron jobs to be updated without downtime. Only supported for HEARTBEAT monitors.", - "operationId": "rotateToken", + "summary": "List raw check results", + "description": "Returns check results for the given monitor with optional time-range, region, and pass/fail filtering. Uses cursor-based pagination — pass the returned `cursor` value on subsequent requests to retrieve the next page. The cursor encodes the original time bounds, so `from`/`to` are ignored when a cursor is present.", + "operationId": "getResults", "parameters": [ { "name": "id", @@ -8462,25 +8422,84 @@ "type": "string", "format": "uuid" } + }, + { + "name": "from", + "in": "query", + "description": "Start of time range (ISO 8601, inclusive); defaults to 24 hours ago", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "End of time range (ISO 8601, inclusive); defaults to now", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor from a previous response for pagination", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Maximum results per page (1–200)", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 50 + }, + "example": 50 + }, + { + "name": "region", + "in": "query", + "description": "Filter by region (e.g. us-east)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "passed", + "in": "query", + "description": "Filter by pass/fail status", + "required": false, + "schema": { + "type": "boolean" + } } ], "responses": { "200": { - "description": "OK", + "description": "Paginated check results", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorDto" + "$ref": "#/components/schemas/CursorPageCheckResultDto" } } } }, "400": { - "description": "Bad request — the payload failed validation", + "description": "Invalid query parameters", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/CursorPageCheckResultDto" } } } @@ -8496,21 +8515,21 @@ } }, "403": { - "description": "Forbidden — the actor lacks permission for this resource", + "description": "Monitor does not belong to the caller's org", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/CursorPageCheckResultDto" } } } }, "404": { - "description": "Not found — the requested resource does not exist", + "description": "Monitor not found", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/CursorPageCheckResultDto" } } } @@ -8558,14 +8577,14 @@ } } }, - "/api/v1/monitors/{id}/status-pages": { + "/api/v1/monitors/{id}/results/summary": { "get": { "tags": [ - "Monitors" + "Check Results" ], - "summary": "List status pages that contain this monitor as a component", - "description": "Returns all status pages where this monitor appears as a component, enabling the detail page to show 'Appears On' cross-links.", - "operationId": "listStatusPagesForMonitor", + "summary": "Get results summary", + "description": "Returns a dashboard summary for the monitor: current status derived from the latest result per region, time-bucketed chart data, the 24-hour uptime percentage, and the selected window's uptime percentage.", + "operationId": "getSummary", "parameters": [ { "name": "id", @@ -8575,25 +8594,40 @@ "type": "string", "format": "uuid" } + }, + { + "name": "chartWindow", + "in": "query", + "description": "Chart window: 24h returns hourly buckets, 7d/30d/90d return daily buckets", + "required": false, + "schema": { + "type": "string", + "enum": [ + "24h", + "7d", + "30d", + "90d" + ] + } } ], "responses": { "200": { - "description": "OK", + "description": "Results summary", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageDto" + "$ref": "#/components/schemas/ResultSummaryDto" } } } }, "400": { - "description": "Bad request — the payload failed validation", + "description": "Invalid chartWindow parameter", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" } } } @@ -8609,21 +8643,21 @@ } }, "403": { - "description": "Forbidden — the actor lacks permission for this resource", + "description": "Monitor does not belong to the caller's org", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" } } } }, "404": { - "description": "Not found — the requested resource does not exist", + "description": "Monitor not found", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" } } } @@ -8671,13 +8705,13 @@ } } }, - "/api/v1/monitors/{id}/tags": { - "get": { + "/api/v1/monitors/{id}/resume": { + "post": { "tags": [ "Monitors" ], - "summary": "Get all tags applied to a monitor", - "operationId": "getMonitorTags", + "summary": "Resume a paused monitor", + "operationId": "resume", "parameters": [ { "name": "id", @@ -8695,7 +8729,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -8781,13 +8815,16 @@ } } } - }, + } + }, + "/api/v1/monitors/{id}/rotate-token": { "post": { "tags": [ "Monitors" ], - "summary": "Add tags to a monitor; supports existing tag IDs and inline creation of new tags", - "operationId": "addMonitorTags", + "summary": "Rotate the ping token for a heartbeat monitor", + "description": "Generates a new ping token. The old token remains valid for 24 hours to allow cron jobs to be updated without downtime. Only supported for HEARTBEAT monitors.", + "operationId": "rotateToken", "parameters": [ { "name": "id", @@ -8799,140 +8836,17 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AddMonitorTagsRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" - } - } - } - }, - "400": { - "description": "Bad request — the payload failed validation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "401": { - "description": "Unauthorized — missing or invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "403": { - "description": "Forbidden — the actor lacks permission for this resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "404": { - "description": "Not found — the requested resource does not exist", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "409": { - "description": "Conflict — the request collides with current resource state", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "502": { - "description": "Bad gateway — an upstream provider returned an error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } }, - "503": { - "description": "Service unavailable — try again shortly", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Monitors" - ], - "summary": "Remove tags from a monitor by their IDs", - "operationId": "removeMonitorTags", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RemoveMonitorTagsRequest" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "No Content" - }, "400": { "description": "Bad request — the payload failed validation", "content": { @@ -9016,14 +8930,13 @@ } } }, - "/api/v1/monitors/{id}/test": { - "post": { + "/api/v1/monitors/{id}/secret-requests": { + "get": { "tags": [ - "Monitors" + "Monitor secret requests" ], - "summary": "Test an existing monitor", - "description": "Runs the saved config and assertions of an existing monitor once, without persisting any result. Runs synchronously and returns the same shape as the ad-hoc test. MULTI_STEP_API and BROWSER are rejected with MONITOR_CODE_CHECK_TEST_UNAVAILABLE until fleet dry-run is available.", - "operationId": "testExisting", + "summary": "List secret requests for a monitor", + "operationId": "list_18", "parameters": [ { "name": "id", @@ -9041,7 +8954,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorSecretRequestsDto" } } } @@ -9129,14 +9042,13 @@ } } }, - "/api/v1/monitors/{id}/test-notifications": { - "post": { + "/api/v1/monitors/{id}/secret-requests/{key}": { + "put": { "tags": [ - "Monitors" + "Monitor secret requests" ], - "summary": "Send test notifications through the monitor's alert channels", - "description": "Sends a test alert to all specified channel IDs (must be channels attached to this monitor). If no channelIds are provided, tests all attached channels. Returns per-channel results.", - "operationId": "testNotifications", + "summary": "Attach or clear a remapped secret for a key", + "operationId": "remap", "parameters": [ { "name": "id", @@ -9146,13 +9058,21 @@ "type": "string", "format": "uuid" } + }, + { + "name": "key", + "in": "path", + "required": true, + "schema": { + "type": "string" + } } ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TestMonitorNotificationsRequest" + "$ref": "#/components/schemas/RemapSecretRequest" } } }, @@ -9164,7 +9084,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTestChannelResult" + "$ref": "#/components/schemas/SingleValueResponseMonitorSecretRequestsDto" } } } @@ -9252,14 +9172,13 @@ } } }, - "/api/v1/monitors/{id}/uptime": { - "get": { + "/api/v1/monitors/{id}/secret-requests/rescan": { + "post": { "tags": [ - "Check Results" + "Monitor secret requests" ], - "summary": "Get uptime statistics", - "description": "Returns uptime percentage and latency statistics for the requested time window, computed from continuous aggregates. Uses hourly aggregates for 24h/7d windows and daily aggregates for 30d/90d windows.", - "operationId": "getUptime", + "summary": "Rescan secret requests from the active package", + "operationId": "rescan", "parameters": [ { "name": "id", @@ -9269,40 +9188,25 @@ "type": "string", "format": "uuid" } - }, - { - "name": "window", - "in": "query", - "description": "Time window for uptime calculation", - "required": false, - "schema": { - "type": "string", - "enum": [ - "24h", - "7d", - "30d", - "90d" - ] - } } ], "responses": { "200": { - "description": "Uptime statistics", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/UptimeDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorSecretRequestsDto" } } } }, "400": { - "description": "Invalid window parameter", + "description": "Bad request — the payload failed validation", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseUptimeDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -9318,21 +9222,21 @@ } }, "403": { - "description": "Monitor does not belong to the caller's org", + "description": "Forbidden — the actor lacks permission for this resource", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseUptimeDto" + "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { - "description": "Monitor not found", + "description": "Not found — the requested resource does not exist", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseUptimeDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -9380,14 +9284,13 @@ } } }, - "/api/v1/monitors/{id}/versions": { + "/api/v1/monitors/{id}/session": { "get": { "tags": [ - "Monitors" + "Monitor session" ], - "summary": "List version history for a monitor", - "description": "Returns a paginated list of mutation snapshots for the monitor, newest first. Each version captures the full monitor config at the time of a PUT /monitors/{id} call.", - "operationId": "listVersions", + "summary": "Get the monitor session", + "operationId": "getSession", "parameters": [ { "name": "id", @@ -9397,14 +9300,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "pageable", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/Pageable" - } } ], "responses": { @@ -9413,7 +9308,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultMonitorVersionDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorSessionDto" } } } @@ -9499,140 +9394,16 @@ } } } - } - }, - "/api/v1/monitors/{id}/versions/{version}": { - "get": { - "tags": [ - "Monitors" - ], - "summary": "Get a specific version snapshot for a monitor", - "description": "Returns the full monitor config snapshot captured at the given version number.", - "operationId": "getVersion", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "version", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorVersionDto" - } - } - } - }, - "400": { - "description": "Bad request — the payload failed validation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "401": { - "description": "Unauthorized — missing or invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "403": { - "description": "Forbidden — the actor lacks permission for this resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "404": { - "description": "Not found — the requested resource does not exist", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "409": { - "description": "Conflict — the request collides with current resource state", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "502": { - "description": "Bad gateway — an upstream provider returned an error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "503": { - "description": "Service unavailable — try again shortly", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v1/monitors/{monitorId}/alert-channels": { + }, "put": { "tags": [ - "Monitor Alert Channels" + "Monitor session" ], - "summary": "Replace the linked alert channel set for a monitor", - "operationId": "setChannels", + "summary": "Create or update the monitor session", + "operationId": "putSession", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -9645,7 +9416,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SetAlertChannelsRequest" + "$ref": "#/components/schemas/UpsertMonitorSessionRequest" } } }, @@ -9657,7 +9428,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseListUUID" + "$ref": "#/components/schemas/SingleValueResponseMonitorSessionDto" } } } @@ -9745,16 +9516,16 @@ } } }, - "/api/v1/monitors/{monitorId}/assertions": { + "/api/v1/monitors/{id}/session/renew": { "post": { "tags": [ - "Monitor Assertions" + "Monitor session" ], - "summary": "Add an assertion to a monitor", - "operationId": "add", + "summary": "Renew the monitor session", + "operationId": "renewSession", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -9763,23 +9534,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateAssertionRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "202": { + "description": "Accepted", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" + "$ref": "#/components/schemas/SingleValueResponseRunDto" } } } @@ -9867,25 +9628,16 @@ } } }, - "/api/v1/monitors/{monitorId}/assertions/{assertionId}": { - "put": { + "/api/v1/monitors/{id}/session/revoke": { + "post": { "tags": [ - "Monitor Assertions" + "Monitor session" ], - "summary": "Update an assertion on a monitor", - "operationId": "update_10", + "summary": "Revoke the monitor session", + "operationId": "revokeSession", "parameters": [ { - "name": "monitorId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "assertionId", + "name": "id", "in": "path", "required": true, "schema": { @@ -9894,23 +9646,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateAssertionRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorSessionDto" } } } @@ -9996,25 +9738,19 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{id}/status-pages": { + "get": { "tags": [ - "Monitor Assertions" + "Monitors" ], - "summary": "Remove an assertion from a monitor", - "operationId": "remove_1", + "summary": "List status pages that contain this monitor as a component", + "description": "Returns all status pages where this monitor appears as a component, enabling the detail page to show 'Appears On' cross-links.", + "operationId": "listStatusPagesForMonitor", "parameters": [ { - "name": "monitorId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "assertionId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10024,8 +9760,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -10110,16 +9853,16 @@ } } }, - "/api/v1/monitors/{monitorId}/auth": { - "put": { + "/api/v1/monitors/{id}/tags": { + "get": { "tags": [ - "Monitor Auth" + "Monitors" ], - "summary": "Update authentication config for a monitor", - "operationId": "update_9", + "summary": "Get all tags applied to a monitor", + "operationId": "getMonitorTags", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10128,23 +9871,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateMonitorAuthRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" + "$ref": "#/components/schemas/TableValueResultTagDto" } } } @@ -10233,13 +9966,13 @@ }, "post": { "tags": [ - "Monitor Auth" + "Monitors" ], - "summary": "Set authentication config for a monitor", - "operationId": "set", + "summary": "Add tags to a monitor; supports existing tag IDs and inline creation of new tags", + "operationId": "addMonitorTags", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10252,19 +9985,19 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SetMonitorAuthRequest" + "$ref": "#/components/schemas/AddMonitorTagsRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" + "$ref": "#/components/schemas/TableValueResultTagDto" } } } @@ -10353,13 +10086,13 @@ }, "delete": { "tags": [ - "Monitor Auth" + "Monitors" ], - "summary": "Remove authentication config from a monitor", - "operationId": "remove", + "summary": "Remove tags from a monitor by their IDs", + "operationId": "removeMonitorTags", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10368,6 +10101,16 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RemoveMonitorTagsRequest" + } + } + }, + "required": true + }, "responses": { "204": { "description": "No Content" @@ -10455,19 +10198,18 @@ } } }, - "/api/v1/monitors/{monitorId}/policy": { - "get": { + "/api/v1/monitors/{id}/test": { + "post": { "tags": [ - "Incident Policies" + "Monitors" ], - "summary": "Get incident policy for a monitor", - "description": "Returns the trigger rules, confirmation settings, and recovery settings for the given monitor.", - "operationId": "get_5", + "summary": "Test an existing monitor", + "description": "Runs the saved config and assertions of an existing monitor once, without persisting any result. Runs synchronously and returns the same shape as the ad-hoc test. MULTI_STEP_API and BROWSER are rejected with MONITOR_CODE_CHECK_TEST_UNAVAILABLE until fleet dry-run is available.", + "operationId": "testExisting", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", - "description": "Monitor UUID", "required": true, "schema": { "type": "string", @@ -10477,11 +10219,11 @@ ], "responses": { "200": { - "description": "Policy found", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/IncidentPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" } } } @@ -10517,11 +10259,11 @@ } }, "404": { - "description": "Monitor or policy not found", + "description": "Not found — the requested resource does not exist", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -10567,19 +10309,20 @@ } } } - }, - "put": { + } + }, + "/api/v1/monitors/{id}/test-notifications": { + "post": { "tags": [ - "Incident Policies" + "Monitors" ], - "summary": "Update incident policy for a monitor", - "description": "Replaces the trigger rules, confirmation settings, and recovery settings. All fields are validated before saving.", - "operationId": "update_8", + "summary": "Send test notifications through the monitor's alert channels", + "description": "Sends a test alert to all specified channel IDs (must be channels attached to this monitor). If no channelIds are provided, tests all attached channels. Returns per-channel results.", + "operationId": "testNotifications", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", - "description": "Monitor UUID", "required": true, "schema": { "type": "string", @@ -10591,7 +10334,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateIncidentPolicyRequest" + "$ref": "#/components/schemas/TestMonitorNotificationsRequest" } } }, @@ -10599,21 +10342,21 @@ }, "responses": { "200": { - "description": "Policy updated", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/IncidentPolicyDto" + "$ref": "#/components/schemas/TableValueResultTestChannelResult" } } } }, "400": { - "description": "Validation error in JSONB shape", + "description": "Bad request — the payload failed validation", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -10639,11 +10382,11 @@ } }, "404": { - "description": "Monitor or policy not found", + "description": "Not found — the requested resource does not exist", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -10691,31 +10434,31 @@ } } }, - "/api/v1/monitors/bulk": { + "/api/v1/monitors/{id}/unmute": { "post": { "tags": [ "Monitors" ], - "summary": "Bulk action on monitors", - "description": "Applies PAUSE, RESUME, DELETE, ADD_TAG, or REMOVE_TAG to a list of monitors. Returns a partial-success response indicating which monitors succeeded and which failed.", - "operationId": "bulkAction", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BulkMonitorActionRequest" - } + "summary": "Clear mute overlay", + "operationId": "unmute", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } - }, - "required": true - }, + } + ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseBulkMonitorActionResult" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -10803,41 +10546,57 @@ } } }, - "/api/v1/monitors/test": { - "post": { + "/api/v1/monitors/{id}/uptime": { + "get": { "tags": [ - "Monitors" + "Check Results" ], - "summary": "Ad-hoc monitor test", - "description": "Executes a one-off check from an inline config without saving the monitor. Runs synchronously and returns status code, response time, assertion results, body preview, and headers. MULTI_STEP_API and BROWSER are rejected with MONITOR_CODE_CHECK_TEST_UNAVAILABLE until fleet dry-run is available.", - "operationId": "testAdHoc", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MonitorTestRequest" - } + "summary": "Get uptime statistics", + "description": "Returns uptime percentage and latency statistics for the requested time window, computed from continuous aggregates. Uses hourly aggregates for 24h/7d windows and daily aggregates for 30d/90d windows.", + "operationId": "getUptime", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "required": true - }, + { + "name": "window", + "in": "query", + "description": "Time window for uptime calculation", + "required": false, + "schema": { + "type": "string", + "enum": [ + "24h", + "7d", + "30d", + "90d" + ] + } + } + ], "responses": { "200": { - "description": "OK", + "description": "Uptime statistics", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" + "$ref": "#/components/schemas/UptimeDto" } } } }, "400": { - "description": "Bad request — the payload failed validation", + "description": "Invalid window parameter", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseUptimeDto" } } } @@ -10853,21 +10612,21 @@ } }, "403": { - "description": "Forbidden — the actor lacks permission for this resource", + "description": "Monitor does not belong to the caller's org", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseUptimeDto" } } } }, "404": { - "description": "Not found — the requested resource does not exist", + "description": "Monitor not found", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseUptimeDto" } } } @@ -10915,24 +10674,31 @@ } } }, - "/api/v1/notification-dispatches": { + "/api/v1/monitors/{id}/versions": { "get": { "tags": [ - "Notification Dispatches" + "Monitors" ], - "summary": "List all dispatches for an incident", - "description": "Returns all notification dispatches for the given incident that belong to the authenticated org's policies. Each dispatch includes delivery records for all associated channels.", - "operationId": "listByIncident", + "summary": "List version history for a monitor", + "description": "Returns a paginated list of mutation snapshots for the monitor, newest first. Each version captures the full monitor config at the time of a PUT /monitors/{id} call.", + "operationId": "listVersions", "parameters": [ { - "name": "incident_id", - "in": "query", - "description": "UUID of the incident to inspect", + "name": "id", + "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } } ], "responses": { @@ -10941,7 +10707,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" + "$ref": "#/components/schemas/TableValueResultMonitorVersionDto" } } } @@ -11029,14 +10795,14 @@ } } }, - "/api/v1/notification-dispatches/{id}": { + "/api/v1/monitors/{id}/versions/{version}": { "get": { "tags": [ - "Notification Dispatches" + "Monitors" ], - "summary": "Get a single dispatch with full escalation and delivery history", - "description": "Returns the dispatch state including current escalation step, acknowledgment info, and all delivery attempts made across every step.", - "operationId": "getById_3", + "summary": "Get a specific version snapshot for a monitor", + "description": "Returns the full monitor config snapshot captured at the given version number.", + "operationId": "getVersion", "parameters": [ { "name": "id", @@ -11046,6 +10812,15 @@ "type": "string", "format": "uuid" } + }, + { + "name": "version", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } } ], "responses": { @@ -11054,7 +10829,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorVersionDto" } } } @@ -11142,17 +10917,16 @@ } } }, - "/api/v1/notification-dispatches/{id}/acknowledge": { - "post": { + "/api/v1/monitors/{monitorId}/alert-channels": { + "put": { "tags": [ - "Notification Dispatches" + "Monitor Alert Channels" ], - "summary": "Acknowledge a notification dispatch", - "description": "Marks the dispatch as acknowledged. The dispatch must be in DELIVERED or ESCALATING state. Sets acknowledgedAt, acknowledgedBy (actor email), and acknowledgedVia (DASHBOARD).", - "operationId": "acknowledge", + "summary": "Replace the linked alert channel set for a monitor", + "operationId": "setChannels", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { @@ -11161,13 +10935,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetAlertChannelsRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$ref": "#/components/schemas/SingleValueResponseListUUID" } } } @@ -11255,17 +11039,16 @@ } } }, - "/api/v1/notification-dispatches/{id}/unacknowledge": { + "/api/v1/monitors/{monitorId}/assertions": { "post": { "tags": [ - "Notification Dispatches" + "Monitor Assertions" ], - "summary": "Unacknowledge a notification dispatch", - "description": "Reverses a mistaken acknowledgment without reopening the incident. Allowed only from ACKNOWLEDGED. Clears ack fields, stays on the current escalation step, restores nextEscalationAt, and resumes escalation (ESCALATING if more steps remain, else DELIVERED). MEMBER+.", - "operationId": "unacknowledge", + "summary": "Add an assertion to a monitor", + "operationId": "add", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { @@ -11274,13 +11057,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateAssertionRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" } } } @@ -11368,129 +11161,50 @@ } } }, - "/api/v1/notification-policies": { - "get": { + "/api/v1/monitors/{monitorId}/assertions/{assertionId}": { + "put": { "tags": [ - "Notification Policies" + "Monitor Assertions" ], - "summary": "List all notification policies for the authenticated org", - "operationId": "list_7", - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" - } - } - } - }, - "400": { - "description": "Bad request — the payload failed validation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "401": { - "description": "Unauthorized — missing or invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "403": { - "description": "Forbidden — the actor lacks permission for this resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "404": { - "description": "Not found — the requested resource does not exist", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "409": { - "description": "Conflict — the request collides with current resource state", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "502": { - "description": "Bad gateway — an upstream provider returned an error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + "summary": "Update an assertion on a monitor", + "operationId": "update_10", + "parameters": [ + { + "name": "monitorId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "503": { - "description": "Service unavailable — try again shortly", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + { + "name": "assertionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } - } - }, - "post": { - "tags": [ - "Notification Policies" ], - "summary": "Create a notification policy with match rules and escalation chain", - "operationId": "create_8", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateNotificationPolicyRequest" + "$ref": "#/components/schemas/UpdateAssertionRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" } } } @@ -11576,18 +11290,25 @@ } } } - } - }, - "/api/v1/notification-policies/{id}": { - "get": { + }, + "delete": { "tags": [ - "Notification Policies" + "Monitor Assertions" ], - "summary": "Get a notification policy by ID", - "operationId": "getById_1", + "summary": "Remove an assertion from a monitor", + "operationId": "remove_1", "parameters": [ { - "name": "id", + "name": "monitorId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "assertionId", "in": "path", "required": true, "schema": { @@ -11597,15 +11318,8 @@ } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -11688,16 +11402,18 @@ } } } - }, + } + }, + "/api/v1/monitors/{monitorId}/auth": { "put": { "tags": [ - "Notification Policies" + "Monitor Auth" ], - "summary": "Update a notification policy", - "operationId": "update_7", + "summary": "Update authentication config for a monitor", + "operationId": "update_9", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { @@ -11710,7 +11426,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateNotificationPolicyRequest" + "$ref": "#/components/schemas/UpdateMonitorAuthRequest" } } }, @@ -11722,7 +11438,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" } } } @@ -11809,15 +11525,15 @@ } } }, - "delete": { + "post": { "tags": [ - "Notification Policies" + "Monitor Auth" ], - "summary": "Delete a notification policy", - "operationId": "delete_6", + "summary": "Set authentication config for a monitor", + "operationId": "set", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { @@ -11826,9 +11542,26 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetMonitorAuthRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -11911,76 +11644,27 @@ } } } - } - }, - "/api/v1/notification-policies/{id}/dispatches": { - "get": { + }, + "delete": { "tags": [ - "Notification Policies" + "Monitor Auth" ], - "summary": "List dispatches (firing history) for a notification policy", - "description": "Additive optional query params: since/until/cursor/limit. When all are omitted, returns the full history (legacy). When any is set, defaults to a 30-day window and limit 50, and may include nextCursor. Response remains TableValueResult — no CursorPage swap.", - "operationId": "listDispatches", + "summary": "Remove authentication config from a monitor", + "operationId": "remove", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } - }, - { - "name": "since", - "in": "query", - "description": "Inclusive lower bound (ISO-8601); defaults to now−30d when windowing", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "until", - "in": "query", - "description": "Exclusive upper bound (ISO-8601); defaults to now when windowing", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "cursor", - "in": "query", - "description": "Opaque cursor from a previous nextCursor", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "Page size 1–100 when windowing/paginating (default 50)", - "required": false, - "schema": { - "type": "integer", - "format": "int32" - } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -12065,17 +11749,19 @@ } } }, - "/api/v1/notification-policies/{id}/test": { - "post": { + "/api/v1/monitors/{monitorId}/policy": { + "get": { "tags": [ - "Notification Policies" + "Incident Policies" ], - "summary": "Dry-run: evaluate a policy's match rules against a supplied incident context", - "operationId": "test_1", + "summary": "Get incident policy for a monitor", + "description": "Returns the trigger rules, confirmation settings, and recovery settings for the given monitor.", + "operationId": "get_5", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", + "description": "Monitor UUID", "required": true, "schema": { "type": "string", @@ -12083,22 +11769,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestNotificationPolicyRequest" - } - } - } - }, "responses": { "200": { - "description": "OK", + "description": "Policy found", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseTestMatchResult" + "$ref": "#/components/schemas/IncidentPolicyDto" } } } @@ -12134,11 +11811,11 @@ } }, "404": { - "description": "Not found — the requested resource does not exist", + "description": "Monitor or policy not found", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" } } } @@ -12184,63 +11861,53 @@ } } } - } - }, - "/api/v1/notifications": { - "get": { + }, + "put": { "tags": [ - "Notifications" + "Incident Policies" ], - "summary": "List notifications for the current user", - "operationId": "list_17", + "summary": "Update incident policy for a monitor", + "description": "Replaces the trigger rules, confirmation settings, and recovery settings. All fields are validated before saving.", + "operationId": "update_8", "parameters": [ { - "name": "unreadOnly", - "in": "query", - "required": false, - "schema": { - "type": "boolean", - "default": false - } - }, - { - "name": "page", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 0 - } - }, - { - "name": "size", - "in": "query", - "required": false, + "name": "monitorId", + "in": "path", + "description": "Monitor UUID", + "required": true, "schema": { - "type": "integer", - "format": "int32", - "default": 20 + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateIncidentPolicyRequest" + } + } + }, + "required": true + }, "responses": { "200": { - "description": "OK", + "description": "Policy updated", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDto" + "$ref": "#/components/schemas/IncidentPolicyDto" } } } }, "400": { - "description": "Bad request — the payload failed validation", + "description": "Validation error in JSONB shape", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" } } } @@ -12266,11 +11933,11 @@ } }, "404": { - "description": "Not found — the requested resource does not exist", + "description": "Monitor or policy not found", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" } } } @@ -12318,121 +11985,34 @@ } } }, - "/api/v1/notifications/{id}/read": { - "put": { + "/api/v1/monitors/bulk": { + "post": { "tags": [ - "Notifications" - ], - "summary": "Mark a notification as read", - "operationId": "markRead", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - } + "Monitors" ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad request — the payload failed validation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "401": { - "description": "Unauthorized — missing or invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "403": { - "description": "Forbidden — the actor lacks permission for this resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "404": { - "description": "Not found — the requested resource does not exist", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "409": { - "description": "Conflict — the request collides with current resource state", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "502": { - "description": "Bad gateway — an upstream provider returned an error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "summary": "Bulk action on monitors", + "description": "Applies PAUSE, RESUME, DELETE, ADD_TAG, or REMOVE_TAG to a list of monitors. Returns a partial-success response indicating which monitors succeeded and which failed.", + "operationId": "bulkAction", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkMonitorActionRequest" } } }, - "503": { - "description": "Service unavailable — try again shortly", + "required": true + }, + "responses": { + "200": { + "description": "OK", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseBulkMonitorActionResult" } } } - } - } - } - }, - "/api/v1/notifications/read-all": { - "put": { - "tags": [ - "Notifications" - ], - "summary": "Mark all notifications as read", - "operationId": "markAllRead", - "responses": { - "204": { - "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -12517,20 +12097,30 @@ } } }, - "/api/v1/notifications/unread-count": { - "get": { + "/api/v1/monitors/package-uploads": { + "post": { "tags": [ - "Notifications" + "Monitors" ], - "summary": "Get unread notification count", - "operationId": "unreadCount", + "summary": "Mint a signed package upload URL", + "operationId": "createPackageUpload", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreatePackageUploadRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseLong" + "$ref": "#/components/schemas/SingleValueResponsePackageUploadDto" } } } @@ -12618,20 +12208,31 @@ } } }, - "/api/v1/org": { - "get": { + "/api/v1/monitors/test": { + "post": { "tags": [ - "Organizations" + "Monitors" ], - "summary": "Get the current organization", - "operationId": "get_4", + "summary": "Ad-hoc monitor test", + "description": "Executes a one-off check from an inline config without saving the monitor. Runs synchronously and returns status code, response time, assertion results, body preview, and headers. MULTI_STEP_API and BROWSER are rejected with MONITOR_CODE_CHECK_TEST_UNAVAILABLE until fleet dry-run is available.", + "operationId": "testAdHoc", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MonitorTestRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" } } } @@ -12717,30 +12318,35 @@ } } } - }, - "put": { + } + }, + "/api/v1/notification-dispatches": { + "get": { "tags": [ - "Organizations" + "Notification Dispatches" ], - "summary": "Update the current organization", - "operationId": "update_6", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateOrgDetailsRequest" - } + "summary": "List all dispatches for an incident", + "description": "Returns all notification dispatches for the given incident that belong to the authenticated org's policies. Each dispatch includes delivery records for all associated channels.", + "operationId": "listByIncident", + "parameters": [ + { + "name": "incident_id", + "in": "query", + "description": "UUID of the incident to inspect", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } - }, - "required": true - }, + } + ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" + "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" } } } @@ -12828,20 +12434,32 @@ } } }, - "/api/v1/resource-groups": { + "/api/v1/notification-dispatches/{id}": { "get": { "tags": [ - "Resource Groups" + "Notification Dispatches" + ], + "summary": "Get a single dispatch with full escalation and delivery history", + "description": "Returns the dispatch state including current escalation step, acknowledgment info, and all delivery attempts made across every step.", + "operationId": "getById_3", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } ], - "summary": "List all resource groups for the authenticated org with health summaries", - "operationId": "list_6", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultResourceGroupDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" } } } @@ -12927,30 +12545,34 @@ } } } - }, + } + }, + "/api/v1/notification-dispatches/{id}/acknowledge": { "post": { "tags": [ - "Resource Groups" + "Notification Dispatches" ], - "summary": "Create a new resource group", - "operationId": "create_7", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateResourceGroupRequest" - } + "summary": "Acknowledge a notification dispatch", + "description": "Marks the dispatch as acknowledged. The dispatch must be in DELIVERED or ESCALATING state. Sets acknowledgedAt, acknowledgedBy (actor email), and acknowledgedVia (DASHBOARD).", + "operationId": "acknowledge", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } - }, - "required": true - }, + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" } } } @@ -13038,14 +12660,14 @@ } } }, - "/api/v1/resource-groups/{id}": { - "get": { + "/api/v1/notification-dispatches/{id}/unacknowledge": { + "post": { "tags": [ - "Resource Groups" + "Notification Dispatches" ], - "summary": "Get a resource group by id with member statuses and inherited settings", - "description": "Pass includeMetrics=true to enrich each member with 24h uptime, chart data, and latency metrics.", - "operationId": "get_3", + "summary": "Unacknowledge a notification dispatch", + "description": "Reverses a mistaken acknowledgment without reopening the incident. Allowed only from ACKNOWLEDGED. Clears ack fields, stays on the current escalation step, restores nextEscalationAt, and resumes escalation (ESCALATING if more steps remain, else DELIVERED). MEMBER+.", + "operationId": "unacknowledge", "parameters": [ { "name": "id", @@ -13055,15 +12677,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "includeMetrics", - "in": "query", - "required": false, - "schema": { - "type": "boolean", - "default": false - } } ], "responses": { @@ -13072,7 +12685,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" } } } @@ -13158,41 +12771,22 @@ } } } - }, - "put": { + } + }, + "/api/v1/notification-policies": { + "get": { "tags": [ - "Resource Groups" - ], - "summary": "Update a resource group's name, description, alert policy, inherited settings, and health threshold", - "operationId": "update_5", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "Notification Policies" ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateResourceGroupRequest" - } - } - }, - "required": true - }, + "summary": "List all notification policies for the authenticated org", + "operationId": "list_7", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" + "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" } } } @@ -13279,26 +12873,32 @@ } } }, - "delete": { + "post": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "Delete a resource group (cascades to member rows)", - "operationId": "delete_5", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" + "summary": "Create a notification policy with match rules and escalation chain", + "operationId": "create_8", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateNotificationPolicyRequest" + } } - } - ], + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -13383,14 +12983,13 @@ } } }, - "/api/v1/resource-groups/{id}/health": { + "/api/v1/notification-policies/{id}": { "get": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "Get the detailed health breakdown for a resource group", - "description": "Returns member counts, worst-of status, and threshold-based health evaluation. The thresholdStatus field is populated only when a health threshold is configured.", - "operationId": "getHealth", + "summary": "Get a notification policy by ID", + "operationId": "getById_1", "parameters": [ { "name": "id", @@ -13408,7 +13007,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupHealthDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" } } } @@ -13494,16 +13093,13 @@ } } } - } - }, - "/api/v1/resource-groups/{id}/matched-policies": { - "get": { + }, + "put": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "List notification policies that match this resource group", - "description": "Policies whose match rules evaluate true for a DEGRADED or DOWN group-origin INCIDENT_CREATED context on this resource group (includes paused)", - "operationId": "listMatchedPolicies", + "summary": "Update a notification policy", + "operationId": "update_7", "parameters": [ { "name": "id", @@ -13515,13 +13111,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateNotificationPolicyRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" } } } @@ -13607,15 +13213,13 @@ } } } - } - }, - "/api/v1/resource-groups/{id}/members": { - "post": { + }, + "delete": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "Add a monitor or service member to a resource group", - "operationId": "addMember_1", + "summary": "Delete a notification policy", + "operationId": "delete_6", "parameters": [ { "name": "id", @@ -13627,26 +13231,9 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AddResourceGroupMemberRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupMemberDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -13731,13 +13318,14 @@ } } }, - "/api/v1/resource-groups/{id}/members/{memberId}": { - "delete": { + "/api/v1/notification-policies/{id}/dispatches": { + "get": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "Remove a member from a resource group", - "operationId": "removeMember_1", + "summary": "List dispatches (firing history) for a notification policy", + "description": "Optional query params: since/until/cursor/limit. When all are omitted, returns the full history (legacy). When any is set, defaults to a 30-day window and limit 50. Response is CursorPage (hasMore + nextCursor), the same wrapper used by other append-only history endpoints.", + "operationId": "listDispatches", "parameters": [ { "name": "id", @@ -13749,18 +13337,55 @@ } }, { - "name": "memberId", - "in": "path", - "required": true, + "name": "since", + "in": "query", + "description": "Inclusive lower bound (ISO-8601); defaults to now−30d when windowing", + "required": false, "schema": { "type": "string", - "format": "uuid" + "format": "date-time" + } + }, + { + "name": "until", + "in": "query", + "description": "Exclusive upper bound (ISO-8601); defaults to now when windowing", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor from a previous nextCursor", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size 1–100 when windowing/paginating (default 50)", + "required": false, + "schema": { + "type": "integer", + "format": "int32" } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/CursorPageNotificationDispatchDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -13845,20 +13470,40 @@ } } }, - "/api/v1/secrets": { - "get": { + "/api/v1/notification-policies/{id}/test": { + "post": { "tags": [ - "Secrets" + "Notification Policies" ], - "summary": "List secrets", - "operationId": "list_5", + "summary": "Dry-run: evaluate a policy's match rules against a supplied incident context", + "operationId": "test_1", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestNotificationPolicyRequest" + } + } + } + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultSecretDto" + "$ref": "#/components/schemas/SingleValueResponseTestMatchResult" } } } @@ -13944,30 +13589,53 @@ } } } - }, - "post": { + } + }, + "/api/v1/notifications": { + "get": { "tags": [ - "Secrets" + "Notifications" ], - "summary": "Create secret", - "operationId": "create_6", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSecretRequest" - } + "summary": "List notifications for the current user", + "operationId": "list_17", + "parameters": [ + { + "name": "unreadOnly", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": false } }, - "required": true - }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 0 + } + }, + { + "name": "size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 20 + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseSecretDto" + "$ref": "#/components/schemas/TableValueResultNotificationDto" } } } @@ -14055,43 +13723,27 @@ } } }, - "/api/v1/secrets/{key}": { + "/api/v1/notifications/{id}/read": { "put": { "tags": [ - "Secrets" + "Notifications" ], - "summary": "Update secret", - "operationId": "update_4", + "summary": "Mark a notification as read", + "operationId": "markRead", "parameters": [ { - "name": "key", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" + "type": "integer", + "format": "int64" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateSecretRequest" - } - } - }, - "required": true - }, "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseSecretDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -14174,23 +13826,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/notifications/read-all": { + "put": { "tags": [ - "Secrets" - ], - "summary": "Delete secret", - "operationId": "delete_4", - "parameters": [ - { - "name": "key", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } + "Notifications" ], + "summary": "Mark all notifications as read", + "operationId": "markAllRead", "responses": { "204": { "description": "No Content" @@ -14278,20 +13922,20 @@ } } }, - "/api/v1/service-subscriptions": { + "/api/v1/notifications/unread-count": { "get": { "tags": [ - "Service Subscriptions" + "Notifications" ], - "summary": "List all service subscriptions for the organization", - "operationId": "list_16", + "summary": "Get unread notification count", + "operationId": "unreadCount", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultServiceSubscriptionDto" + "$ref": "#/components/schemas/SingleValueResponseLong" } } } @@ -14379,31 +14023,20 @@ } } }, - "/api/v1/service-subscriptions/{id}": { + "/api/v1/org": { "get": { "tags": [ - "Service Subscriptions" - ], - "summary": "Get a subscription by its ID", - "operationId": "get_11", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "Organizations" ], + "summary": "Get the current organization", + "operationId": "get_4", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" } } } @@ -14490,27 +14123,32 @@ } } }, - "delete": { + "put": { "tags": [ - "Service Subscriptions" + "Organizations" ], - "summary": "Remove a subscription by its ID", - "description": "Removes a specific subscription (whole-service or component-level). No-op if not found.", - "operationId": "unsubscribe_1", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" + "summary": "Update the current organization", + "operationId": "update_6", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOrgDetailsRequest" + } } - } - ], + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -14595,42 +14233,20 @@ } } }, - "/api/v1/service-subscriptions/{id}/alert-sensitivity": { - "patch": { + "/api/v1/resource-groups": { + "get": { "tags": [ - "Service Subscriptions" - ], - "summary": "Update alert sensitivity for a subscription", - "description": "Controls which external incidents trigger alerts and whether they page anyone: ALL (any status change, paged), INCIDENTS_ONLY (real vendor incidents, paged), MAJOR_ONLY (only DOWN-level incidents, paged), AWARENESS (real vendor incidents tracked silently — visible on the dashboard but no alert channels fire; default for new subscriptions).", - "operationId": "updateAlertSensitivity", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "Resource Groups" ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateAlertSensitivityRequest" - } - } - }, - "required": true - }, + "summary": "List all resource groups for the authenticated org with health summaries", + "operationId": "list_6", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + "$ref": "#/components/schemas/TableValueResultResourceGroupDto" } } } @@ -14716,34 +14332,22 @@ } } } - } - }, - "/api/v1/service-subscriptions/{slug}": { + }, "post": { "tags": [ - "Service Subscriptions" - ], - "summary": "Subscribe to a service or a component of a service", - "description": "Idempotent — returns the existing subscription if an identical one exists. Omit the request body or set componentId to null for a whole-service subscription. When alertSensitivity is omitted, new subscriptions default to AWARENESS (silent tracking — the incident appears on the dashboard but no alert channels fire). PATCH /alert-sensitivity to opt in to paging. Free tier: max 10 subscriptions. Paid tier: unlimited.", - "operationId": "subscribe_1", - "parameters": [ - { - "name": "slug", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } + "Resource Groups" ], + "summary": "Create a new resource group", + "operationId": "create_7", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ServiceSubscribeRequest" + "$ref": "#/components/schemas/CreateResourceGroupRequest" } } - } + }, + "required": true }, "responses": { "201": { @@ -14751,7 +14355,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -14839,86 +14443,31 @@ } } }, - "/api/v1/services": { + "/api/v1/resource-groups/{id}": { "get": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "List all enabled services (cursor-paginated)", - "operationId": "listServices", + "summary": "Get a resource group by id with member statuses and inherited settings", + "description": "Pass includeMetrics=true to enrich each member with 24h uptime, chart data, and latency metrics.", + "operationId": "get_3", "parameters": [ { - "name": "category", - "in": "query", - "description": "Filter by category (exact match)", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "status", - "in": "query", - "description": "Filter by current overall_status (exact match)", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "published", - "in": "query", - "description": "Filter by published status for pSEO pages", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "slaPublished", - "in": "query", - "description": "Filter by SLA page publication status", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "search", - "in": "query", - "description": "Case-insensitive substring match on service name or slug", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Result ordering: 'recent' (default, newest first) or 'curated' (curated/recognizable first)", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "cursor", - "in": "query", - "description": "Opaque cursor from a previous response", - "required": false, + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } }, { - "name": "limit", + "name": "includeMetrics", "in": "query", - "description": "Page size (1–100, default 20)", "required": false, "schema": { - "type": "integer", - "format": "int32", - "default": 20 + "type": "boolean", + "default": false } } ], @@ -14928,7 +14477,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/CursorPageServiceCatalogDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -15014,53 +14563,41 @@ } } } - } - }, - "/api/v1/services/{slugOrId}": { - "get": { + }, + "put": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "Get a single service by slug or UUID with current status, components, and recent incidents", - "description": "When ``summary=true``, the inline ``components`` list is trimmed to groups + showcase leaves + currently-impacted leaves + ungrouped leaves, and a ``componentsSummary`` block is added with the trimmed counts. Powers SSR for vendors with hundreds of components (Snowflake, Cloudflare, DigitalOcean) without OOM-ing the renderer. Default false for full back-compat.", - "operationId": "getService", + "summary": "Update a resource group's name, description, alert policy, inherited settings, and health threshold", + "operationId": "update_5", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" - } - }, - { - "name": "summary", - "in": "query", - "description": "Return a curated subset of components (groups + showcase + impacted + ungrouped) and a componentsSummary block; default false", - "required": false, - "schema": { - "type": "boolean", - "default": false - } - }, - { - "name": "publishedOnly", - "in": "query", - "description": "Resolve only published services (curated public pSEO set); 404 otherwise. Default false", - "required": false, - "schema": { - "type": "boolean", - "default": false + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateResourceGroupRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceDetailDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -15146,75 +14683,27 @@ } } } - } - }, - "/api/v1/services/{slugOrId}/components": { - "get": { + }, + "delete": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "List active components for a service with current status and inline uptime", - "description": "When ``groupId`` is supplied, only direct children of that group are returned — used by the pSEO renderer to lazy-load the leaves under a group that summary mode trimmed. Without ``groupId`` the response includes every active component for the service. Supports pagination via ``page``/``size`` and case-insensitive name search via ``search``.", - "operationId": "getComponents", + "summary": "Delete a resource group (cascades to member rows)", + "operationId": "delete_5", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Restrict result to direct children of this group component id", - "required": false, "schema": { "type": "string", "format": "uuid" } - }, - { - "name": "search", - "in": "query", - "description": "Case-insensitive substring match on component name", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "Zero-based page index", - "required": false, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "size", - "in": "query", - "description": "Page size (default 25, max 100)", - "required": false, - "schema": { - "type": "integer", - "format": "int32" - } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultServiceComponentDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -15299,66 +14788,23 @@ } } }, - "/api/v1/services/{slugOrId}/components/{componentId}/uptime": { + "/api/v1/resource-groups/{id}/health": { "get": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "Get daily uptime data for a component", - "description": "Pass either ``period`` (preset window) or an explicit ``from``/``to`` calendar window (ISO yyyy-MM-dd, max 730 days, ``to`` defaults to today). When both are supplied, the explicit window wins.", - "operationId": "getComponentUptime", + "summary": "Get the detailed health breakdown for a resource group", + "description": "Returns member counts, worst-of status, and threshold-based health evaluation. The thresholdStatus field is populated only when a health threshold is configured.", + "operationId": "getHealth", "parameters": [ { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "componentId", + "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } - }, - { - "name": "period", - "in": "query", - "description": "Preset time window (used when ``from`` is omitted)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "7d", - "30d", - "90d", - "1y" - ] - } - }, - { - "name": "from", - "in": "query", - "description": "Explicit window start (ISO date); overrides ``period``", - "required": false, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "to", - "in": "query", - "description": "Explicit window end (ISO date); defaults to today", - "required": false, - "schema": { - "type": "string", - "format": "date" - } } ], "responses": { @@ -15367,7 +14813,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupHealthDto" } } } @@ -15455,56 +14901,22 @@ } } }, - "/api/v1/services/{slugOrId}/components/uptime": { + "/api/v1/resource-groups/{id}/matched-policies": { "get": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "Batch daily uptime data for all leaf components", - "description": "Returns daily uptime for every active non-group component with uptime data, keyed by component ID. Replaces N individual per-component uptime calls with a single request. Supports either a preset ``period`` or an explicit ``from``/``to`` window (ISO yyyy-MM-dd, max 730 days). The explicit window wins when both are supplied — this is what powers the sliding 90-day navigator on the public uptime history page.", - "operationId": "getBatchComponentUptime", + "summary": "List notification policies that match this resource group", + "description": "Policies whose match rules evaluate true for a DEGRADED or DOWN group-origin INCIDENT_CREATED context on this resource group (includes paused)", + "operationId": "listMatchedPolicies", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "period", - "in": "query", - "description": "Preset time window (used when ``from`` is omitted)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "7d", - "30d", - "90d", - "1y" - ] - } - }, - { - "name": "from", - "in": "query", - "description": "Explicit window start (ISO date); overrides ``period``", - "required": false, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "to", - "in": "query", - "description": "Explicit window end (ISO date); defaults to today", - "required": false, "schema": { "type": "string", - "format": "date" + "format": "uuid" } } ], @@ -15514,7 +14926,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseBatchComponentUptimeDto" + "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" } } } @@ -15602,41 +15014,41 @@ } } }, - "/api/v1/services/{slugOrId}/days/{date}": { - "get": { + "/api/v1/resource-groups/{id}/members": { + "post": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "One-day rollup for a service: aggregated uptime, per-component impacts, and overlapping incidents", - "description": "Powers the click/hover-to-expand panel under each uptime bar on the public status page. Single round-trip — components, sums, and overlapping incidents (with affected component names) are returned in one response.", - "operationId": "getServiceDayDetail", + "summary": "Add a monitor or service member to a resource group", + "operationId": "addMember_1", "parameters": [ { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "date", + "name": "id", "in": "path", - "description": "UTC calendar day in ISO format (YYYY-MM-DD)", "required": true, "schema": { "type": "string", - "format": "date" + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddResourceGroupMemberRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceDayDetailDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupMemberDto" } } } @@ -15724,64 +15136,36 @@ } } }, - "/api/v1/services/{slugOrId}/incidents": { - "get": { + "/api/v1/resource-groups/{id}/members/{memberId}": { + "delete": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "List incident history for a service (paginated)", - "operationId": "listIncidents_1", + "summary": "Remove a member from a resource group", + "operationId": "removeMember_1", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "from", - "in": "query", - "description": "Earliest start date (ISO 8601 date)", - "required": false, "schema": { "type": "string", - "format": "date" - } - }, - { - "name": "status", - "in": "query", - "description": "Filter: active (unresolved), resolved, or omit for all", - "required": false, - "schema": { - "type": "string", - "enum": [ - "active", - "resolved" - ] + "format": "uuid" } }, { - "name": "pageable", - "in": "query", + "name": "memberId", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -15866,39 +15250,20 @@ } } }, - "/api/v1/services/{slugOrId}/incidents/{incidentId}": { + "/api/v1/secrets": { "get": { "tags": [ - "Status Data" - ], - "summary": "Get incident detail with full update timeline", - "operationId": "getIncident_1", - "parameters": [ - { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "incidentId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "Secrets" ], + "summary": "List organization secrets", + "operationId": "list_5", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceIncidentDetailDto" + "$ref": "#/components/schemas/TableValueResultSecretDto" } } } @@ -15984,33 +15349,30 @@ } } } - } - }, - "/api/v1/services/{slugOrId}/live-status": { - "get": { + }, + "post": { "tags": [ - "Status Data" + "Secrets" ], - "summary": "Lightweight live-status snapshot for polling", - "description": "Returns only the current overall status, component statuses, and active incident count. Designed for frequent polling with minimal payload.", - "operationId": "getServiceLiveStatus", - "parameters": [ - { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" + "summary": "Create secret", + "operationId": "create_6", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSecretRequest" + } } - } - ], + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceLiveStatusDto" + "$ref": "#/components/schemas/SingleValueResponseSecretDto" } } } @@ -16098,42 +15460,40 @@ } } }, - "/api/v1/services/{slugOrId}/maintenances": { - "get": { + "/api/v1/secrets/{key}": { + "put": { "tags": [ - "Status Data" + "Secrets" ], - "summary": "List scheduled maintenances for a service", - "operationId": "getScheduledMaintenances", + "summary": "Update secret", + "operationId": "update_4", "parameters": [ { - "name": "slugOrId", + "name": "key", "in": "path", "required": true, "schema": { "type": "string" } - }, - { - "name": "status", - "in": "query", - "description": "Filter by status (e.g. scheduled, in_progress, verifying, completed)", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string" - } - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSecretRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultScheduledMaintenanceDto" + "$ref": "#/components/schemas/SingleValueResponseSecretDto" } } } @@ -16219,55 +15579,26 @@ } } } - } - }, - "/api/v1/services/{slugOrId}/poll-results": { - "get": { + }, + "delete": { "tags": [ - "Status Data" + "Secrets" ], - "summary": "List poll results for a service (cursor-paginated)", - "operationId": "listPollResults", + "summary": "Delete secret", + "operationId": "delete_4", "parameters": [ { - "name": "slugOrId", + "name": "key", "in": "path", "required": true, "schema": { "type": "string" } - }, - { - "name": "cursor", - "in": "query", - "description": "ISO 8601 timestamp cursor from a previous response", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "Page size (1–100, default 50)", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 50 - } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/CursorPageServicePollResultDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -16352,35 +15683,21 @@ } } }, - "/api/v1/services/{slugOrId}/poll-summary": { + "/api/v1/secrets/{key}/audit": { "get": { "tags": [ - "Status Data" + "Secrets" ], - "summary": "Get aggregated poll metrics and chart data for a service", - "operationId": "getPollSummary", + "summary": "Last update metadata for a secret", + "operationId": "audit", "parameters": [ { - "name": "slugOrId", + "name": "key", "in": "path", "required": true, "schema": { "type": "string" } - }, - { - "name": "window", - "in": "query", - "description": "Time window", - "required": false, - "schema": { - "type": "string", - "enum": [ - "24h", - "7d", - "30d" - ] - } } ], "responses": { @@ -16389,7 +15706,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServicePollSummaryDto" + "$ref": "#/components/schemas/SingleValueResponseSecretAuditDto" } } } @@ -16477,17 +15794,16 @@ } } }, - "/api/v1/services/{slugOrId}/status-events": { - "get": { + "/api/v1/secrets/{key}/environments/{environmentId}": { + "put": { "tags": [ - "Status Data" + "Secrets" ], - "summary": "List curated vendor status events for a service", - "description": "Reverse-chronological merge of vendor incidents, maintenances, and rolled-up component transitions for the Dependencies Detail rail. Optional JWT + x-phelm-org-id annotates incident.opened rows with the caller's linked internal incident.", - "operationId": "listStatusEvents", + "summary": "Write a secret value for one environment", + "operationId": "writeEnvironmentValue", "parameters": [ { - "name": "slugOrId", + "name": "key", "in": "path", "required": true, "schema": { @@ -16495,66 +15811,126 @@ } }, { - "name": "types", - "in": "query", - "description": "Comma-separated type buckets: incident, maintenance, component (default: all)", - "required": false, + "name": "environmentId", + "in": "path", + "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WriteSecretEnvironmentValueRequest" + } } }, - { - "name": "period", - "in": "query", - "description": "Preset window", - "required": false, - "schema": { - "type": "string", - "enum": [ - "7d", - "30d", - "90d" - ] + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } }, - { - "name": "from", - "in": "query", - "description": "Explicit lower bound (ISO 8601); overrides period", - "required": false, - "schema": { - "type": "string", - "format": "date-time" + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } }, - { - "name": "to", - "in": "query", - "description": "Explicit upper bound (ISO 8601); default now", - "required": false, - "schema": { - "type": "string", - "format": "date-time" + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } }, - { - "name": "cursor", - "in": "query", - "description": "Opaque cursor from a previous response", - "required": false, - "schema": { - "type": "string" + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/secrets/{key}/usage": { + "get": { + "tags": [ + "Secrets" + ], + "summary": "Secret usage across monitors", + "operationId": "usage", + "parameters": [ { - "name": "limit", - "in": "query", - "description": "Page size (1–100, default 50)", - "required": false, + "name": "key", + "in": "path", + "required": true, "schema": { - "type": "integer", - "format": "int32", - "default": 50 + "type": "string" } } ], @@ -16564,7 +15940,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/CursorPageStatusEventDto" + "$ref": "#/components/schemas/SingleValueResponseSecretUsageDto" } } } @@ -16652,63 +16028,20 @@ } } }, - "/api/v1/services/{slugOrId}/uptime": { + "/api/v1/service-subscriptions": { "get": { "tags": [ - "Status Data" - ], - "summary": "Get uptime statistics for a service", - "description": "Uptime data aggregated across active non-group components.", - "operationId": "getServiceUptime", - "parameters": [ - { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "period", - "in": "query", - "description": "Time window", - "required": false, - "schema": { - "type": "string", - "enum": [ - "24h", - "7d", - "30d", - "90d", - "1y", - "2y", - "all" - ] - } - }, - { - "name": "granularity", - "in": "query", - "description": "Bucket granularity", - "required": false, - "schema": { - "type": "string", - "enum": [ - "hourly", - "daily", - "monthly" - ] - } - } + "Service Subscriptions" ], + "summary": "List all service subscriptions for the organization", + "operationId": "list_16", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceUptimeResponse" + "$ref": "#/components/schemas/TableValueResultServiceSubscriptionDto" } } } @@ -16793,61 +16126,24 @@ } } } - }, - "security": [ - { - "BearerAuth": [] - } - ] + } } }, - "/api/v1/services/incidents": { + "/api/v1/service-subscriptions/{id}": { "get": { "tags": [ - "Status Data" + "Service Subscriptions" ], - "summary": "List vendor incidents across all services (paginated)", - "description": "Cross-service vendor incident feed ordered by start date descending.", - "operationId": "listCrossServiceIncidents", + "summary": "Get a subscription by its ID", + "operationId": "get_11", "parameters": [ { - "name": "from", - "in": "query", - "description": "Earliest start date (ISO 8601 date)", - "required": false, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "status", - "in": "query", - "description": "Filter: active (unresolved), resolved, or omit for all", - "required": false, - "schema": { - "type": "string", - "enum": [ - "active", - "resolved" - ] - } - }, - { - "name": "category", - "in": "query", - "description": "Filter by service category", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "pageable", - "in": "query", + "name": "id", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" } } ], @@ -16857,7 +16153,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" } } } @@ -16943,38 +16239,28 @@ } } } - } - }, - "/api/v1/services/summary": { - "get": { + }, + "delete": { "tags": [ - "Status Data" + "Service Subscriptions" ], - "summary": "Global status summary across all services", - "description": "Returns aggregate counts of services by status and a list of services currently experiencing issues.", - "operationId": "getGlobalStatusSummary", + "summary": "Remove a subscription by its ID", + "description": "Removes a specific subscription (whole-service or component-level). No-op if not found.", + "operationId": "unsubscribe_1", "parameters": [ { - "name": "publishedOnly", - "in": "query", - "description": "Aggregate only published services (curated public pSEO set); default false", - "required": false, + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "boolean", - "default": false + "type": "string", + "format": "uuid" } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseGlobalStatusSummaryDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -17059,20 +16345,42 @@ } } }, - "/api/v1/status-pages": { - "get": { + "/api/v1/service-subscriptions/{id}/alert-sensitivity": { + "patch": { "tags": [ - "Status Pages" + "Service Subscriptions" ], - "summary": "List status pages for the workspace", - "operationId": "list_4", + "summary": "Update alert sensitivity for a subscription", + "description": "Controls which external incidents trigger alerts and whether they page anyone: ALL (any status change, paged), INCIDENTS_ONLY (real vendor incidents, paged), MAJOR_ONLY (only DOWN-level incidents, paged), AWARENESS (real vendor incidents tracked silently — visible on the dashboard but no alert channels fire; default for new subscriptions).", + "operationId": "updateAlertSensitivity", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateAlertSensitivityRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageDto" + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" } } } @@ -17158,22 +16466,34 @@ } } } - }, + } + }, + "/api/v1/service-subscriptions/{slug}": { "post": { "tags": [ - "Status Pages" + "Service Subscriptions" + ], + "summary": "Subscribe to a service or a component of a service", + "description": "Idempotent — returns the existing subscription if an identical one exists. Omit the request body or set componentId to null for a whole-service subscription. When alertSensitivity is omitted, new subscriptions default to AWARENESS (silent tracking — the incident appears on the dashboard but no alert channels fire). PATCH /alert-sensitivity to opt in to paging. Free tier: max 10 subscriptions. Paid tier: unlimited.", + "operationId": "subscribe_1", + "parameters": [ + { + "name": "slug", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } ], - "summary": "Create a status page", - "operationId": "create_5", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateStatusPageRequest" + "$ref": "#/components/schemas/ServiceSubscribeRequest" } } - }, - "required": true + } }, "responses": { "201": { @@ -17181,7 +16501,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" } } } @@ -17269,21 +16589,86 @@ } } }, - "/api/v1/status-pages/{id}": { + "/api/v1/services": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Get a status page", - "operationId": "get_2", + "summary": "List all enabled services (cursor-paginated)", + "operationId": "listServices", "parameters": [ { - "name": "id", - "in": "path", - "required": true, + "name": "category", + "in": "query", + "description": "Filter by category (exact match)", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "Filter by current overall_status (exact match)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "published", + "in": "query", + "description": "Filter by published status for pSEO pages", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "slaPublished", + "in": "query", + "description": "Filter by SLA page publication status", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "search", + "in": "query", + "description": "Case-insensitive substring match on service name or slug", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Result ordering: 'recent' (default, newest first) or 'curated' (curated/recognizable first)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor from a previous response", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size (1–100, default 20)", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 20 } } ], @@ -17293,7 +16678,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + "$ref": "#/components/schemas/CursorPageServiceCatalogDto" } } } @@ -17379,41 +16764,53 @@ } } } - }, - "put": { + } + }, + "/api/v1/services/{slugOrId}": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Update a status page", - "operationId": "update_3", + "summary": "Get a single service by slug or UUID with current status, components, and recent incidents", + "description": "When ``summary=true``, the inline ``components`` list is trimmed to groups + showcase leaves + currently-impacted leaves + ungrouped leaves, and a ``componentsSummary`` block is added with the trimmed counts. Powers SSR for vendors with hundreds of components (Snowflake, Cloudflare, DigitalOcean) without OOM-ing the renderer. Default false for full back-compat.", + "operationId": "getService", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageRequest" - } + }, + { + "name": "summary", + "in": "query", + "description": "Return a curated subset of components (groups + showcase + impacted + ungrouped) and a componentsSummary block; default false", + "required": false, + "schema": { + "type": "boolean", + "default": false } }, - "required": true - }, + { + "name": "publishedOnly", + "in": "query", + "description": "Resolve only published services (curated public pSEO set); 404 otherwise. Default false", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + } + ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + "$ref": "#/components/schemas/SingleValueResponseServiceDetailDto" } } } @@ -17499,27 +16896,75 @@ } } } - }, - "delete": { + } + }, + "/api/v1/services/{slugOrId}/components": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Delete a status page", - "operationId": "delete_3", + "summary": "List active components for a service with current status and inline uptime", + "description": "When ``groupId`` is supplied, only direct children of that group are returned — used by the pSEO renderer to lazy-load the leaves under a group that summary mode trimmed. Without ``groupId`` the response includes every active component for the service. Supports pagination via ``page``/``size`` and case-insensitive name search via ``search``.", + "operationId": "getComponents", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Restrict result to direct children of this group component id", + "required": false, "schema": { "type": "string", "format": "uuid" } + }, + { + "name": "search", + "in": "query", + "description": "Case-insensitive substring match on component name", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "Zero-based page index", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "size", + "in": "query", + "description": "Page size (default 25, max 100)", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultServiceComponentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -17604,22 +17049,66 @@ } } }, - "/api/v1/status-pages/{id}/components": { + "/api/v1/services/{slugOrId}/components/{componentId}/uptime": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "List all components", - "operationId": "listComponents", + "summary": "Get daily uptime data for a component", + "description": "Pass either ``period`` (preset window) or an explicit ``from``/``to`` calendar window (ISO yyyy-MM-dd, max 730 days, ``to`` defaults to today). When both are supplied, the explicit window wins.", + "operationId": "getComponentUptime", "parameters": [ { - "name": "id", + "name": "slugOrId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "componentId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + }, + { + "name": "period", + "in": "query", + "description": "Preset time window (used when ``from`` is omitted)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "7d", + "30d", + "90d", + "1y" + ] + } + }, + { + "name": "from", + "in": "query", + "description": "Explicit window start (ISO date); overrides ``period``", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "to", + "in": "query", + "description": "Explicit window end (ISO date); defaults to today", + "required": false, + "schema": { + "type": "string", + "format": "date" + } } ], "responses": { @@ -17628,7 +17117,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageComponentDto" + "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" } } } @@ -17714,41 +17203,68 @@ } } } - }, - "post": { + } + }, + "/api/v1/services/{slugOrId}/components/uptime": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Add a component to the status page", - "operationId": "createComponent", + "summary": "Batch daily uptime data for all leaf components", + "description": "Returns daily uptime for every active non-group component with uptime data, keyed by component ID. Replaces N individual per-component uptime calls with a single request. Supports either a preset ``period`` or an explicit ``from``/``to`` window (ISO yyyy-MM-dd, max 730 days). The explicit window wins when both are supplied — this is what powers the sliding 90-day navigator on the public uptime history page.", + "operationId": "getBatchComponentUptime", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "period", + "in": "query", + "description": "Preset time window (used when ``from`` is omitted)", + "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "7d", + "30d", + "90d", + "1y" + ] } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageComponentRequest" - } + }, + { + "name": "from", + "in": "query", + "description": "Explicit window start (ISO date); overrides ``period``", + "required": false, + "schema": { + "type": "string", + "format": "date" } }, - "required": true - }, + { + "name": "to", + "in": "query", + "description": "Explicit window end (ISO date); defaults to today", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/SingleValueResponseBatchComponentUptimeDto" } } } @@ -17836,50 +17352,41 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}": { - "put": { + "/api/v1/services/{slugOrId}/days/{date}": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Update a component", - "operationId": "updateComponent", + "summary": "One-day rollup for a service: aggregated uptime, per-component impacts, and overlapping incidents", + "description": "Powers the click/hover-to-expand panel under each uptime bar on the public status page. Single round-trip — components, sums, and overlapping incidents (with affected component names) are returned in one response.", + "operationId": "getServiceDayDetail", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { - "name": "componentId", + "name": "date", "in": "path", + "description": "UTC calendar day in ISO format (YYYY-MM-DD)", "required": true, "schema": { "type": "string", - "format": "uuid" + "format": "date" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageComponentRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/SingleValueResponseServiceDayDetailDto" } } } @@ -17965,36 +17472,66 @@ } } } - }, - "delete": { + } + }, + "/api/v1/services/{slugOrId}/incidents": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Remove a component from the status page", - "operationId": "deleteComponent", + "summary": "List incident history for a service (paginated)", + "operationId": "listIncidents_1", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "from", + "in": "query", + "description": "Earliest start date (ISO 8601 date)", + "required": false, "schema": { "type": "string", - "format": "uuid" + "format": "date" } }, { - "name": "componentId", - "in": "path", - "required": true, + "name": "status", + "in": "query", + "description": "Filter: active (unresolved), resolved, or omit for all", + "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "active", + "resolved" + ] + } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -18079,41 +17616,141 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}/measured-uptime": { + "/api/v1/services/{slugOrId}/incidents/{incidentId}": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Get measured (check-based) component uptime history", - "description": "Additive measured daily uptime for MONITOR components (ASK-SP-2 / CHG-2). Reads time-bounded check_results_daily rollups for the linked monitor. Response source is always measured. Does not change legacy GET …/uptime incident-window semantics. days default 90, max 365.", - "operationId": "componentMeasuredUptime", + "summary": "Get incident detail with full update timeline", + "operationId": "getIncident_1", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { - "name": "componentId", + "name": "incidentId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseServiceIncidentDetailDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/services/{slugOrId}/live-status": { + "get": { + "tags": [ + "Status Data" + ], + "summary": "Lightweight live-status snapshot for polling", + "description": "Returns only the current overall status, component statuses, and active incident count. Designed for frequent polling with minimal payload.", + "operationId": "getServiceLiveStatus", + "parameters": [ { - "name": "days", - "in": "query", - "required": false, + "name": "slugOrId", + "in": "path", + "required": true, "schema": { - "type": "integer", - "format": "int32", - "default": 90 + "type": "string" } } ], @@ -18123,7 +17760,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageMeasuredComponentUptimeDto" + "$ref": "#/components/schemas/SingleValueResponseServiceLiveStatusDto" } } } @@ -18211,51 +17848,42 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}/override": { - "put": { + "/api/v1/services/{slugOrId}/maintenances": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Set a timed human status override on a component", - "description": "ASK-SP-1 / CHG-1. Effective currentStatus reflects the override until expiry or clear, unless an active incident takes precedence (incident > override > binding). Max expiry horizon is 24 hours.", - "operationId": "setComponentOverride", + "summary": "List scheduled maintenances for a service", + "operationId": "getScheduledMaintenances", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { - "name": "componentId", - "in": "path", - "required": true, + "name": "status", + "in": "query", + "description": "Filter by status (e.g. scheduled, in_progress, verifying, completed)", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "array", + "items": { + "type": "string" + } } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SetStatusPageComponentOverrideRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/TableValueResultScheduledMaintenanceDto" } } } @@ -18341,30 +17969,42 @@ } } } - }, - "delete": { + } + }, + "/api/v1/services/{slugOrId}/poll-results": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Clear a timed human status override on a component", - "operationId": "clearComponentOverride", + "summary": "List poll results for a service (cursor-paginated)", + "operationId": "listPollResults", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { - "name": "componentId", - "in": "path", - "required": true, + "name": "cursor", + "in": "query", + "description": "ISO 8601 timestamp cursor from a previous response", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size (1–100, default 50)", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 50 } } ], @@ -18374,7 +18014,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/CursorPageServicePollResultDto" } } } @@ -18462,41 +18102,34 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}/uptime": { + "/api/v1/services/{slugOrId}/poll-summary": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Get component uptime history from published incident windows", - "description": "Legacy incident-window rollup (source semantics: incident_window). Daily % is derived from published status-page incident windows, not probe checks. For measured check-based uptime use GET …/measured-uptime (ASK-SP-2 / CHG-2).", - "operationId": "componentUptime_1", + "summary": "Get aggregated poll metrics and chart data for a service", + "operationId": "getPollSummary", "parameters": [ { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "componentId", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { - "name": "days", + "name": "window", "in": "query", + "description": "Time window", "required": false, "schema": { - "type": "integer", - "format": "int32", - "default": 90 + "type": "string", + "enum": [ + "24h", + "7d", + "30d" + ] } } ], @@ -18506,7 +18139,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" + "$ref": "#/components/schemas/SingleValueResponseServicePollSummaryDto" } } } @@ -18594,38 +18227,98 @@ } } }, - "/api/v1/status-pages/{id}/components/reorder": { - "put": { + "/api/v1/services/{slugOrId}/status-events": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Batch reorder components (and optionally move between groups)", - "operationId": "reorderComponents", + "summary": "List curated vendor status events for a service", + "description": "Reverse-chronological merge of vendor incidents, maintenances, and rolled-up component transitions for the Dependencies Detail rail. Optional JWT + x-phelm-org-id annotates incident.opened rows with the caller's linked internal incident.", + "operationId": "listStatusEvents", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "types", + "in": "query", + "description": "Comma-separated type buckets: incident, maintenance, component (default: all)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "period", + "in": "query", + "description": "Preset window", + "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "7d", + "30d", + "90d" + ] + } + }, + { + "name": "from", + "in": "query", + "description": "Explicit lower bound (ISO 8601); overrides period", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "Explicit upper bound (ISO 8601); default now", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor from a previous response", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size (1–100, default 50)", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 50 } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ReorderComponentsRequest" + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/CursorPageStatusEventDto" + } } } }, - "required": true - }, - "responses": { - "204": { - "description": "No Content" - }, "400": { "description": "Bad request — the payload failed validation", "content": { @@ -18709,21 +18402,53 @@ } } }, - "/api/v1/status-pages/{id}/domains": { + "/api/v1/services/{slugOrId}/uptime": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "List custom domains", - "operationId": "listDomains", + "summary": "Get uptime statistics for a service", + "description": "Uptime data aggregated across active non-group components.", + "operationId": "getServiceUptime", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "period", + "in": "query", + "description": "Time window", + "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "24h", + "7d", + "30d", + "90d", + "1y", + "2y", + "all" + ] + } + }, + { + "name": "granularity", + "in": "query", + "description": "Bucket granularity", + "required": false, + "schema": { + "type": "string", + "enum": [ + "hourly", + "daily", + "monthly" + ] } } ], @@ -18733,7 +18458,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageCustomDomainDto" + "$ref": "#/components/schemas/SingleValueResponseServiceUptimeResponse" } } } @@ -18818,42 +18543,71 @@ } } } - } - }, - "post": { + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/v1/services/incidents": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Add a custom domain", - "operationId": "addDomain", + "summary": "List vendor incidents across all services (paginated)", + "description": "Cross-service vendor incident feed ordered by start date descending.", + "operationId": "listCrossServiceIncidents", "parameters": [ { - "name": "id", - "in": "path", - "required": true, + "name": "from", + "in": "query", + "description": "Earliest start date (ISO 8601 date)", + "required": false, "schema": { "type": "string", - "format": "uuid" + "format": "date" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AddCustomDomainRequest" - } + }, + { + "name": "status", + "in": "query", + "description": "Filter: active (unresolved), resolved, or omit for all", + "required": false, + "schema": { + "type": "string", + "enum": [ + "active", + "resolved" + ] } }, - "required": true - }, + { + "name": "category", + "in": "query", + "description": "Filter by service category", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" + "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" } } } @@ -18941,36 +18695,36 @@ } } }, - "/api/v1/status-pages/{id}/domains/{domainId}": { - "delete": { + "/api/v1/services/summary": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Remove a custom domain", - "operationId": "removeDomain", + "summary": "Global status summary across all services", + "description": "Returns aggregate counts of services by status and a list of services currently experiencing issues.", + "operationId": "getGlobalStatusSummary", "parameters": [ { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "domainId", - "in": "path", - "required": true, + "name": "publishedOnly", + "in": "query", + "description": "Aggregate only published services (curated public pSEO set); default false", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "boolean", + "default": false } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseGlobalStatusSummaryDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -19055,40 +18809,20 @@ } } }, - "/api/v1/status-pages/{id}/domains/{domainId}/primary": { - "post": { + "/api/v1/status-pages": { + "get": { "tags": [ "Status Pages" ], - "summary": "Mark a verified custom domain as the page's primary host", - "operationId": "setPrimaryDomain", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "domainId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], + "summary": "List status pages for the workspace", + "operationId": "list_4", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" + "$ref": "#/components/schemas/TableValueResultStatusPageDto" } } } @@ -19174,42 +18908,30 @@ } } } - } - }, - "/api/v1/status-pages/{id}/domains/{domainId}/verify": { + }, "post": { "tags": [ "Status Pages" ], - "summary": "Trigger domain verification check", - "operationId": "verifyDomain", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" + "summary": "Create a status page", + "operationId": "create_5", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageRequest" + } } }, - { - "name": "domainId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" } } } @@ -19297,13 +19019,13 @@ } } }, - "/api/v1/status-pages/{id}/groups": { + "/api/v1/status-pages/{id}": { "get": { "tags": [ "Status Pages" ], - "summary": "List component groups with nested components", - "operationId": "listGroups", + "summary": "Get a status page", + "operationId": "get_2", "parameters": [ { "name": "id", @@ -19321,7 +19043,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageComponentGroupDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" } } } @@ -19408,12 +19130,12 @@ } } }, - "post": { + "put": { "tags": [ "Status Pages" ], - "summary": "Create a component group", - "operationId": "createGroup", + "summary": "Update a status page", + "operationId": "update_3", "parameters": [ { "name": "id", @@ -19429,19 +19151,19 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateStatusPageComponentGroupRequest" + "$ref": "#/components/schemas/UpdateStatusPageRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" } } } @@ -19527,15 +19249,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/groups/{groupId}": { - "put": { + }, + "delete": { "tags": [ "Status Pages" ], - "summary": "Update a component group", - "operationId": "updateGroup", + "summary": "Delete a status page", + "operationId": "delete_3", "parameters": [ { "name": "id", @@ -19545,9 +19265,105 @@ "type": "string", "format": "uuid" } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/components": { + "get": { + "tags": [ + "Status Pages" + ], + "summary": "List all components", + "operationId": "listComponents", + "parameters": [ { - "name": "groupId", + "name": "id", "in": "path", "required": true, "schema": { @@ -19556,23 +19372,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageComponentGroupRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" + "$ref": "#/components/schemas/TableValueResultStatusPageComponentDto" } } } @@ -19659,12 +19465,12 @@ } } }, - "delete": { + "post": { "tags": [ "Status Pages" ], - "summary": "Delete a component group (components become ungrouped)", - "operationId": "deleteGroup", + "summary": "Add a component to the status page", + "operationId": "createComponent", "parameters": [ { "name": "id", @@ -19674,20 +19480,28 @@ "type": "string", "format": "uuid" } - }, - { - "name": "groupId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageComponentRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -19772,13 +19586,13 @@ } } }, - "/api/v1/status-pages/{id}/incidents": { - "get": { + "/api/v1/status-pages/{id}/components/{componentId}": { + "put": { "tags": [ "Status Pages" ], - "summary": "List incidents for this status page (paginated)", - "operationId": "listIncidents", + "summary": "Update a component", + "operationId": "updateComponent", "parameters": [ { "name": "id", @@ -19790,38 +19604,32 @@ } }, { - "name": "status", - "in": "query", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] - } - } - }, - { - "name": "pageable", - "in": "query", + "name": "componentId", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageComponentRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" } } } @@ -19908,12 +19716,12 @@ } } }, - "post": { + "delete": { "tags": [ "Status Pages" ], - "summary": "Create a status page incident (manual)", - "operationId": "createIncident", + "summary": "Remove a component from the status page", + "operationId": "deleteComponent", "parameters": [ { "name": "id", @@ -19923,28 +19731,20 @@ "type": "string", "format": "uuid" } + }, + { + "name": "componentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageIncidentRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -20029,13 +19829,14 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}": { + "/api/v1/status-pages/{id}/components/{componentId}/measured-uptime": { "get": { "tags": [ "Status Pages" ], - "summary": "Get incident details with timeline", - "operationId": "getIncident", + "summary": "Get measured (check-based) component uptime history", + "description": "Additive measured daily uptime for MONITOR components (ASK-SP-2 / CHG-2). Reads time-bounded check_results_daily rollups for the linked monitor. Response source is always measured. Does not change legacy GET …/uptime incident-window semantics. days default 90, max 365.", + "operationId": "componentMeasuredUptime", "parameters": [ { "name": "id", @@ -20047,13 +19848,23 @@ } }, { - "name": "incidentId", + "name": "componentId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + }, + { + "name": "days", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 90 + } } ], "responses": { @@ -20062,7 +19873,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageMeasuredComponentUptimeDto" } } } @@ -20148,13 +19959,16 @@ } } } - }, + } + }, + "/api/v1/status-pages/{id}/components/{componentId}/override": { "put": { "tags": [ "Status Pages" ], - "summary": "Update an incident", - "operationId": "updateIncident", + "summary": "Set a timed human status override on a component", + "description": "ASK-SP-1 / CHG-1. Effective currentStatus reflects the override until expiry or clear, unless an active incident takes precedence (incident > override > binding). Max expiry horizon is 24 hours.", + "operationId": "setComponentOverride", "parameters": [ { "name": "id", @@ -20166,7 +19980,7 @@ } }, { - "name": "incidentId", + "name": "componentId", "in": "path", "required": true, "schema": { @@ -20179,7 +19993,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateStatusPageIncidentRequest" + "$ref": "#/components/schemas/SetStatusPageComponentOverrideRequest" } } }, @@ -20191,7 +20005,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" } } } @@ -20282,8 +20096,8 @@ "tags": [ "Status Pages" ], - "summary": "Delete an incident", - "operationId": "deleteIncident", + "summary": "Clear a timed human status override on a component", + "operationId": "clearComponentOverride", "parameters": [ { "name": "id", @@ -20295,7 +20109,7 @@ } }, { - "name": "incidentId", + "name": "componentId", "in": "path", "required": true, "schema": { @@ -20305,8 +20119,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -20391,13 +20212,14 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/dismiss": { - "post": { + "/api/v1/status-pages/{id}/components/{componentId}/uptime": { + "get": { "tags": [ "Status Pages" ], - "summary": "Dismiss a draft incident (soft-deletes: resolves without publishing)", - "operationId": "dismissIncident", + "summary": "Get component uptime history from published incident windows", + "description": "Legacy incident-window rollup (source semantics: incident_window). Daily % is derived from published status-page incident windows, not probe checks. For measured check-based uptime use GET …/measured-uptime (ASK-SP-2 / CHG-2).", + "operationId": "componentUptime_1", "parameters": [ { "name": "id", @@ -20409,18 +20231,35 @@ } }, { - "name": "incidentId", + "name": "componentId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + }, + { + "name": "days", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 90 + } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -20505,13 +20344,13 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/publish": { - "post": { + "/api/v1/status-pages/{id}/components/reorder": { + "put": { "tags": [ "Status Pages" ], - "summary": "Publish a draft incident (sets publishedAt, applies component statuses, notifies subscribers)", - "operationId": "publishIncident", + "summary": "Batch reorder components (and optionally move between groups)", + "operationId": "reorderComponents", "parameters": [ { "name": "id", @@ -20521,36 +20360,21 @@ "type": "string", "format": "uuid" } - }, - { - "name": "incidentId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PublishStatusPageIncidentRequest" + "$ref": "#/components/schemas/ReorderComponentsRequest" } } - } + }, + "required": true }, "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -20635,13 +20459,13 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/updates": { - "post": { + "/api/v1/status-pages/{id}/domains": { + "get": { "tags": [ "Status Pages" ], - "summary": "Post an incident timeline update", - "operationId": "postIncidentUpdate", + "summary": "List custom domains", + "operationId": "listDomains", "parameters": [ { "name": "id", @@ -20651,9 +20475,110 @@ "type": "string", "format": "uuid" } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageCustomDomainDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "post": { + "tags": [ + "Status Pages" + ], + "summary": "Add a custom domain", + "operationId": "addDomain", + "parameters": [ { - "name": "incidentId", + "name": "id", "in": "path", "required": true, "schema": { @@ -20666,7 +20591,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateStatusPageIncidentUpdateRequest" + "$ref": "#/components/schemas/AddCustomDomainRequest" } } }, @@ -20678,7 +20603,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" } } } @@ -20766,13 +20691,13 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/updates/{updateId}": { - "patch": { + "/api/v1/status-pages/{id}/domains/{domainId}": { + "delete": { "tags": [ "Status Pages" ], - "summary": "Edit an existing incident timeline update body", - "operationId": "patchIncidentUpdate", + "summary": "Remove a custom domain", + "operationId": "removeDomain", "parameters": [ { "name": "id", @@ -20784,16 +20709,121 @@ } }, { - "name": "incidentId", + "name": "domainId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/domains/{domainId}/primary": { + "post": { + "tags": [ + "Status Pages" + ], + "summary": "Mark a verified custom domain as the page's primary host", + "operationId": "setPrimaryDomain", + "parameters": [ { - "name": "updateId", + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "domainId", "in": "path", "required": true, "schema": { @@ -20802,23 +20832,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageIncidentUpdateRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentUpdateDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" } } } @@ -20906,13 +20926,13 @@ } } }, - "/api/v1/status-pages/{id}/layout/reorder": { - "put": { + "/api/v1/status-pages/{id}/domains/{domainId}/verify": { + "post": { "tags": [ "Status Pages" ], - "summary": "Reorder page-level layout: groups and ungrouped components share one ordering", - "operationId": "reorderLayout", + "summary": "Trigger domain verification check", + "operationId": "verifyDomain", "parameters": [ { "name": "id", @@ -20922,22 +20942,28 @@ "type": "string", "format": "uuid" } + }, + { + "name": "domainId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ReorderPageLayoutRequest" + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" + } } } }, - "required": true - }, - "responses": { - "204": { - "description": "No Content" - }, "400": { "description": "Bad request — the payload failed validation", "content": { @@ -21021,13 +21047,13 @@ } } }, - "/api/v1/status-pages/{id}/maintenance": { + "/api/v1/status-pages/{id}/groups": { "get": { "tags": [ "Status Pages" ], - "summary": "List maintenance windows for this status page (paginated)", - "operationId": "listMaintenance", + "summary": "List component groups with nested components", + "operationId": "listGroups", "parameters": [ { "name": "id", @@ -21037,31 +21063,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "status", - "in": "query", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] - } - } - }, - { - "name": "pageable", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/Pageable" - } } ], "responses": { @@ -21070,7 +21071,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" + "$ref": "#/components/schemas/TableValueResultStatusPageComponentGroupDto" } } } @@ -21161,8 +21162,8 @@ "tags": [ "Status Pages" ], - "summary": "Schedule a maintenance window", - "operationId": "createMaintenance", + "summary": "Create a component group", + "operationId": "createGroup", "parameters": [ { "name": "id", @@ -21178,7 +21179,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateStatusPageMaintenanceRequest" + "$ref": "#/components/schemas/CreateStatusPageComponentGroupRequest" } } }, @@ -21190,7 +21191,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" } } } @@ -21278,13 +21279,13 @@ } } }, - "/api/v1/status-pages/{id}/maintenance/{windowId}": { - "get": { + "/api/v1/status-pages/{id}/groups/{groupId}": { + "put": { "tags": [ "Status Pages" ], - "summary": "Get a maintenance window with timeline", - "operationId": "getMaintenance", + "summary": "Update a component group", + "operationId": "updateGroup", "parameters": [ { "name": "id", @@ -21296,7 +21297,7 @@ } }, { - "name": "windowId", + "name": "groupId", "in": "path", "required": true, "schema": { @@ -21305,13 +21306,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageComponentGroupRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" } } } @@ -21398,12 +21409,12 @@ } } }, - "put": { + "delete": { "tags": [ "Status Pages" ], - "summary": "Update a maintenance window", - "operationId": "updateMaintenance", + "summary": "Delete a component group (components become ungrouped)", + "operationId": "deleteGroup", "parameters": [ { "name": "id", @@ -21415,7 +21426,7 @@ } }, { - "name": "windowId", + "name": "groupId", "in": "path", "required": true, "schema": { @@ -21424,26 +21435,9 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageIncidentRequest" - } - } - }, - "required": true - }, "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -21526,13 +21520,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/status-pages/{id}/incidents": { + "get": { "tags": [ "Status Pages" ], - "summary": "Cancel a maintenance window", - "operationId": "deleteMaintenance", + "summary": "List incidents for this status page (paginated)", + "operationId": "listIncidents", "parameters": [ { "name": "id", @@ -21544,18 +21540,41 @@ } }, { - "name": "windowId", - "in": "path", + "name": "status", + "in": "query", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" + ] + } + } + }, + { + "name": "pageable", + "in": "query", "required": true, "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/Pageable" } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -21638,15 +21657,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/dismiss": { + }, "post": { "tags": [ "Status Pages" ], - "summary": "Dismiss a draft maintenance window", - "operationId": "dismissMaintenance", + "summary": "Create a status page incident (manual)", + "operationId": "createIncident", "parameters": [ { "name": "id", @@ -21656,20 +21673,28 @@ "type": "string", "format": "uuid" } - }, - { - "name": "windowId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageIncidentRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -21754,13 +21779,13 @@ } } }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/publish": { - "post": { + "/api/v1/status-pages/{id}/incidents/{incidentId}": { + "get": { "tags": [ "Status Pages" ], - "summary": "Publish a draft maintenance window", - "operationId": "publishMaintenance", + "summary": "Get incident details with timeline", + "operationId": "getIncident", "parameters": [ { "name": "id", @@ -21772,7 +21797,7 @@ } }, { - "name": "windowId", + "name": "incidentId", "in": "path", "required": true, "schema": { @@ -21781,15 +21806,6 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PublishStatusPageIncidentRequest" - } - } - } - }, "responses": { "200": { "description": "OK", @@ -21882,15 +21898,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/updates": { - "post": { + }, + "put": { "tags": [ "Status Pages" ], - "summary": "Post a maintenance window timeline update", - "operationId": "postMaintenanceUpdate", + "summary": "Update an incident", + "operationId": "updateIncident", "parameters": [ { "name": "id", @@ -21902,7 +21916,7 @@ } }, { - "name": "windowId", + "name": "incidentId", "in": "path", "required": true, "schema": { @@ -21915,15 +21929,15 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateStatusPageIncidentUpdateRequest" + "$ref": "#/components/schemas/UpdateStatusPageIncidentRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { @@ -22013,15 +22027,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/updates/{updateId}": { - "patch": { + }, + "delete": { "tags": [ "Status Pages" ], - "summary": "Edit an existing maintenance timeline update body", - "operationId": "patchMaintenanceUpdate", + "summary": "Delete an incident", + "operationId": "deleteIncident", "parameters": [ { "name": "id", @@ -22033,7 +22045,112 @@ } }, { - "name": "windowId", + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/incidents/{incidentId}/dismiss": { + "post": { + "tags": [ + "Status Pages" + ], + "summary": "Dismiss a draft incident (soft-deletes: resolves without publishing)", + "operationId": "dismissIncident", + "parameters": [ + { + "name": "id", "in": "path", "required": true, "schema": { @@ -22042,7 +22159,7 @@ } }, { - "name": "updateId", + "name": "incidentId", "in": "path", "required": true, "schema": { @@ -22051,26 +22168,9 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageIncidentUpdateRequest" - } - } - }, - "required": true - }, "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentUpdateDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -22155,14 +22255,13 @@ } } }, - "/api/v1/status-pages/{id}/notification-deliveries": { - "get": { + "/api/v1/status-pages/{id}/incidents/{incidentId}/publish": { + "post": { "tags": [ "Status Pages" ], - "summary": "List notification delivery receipts", - "description": "Returns delivery rows for this status page (newest first). Optional filters: incidentId, eventType.", - "operationId": "listNotificationDeliveries", + "summary": "Publish a draft incident (sets publishedAt, applies component statuses, notifies subscribers)", + "operationId": "publishIncident", "parameters": [ { "name": "id", @@ -22175,35 +22274,30 @@ }, { "name": "incidentId", - "in": "query", - "required": false, + "in": "path", + "required": true, "schema": { "type": "string", "format": "uuid" } - }, - { - "name": "eventType", - "in": "query", - "required": false, - "schema": { - "type": "string", - "enum": [ - "SUBSCRIPTION_CONFIRMATION", - "INCIDENT_CREATED", - "INCIDENT_UPDATED", - "INCIDENT_RESOLVED" - ] - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublishStatusPageIncidentRequest" + } + } + } + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageNotificationDeliveryDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -22291,13 +22385,13 @@ } } }, - "/api/v1/status-pages/{id}/notification-deliveries/{deliveryId}": { - "get": { + "/api/v1/status-pages/{id}/incidents/{incidentId}/updates": { + "post": { "tags": [ "Status Pages" ], - "summary": "Get a notification delivery receipt", - "operationId": "getNotificationDelivery", + "summary": "Post an incident timeline update", + "operationId": "postIncidentUpdate", "parameters": [ { "name": "id", @@ -22309,7 +22403,7 @@ } }, { - "name": "deliveryId", + "name": "incidentId", "in": "path", "required": true, "schema": { @@ -22318,13 +22412,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageIncidentUpdateRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageNotificationDeliveryDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -22412,14 +22516,13 @@ } } }, - "/api/v1/status-pages/{id}/notification-deliveries/{deliveryId}/retry": { - "post": { + "/api/v1/status-pages/{id}/incidents/{incidentId}/updates/{updateId}": { + "patch": { "tags": [ "Status Pages" ], - "summary": "Retry a failed notification delivery", - "description": "Queues a FAILED delivery for another attempt. Refuses terminal attempt_count (~5). Idempotent when already RETRY_PENDING.", - "operationId": "retryNotificationDelivery", + "summary": "Edit an existing incident timeline update body", + "operationId": "patchIncidentUpdate", "parameters": [ { "name": "id", @@ -22431,7 +22534,16 @@ } }, { - "name": "deliveryId", + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "updateId", "in": "path", "required": true, "schema": { @@ -22440,13 +22552,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageIncidentUpdateRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageNotificationDeliveryDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentUpdateDto" } } } @@ -22534,13 +22656,128 @@ } } }, - "/api/v1/status-pages/{id}/subscribers": { + "/api/v1/status-pages/{id}/layout/reorder": { + "put": { + "tags": [ + "Status Pages" + ], + "summary": "Reorder page-level layout: groups and ungrouped components share one ordering", + "operationId": "reorderLayout", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReorderPageLayoutRequest" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/maintenance": { "get": { "tags": [ "Status Pages" ], - "summary": "List subscribers including awaiting confirmation (paginated)", - "operationId": "listSubscribers", + "summary": "List maintenance windows for this status page (paginated)", + "operationId": "listMaintenance", "parameters": [ { "name": "id", @@ -22551,6 +22788,23 @@ "format": "uuid" } }, + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" + ] + } + } + }, { "name": "pageable", "in": "query", @@ -22566,7 +22820,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageSubscriberDto" + "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" } } } @@ -22657,8 +22911,8 @@ "tags": [ "Status Pages" ], - "summary": "Add a subscriber; requireConfirmation=true for EMAIL double opt-in, omit/false confirms immediately", - "operationId": "addSubscriber", + "summary": "Schedule a maintenance window", + "operationId": "createMaintenance", "parameters": [ { "name": "id", @@ -22674,7 +22928,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AdminAddSubscriberRequest" + "$ref": "#/components/schemas/CreateStatusPageMaintenanceRequest" } } }, @@ -22686,7 +22940,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageSubscriberDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -22774,13 +23028,13 @@ } } }, - "/api/v1/status-pages/{id}/subscribers/{subscriberId}": { - "delete": { + "/api/v1/status-pages/{id}/maintenance/{windowId}": { + "get": { "tags": [ "Status Pages" ], - "summary": "Remove a subscriber", - "operationId": "removeSubscriber", + "summary": "Get a maintenance window with timeline", + "operationId": "getMaintenance", "parameters": [ { "name": "id", @@ -22792,7 +23046,7 @@ } }, { - "name": "subscriberId", + "name": "windowId", "in": "path", "required": true, "schema": { @@ -22802,8 +23056,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -22886,32 +23147,50 @@ } } } - } - }, - "/api/v1/tags": { - "get": { + }, + "put": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "List tags for the authenticated organization", - "operationId": "list_3", + "summary": "Update a maintenance window", + "operationId": "updateMaintenance", "parameters": [ { - "name": "pageable", - "in": "query", + "name": "id", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" + } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageIncidentRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -22998,32 +23277,35 @@ } } }, - "post": { + "delete": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "Create a new tag", - "operationId": "create_4", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateTagRequest" - } + "summary": "Cancel a maintenance window", + "operationId": "deleteMaintenance", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "required": true - }, - "responses": { - "201": { - "description": "Created", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseTagDto" - } - } + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } + } + ], + "responses": { + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -23108,13 +23390,13 @@ } } }, - "/api/v1/tags/{id}": { - "get": { + "/api/v1/status-pages/{id}/maintenance/{windowId}/dismiss": { + "post": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "Get a tag by ID", - "operationId": "getById", + "summary": "Dismiss a draft maintenance window", + "operationId": "dismissMaintenance", "parameters": [ { "name": "id", @@ -23124,18 +23406,20 @@ "type": "string", "format": "uuid" } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseTagDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -23218,13 +23502,15 @@ } } } - }, - "put": { + } + }, + "/api/v1/status-pages/{id}/maintenance/{windowId}/publish": { + "post": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "Update a tag's name and/or color", - "operationId": "update_2", + "summary": "Publish a draft maintenance window", + "operationId": "publishMaintenance", "parameters": [ { "name": "id", @@ -23234,17 +23520,25 @@ "type": "string", "format": "uuid" } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTagRequest" + "$ref": "#/components/schemas/PublishStatusPageIncidentRequest" } } - }, - "required": true + } }, "responses": { "200": { @@ -23252,7 +23546,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseTagDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -23338,13 +23632,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/status-pages/{id}/maintenance/{windowId}/updates": { + "post": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "Delete a tag (cascades to all monitor associations)", - "operationId": "delete_2", + "summary": "Post a maintenance window timeline update", + "operationId": "postMaintenanceUpdate", "parameters": [ { "name": "id", @@ -23354,110 +23650,34 @@ "type": "string", "format": "uuid" } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad request — the payload failed validation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "401": { - "description": "Unauthorized — missing or invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "403": { - "description": "Forbidden — the actor lacks permission for this resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "404": { - "description": "Not found — the requested resource does not exist", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "409": { - "description": "Conflict — the request collides with current resource state", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } - }, - "502": { - "description": "Bad gateway — an upstream provider returned an error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageIncidentUpdateRequest" } } }, - "503": { - "description": "Service unavailable — try again shortly", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v1/vaults/rotate": { - "post": { - "tags": [ - "Vault" - ], - "summary": "Rotate DEK", - "description": "Generates a new Data Encryption Key, re-encrypts all secrets and alert-channel configs, and bumps the vault version. Admin-only. Pipeline DEK caches expire within ~10 minutes.", - "operationId": "rotateDek", + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseDekRotationResultDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -23545,30 +23765,59 @@ } } }, - "/api/v1/webhooks": { - "get": { + "/api/v1/status-pages/{id}/maintenance/{windowId}/updates/{updateId}": { + "patch": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "List webhook endpoints for the authenticated org", - "operationId": "list_2", + "summary": "Edit an existing maintenance timeline update body", + "operationId": "patchMaintenanceUpdate", "parameters": [ { - "name": "pageable", - "in": "query", + "name": "id", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" + } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "updateId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageIncidentUpdateRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultWebhookEndpointDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentUpdateDto" } } } @@ -23654,30 +23903,57 @@ } } } - }, - "post": { + } + }, + "/api/v1/status-pages/{id}/notification-deliveries": { + "get": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Register a new webhook endpoint", - "operationId": "create_3", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateWebhookEndpointRequest" - } + "summary": "List notification delivery receipts", + "description": "Returns delivery rows for this status page (newest first). Optional filters: incidentId, eventType.", + "operationId": "listNotificationDeliveries", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "required": true - }, + { + "name": "incidentId", + "in": "query", + "required": false, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "eventType", + "in": "query", + "required": false, + "schema": { + "type": "string", + "enum": [ + "SUBSCRIPTION_CONFIRMATION", + "INCIDENT_CREATED", + "INCIDENT_UPDATED", + "INCIDENT_RESOLVED" + ] + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + "$ref": "#/components/schemas/TableValueResultStatusPageNotificationDeliveryDto" } } } @@ -23765,13 +24041,13 @@ } } }, - "/api/v1/webhooks/{id}": { + "/api/v1/status-pages/{id}/notification-deliveries/{deliveryId}": { "get": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Get a single webhook endpoint", - "operationId": "get_1", + "summary": "Get a notification delivery receipt", + "operationId": "getNotificationDelivery", "parameters": [ { "name": "id", @@ -23781,6 +24057,15 @@ "type": "string", "format": "uuid" } + }, + { + "name": "deliveryId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], "responses": { @@ -23789,7 +24074,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageNotificationDeliveryDto" } } } @@ -23875,13 +24160,16 @@ } } } - }, - "put": { + } + }, + "/api/v1/status-pages/{id}/notification-deliveries/{deliveryId}/retry": { + "post": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Update a webhook endpoint", - "operationId": "update_1", + "summary": "Retry a failed notification delivery", + "description": "Queues a FAILED delivery for another attempt. Refuses terminal attempt_count (~5). Idempotent when already RETRY_PENDING.", + "operationId": "retryNotificationDelivery", "parameters": [ { "name": "id", @@ -23891,25 +24179,24 @@ "type": "string", "format": "uuid" } + }, + { + "name": "deliveryId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateWebhookEndpointRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageNotificationDeliveryDto" } } } @@ -23995,13 +24282,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/status-pages/{id}/subscribers": { + "get": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Delete a webhook endpoint", - "operationId": "delete_1", + "summary": "List subscribers including awaiting confirmation (paginated)", + "operationId": "listSubscribers", "parameters": [ { "name": "id", @@ -24011,11 +24300,26 @@ "type": "string", "format": "uuid" } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageSubscriberDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -24098,15 +24402,13 @@ } } } - } - }, - "/api/v1/webhooks/{id}/deliveries": { - "get": { + }, + "post": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "List recent deliveries for a webhook endpoint", - "operationId": "listDeliveries", + "summary": "Add a subscriber; requireConfirmation=true for EMAIL double opt-in, omit/false confirms immediately", + "operationId": "addSubscriber", "parameters": [ { "name": "id", @@ -24116,25 +24418,25 @@ "type": "string", "format": "uuid" } - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 20 - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminAddSubscriberRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultWebhookDeliveryDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageSubscriberDto" } } } @@ -24222,13 +24524,13 @@ } } }, - "/api/v1/webhooks/{id}/test": { - "post": { + "/api/v1/status-pages/{id}/subscribers/{subscriberId}": { + "delete": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Send a test delivery to a webhook endpoint", - "operationId": "test", + "summary": "Remove a subscriber", + "operationId": "removeSubscriber", "parameters": [ { "name": "id", @@ -24238,27 +24540,20 @@ "type": "string", "format": "uuid" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestWebhookEndpointRequest" - } + }, + { + "name": "subscriberId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } - }, + ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookTestResult" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -24343,21 +24638,30 @@ } } }, - "/api/v1/webhooks/events": { + "/api/v1/tags": { "get": { "tags": [ - "Webhooks" + "Tags" + ], + "summary": "List tags for the authenticated organization", + "operationId": "list_3", + "parameters": [ + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } + } ], - "summary": "List all available webhook event types", - "description": "Returns the full catalog of supported outbound webhook event types with their surface grouping and human-readable descriptions. Use this to populate subscription checkboxes when creating or updating a webhook endpoint.", - "operationId": "listEvents", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/WebhookEventCatalogResponse" + "$ref": "#/components/schemas/TableValueResultTagDto" } } } @@ -24443,22 +24747,30 @@ } } } - } - }, - "/api/v1/webhooks/signing-secret": { - "get": { + }, + "post": { "tags": [ - "Webhooks" + "Tags" ], - "summary": "Get signing secret metadata for the authenticated org", - "operationId": "getSigningSecretInfo", + "summary": "Create a new tag", + "operationId": "create_4", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTagRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookSigningSecretDto" + "$ref": "#/components/schemas/SingleValueResponseTagDto" } } } @@ -24546,20 +24858,31 @@ } } }, - "/api/v1/webhooks/signing-secret/rotate": { - "post": { + "/api/v1/tags/{id}": { + "get": { "tags": [ - "Webhooks" + "Tags" + ], + "summary": "Get a tag by ID", + "operationId": "getById", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } ], - "summary": "Generate or rotate the organization webhook signing secret", - "operationId": "rotateSigningSecret", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseString" + "$ref": "#/components/schemas/SingleValueResponseTagDto" } } } @@ -24645,32 +24968,41 @@ } } } - } - }, - "/api/v1/workspaces": { - "get": { + }, + "put": { "tags": [ - "Workspaces" + "Tags" ], - "summary": "List workspaces", - "operationId": "list_1", + "summary": "Update a tag's name and/or color", + "operationId": "update_2", "parameters": [ { - "name": "pageable", - "in": "query", + "name": "id", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateTagRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultWorkspaceDto" + "$ref": "#/components/schemas/SingleValueResponseTagDto" } } } @@ -24757,29 +25089,125 @@ } } }, - "post": { + "delete": { "tags": [ - "Workspaces" + "Tags" ], - "summary": "Create workspace", - "operationId": "create_2", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateWorkspaceRequest" + "summary": "Delete a tag (cascades to all monitor associations)", + "operationId": "delete_2", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } } } }, - "required": true - }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/vaults/rotate": { + "post": { + "tags": [ + "Vault" + ], + "summary": "Rotate DEK", + "description": "Generates a new Data Encryption Key, re-encrypts all secrets and alert-channel configs, and bumps the vault version. Admin-only. Pipeline DEK caches expire within ~10 minutes.", + "operationId": "rotateDek", "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + "$ref": "#/components/schemas/SingleValueResponseDekRotationResultDto" } } } @@ -24867,21 +25295,20 @@ } } }, - "/api/v1/workspaces/{workspaceId}": { + "/api/v1/webhooks": { "get": { "tags": [ - "Workspaces" + "Webhooks" ], - "summary": "Get workspace by ID", - "operationId": "get", + "summary": "List webhook endpoints for the authenticated org", + "operationId": "list_2", "parameters": [ { - "name": "workspaceId", - "in": "path", + "name": "pageable", + "in": "query", "required": true, "schema": { - "type": "integer", - "format": "int32" + "$ref": "#/components/schemas/Pageable" } } ], @@ -24891,7 +25318,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + "$ref": "#/components/schemas/TableValueResultWebhookEndpointDto" } } } @@ -24978,40 +25405,1363 @@ } } }, - "put": { + "post": { "tags": [ - "Workspaces" - ], - "summary": "Update workspace", - "operationId": "update", - "parameters": [ - { - "name": "workspaceId", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - } + "Webhooks" ], + "summary": "Register a new webhook endpoint", + "operationId": "create_3", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateWorkspaceRequest" + "$ref": "#/components/schemas/CreateWebhookEndpointRequest" } } }, "required": true }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/{id}": { + "get": { + "tags": [ + "Webhooks" + ], + "summary": "Get a single webhook endpoint", + "operationId": "get_1", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "put": { + "tags": [ + "Webhooks" + ], + "summary": "Update a webhook endpoint", + "operationId": "update_1", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateWebhookEndpointRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Webhooks" + ], + "summary": "Delete a webhook endpoint", + "operationId": "delete_1", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/{id}/deliveries": { + "get": { + "tags": [ + "Webhooks" + ], + "summary": "List recent deliveries for a webhook endpoint", + "operationId": "listDeliveries", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 20 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultWebhookDeliveryDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/{id}/test": { + "post": { + "tags": [ + "Webhooks" + ], + "summary": "Send a test delivery to a webhook endpoint", + "operationId": "test", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestWebhookEndpointRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWebhookTestResult" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/events": { + "get": { + "tags": [ + "Webhooks" + ], + "summary": "List all available webhook event types", + "description": "Returns the full catalog of supported outbound webhook event types with their surface grouping and human-readable descriptions. Use this to populate subscription checkboxes when creating or updating a webhook endpoint.", + "operationId": "listEvents", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/WebhookEventCatalogResponse" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/signing-secret": { + "get": { + "tags": [ + "Webhooks" + ], + "summary": "Get signing secret metadata for the authenticated org", + "operationId": "getSigningSecretInfo", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWebhookSigningSecretDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/signing-secret/rotate": { + "post": { + "tags": [ + "Webhooks" + ], + "summary": "Generate or rotate the organization webhook signing secret", + "operationId": "rotateSigningSecret", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseString" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/workspaces": { + "get": { + "tags": [ + "Workspaces" + ], + "summary": "List workspaces", + "operationId": "list_1", + "parameters": [ + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultWorkspaceDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "post": { + "tags": [ + "Workspaces" + ], + "summary": "Create workspace", + "operationId": "create_2", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateWorkspaceRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/workspaces/{workspaceId}": { + "get": { + "tags": [ + "Workspaces" + ], + "summary": "Get workspace by ID", + "operationId": "get", + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "put": { + "tags": [ + "Workspaces" + ], + "summary": "Update workspace", + "operationId": "update", + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateWorkspaceRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" } } } @@ -26247,6 +27997,42 @@ }, "description": "Result of a bulk monitor action, including partial-success details" }, + "CapturePolicy": { + "type": "object", + "properties": { + "screenshots": { + "type": "string", + "description": "When to capture screenshots", + "nullable": true, + "enum": [ + "always", + "on_failure", + "off" + ] + }, + "trace": { + "type": "string", + "description": "When to capture a Playwright trace", + "nullable": true, + "enum": [ + "always", + "on_failure", + "off" + ] + }, + "video": { + "type": "string", + "description": "When to capture video", + "nullable": true, + "enum": [ + "always", + "on_failure", + "off" + ] + } + }, + "description": "When to capture screenshots, traces, and video during a code run" + }, "CategoryDto": { "required": [ "category", @@ -27189,7 +28975,7 @@ ] } }, - "description": "Replace all assertions; null preserves current" + "description": "Replace all assertions. Null preserves current" }, "CreateEnvironmentRequest": { "required": [ @@ -27345,7 +29131,6 @@ }, "CreateMonitorRequest": { "required": [ - "config", "name", "type" ], @@ -27372,6 +29157,7 @@ ] }, "config": { + "nullable": true, "oneOf": [ { "$ref": "#/components/schemas/DnsMonitorConfig" @@ -27400,7 +29186,7 @@ "maximum": 86400, "minimum": 10, "type": "integer", - "description": "Check frequency in seconds (10–86400); null defaults to plan minimum (60s on most paid plans)", + "description": "Check frequency in seconds (10–86400). Null defaults to the plan minimum", "format": "int32", "nullable": true }, @@ -27411,16 +29197,16 @@ }, "regions": { "type": "array", - "description": "Probe regions to run checks from. Allowed values are deployment-dependent; production: us-east, us-west, eu-west, ap-south.", + "description": "Probe regions to run checks from. Allowed values are deployment-dependent. Production: us-east, us-west, eu-west, ap-south", "nullable": true, "items": { "type": "string", - "description": "Probe regions to run checks from. Allowed values are deployment-dependent; production: us-east, us-west, eu-west, ap-south." + "description": "Probe regions to run checks from. Allowed values are deployment-dependent. Production: us-east, us-west, eu-west, ap-south" } }, "managedBy": { "type": "string", - "description": "Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted; set to your surface so audit logs, drift detection, and analytics attribute correctly.", + "description": "Source that created this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API", "nullable": true, "enum": [ "DASHBOARD", @@ -27432,7 +29218,7 @@ }, "environmentId": { "type": "string", - "description": "Environment to associate with this monitor", + "description": "Environment to associate with this monitor. Required for browser and multi-step monitors", "format": "uuid", "nullable": true }, @@ -27477,6 +29263,36 @@ "$ref": "#/components/schemas/AddMonitorTagsRequest" } ] + }, + "capturePolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CapturePolicy" + } + ] + }, + "fastRetryMaxAttempts": { + "maximum": 10, + "minimum": 0, + "type": "integer", + "description": "Fast-retry attempts after failure. Null or 0 disables", + "format": "int32", + "nullable": true + }, + "definitionId": { + "type": "string", + "description": "Existing definition to reuse for a sibling monitor", + "format": "uuid", + "nullable": true + }, + "package": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/MonitorPackageSpec" + } + ] } } }, @@ -27527,6 +29343,20 @@ }, "description": "Request body for creating a notification policy" }, + "CreatePackageUploadRequest": { + "required": [ + "digest" + ], + "type": "object", + "properties": { + "digest": { + "maxLength": 64, + "minLength": 64, + "type": "string", + "description": "SHA-256 hex digest of the package zip to upload (64 chars)" + } + } + }, "CreateResourceGroupRequest": { "required": [ "name" @@ -28219,6 +30049,32 @@ }, "description": "Cursor-paginated response for time-series and append-only data" }, + "CursorPageNotificationDispatchDto": { + "required": [ + "data", + "hasMore" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "description": "Items on this page", + "items": { + "$ref": "#/components/schemas/NotificationDispatchDto" + } + }, + "nextCursor": { + "type": "string", + "description": "Opaque cursor for the next page; null when there are no more results", + "nullable": true + }, + "hasMore": { + "type": "boolean", + "description": "Whether more results exist beyond this page" + } + }, + "description": "Cursor-paginated response for time-series and append-only data" + }, "CursorPageServiceCatalogDto": { "required": [ "data", @@ -28966,6 +30822,10 @@ ] }, "DnsTtlLowAssertion": { + "required": [ + "type", + "minTtl" + ], "type": "object", "properties": { "type": { @@ -28979,11 +30839,7 @@ "description": "Minimum acceptable TTL in seconds before a warning is raised", "format": "int32" } - }, - "required": [ - "type", - "minTtl" - ] + } }, "DnsTxtContainsAssertion": { "required": [ @@ -29783,6 +31639,10 @@ } }, "IcmpPacketLossAssertion": { + "required": [ + "type", + "maxPercent" + ], "type": "object", "properties": { "type": { @@ -29800,11 +31660,7 @@ "description": "Maximum allowed packet loss percentage before the check fails (0–100)", "format": "double" } - }, - "required": [ - "type", - "maxPercent" - ] + } }, "IcmpReachableAssertion": { "type": "object", @@ -31657,6 +33513,10 @@ } }, "McpMinToolsAssertion": { + "required": [ + "type", + "min" + ], "type": "object", "properties": { "type": { @@ -31670,11 +33530,7 @@ "description": "Minimum number of tools the server must expose", "format": "int32" } - }, - "required": [ - "type", - "min" - ] + } }, "McpProtocolVersionAssertion": { "required": [ @@ -31843,6 +33699,10 @@ } }, "McpToolCountChangedAssertion": { + "required": [ + "type", + "expectedCount" + ], "type": "object", "properties": { "type": { @@ -31856,11 +33716,7 @@ "description": "Expected tool count; warns when the live count differs", "format": "int32" } - }, - "required": [ - "type", - "expectedCount" - ] + } }, "MemberDto": { "required": [ @@ -32236,7 +34092,8 @@ "updatedAt", "organizationId", "frequencySeconds", - "enabled" + "enabled", + "muted" ], "type": "object", "properties": { @@ -32388,7 +34245,7 @@ }, "currentStatus": { "type": "string", - "description": "Current operational state — UP, DOWN, DEGRADED, PAUSED, or UNKNOWN if no probe data yet", + "description": "Current operational state. One of UP, DOWN, DEGRADED, PAUSED, or UNKNOWN", "nullable": true, "enum": [ "up", @@ -32397,10 +34254,180 @@ "paused", "unknown" ] + }, + "definitionId": { + "type": "string", + "description": "Definition id for a browser or multi-step monitor. Null on probe monitors", + "format": "uuid", + "nullable": true + }, + "capturePolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CapturePolicy" + } + ] + }, + "fastRetryMaxAttempts": { + "type": "integer", + "description": "Fast-retry max attempts; null/0 = off", + "format": "int32", + "nullable": true + }, + "muted": { + "type": "boolean", + "description": "Whether alert delivery is muted" + }, + "mutedUntil": { + "type": "string", + "description": "Mute expiry; null means indefinite while muted", + "format": "date-time", + "nullable": true + }, + "muteReason": { + "type": "string", + "description": "Optional mute reason", + "nullable": true + }, + "pausedAt": { + "type": "string", + "description": "When the monitor was paused", + "format": "date-time", + "nullable": true + }, + "pauseReason": { + "type": "string", + "description": "Optional pause reason", + "nullable": true + }, + "pauseExpiresAt": { + "type": "string", + "description": "Pause expiry", + "format": "date-time", + "nullable": true + }, + "quarantineOwnerId": { + "type": "string", + "description": "Quarantine person owner id", + "nullable": true + }, + "quarantineUntil": { + "type": "string", + "description": "Quarantine expiry; non-null means quarantined", + "format": "date-time", + "nullable": true + }, + "quarantineReason": { + "type": "string", + "description": "Quarantine reason", + "nullable": true + }, + "upload": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/PackageUploadDto" + } + ] } }, "description": "Full monitor representation" }, + "MonitorOverlayRequest": { + "type": "object", + "properties": { + "reason": { + "maxLength": 280, + "minLength": 0, + "type": "string", + "description": "Optional human-readable reason (max 280)", + "nullable": true + }, + "expiresAt": { + "type": "string", + "description": "When this overlay expires", + "format": "date-time", + "nullable": true + } + } + }, + "MonitorPackageSpec": { + "required": [ + "digest", + "entrypoint", + "files" + ], + "type": "object", + "properties": { + "digest": { + "maxLength": 64, + "minLength": 64, + "type": "string", + "description": "SHA-256 hex digest of the package zip (64 characters)" + }, + "entrypoint": { + "maxLength": 512, + "minLength": 0, + "type": "string", + "description": "Entrypoint path inside the zip, e.g. tests/login.spec.ts" + }, + "files": { + "maxItems": 256, + "minItems": 0, + "type": "array", + "description": "Relative file paths included in the zip", + "items": { + "maxLength": 512, + "minLength": 0, + "type": "string", + "description": "Relative file paths included in the zip" + } + }, + "keys": { + "maxItems": 64, + "minItems": 0, + "type": "array", + "description": "Secret names the zip demanded. PUT: null preserves, [] clears", + "nullable": true, + "items": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Secret names the zip demanded. PUT: null preserves, [] clears" + } + }, + "gitSha": { + "maxLength": 64, + "minLength": 0, + "type": "string", + "description": "Commit SHA from the repo that produced this zip. Client-supplied provenance only", + "nullable": true + }, + "gitMessage": { + "maxLength": 1024, + "minLength": 0, + "type": "string", + "description": "Commit message from the repo that produced this zip", + "nullable": true + }, + "gitFile": { + "maxLength": 512, + "minLength": 0, + "type": "string", + "description": "Path of the declaring file in that repo", + "nullable": true + }, + "authoredBy": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Author attribution supplied with the package", + "nullable": true + } + }, + "description": "New package zip metadata for this environment" + }, "MonitorReference": { "required": [ "id", @@ -32418,7 +34445,97 @@ "description": "Monitor name" } }, - "description": "Monitors that reference this secret; null on create/update responses" + "description": "Monitors that reference this secret for authentication" + }, + "MonitorSecretRequestsDto": { + "required": [ + "environment", + "requests" + ], + "type": "object", + "properties": { + "environment": { + "$ref": "#/components/schemas/EnvironmentDto" + }, + "requests": { + "type": "array", + "description": "Secret keys this monitor requires and their resolve state", + "items": { + "$ref": "#/components/schemas/SecretRequestDto" + } + } + }, + "description": "Environment and secret keys this monitor requires" + }, + "MonitorSessionDto": { + "required": [ + "cookieNames", + "lifecycle", + "reusePolicy", + "setupFile", + "storageKeys" + ], + "type": "object", + "properties": { + "lifecycle": { + "type": "string", + "description": "Current session cache state", + "enum": [ + "active", + "expired", + "failed", + "revoked" + ] + }, + "reusePolicy": { + "type": "string", + "description": "When the cached session is reused across runs", + "enum": [ + "reuse", + "every_run", + "on_failure" + ] + }, + "setupFile": { + "type": "string", + "description": "Setup file path inside the package zip" + }, + "expiresAt": { + "type": "string", + "description": "When the cached session expires", + "format": "date-time", + "nullable": true + }, + "cookieNames": { + "type": "array", + "description": "Cookie names in the cached session", + "items": { + "type": "string", + "description": "Cookie names in the cached session" + } + }, + "storageKeys": { + "type": "array", + "description": "Storage key names in the cached session", + "items": { + "type": "string", + "description": "Storage key names in the cached session" + } + }, + "sizeBytes": { + "type": "integer", + "description": "Cached session size in bytes", + "format": "int32", + "nullable": true + }, + "lastRejectedRunId": { + "type": "string", + "description": "Run that last rejected this cache", + "format": "uuid", + "nullable": true + } + }, + "description": "Cached sign-in session for a monitor" }, "MonitorsSummaryDto": { "type": "object", @@ -33215,6 +35332,35 @@ }, "description": "Organization the key belongs to" }, + "PackageUploadDto": { + "required": [ + "expiresAt", + "putUrl", + "requiredHeaders" + ], + "type": "object", + "properties": { + "putUrl": { + "minLength": 1, + "type": "string", + "description": "Presigned PUT URL for the zip bytes" + }, + "expiresAt": { + "type": "string", + "description": "When the signed URL expires", + "format": "date-time" + }, + "requiredHeaders": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Must send Content-Type: application/zip and If-None-Match: *" + }, + "description": "Must send Content-Type: application/zip and If-None-Match: *" + } + }, + "description": "Signed package upload target" + }, "Pageable": { "type": "object", "properties": { @@ -33605,6 +35751,26 @@ } } }, + "QuarantineMonitorRequest": { + "required": [ + "expiresAt", + "reason" + ], + "type": "object", + "properties": { + "reason": { + "maxLength": 280, + "minLength": 0, + "type": "string", + "description": "Reason for this hold (max 280)" + }, + "expiresAt": { + "type": "string", + "description": "When the hold expires", + "format": "date-time" + } + } + }, "RateLimitInfo": { "type": "object", "properties": { @@ -33658,6 +35824,10 @@ ] }, "RedirectCountAssertion": { + "required": [ + "type", + "maxCount" + ], "type": "object", "properties": { "type": { @@ -33671,11 +35841,7 @@ "description": "Maximum number of HTTP redirects allowed before the check fails", "format": "int32" } - }, - "required": [ - "type", - "maxCount" - ] + } }, "RedirectTargetAssertion": { "required": [ @@ -33790,6 +35956,18 @@ }, "description": "Related incidents sharing the same origin within a time window" }, + "RemapSecretRequest": { + "type": "object", + "properties": { + "secretId": { + "type": "string", + "description": "Secret to attach; null restores name-match", + "format": "uuid", + "nullable": true + } + }, + "description": "Attach or clear a remapped secret" + }, "RemoveMonitorTagsRequest": { "required": [ "tagIds" @@ -34562,6 +36740,76 @@ }, "description": "All rule evaluations that ran for this check" }, + "RunDto": { + "required": [ + "enqueuedAt", + "executionClass", + "id", + "monitorId", + "phase", + "source", + "organizationId" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique run identifier", + "format": "uuid" + }, + "monitorId": { + "type": "string", + "description": "Monitor this run belongs to", + "format": "uuid" + }, + "organizationId": { + "type": "integer", + "description": "Organization this run belongs to", + "format": "int32" + }, + "source": { + "type": "string", + "description": "What triggered this run", + "enum": [ + "schedule", + "run_now", + "ci", + "fast_retry", + "remote_validation", + "deployment_validation", + "session_renew" + ] + }, + "phase": { + "type": "string", + "description": "Current run phase", + "enum": [ + "created", + "queued", + "starting", + "running", + "finalizing", + "finished" + ] + }, + "executionClass": { + "type": "string", + "description": "Whether this run is scheduled, retry, manual, or candidate", + "enum": [ + "scheduled", + "retry", + "manual", + "candidate" + ] + }, + "enqueuedAt": { + "type": "string", + "description": "When this run was enqueued", + "format": "date-time" + } + }, + "description": "Identity of a monitor run" + }, "ScheduledMaintenanceDto": { "required": [ "affectedComponents", @@ -34642,16 +36890,16 @@ "description": "A scheduled maintenance window from a vendor status page" }, "ScriptMonitorConfig": { - "required": [ - "script" - ], "type": "object", + "additionalProperties": false, "properties": { "script": { "maxLength": 65536, - "minLength": 1, + "minLength": 0, "type": "string", - "description": "Playwright test script source code" + "description": "Legacy inline script on existing rows", + "nullable": true, + "readOnly": true }, "timeoutSeconds": { "maximum": 120, @@ -34663,6 +36911,26 @@ } } }, + "SecretAuditDto": { + "type": "object", + "properties": { + "updatedAt": { + "type": "string", + "description": "When this secret was last updated", + "format": "date-time", + "nullable": true + }, + "updatedBy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/UserDto" + } + ] + } + }, + "description": "Last update time and author for a secret" + }, "SecretDto": { "required": [ "createdAt", @@ -34704,14 +36972,69 @@ }, "usedByMonitors": { "type": "array", - "description": "Monitors that reference this secret; null on create/update responses", + "description": "Monitors that reference this secret for authentication", "nullable": true, "items": { "$ref": "#/components/schemas/MonitorReference" } } }, - "description": "Secret with change-detection hash; plaintext value is never returned" + "description": "Organization secret and its change-detection hash" + }, + "SecretRequestDto": { + "required": [ + "key", + "readiness" + ], + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "Secret key this monitor requires" + }, + "secret": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/SecretDto" + } + ] + }, + "readiness": { + "type": "string", + "description": "Whether this key is resolved or missing", + "enum": [ + "resolved", + "missing" + ] + }, + "fulfilledBy": { + "type": "string", + "description": "Fulfilled from environment variables or a secret", + "nullable": true, + "enum": [ + "env", + "secret" + ] + } + }, + "description": "Secret key a monitor requires and how it is fulfilled" + }, + "SecretUsageDto": { + "required": [ + "monitors" + ], + "type": "object", + "properties": { + "monitors": { + "type": "array", + "description": "Monitors that reference this secret", + "items": { + "$ref": "#/components/schemas/MonitorDto" + } + } + }, + "description": "Monitors that reference this secret" }, "SeoMetadataDto": { "type": "object", @@ -36037,6 +38360,28 @@ } } }, + "SingleValueResponseMonitorSecretRequestsDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/MonitorSecretRequestsDto" + } + } + }, + "SingleValueResponseMonitorSessionDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/MonitorSessionDto" + } + } + }, "SingleValueResponseMonitorTestResultDto": { "required": [ "data" @@ -36092,6 +38437,17 @@ } } }, + "SingleValueResponsePackageUploadDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PackageUploadDto" + } + } + }, "SingleValueResponsePolicySnapshotDto": { "required": [ "data" @@ -36147,6 +38503,28 @@ } } }, + "SingleValueResponseRunDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/RunDto" + } + } + }, + "SingleValueResponseSecretAuditDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/SecretAuditDto" + } + } + }, "SingleValueResponseSecretDto": { "required": [ "data" @@ -36158,6 +38536,17 @@ } } }, + "SingleValueResponseSecretUsageDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/SecretUsageDto" + } + } + }, "SingleValueResponseServiceDayDetailDto": { "required": [ "data" @@ -36658,6 +39047,10 @@ } }, "SslExpiryAssertion": { + "required": [ + "type", + "minDaysRemaining" + ], "type": "object", "properties": { "type": { @@ -36671,11 +39064,7 @@ "description": "Minimum days before TLS certificate expiry; fails or warns below this threshold", "format": "int32" } - }, - "required": [ - "type", - "minDaysRemaining" - ] + } }, "StateTransitionDetails": { "required": [ @@ -37822,10 +40211,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37858,10 +40243,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37894,10 +40275,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37930,10 +40307,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37966,10 +40339,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38002,10 +40371,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38038,10 +40403,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38074,10 +40435,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38110,10 +40467,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38146,10 +40499,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38182,10 +40531,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38218,10 +40563,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38254,10 +40595,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38290,10 +40627,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38326,10 +40659,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38362,10 +40691,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38398,10 +40723,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38434,10 +40755,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38470,10 +40787,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38506,10 +40819,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38542,10 +40851,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38578,10 +40883,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38614,10 +40915,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38650,10 +40947,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38686,10 +40979,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38722,10 +41011,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38758,10 +41043,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38794,10 +41075,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38830,10 +41107,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38866,10 +41139,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38902,10 +41171,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38938,10 +41203,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38974,10 +41235,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39010,10 +41267,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39046,10 +41299,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39082,10 +41331,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39118,10 +41363,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39154,10 +41395,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39190,10 +41427,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -40474,7 +42707,7 @@ "maxLength": 255, "minLength": 0, "type": "string", - "description": "New monitor name; null preserves current", + "description": "New monitor name. Null preserves current", "nullable": true }, "config": { @@ -40507,27 +42740,27 @@ "maximum": 86400, "minimum": 10, "type": "integer", - "description": "New check frequency in seconds (10–86400); null preserves current", + "description": "New check frequency in seconds (10–86400). Null preserves current", "format": "int32", "nullable": true }, "enabled": { "type": "boolean", - "description": "Enable or disable the monitor; null preserves current", + "description": "Enable or disable the monitor (pause or resume). Null preserves current", "nullable": true }, "regions": { "type": "array", - "description": "New probe regions; null preserves current. Allowed values are deployment-dependent.", + "description": "New probe regions. Null preserves current. Allowed values are deployment-dependent", "nullable": true, "items": { "type": "string", - "description": "New probe regions; null preserves current. Allowed values are deployment-dependent." + "description": "New probe regions. Null preserves current. Allowed values are deployment-dependent" } }, "managedBy": { "type": "string", - "description": "New ownership source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value", + "description": "New ownership source: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null preserves current", "nullable": true, "enum": [ "DASHBOARD", @@ -40539,7 +42772,7 @@ }, "environmentId": { "type": "string", - "description": "New environment ID; null preserves current (use clearEnvironmentId to unset)", + "description": "New environment; null preserves current", "format": "uuid", "nullable": true }, @@ -40550,7 +42783,7 @@ }, "assertions": { "type": "array", - "description": "Replace all assertions; null preserves current", + "description": "Replace all assertions. Null preserves current", "nullable": true, "items": { "$ref": "#/components/schemas/CreateAssertionRequest" @@ -40579,11 +42812,11 @@ }, "alertChannelIds": { "type": "array", - "description": "Replace alert channel list; null preserves current", + "description": "Replace alert channel list. Null preserves current", "nullable": true, "items": { "type": "string", - "description": "Replace alert channel list; null preserves current", + "description": "Replace alert channel list. Null preserves current", "format": "uuid" } }, @@ -40594,6 +42827,35 @@ "$ref": "#/components/schemas/AddMonitorTagsRequest" } ] + }, + "capturePolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CapturePolicy" + } + ] + }, + "fastRetryMaxAttempts": { + "maximum": 10, + "minimum": 0, + "type": "integer", + "description": "Fast-retry attempts after failure. Null preserves current. 0 disables", + "format": "int32", + "nullable": true + }, + "package": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/MonitorPackageSpec" + } + ] + }, + "status": { + "type": "string", + "description": "Not writable; use pause or resume", + "nullable": true } } }, @@ -41508,6 +43770,35 @@ "channelType" ] }, + "UpsertMonitorSessionRequest": { + "required": [ + "reusePolicy", + "setupFile" + ], + "type": "object", + "properties": { + "reusePolicy": { + "type": "string", + "description": "When to reuse the cached session across runs", + "enum": [ + "reuse", + "every_run", + "on_failure" + ] + }, + "setupFile": { + "minLength": 1, + "type": "string", + "description": "Setup file path inside the package zip" + }, + "expiresAt": { + "type": "string", + "description": "When the cached session expires", + "format": "date-time", + "nullable": true + } + } + }, "UptimeBucketDto": { "required": [ "timestamp", @@ -41594,6 +43885,73 @@ "incidentCount" ] }, + "UserDto": { + "required": [ + "createdAt", + "email", + "updatedAt", + "userRole", + "id", + "emailVerified" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Unique user identifier", + "format": "int32" + }, + "email": { + "type": "string", + "description": "User email address" + }, + "emailVerified": { + "type": "boolean", + "description": "Whether the email address has been verified" + }, + "name": { + "type": "string", + "description": "Display name; null if not set", + "nullable": true + }, + "userRole": { + "type": "string", + "description": "Platform role: USER or SUPERADMIN", + "enum": [ + "SUPERADMIN", + "ADMIN", + "USER" + ] + }, + "onboardingStage": { + "type": "string", + "description": "Current onboarding progress stage; null when completed", + "nullable": true, + "enum": [ + "WELCOME", + "FIRST_MONITOR", + "SETUP_COMPLETE", + "COMPLETED" + ] + }, + "imageUrl": { + "type": "string", + "description": "Profile image URL; null if not set", + "nullable": true + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the account was created", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "description": "Timestamp when the account was last updated", + "format": "date-time" + } + }, + "description": "User account details" + }, "VoiceLanguageDto": { "required": [ "code", @@ -41905,6 +44263,19 @@ }, "description": "Workspace within an organization" }, + "WriteSecretEnvironmentValueRequest": { + "required": [ + "value" + ], + "type": "object", + "properties": { + "value": { + "minLength": 1, + "type": "string", + "description": "Plaintext value to encrypt for this environment" + } + } + }, "ZapierChannelConfig": { "required": [ "channelType", diff --git a/src/devhelm/_generated.py b/src/devhelm/_generated.py index 1a01743..801e5a2 100644 --- a/src/devhelm/_generated.py +++ b/src/devhelm/_generated.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Annotated, Any, Literal -from pydantic import ConfigDict, AwareDatetime, BaseModel, EmailStr, Field, RootModel +from pydantic import AwareDatetime, BaseModel, ConfigDict, EmailStr, Field, RootModel from enum import StrEnum from uuid import UUID from datetime import date as date_aliased @@ -538,6 +538,35 @@ class Action(StrEnum): remove_tag = "REMOVE_TAG" +class Screenshots(StrEnum): + always = "always" + on_failure = "on_failure" + off = "off" + + +class Trace(StrEnum): + always = "always" + on_failure = "on_failure" + off = "off" + + +class Video(StrEnum): + always = "always" + on_failure = "on_failure" + off = "off" + + +class CapturePolicy(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + screenshots: Annotated[ + Screenshots | None, Field(description="When to capture screenshots") + ] = None + trace: Annotated[ + Trace | None, Field(description="When to capture a Playwright trace") + ] = None + video: Annotated[Video | None, Field(description="When to capture video")] = None + + class CategoryDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) category: Annotated[ @@ -989,6 +1018,18 @@ class Type(StrEnum): multi_step_api = "MULTI_STEP_API" +class CreatePackageUploadRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + digest: Annotated[ + str, + Field( + description="SHA-256 hex digest of the package zip to upload (64 chars)", + max_length=64, + min_length=64, + ), + ] + + class HealthThresholdType(StrEnum): count = "COUNT" # type: ignore[assignment] percentage = "PERCENTAGE" @@ -3237,12 +3278,161 @@ class MonitorAuthDto(BaseModel): config: ApiKeyAuthConfig | BasicAuthConfig | BearerAuthConfig | HeaderAuthConfig +class MonitorOverlayRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + reason: Annotated[ + str | None, + Field( + description="Optional human-readable reason (max 280)", + max_length=280, + min_length=0, + ), + ] = None + expires_at: Annotated[ + AwareDatetime | None, + Field(alias="expiresAt", description="When this overlay expires"), + ] = None + + +class File(RootModel[str]): + root: Annotated[ + str, + Field( + description="Relative file paths included in the zip", + max_length=512, + min_length=0, + ), + ] + + +class Key(RootModel[str]): + root: Annotated[ + str, + Field( + description="Secret names the zip demanded. PUT: null preserves, [] clears", + max_length=255, + min_length=0, + ), + ] + + +class MonitorPackageSpec(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + digest: Annotated[ + str, + Field( + description="SHA-256 hex digest of the package zip (64 characters)", + max_length=64, + min_length=64, + ), + ] + entrypoint: Annotated[ + str, + Field( + description="Entrypoint path inside the zip, e.g. tests/login.spec.ts", + max_length=512, + min_length=0, + ), + ] + files: Annotated[ + list[File], + Field( + description="Relative file paths included in the zip", + max_length=256, + min_length=0, + ), + ] + keys: Annotated[ + list[Key] | None, + Field( + description="Secret names the zip demanded. PUT: null preserves, [] clears", + max_length=64, + min_length=0, + ), + ] = None + git_sha: Annotated[ + str | None, + Field( + alias="gitSha", + description="Commit SHA from the repo that produced this zip. Client-supplied provenance only", + max_length=64, + min_length=0, + ), + ] = None + git_message: Annotated[ + str | None, + Field( + alias="gitMessage", + description="Commit message from the repo that produced this zip", + max_length=1024, + min_length=0, + ), + ] = None + git_file: Annotated[ + str | None, + Field( + alias="gitFile", + description="Path of the declaring file in that repo", + max_length=512, + min_length=0, + ), + ] = None + authored_by: Annotated[ + str | None, + Field( + alias="authoredBy", + description="Author attribution supplied with the package", + max_length=255, + min_length=0, + ), + ] = None + + class MonitorReference(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: Annotated[UUID, Field(description="Monitor identifier")] name: Annotated[str, Field(description="Monitor name")] +class MonitorSessionDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + lifecycle: Annotated[str, Field(description="Current session cache state")] + reuse_policy: Annotated[ + str, + Field( + alias="reusePolicy", + description="When the cached session is reused across runs", + ), + ] + setup_file: Annotated[ + str, + Field(alias="setupFile", description="Setup file path inside the package zip"), + ] + expires_at: Annotated[ + AwareDatetime | None, + Field(alias="expiresAt", description="When the cached session expires"), + ] = None + cookie_names: Annotated[ + list[str], + Field(alias="cookieNames", description="Cookie names in the cached session"), + ] + storage_keys: Annotated[ + list[str], + Field( + alias="storageKeys", description="Storage key names in the cached session" + ), + ] + size_bytes: Annotated[ + int | None, Field(alias="sizeBytes", description="Cached session size in bytes") + ] = None + last_rejected_run_id: Annotated[ + UUID | None, + Field( + alias="lastRejectedRunId", description="Run that last rejected this cache" + ), + ] = None + + class MonitorsSummaryDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) total: Annotated[ @@ -3634,6 +3824,29 @@ class OrgInfo(BaseModel): name: Annotated[str, Field(description="Organization name")] +class PackageUploadDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + put_url: Annotated[ + str, + Field( + alias="putUrl", + description="Presigned PUT URL for the zip bytes", + min_length=1, + ), + ] + expires_at: Annotated[ + AwareDatetime, + Field(alias="expiresAt", description="When the signed URL expires"), + ] + required_headers: Annotated[ + dict[str, str], + Field( + alias="requiredHeaders", + description="Must send Content-Type: application/zip and If-None-Match: *", + ), + ] + + class Pageable(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) page: Annotated[int, Field(ge=0)] @@ -3934,6 +4147,19 @@ class PushoverChannelConfig(BaseModel): ) +class QuarantineMonitorRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + reason: Annotated[ + str, + Field( + description="Reason for this hold (max 280)", max_length=280, min_length=0 + ), + ] + expires_at: Annotated[ + AwareDatetime, Field(alias="expiresAt", description="When the hold expires") + ] + + class RateLimitInfo(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) requests_per_minute: Annotated[ @@ -4043,6 +4269,16 @@ class RegionStatusDto(BaseModel): ] = None +class RemapSecretRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + secret_id: Annotated[ + UUID | None, + Field( + alias="secretId", description="Secret to attach; null restores name-match" + ), + ] = None + + class RemoveMonitorTagsRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) tag_ids: Annotated[ @@ -4410,6 +4646,31 @@ class RuleEvaluationDto(BaseModel): ] = None +class RunDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[UUID, Field(description="Unique run identifier")] + monitor_id: Annotated[ + UUID, Field(alias="monitorId", description="Monitor this run belongs to") + ] + organization_id: Annotated[ + int, + Field(alias="organizationId", description="Organization this run belongs to"), + ] + source: Annotated[str, Field(description="What triggered this run")] + phase: Annotated[str, Field(description="Current run phase")] + execution_class: Annotated[ + str, + Field( + alias="executionClass", + description="Whether this run is scheduled, retry, manual, or candidate", + ), + ] + enqueued_at: Annotated[ + AwareDatetime, + Field(alias="enqueuedAt", description="When this run was enqueued"), + ] + + class ScheduledMaintenanceDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: Annotated[UUID, Field(description="Unique maintenance record identifier")] @@ -4475,13 +4736,13 @@ class ScheduledMaintenanceDto(BaseModel): class ScriptMonitorConfig(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) script: Annotated[ - str, + str | None, Field( - description="Playwright test script source code", + description="Legacy inline script on existing rows", max_length=65536, - min_length=1, + min_length=0, ), - ] + ] = None timeout_seconds: Annotated[ int | None, Field( @@ -4526,7 +4787,23 @@ class SecretDto(BaseModel): list[MonitorReference] | None, Field( alias="usedByMonitors", - description="Monitors that reference this secret; null on create/update responses", + description="Monitors that reference this secret for authentication", + ), + ] = None + + +class SecretRequestDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + key: Annotated[str, Field(description="Secret key this monitor requires")] + secret: SecretDto | None = None + readiness: Annotated[ + str, Field(description="Whether this key is resolved or missing") + ] + fulfilled_by: Annotated[ + str | None, + Field( + alias="fulfilledBy", + description="Fulfilled from environment variables or a secret", ), ] = None @@ -5084,6 +5361,11 @@ class SingleValueResponseMonitorAuthDto(BaseModel): data: MonitorAuthDto +class SingleValueResponseMonitorSessionDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: MonitorSessionDto + + class SingleValueResponseMonitorTestResultDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: MonitorTestResultDto @@ -5099,6 +5381,11 @@ class SingleValueResponseOrganizationDto(BaseModel): data: OrganizationDto +class SingleValueResponsePackageUploadDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: PackageUploadDto + + class SingleValueResponsePolicySnapshotDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: PolicySnapshotDto @@ -5114,6 +5401,11 @@ class SingleValueResponseResultSummaryDto(BaseModel): data: ResultSummaryDto +class SingleValueResponseRunDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: RunDto + + class SingleValueResponseSecretDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: SecretDto @@ -5766,7 +6058,6 @@ class TableValueResultAlertChannelDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultAlertDeliveryDto(BaseModel): @@ -5776,7 +6067,6 @@ class TableValueResultAlertDeliveryDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultApiKeyDto(BaseModel): @@ -5786,7 +6076,6 @@ class TableValueResultApiKeyDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultCategoryDto(BaseModel): @@ -5796,7 +6085,6 @@ class TableValueResultCategoryDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultDeliveryAttemptDto(BaseModel): @@ -5806,7 +6094,6 @@ class TableValueResultDeliveryAttemptDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultEnvironmentDto(BaseModel): @@ -5816,7 +6103,6 @@ class TableValueResultEnvironmentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultInviteDto(BaseModel): @@ -5826,7 +6112,6 @@ class TableValueResultInviteDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultMaintenanceWindowDto(BaseModel): @@ -5836,7 +6121,6 @@ class TableValueResultMaintenanceWindowDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultMemberDto(BaseModel): @@ -5846,7 +6130,6 @@ class TableValueResultMemberDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultNotificationDispatchDto(BaseModel): @@ -5856,7 +6139,6 @@ class TableValueResultNotificationDispatchDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultNotificationDto(BaseModel): @@ -5866,7 +6148,6 @@ class TableValueResultNotificationDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultRuleEvaluationDto(BaseModel): @@ -5876,7 +6157,6 @@ class TableValueResultRuleEvaluationDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultScheduledMaintenanceDto(BaseModel): @@ -5886,7 +6166,6 @@ class TableValueResultScheduledMaintenanceDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultSecretDto(BaseModel): @@ -5896,7 +6175,6 @@ class TableValueResultSecretDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultServiceComponentDto(BaseModel): @@ -5906,7 +6184,6 @@ class TableValueResultServiceComponentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultServiceIncidentDto(BaseModel): @@ -5916,7 +6193,6 @@ class TableValueResultServiceIncidentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultServiceSubscriptionDto(BaseModel): @@ -5926,7 +6202,6 @@ class TableValueResultServiceSubscriptionDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageComponentDto(BaseModel): @@ -5936,7 +6211,6 @@ class TableValueResultStatusPageComponentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageComponentGroupDto(BaseModel): @@ -5946,7 +6220,6 @@ class TableValueResultStatusPageComponentGroupDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageCustomDomainDto(BaseModel): @@ -5956,7 +6229,6 @@ class TableValueResultStatusPageCustomDomainDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageNotificationDeliveryDto(BaseModel): @@ -5966,7 +6238,6 @@ class TableValueResultStatusPageNotificationDeliveryDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageSubscriberDto(BaseModel): @@ -5976,7 +6247,6 @@ class TableValueResultStatusPageSubscriberDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TagDto(BaseModel): @@ -7400,6 +7670,35 @@ class UpdateZapierChannelConfig(BaseModel): ] = None +class ReusePolicy(StrEnum): + reuse = "reuse" + every_run = "every_run" + on_failure = "on_failure" + + +class UpsertMonitorSessionRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + reuse_policy: Annotated[ + ReusePolicy, + Field( + alias="reusePolicy", + description="When to reuse the cached session across runs", + ), + ] + setup_file: Annotated[ + str, + Field( + alias="setupFile", + description="Setup file path inside the package zip", + min_length=1, + ), + ] + expires_at: Annotated[ + AwareDatetime | None, + Field(alias="expiresAt", description="When the cached session expires"), + ] = None + + class UptimeBucketDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) timestamp: Annotated[ @@ -7487,6 +7786,46 @@ class UptimeDto(BaseModel): ] +class UserDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[int, Field(description="Unique user identifier")] + email: Annotated[str, Field(description="User email address")] + email_verified: Annotated[ + bool, + Field( + alias="emailVerified", + description="Whether the email address has been verified", + ), + ] + name: Annotated[str | None, Field(description="Display name; null if not set")] = ( + None + ) + user_role: Annotated[ + str, Field(alias="userRole", description="Platform role: USER or SUPERADMIN") + ] + onboarding_stage: Annotated[ + str | None, + Field( + alias="onboardingStage", + description="Current onboarding progress stage; null when completed", + ), + ] = None + image_url: Annotated[ + str | None, + Field(alias="imageUrl", description="Profile image URL; null if not set"), + ] = None + created_at: Annotated[ + AwareDatetime, + Field(alias="createdAt", description="Timestamp when the account was created"), + ] + updated_at: Annotated[ + AwareDatetime, + Field( + alias="updatedAt", description="Timestamp when the account was last updated" + ), + ] + + class VoiceLanguageDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) code: Annotated[ @@ -7654,6 +7993,16 @@ class WorkspaceDto(BaseModel): ] +class WriteSecretEnvironmentValueRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + value: Annotated[ + str, + Field( + description="Plaintext value to encrypt for this environment", min_length=1 + ), + ] + + class ZapierChannelConfig(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) channel_type: Annotated[Literal["zapier"], Field(alias="channelType")] = "zapier" @@ -7952,12 +8301,13 @@ class CreateMonitorRequest(BaseModel): | McpServerMonitorConfig | ScriptMonitorConfig | TcpMonitorConfig - ) + | None + ) = None frequency_seconds: Annotated[ int | None, Field( alias="frequencySeconds", - description="Check frequency in seconds (10–86400); null defaults to plan minimum (60s on most paid plans)", + description="Check frequency in seconds (10–86400). Null defaults to the plan minimum", ge=10, le=86400, ), @@ -7968,21 +8318,21 @@ class CreateMonitorRequest(BaseModel): regions: Annotated[ list[str] | None, Field( - description="Probe regions to run checks from. Allowed values are deployment-dependent; production: us-east, us-west, eu-west, ap-south." + description="Probe regions to run checks from. Allowed values are deployment-dependent. Production: us-east, us-west, eu-west, ap-south" ), ] = None managed_by: Annotated[ ManagedBy | None, Field( alias="managedBy", - description="Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted; set to your surface so audit logs, drift detection, and analytics attribute correctly.", + description="Source that created this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API", ), ] = None environment_id: Annotated[ UUID | None, Field( alias="environmentId", - description="Environment to associate with this monitor", + description="Environment to associate with this monitor. Required for browser and multi-step monitors", ), ] = None assertions: Annotated[ @@ -8001,6 +8351,24 @@ class CreateMonitorRequest(BaseModel): ), ] = None tags: AddMonitorTagsRequest | None = None + capture_policy: Annotated[CapturePolicy | None, Field(alias="capturePolicy")] = None + fast_retry_max_attempts: Annotated[ + int | None, + Field( + alias="fastRetryMaxAttempts", + description="Fast-retry attempts after failure. Null or 0 disables", + ge=0, + le=10, + ), + ] = None + definition_id: Annotated[ + UUID | None, + Field( + alias="definitionId", + description="Existing definition to reuse for a sibling monitor", + ), + ] = None + package: MonitorPackageSpec | None = None class CreateResourceGroupRequest(BaseModel): @@ -8192,6 +8560,26 @@ class CreditPolicy(BaseModel): ] = None +class CursorPageNotificationDispatchDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: Annotated[ + list[NotificationDispatchDto], Field(description="Items on this page") + ] + next_cursor: Annotated[ + str | None, + Field( + alias="nextCursor", + description="Opaque cursor for the next page; null when there are no more results", + ), + ] = None + has_more: Annotated[ + bool, + Field( + alias="hasMore", description="Whether more results exist beyond this page" + ), + ] + + class CursorPageServiceCatalogDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: Annotated[list[ServiceCatalogDto], Field(description="Items on this page")] @@ -8922,9 +9310,69 @@ class MonitorDto(BaseModel): str | None, Field( alias="currentStatus", - description="Current operational state — UP, DOWN, DEGRADED, PAUSED, or UNKNOWN if no probe data yet", + description="Current operational state. One of UP, DOWN, DEGRADED, PAUSED, or UNKNOWN", + ), + ] = None + definition_id: Annotated[ + UUID | None, + Field( + alias="definitionId", + description="Definition id for a browser or multi-step monitor. Null on probe monitors", + ), + ] = None + capture_policy: Annotated[CapturePolicy | None, Field(alias="capturePolicy")] = None + fast_retry_max_attempts: Annotated[ + int | None, + Field( + alias="fastRetryMaxAttempts", + description="Fast-retry max attempts; null/0 = off", + ), + ] = None + muted: Annotated[bool, Field(description="Whether alert delivery is muted")] + muted_until: Annotated[ + AwareDatetime | None, + Field( + alias="mutedUntil", + description="Mute expiry; null means indefinite while muted", + ), + ] = None + mute_reason: Annotated[ + str | None, Field(alias="muteReason", description="Optional mute reason") + ] = None + paused_at: Annotated[ + AwareDatetime | None, + Field(alias="pausedAt", description="When the monitor was paused"), + ] = None + pause_reason: Annotated[ + str | None, Field(alias="pauseReason", description="Optional pause reason") + ] = None + pause_expires_at: Annotated[ + AwareDatetime | None, Field(alias="pauseExpiresAt", description="Pause expiry") + ] = None + quarantine_owner_id: Annotated[ + str | None, + Field(alias="quarantineOwnerId", description="Quarantine person owner id"), + ] = None + quarantine_until: Annotated[ + AwareDatetime | None, + Field( + alias="quarantineUntil", + description="Quarantine expiry; non-null means quarantined", ), ] = None + quarantine_reason: Annotated[ + str | None, Field(alias="quarantineReason", description="Quarantine reason") + ] = None + upload: PackageUploadDto | None = None + + +class MonitorSecretRequestsDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + environment: EnvironmentDto + requests: Annotated[ + list[SecretRequestDto], + Field(description="Secret keys this monitor requires and their resolve state"), + ] class MonitorTestRequest(BaseModel): @@ -9180,6 +9628,22 @@ class ResourceGroupMemberDto(BaseModel): ] = None +class SecretAuditDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + updated_at: Annotated[ + AwareDatetime | None, + Field(alias="updatedAt", description="When this secret was last updated"), + ] = None + updated_by: Annotated[UserDto | None, Field(alias="updatedBy")] = None + + +class SecretUsageDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + monitors: Annotated[ + list[MonitorDto], Field(description="Monitors that reference this secret") + ] + + class ServiceIncidentDetailDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: UUID @@ -9269,6 +9733,11 @@ class SingleValueResponseMonitorDto(BaseModel): data: MonitorDto +class SingleValueResponseMonitorSecretRequestsDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: MonitorSecretRequestsDto + + class SingleValueResponseMonitorVersionDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: MonitorVersionDto @@ -9284,6 +9753,16 @@ class SingleValueResponseResourceGroupMemberDto(BaseModel): data: ResourceGroupMemberDto +class SingleValueResponseSecretAuditDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: SecretAuditDto + + +class SingleValueResponseSecretUsageDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: SecretUsageDto + + class SingleValueResponseServiceIncidentDetailDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: ServiceIncidentDetailDto @@ -9503,7 +9982,6 @@ class TableValueResultComponentUptimeDayDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultIncidentDto(BaseModel): @@ -9513,7 +9991,6 @@ class TableValueResultIncidentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultIncidentStateTransitionDto(BaseModel): @@ -9523,7 +10000,6 @@ class TableValueResultIncidentStateTransitionDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultIntegrationDto(BaseModel): @@ -9533,7 +10009,6 @@ class TableValueResultIntegrationDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultMonitorDto(BaseModel): @@ -9543,7 +10018,6 @@ class TableValueResultMonitorDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultMonitorVersionDto(BaseModel): @@ -9553,7 +10027,6 @@ class TableValueResultMonitorVersionDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultNotificationPolicyDto(BaseModel): @@ -9563,7 +10036,6 @@ class TableValueResultNotificationPolicyDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageDto(BaseModel): @@ -9573,7 +10045,6 @@ class TableValueResultStatusPageDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageIncidentDto(BaseModel): @@ -9583,7 +10054,6 @@ class TableValueResultStatusPageIncidentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultTagDto(BaseModel): @@ -9593,7 +10063,6 @@ class TableValueResultTagDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultTestChannelResult(BaseModel): @@ -9603,7 +10072,6 @@ class TableValueResultTestChannelResult(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultVoiceLanguageDto(BaseModel): @@ -9613,7 +10081,6 @@ class TableValueResultVoiceLanguageDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultWebhookDeliveryDto(BaseModel): @@ -9623,7 +10090,6 @@ class TableValueResultWebhookDeliveryDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultWebhookEndpointDto(BaseModel): @@ -9633,7 +10099,6 @@ class TableValueResultWebhookEndpointDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultWorkspaceDto(BaseModel): @@ -9643,7 +10108,6 @@ class TableValueResultWorkspaceDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TestAlertChannelRequest(BaseModel): @@ -9730,7 +10194,7 @@ class UpdateMonitorRequest(BaseModel): name: Annotated[ str | None, Field( - description="New monitor name; null preserves current", + description="New monitor name. Null preserves current", max_length=255, min_length=0, ), @@ -9749,33 +10213,34 @@ class UpdateMonitorRequest(BaseModel): int | None, Field( alias="frequencySeconds", - description="New check frequency in seconds (10–86400); null preserves current", + description="New check frequency in seconds (10–86400). Null preserves current", ge=10, le=86400, ), ] = None enabled: Annotated[ bool | None, - Field(description="Enable or disable the monitor; null preserves current"), + Field( + description="Enable or disable the monitor (pause or resume). Null preserves current" + ), ] = None regions: Annotated[ list[str] | None, Field( - description="New probe regions; null preserves current. Allowed values are deployment-dependent." + description="New probe regions. Null preserves current. Allowed values are deployment-dependent" ), ] = None managed_by: Annotated[ ManagedBy | None, Field( alias="managedBy", - description="New ownership source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value", + description="New ownership source: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null preserves current", ), ] = None environment_id: Annotated[ UUID | None, Field( - alias="environmentId", - description="New environment ID; null preserves current (use clearEnvironmentId to unset)", + alias="environmentId", description="New environment; null preserves current" ), ] = None clear_environment_id: Annotated[ @@ -9787,7 +10252,7 @@ class UpdateMonitorRequest(BaseModel): ] = None assertions: Annotated[ list[CreateAssertionRequest] | None, - Field(description="Replace all assertions; null preserves current"), + Field(description="Replace all assertions. Null preserves current"), ] = None auth: MonitorAuthConfig | None = None clear_auth: Annotated[ @@ -9801,10 +10266,24 @@ class UpdateMonitorRequest(BaseModel): list[UUID] | None, Field( alias="alertChannelIds", - description="Replace alert channel list; null preserves current", + description="Replace alert channel list. Null preserves current", ), ] = None tags: AddMonitorTagsRequest | None = None + capture_policy: Annotated[CapturePolicy | None, Field(alias="capturePolicy")] = None + fast_retry_max_attempts: Annotated[ + int | None, + Field( + alias="fastRetryMaxAttempts", + description="Fast-retry attempts after failure. Null preserves current. 0 disables", + ge=0, + le=10, + ), + ] = None + package: MonitorPackageSpec | None = None + status: Annotated[ + str | None, Field(description="Not writable; use pause or resume") + ] = None class UpdateNotificationPolicyRequest(BaseModel): @@ -10214,7 +10693,6 @@ class TableValueResultAuditEventDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultResourceGroupDto(BaseModel): @@ -10224,7 +10702,6 @@ class TableValueResultResourceGroupDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class CheckResultDetailsDto(BaseModel):