diff --git a/docs/openapi/monitoring-api.json b/docs/openapi/monitoring-api.json index 146f30f..9b4a190 100644 --- a/docs/openapi/monitoring-api.json +++ b/docs/openapi/monitoring-api.json @@ -7921,13 +7921,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 +7939,15 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MonitorOverlayRequest" + } + } + } + }, "responses": { "200": { "description": "OK", @@ -8033,14 +8042,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 +8058,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 +8101,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 +8163,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 +8179,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 +8223,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 +8285,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 +8397,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 +8414,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 +8507,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 +8569,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 +8586,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 +8635,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 +8697,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 +8721,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -8781,13 +8807,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,23 +8828,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AddMonitorTagsRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -8901,13 +8920,16 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{id}/status-pages": { + "get": { "tags": [ "Monitors" ], - "summary": "Remove tags from a monitor by their IDs", - "operationId": "removeMonitorTags", + "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": "id", @@ -8919,20 +8941,17 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RemoveMonitorTagsRequest" + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageDto" + } } } }, - "required": true - }, - "responses": { - "204": { - "description": "No Content" - }, "400": { "description": "Bad request — the payload failed validation", "content": { @@ -9016,14 +9035,13 @@ } } }, - "/api/v1/monitors/{id}/test": { - "post": { + "/api/v1/monitors/{id}/tags": { + "get": { "tags": [ "Monitors" ], - "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": "Get all tags applied to a monitor", + "operationId": "getMonitorTags", "parameters": [ { "name": "id", @@ -9041,7 +9059,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" + "$ref": "#/components/schemas/TableValueResultTagDto" } } } @@ -9127,16 +9145,13 @@ } } } - } - }, - "/api/v1/monitors/{id}/test-notifications": { + }, "post": { "tags": [ "Monitors" ], - "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": "Add tags to a monitor; supports existing tag IDs and inline creation of new tags", + "operationId": "addMonitorTags", "parameters": [ { "name": "id", @@ -9152,7 +9167,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TestMonitorNotificationsRequest" + "$ref": "#/components/schemas/AddMonitorTagsRequest" } } }, @@ -9164,7 +9179,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTestChannelResult" + "$ref": "#/components/schemas/TableValueResultTagDto" } } } @@ -9250,16 +9265,13 @@ } } } - } - }, - "/api/v1/monitors/{id}/uptime": { - "get": { + }, + "delete": { "tags": [ - "Check Results" + "Monitors" ], - "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": "Remove tags from a monitor by their IDs", + "operationId": "removeMonitorTags", "parameters": [ { "name": "id", @@ -9269,40 +9281,28 @@ "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", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/UptimeDto" - } + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RemoveMonitorTagsRequest" } } }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, "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 +9318,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 +9380,14 @@ } } }, - "/api/v1/monitors/{id}/versions": { - "get": { + "/api/v1/monitors/{id}/test": { + "post": { "tags": [ "Monitors" ], - "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": "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": "id", @@ -9397,14 +9397,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "pageable", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/Pageable" - } } ], "responses": { @@ -9413,7 +9405,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultMonitorVersionDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" } } } @@ -9501,14 +9493,14 @@ } } }, - "/api/v1/monitors/{id}/versions/{version}": { - "get": { + "/api/v1/monitors/{id}/test-notifications": { + "post": { "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", + "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": "id", @@ -9518,24 +9510,25 @@ "type": "string", "format": "uuid" } - }, - { - "name": "version", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestMonitorNotificationsRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorVersionDto" + "$ref": "#/components/schemas/TableValueResultTestChannelResult" } } } @@ -9623,16 +9616,16 @@ } } }, - "/api/v1/monitors/{monitorId}/alert-channels": { - "put": { + "/api/v1/monitors/{id}/unmute": { + "post": { "tags": [ - "Monitor Alert Channels" + "Monitors" ], - "summary": "Replace the linked alert channel set for a monitor", - "operationId": "setChannels", + "summary": "Clear mute overlay", + "operationId": "unmute", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -9641,23 +9634,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SetAlertChannelsRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseListUUID" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -9745,51 +9728,57 @@ } } }, - "/api/v1/monitors/{monitorId}/assertions": { - "post": { + "/api/v1/monitors/{id}/uptime": { + "get": { "tags": [ - "Monitor Assertions" + "Check Results" ], - "summary": "Add an assertion to a monitor", - "operationId": "add", + "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": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + }, + { + "name": "window", + "in": "query", + "description": "Time window for uptime calculation", + "required": false, + "schema": { + "type": "string", + "enum": [ + "24h", + "7d", + "30d", + "90d" + ] + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateAssertionRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "Uptime statistics", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" + "$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" } } } @@ -9805,21 +9794,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" } } } @@ -9867,16 +9856,17 @@ } } }, - "/api/v1/monitors/{monitorId}/assertions/{assertionId}": { - "put": { + "/api/v1/monitors/{id}/versions": { + "get": { "tags": [ - "Monitor Assertions" + "Monitors" ], - "summary": "Update an assertion on a monitor", - "operationId": "update_10", + "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": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -9885,32 +9875,21 @@ } }, { - "name": "assertionId", - "in": "path", + "name": "pageable", + "in": "query", "required": true, "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/Pageable" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateAssertionRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" + "$ref": "#/components/schemas/TableValueResultMonitorVersionDto" } } } @@ -9996,16 +9975,19 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{id}/versions/{version}": { + "get": { "tags": [ - "Monitor Assertions" + "Monitors" ], - "summary": "Remove an assertion from a monitor", - "operationId": "remove_1", + "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": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10014,18 +9996,25 @@ } }, { - "name": "assertionId", + "name": "version", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "integer", + "format": "int32" } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseMonitorVersionDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -10110,13 +10099,13 @@ } } }, - "/api/v1/monitors/{monitorId}/auth": { + "/api/v1/monitors/{monitorId}/alert-channels": { "put": { "tags": [ - "Monitor Auth" + "Monitor Alert Channels" ], - "summary": "Update authentication config for a monitor", - "operationId": "update_9", + "summary": "Replace the linked alert channel set for a monitor", + "operationId": "setChannels", "parameters": [ { "name": "monitorId", @@ -10132,7 +10121,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateMonitorAuthRequest" + "$ref": "#/components/schemas/SetAlertChannelsRequest" } } }, @@ -10144,7 +10133,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" + "$ref": "#/components/schemas/SingleValueResponseListUUID" } } } @@ -10230,13 +10219,15 @@ } } } - }, + } + }, + "/api/v1/monitors/{monitorId}/assertions": { "post": { "tags": [ - "Monitor Auth" + "Monitor Assertions" ], - "summary": "Set authentication config for a monitor", - "operationId": "set", + "summary": "Add an assertion to a monitor", + "operationId": "add", "parameters": [ { "name": "monitorId", @@ -10252,7 +10243,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SetMonitorAuthRequest" + "$ref": "#/components/schemas/CreateAssertionRequest" } } }, @@ -10264,7 +10255,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" } } } @@ -10350,13 +10341,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{monitorId}/assertions/{assertionId}": { + "put": { "tags": [ - "Monitor Auth" + "Monitor Assertions" ], - "summary": "Remove authentication config from a monitor", - "operationId": "remove", + "summary": "Update an assertion on a monitor", + "operationId": "update_10", "parameters": [ { "name": "monitorId", @@ -10366,11 +10359,37 @@ "type": "string", "format": "uuid" } + }, + { + "name": "assertionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateAssertionRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -10453,21 +10472,26 @@ } } } - } - }, - "/api/v1/monitors/{monitorId}/policy": { - "get": { + }, + "delete": { "tags": [ - "Incident Policies" + "Monitor Assertions" ], - "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": "Remove an assertion from a monitor", + "operationId": "remove_1", "parameters": [ { "name": "monitorId", "in": "path", - "description": "Monitor UUID", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "assertionId", + "in": "path", "required": true, "schema": { "type": "string", @@ -10476,15 +10500,8 @@ } ], "responses": { - "200": { - "description": "Policy found", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/IncidentPolicyDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -10517,11 +10534,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 +10584,19 @@ } } } - }, + } + }, + "/api/v1/monitors/{monitorId}/auth": { "put": { "tags": [ - "Incident Policies" + "Monitor Auth" ], - "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": "Update authentication config for a monitor", + "operationId": "update_9", "parameters": [ { "name": "monitorId", "in": "path", - "description": "Monitor UUID", "required": true, "schema": { "type": "string", @@ -10591,7 +10608,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateIncidentPolicyRequest" + "$ref": "#/components/schemas/UpdateMonitorAuthRequest" } } }, @@ -10599,133 +10616,21 @@ }, "responses": { "200": { - "description": "Policy updated", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/IncidentPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" } } } }, "400": { - "description": "Validation error in JSONB shape", + "description": "Bad request — the payload failed validation", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" - } - } - } - }, - "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": "Monitor or policy not found", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" - } - } - } - }, - "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/bulk": { - "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" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseBulkMonitorActionResult" - } - } - } - }, - "400": { - "description": "Bad request — the payload failed validation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -10801,33 +10706,41 @@ } } } - } - }, - "/api/v1/monitors/test": { + }, "post": { "tags": [ - "Monitors" + "Monitor Auth" + ], + "summary": "Set authentication config for a monitor", + "operationId": "set", + "parameters": [ + { + "name": "monitorId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } ], - "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" + "$ref": "#/components/schemas/SetMonitorAuthRequest" } } }, "required": true }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" } } } @@ -10913,21 +10826,17 @@ } } } - } - }, - "/api/v1/notification-dispatches": { - "get": { + }, + "delete": { "tags": [ - "Notification Dispatches" + "Monitor Auth" ], - "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": "Remove authentication config from a monitor", + "operationId": "remove", "parameters": [ { - "name": "incident_id", - "in": "query", - "description": "UUID of the incident to inspect", + "name": "monitorId", + "in": "path", "required": true, "schema": { "type": "string", @@ -10936,15 +10845,8 @@ } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -11029,18 +10931,19 @@ } } }, - "/api/v1/notification-dispatches/{id}": { + "/api/v1/monitors/{monitorId}/policy": { "get": { "tags": [ - "Notification Dispatches" + "Incident Policies" ], - "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 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", @@ -11050,11 +10953,11 @@ ], "responses": { "200": { - "description": "OK", + "description": "Policy found", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$ref": "#/components/schemas/IncidentPolicyDto" } } } @@ -11090,11 +10993,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" } } } @@ -11140,20 +11043,19 @@ } } } - } - }, - "/api/v1/notification-dispatches/{id}/acknowledge": { - "post": { + }, + "put": { "tags": [ - "Notification Dispatches" + "Incident Policies" ], - "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": "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": "id", + "name": "monitorId", "in": "path", + "description": "Monitor UUID", "required": true, "schema": { "type": "string", @@ -11161,23 +11063,33 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateIncidentPolicyRequest" + } + } + }, + "required": true + }, "responses": { "200": { - "description": "OK", + "description": "Policy updated", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$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" } } } @@ -11203,11 +11115,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" } } } @@ -11255,32 +11167,31 @@ } } }, - "/api/v1/notification-dispatches/{id}/unacknowledge": { + "/api/v1/monitors/bulk": { "post": { "tags": [ - "Notification Dispatches" + "Monitors" ], - "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", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" + "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" + } } - } - ], + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$ref": "#/components/schemas/SingleValueResponseBulkMonitorActionResult" } } } @@ -11368,20 +11279,31 @@ } } }, - "/api/v1/notification-policies": { - "get": { + "/api/v1/monitors/package-uploads": { + "post": { "tags": [ - "Notification Policies" + "Monitors" ], - "summary": "List all notification policies for the authenticated org", - "operationId": "list_7", + "summary": "Mint a signed package upload URL", + "description": "Dashboard helper for upload-first create. Not a customer resource.", + "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/TableValueResultNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponsePackageUploadDto" } } } @@ -11467,30 +11389,33 @@ } } } - }, + } + }, + "/api/v1/monitors/test": { "post": { "tags": [ - "Notification Policies" + "Monitors" ], - "summary": "Create a notification policy with match rules and escalation chain", - "operationId": "create_8", + "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/CreateNotificationPolicyRequest" + "$ref": "#/components/schemas/MonitorTestRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" } } } @@ -11578,17 +11503,19 @@ } } }, - "/api/v1/notification-policies/{id}": { + "/api/v1/notification-dispatches": { "get": { "tags": [ - "Notification Policies" + "Notification Dispatches" ], - "summary": "Get a notification policy by ID", - "operationId": "getById_1", + "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": "id", - "in": "path", + "name": "incident_id", + "in": "query", + "description": "UUID of the incident to inspect", "required": true, "schema": { "type": "string", @@ -11602,7 +11529,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" } } } @@ -11688,13 +11615,16 @@ } } } - }, - "put": { + } + }, + "/api/v1/notification-dispatches/{id}": { + "get": { "tags": [ - "Notification Policies" + "Notification Dispatches" ], - "summary": "Update a notification policy", - "operationId": "update_7", + "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", @@ -11706,23 +11636,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateNotificationPolicyRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" } } } @@ -11808,13 +11728,16 @@ } } } - }, - "delete": { + } + }, + "/api/v1/notification-dispatches/{id}/acknowledge": { + "post": { "tags": [ - "Notification Policies" + "Notification Dispatches" ], - "summary": "Delete a notification policy", - "operationId": "delete_6", + "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", @@ -11827,8 +11750,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -11913,14 +11843,14 @@ } } }, - "/api/v1/notification-policies/{id}/dispatches": { - "get": { + "/api/v1/notification-dispatches/{id}/unacknowledge": { + "post": { "tags": [ - "Notification Policies" + "Notification Dispatches" ], - "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": "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", @@ -11930,45 +11860,6 @@ "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": { @@ -11977,7 +11868,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" } } } @@ -12065,40 +11956,20 @@ } } }, - "/api/v1/notification-policies/{id}/test": { - "post": { + "/api/v1/notification-policies": { + "get": { "tags": [ "Notification Policies" ], - "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" - } - } - } - }, + "summary": "List all notification policies for the authenticated org", + "operationId": "list_7", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseTestMatchResult" + "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" } } } @@ -12184,53 +12055,30 @@ } } } - } - }, - "/api/v1/notifications": { - "get": { + }, + "post": { "tags": [ - "Notifications" + "Notification Policies" ], - "summary": "List notifications for the current user", - "operationId": "list_17", - "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 + "summary": "Create a notification policy with match rules and escalation chain", + "operationId": "create_8", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateNotificationPolicyRequest" + } } }, - { - "name": "size", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 20 - } - } - ], + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" } } } @@ -12318,27 +12166,34 @@ } } }, - "/api/v1/notifications/{id}/read": { - "put": { + "/api/v1/notification-policies/{id}": { + "get": { "tags": [ - "Notifications" + "Notification Policies" ], - "summary": "Mark a notification as read", - "operationId": "markRead", + "summary": "Get a notification policy by ID", + "operationId": "getById_1", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { - "type": "integer", - "format": "int64" + "type": "string", + "format": "uuid" } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -12421,18 +12276,44 @@ } } } - } - }, - "/api/v1/notifications/read-all": { + }, "put": { "tags": [ - "Notifications" + "Notification Policies" ], - "summary": "Mark all notifications as read", - "operationId": "markAllRead", + "summary": "Update a notification policy", + "operationId": "update_7", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateNotificationPolicyRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -12515,25 +12396,27 @@ } } } - } - }, - "/api/v1/notifications/unread-count": { - "get": { + }, + "delete": { "tags": [ - "Notifications" + "Notification Policies" ], - "summary": "Get unread notification count", - "operationId": "unreadCount", - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseLong" - } - } + "summary": "Delete a notification policy", + "operationId": "delete_6", + "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", @@ -12618,20 +12501,71 @@ } } }, - "/api/v1/org": { + "/api/v1/notification-policies/{id}/dispatches": { "get": { "tags": [ - "Organizations" + "Notification Policies" + ], + "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", + "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" + } + } ], - "summary": "Get the current organization", - "operationId": "get_4", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" + "$ref": "#/components/schemas/CursorPageNotificationDispatchDto" } } } @@ -12717,22 +12651,34 @@ } } } - }, - "put": { + } + }, + "/api/v1/notification-policies/{id}/test": { + "post": { "tags": [ - "Organizations" + "Notification Policies" + ], + "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" + } + } ], - "summary": "Update the current organization", - "operationId": "update_6", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateOrgDetailsRequest" + "$ref": "#/components/schemas/TestNotificationPolicyRequest" } } - }, - "required": true + } }, "responses": { "200": { @@ -12740,7 +12686,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" + "$ref": "#/components/schemas/SingleValueResponseTestMatchResult" } } } @@ -12828,20 +12774,51 @@ } } }, - "/api/v1/resource-groups": { + "/api/v1/notifications": { "get": { "tags": [ - "Resource Groups" + "Notifications" + ], + "summary": "List notifications for the current user", + "operationId": "list_17", + "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, + "schema": { + "type": "integer", + "format": "int32", + "default": 20 + } + } ], - "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/TableValueResultNotificationDto" } } } @@ -12927,33 +12904,29 @@ } } } - }, - "post": { + } + }, + "/api/v1/notifications/{id}/read": { + "put": { "tags": [ - "Resource Groups" + "Notifications" ], - "summary": "Create a new resource group", - "operationId": "create_7", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateResourceGroupRequest" - } + "summary": "Mark a notification as read", + "operationId": "markRead", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int64" } - }, - "required": true - }, + } + ], "responses": { - "201": { - "description": "Created", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -13038,44 +13011,16 @@ } } }, - "/api/v1/resource-groups/{id}": { - "get": { + "/api/v1/notifications/read-all": { + "put": { "tags": [ - "Resource Groups" - ], - "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": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "includeMetrics", - "in": "query", - "required": false, - "schema": { - "type": "boolean", - "default": false - } - } + "Notifications" ], + "summary": "Mark all notifications as read", + "operationId": "markAllRead", "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -13158,41 +13103,22 @@ } } } - }, - "put": { + } + }, + "/api/v1/notifications/unread-count": { + "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" - } - } + "Notifications" ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateResourceGroupRequest" - } - } - }, - "required": true - }, + "summary": "Get unread notification count", + "operationId": "unreadCount", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" + "$ref": "#/components/schemas/SingleValueResponseLong" } } } @@ -13278,27 +13204,25 @@ } } } - }, - "delete": { + } + }, + "/api/v1/org": { + "get": { "tags": [ - "Resource Groups" - ], - "summary": "Delete a resource group (cascades to member rows)", - "operationId": "delete_5", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "Organizations" ], + "summary": "Get the current organization", + "operationId": "get_4", "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -13381,34 +13305,30 @@ } } } - } - }, - "/api/v1/resource-groups/{id}/health": { - "get": { + }, + "put": { "tags": [ - "Resource Groups" + "Organizations" ], - "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": "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": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupHealthDto" + "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" } } } @@ -13496,32 +13416,20 @@ } } }, - "/api/v1/resource-groups/{id}/matched-policies": { + "/api/v1/resource-groups": { "get": { "tags": [ "Resource Groups" ], - "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": "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/TableValueResultNotificationPolicyDto" + "$ref": "#/components/schemas/TableValueResultResourceGroupDto" } } } @@ -13607,31 +13515,18 @@ } } } - } - }, - "/api/v1/resource-groups/{id}/members": { + }, "post": { "tags": [ "Resource Groups" ], - "summary": "Add a monitor or service member to a resource group", - "operationId": "addMember_1", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], + "summary": "Create a new resource group", + "operationId": "create_7", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AddResourceGroupMemberRequest" + "$ref": "#/components/schemas/CreateResourceGroupRequest" } } }, @@ -13643,7 +13538,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupMemberDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -13731,13 +13626,14 @@ } } }, - "/api/v1/resource-groups/{id}/members/{memberId}": { - "delete": { + "/api/v1/resource-groups/{id}": { + "get": { "tags": [ "Resource Groups" ], - "summary": "Remove a member from a resource group", - "operationId": "removeMember_1", + "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": "id", @@ -13749,116 +13645,22 @@ } }, { - "name": "memberId", - "in": "path", - "required": true, + "name": "includeMetrics", + "in": "query", + "required": false, "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" - } - } + "type": "boolean", + "default": false } } - } - } - }, - "/api/v1/secrets": { - "get": { - "tags": [ - "Secrets" ], - "summary": "List secrets", - "operationId": "list_5", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultSecretDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -13945,130 +13747,20 @@ } } }, - "post": { - "tags": [ - "Secrets" - ], - "summary": "Create secret", - "operationId": "create_6", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSecretRequest" - } - } - }, - "required": true - }, - "responses": { - "201": { - "description": "Created", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseSecretDto" - } - } - } - }, - "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/secrets/{key}": { "put": { "tags": [ - "Secrets" + "Resource Groups" ], - "summary": "Update secret", - "operationId": "update_4", + "summary": "Update a resource group's name, description, alert policy, inherited settings, and health threshold", + "operationId": "update_5", "parameters": [ { - "name": "key", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } } ], @@ -14076,7 +13768,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateSecretRequest" + "$ref": "#/components/schemas/UpdateResourceGroupRequest" } } }, @@ -14088,7 +13780,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseSecretDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -14177,17 +13869,18 @@ }, "delete": { "tags": [ - "Secrets" + "Resource Groups" ], - "summary": "Delete secret", - "operationId": "delete_4", + "summary": "Delete a resource group (cascades to member rows)", + "operationId": "delete_5", "parameters": [ { - "name": "key", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } } ], @@ -14278,20 +13971,32 @@ } } }, - "/api/v1/service-subscriptions": { + "/api/v1/resource-groups/{id}/health": { "get": { "tags": [ - "Service Subscriptions" + "Resource Groups" + ], + "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": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } ], - "summary": "List all service subscriptions for the organization", - "operationId": "list_16", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultServiceSubscriptionDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupHealthDto" } } } @@ -14379,13 +14084,14 @@ } } }, - "/api/v1/service-subscriptions/{id}": { + "/api/v1/resource-groups/{id}/matched-policies": { "get": { "tags": [ - "Service Subscriptions" + "Resource Groups" ], - "summary": "Get a subscription by its ID", - "operationId": "get_11", + "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": "id", @@ -14403,7 +14109,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" } } } @@ -14489,14 +14195,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/resource-groups/{id}/members": { + "post": { "tags": [ - "Service Subscriptions" + "Resource Groups" ], - "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", + "summary": "Add a monitor or service member to a resource group", + "operationId": "addMember_1", "parameters": [ { "name": "id", @@ -14508,9 +14215,26 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddResourceGroupMemberRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseResourceGroupMemberDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -14595,14 +14319,13 @@ } } }, - "/api/v1/service-subscriptions/{id}/alert-sensitivity": { - "patch": { + "/api/v1/resource-groups/{id}/members/{memberId}": { + "delete": { "tags": [ - "Service Subscriptions" + "Resource Groups" ], - "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", + "summary": "Remove a member from a resource group", + "operationId": "removeMember_1", "parameters": [ { "name": "id", @@ -14612,28 +14335,20 @@ "type": "string", "format": "uuid" } + }, + { + "name": "memberId", + "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/SingleValueResponseServiceSubscriptionDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -14718,40 +14433,913 @@ } } }, - "/api/v1/service-subscriptions/{slug}": { - "post": { + "/api/v1/secrets": { + "get": { "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" - } - } + "Secrets" ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ServiceSubscribeRequest" - } - } - } - }, + "summary": "List secrets", + "operationId": "list_5", "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + "$ref": "#/components/schemas/TableValueResultSecretDto" + } + } + } + }, + "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": [ + "Secrets" + ], + "summary": "Create secret", + "operationId": "create_6", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSecretRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseSecretDto" + } + } + } + }, + "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/secrets/{key}": { + "put": { + "tags": [ + "Secrets" + ], + "summary": "Update secret", + "operationId": "update_4", + "parameters": [ + { + "name": "key", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSecretRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseSecretDto" + } + } + } + }, + "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": [ + "Secrets" + ], + "summary": "Delete secret", + "operationId": "delete_4", + "parameters": [ + { + "name": "key", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "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/service-subscriptions": { + "get": { + "tags": [ + "Service Subscriptions" + ], + "summary": "List all service subscriptions for the organization", + "operationId": "list_16", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultServiceSubscriptionDto" + } + } + } + }, + "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/service-subscriptions/{id}": { + "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" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + } + } + } + }, + "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": [ + "Service Subscriptions" + ], + "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" + } + } + ], + "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/service-subscriptions/{id}/alert-sensitivity": { + "patch": { + "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" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateAlertSensitivityRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + } + } + } + }, + "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/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" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceSubscribeRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" } } } @@ -27345,7 +27933,6 @@ }, "CreateMonitorRequest": { "required": [ - "config", "name", "type" ], @@ -27372,6 +27959,7 @@ ] }, "config": { + "nullable": true, "oneOf": [ { "$ref": "#/components/schemas/DnsMonitorConfig" @@ -27432,7 +28020,7 @@ }, "environmentId": { "type": "string", - "description": "Environment to associate with this monitor", + "description": "Environment to associate with this monitor; required for code types", "format": "uuid", "nullable": true }, @@ -27477,6 +28065,37 @@ "$ref": "#/components/schemas/AddMonitorTagsRequest" } ] + }, + "capturePolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CapturePolicy" + } + ], + "description": "When to capture screenshots, traces, and video. Omit for probe monitors" + }, + "fastRetryMaxAttempts": { + "maximum": 10, + "minimum": 0, + "type": "integer", + "description": "Fast-retry attempts after failure; null/0 disables", + "format": "int32", + "nullable": true + }, + "definitionId": { + "type": "string", + "description": "Existing definition to reuse for a sibling monitor. Do not send together with package", + "format": "uuid", + "nullable": true + }, + "package": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/MonitorPackageSpec" + } + ] } } }, @@ -27527,6 +28146,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 +28852,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 +29625,10 @@ ] }, "DnsTtlLowAssertion": { + "required": [ + "type", + "minTtl" + ], "type": "object", "properties": { "type": { @@ -28979,11 +29642,7 @@ "description": "Minimum acceptable TTL in seconds before a warning is raised", "format": "int32" } - }, - "required": [ - "type", - "minTtl" - ] + } }, "DnsTxtContainsAssertion": { "required": [ @@ -29783,6 +30442,10 @@ } }, "IcmpPacketLossAssertion": { + "required": [ + "type", + "maxPercent" + ], "type": "object", "properties": { "type": { @@ -29800,11 +30463,7 @@ "description": "Maximum allowed packet loss percentage before the check fails (0–100)", "format": "double" } - }, - "required": [ - "type", - "maxPercent" - ] + } }, "IcmpReachableAssertion": { "type": "object", @@ -31657,6 +32316,10 @@ } }, "McpMinToolsAssertion": { + "required": [ + "type", + "min" + ], "type": "object", "properties": { "type": { @@ -31670,11 +32333,7 @@ "description": "Minimum number of tools the server must expose", "format": "int32" } - }, - "required": [ - "type", - "min" - ] + } }, "McpProtocolVersionAssertion": { "required": [ @@ -31843,6 +32502,10 @@ } }, "McpToolCountChangedAssertion": { + "required": [ + "type", + "expectedCount" + ], "type": "object", "properties": { "type": { @@ -31856,11 +32519,7 @@ "description": "Expected tool count; warns when the live count differs", "format": "int32" } - }, - "required": [ - "type", - "expectedCount" - ] + } }, "MemberDto": { "required": [ @@ -32236,7 +32895,8 @@ "updatedAt", "organizationId", "frequencySeconds", - "enabled" + "enabled", + "muted" ], "type": "object", "properties": { @@ -32388,7 +33048,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 +33057,202 @@ "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" + } + ], + "description": "When screenshots, traces, and video are captured" + }, + "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": "Optional expiry; sweeper clears the overlay after this time", + "format": "date-time", + "nullable": true + } + } + }, + "CapturePolicy": { + "type": "object", + "description": "When to capture screenshots, traces, and video during a code run", + "properties": { + "screenshots": { + "type": "string", + "description": "When to capture screenshots", + "enum": ["always", "on_failure", "off"], + "nullable": true + }, + "trace": { + "type": "string", + "description": "When to capture a Playwright trace", + "enum": ["always", "on_failure", "off"], + "nullable": true + }, + "video": { + "type": "string", + "description": "When to capture video", + "enum": ["always", "on_failure", "off"], + "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": { + "minItems": 1, + "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": { + "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. Bytes upload through the signed putUrl" + }, "MonitorReference": { "required": [ "id", @@ -33215,6 +34067,34 @@ }, "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": "Signed package upload target" + }, "Pageable": { "type": "object", "properties": { @@ -33605,6 +34485,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 +34558,10 @@ ] }, "RedirectCountAssertion": { + "required": [ + "type", + "maxCount" + ], "type": "object", "properties": { "type": { @@ -33671,11 +34575,7 @@ "description": "Maximum number of HTTP redirects allowed before the check fails", "format": "int32" } - }, - "required": [ - "type", - "maxCount" - ] + } }, "RedirectTargetAssertion": { "required": [ @@ -34642,16 +35542,15 @@ "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 }, "timeoutSeconds": { "maximum": 120, @@ -36092,6 +36991,17 @@ } } }, + "SingleValueResponsePackageUploadDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PackageUploadDto" + } + } + }, "SingleValueResponsePolicySnapshotDto": { "required": [ "data" @@ -36658,6 +37568,10 @@ } }, "SslExpiryAssertion": { + "required": [ + "type", + "minDaysRemaining" + ], "type": "object", "properties": { "type": { @@ -36671,11 +37585,7 @@ "description": "Minimum days before TLS certificate expiry; fails or warns below this threshold", "format": "int32" } - }, - "required": [ - "type", - "minDaysRemaining" - ] + } }, "StateTransitionDetails": { "required": [ @@ -37822,10 +38732,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37858,10 +38764,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37894,10 +38796,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37930,10 +38828,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37966,10 +38860,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38002,10 +38892,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38038,10 +38924,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38074,10 +38956,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38110,10 +38988,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38146,10 +39020,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38182,10 +39052,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38218,10 +39084,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38254,10 +39116,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38290,10 +39148,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38326,10 +39180,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38362,10 +39212,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38398,10 +39244,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38434,10 +39276,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38470,10 +39308,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38506,10 +39340,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38542,10 +39372,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38578,10 +39404,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38614,10 +39436,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38650,10 +39468,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38686,10 +39500,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38722,10 +39532,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38758,10 +39564,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38794,10 +39596,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38830,10 +39628,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38866,10 +39660,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38902,10 +39692,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38938,10 +39724,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38974,10 +39756,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39010,10 +39788,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39046,10 +39820,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39082,10 +39852,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39118,10 +39884,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39154,10 +39916,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39190,10 +39948,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -40513,7 +41267,7 @@ }, "enabled": { "type": "boolean", - "description": "Enable or disable the monitor; null preserves current", + "description": "Enable or disable the monitor (pause/resume alias); null preserves current", "nullable": true }, "regions": { @@ -40545,7 +41299,7 @@ }, "clearEnvironmentId": { "type": "boolean", - "description": "Set to true to remove the environment association", + "description": "Set to true to remove the environment association; 409 on code types", "nullable": true }, "assertions": { @@ -40594,6 +41348,31 @@ "$ref": "#/components/schemas/AddMonitorTagsRequest" } ] + }, + "capturePolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CapturePolicy" + } + ], + "description": "When to capture screenshots, traces, and video. Null preserves current" + }, + "fastRetryMaxAttempts": { + "maximum": 10, + "minimum": 0, + "type": "integer", + "description": "Fast-retry attempts after failure; null preserves; 0 disables", + "format": "int32", + "nullable": true + }, + "package": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/MonitorPackageSpec" + } + ] } } }, diff --git a/src/devhelm/_generated.py b/src/devhelm/_generated.py index 1a01743..50cb37b 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 @@ -989,6 +989,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,6 +3249,142 @@ 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="Optional expiry; sweeper clears the overlay after this time", + ), + ] = None + + +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 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", min_length=1), + ] + keys: Annotated[ + list[Key] | None, + Field( + description="Secret names the zip demanded. PUT: null preserves, [] clears" + ), + ] = 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")] @@ -3634,6 +3782,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 +4105,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[ @@ -4475,13 +4659,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( @@ -5099,6 +5283,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 @@ -5766,7 +5955,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 +5964,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 +5973,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 +5982,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 +5991,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 +6000,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 +6009,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 +6018,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 +6027,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 +6036,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 +6045,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 +6054,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 +6063,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 +6072,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 +6081,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 +6090,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 +6099,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 +6108,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 +6117,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 +6126,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 +6135,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 +6144,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): @@ -7952,7 +8119,8 @@ class CreateMonitorRequest(BaseModel): | McpServerMonitorConfig | ScriptMonitorConfig | TcpMonitorConfig - ) + | None + ) = None frequency_seconds: Annotated[ int | None, Field( @@ -7982,7 +8150,7 @@ class CreateMonitorRequest(BaseModel): UUID | None, Field( alias="environmentId", - description="Environment to associate with this monitor", + description="Environment to associate with this monitor; required for code types", ), ] = None assertions: Annotated[ @@ -8001,6 +8169,30 @@ class CreateMonitorRequest(BaseModel): ), ] = None tags: AddMonitorTagsRequest | None = None + capture_policy: Annotated[ + CapturePolicy | None, + Field( + alias="capturePolicy", + description="When to capture screenshots, traces, and video. Omit for probe monitors", + ), + ] = None + fast_retry_max_attempts: Annotated[ + int | None, + Field( + alias="fastRetryMaxAttempts", + description="Fast-retry attempts after failure; null/0 disables", + ge=0, + le=10, + ), + ] = None + definition_id: Annotated[ + UUID | None, + Field( + alias="definitionId", + description="Existing definition to reuse for a sibling monitor. Do not send together with package", + ), + ] = None + package: MonitorPackageSpec | None = None class CreateResourceGroupRequest(BaseModel): @@ -8192,6 +8384,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 +9134,66 @@ 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", + description="When screenshots, traces, and video are captured", + ), + ] = 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 MonitorTestRequest(BaseModel): @@ -9503,7 +9772,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 +9781,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 +9790,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 +9799,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 +9808,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 +9817,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 +9826,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 +9835,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 +9844,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 +9853,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 +9862,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 +9871,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 +9880,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 +9889,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 +9898,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): @@ -9756,7 +10010,9 @@ class UpdateMonitorRequest(BaseModel): ] = None enabled: Annotated[ bool | None, - Field(description="Enable or disable the monitor; null preserves current"), + Field( + description="Enable or disable the monitor (pause/resume alias); null preserves current" + ), ] = None regions: Annotated[ list[str] | None, @@ -9782,7 +10038,7 @@ class UpdateMonitorRequest(BaseModel): bool | None, Field( alias="clearEnvironmentId", - description="Set to true to remove the environment association", + description="Set to true to remove the environment association; 409 on code types", ), ] = None assertions: Annotated[ @@ -9805,6 +10061,23 @@ class UpdateMonitorRequest(BaseModel): ), ] = None tags: AddMonitorTagsRequest | None = None + capture_policy: Annotated[ + CapturePolicy | None, + Field( + alias="capturePolicy", + description="When to capture screenshots, traces, and video. Null preserves current", + ), + ] = None + fast_retry_max_attempts: Annotated[ + int | None, + Field( + alias="fastRetryMaxAttempts", + description="Fast-retry attempts after failure; null preserves; 0 disables", + ge=0, + le=10, + ), + ] = None + package: MonitorPackageSpec | None = None class UpdateNotificationPolicyRequest(BaseModel): @@ -10214,7 +10487,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 +10496,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):