diff --git a/docs/openapi/monitoring-api.json b/docs/openapi/monitoring-api.json index a9b7d44..8816cdd 100644 --- a/docs/openapi/monitoring-api.json +++ b/docs/openapi/monitoring-api.json @@ -196,7 +196,9 @@ "zapier", "datadog", "jira", - "gitlab" + "gitlab", + "sms", + "phone_call" ] } }, @@ -891,6 +893,128 @@ } } }, + "/api/v1/alert-channels/{id}/enabled": { + "patch": { + "tags": [ + "Alert Channels" + ], + "summary": "Enable or disable an alert channel without re-uploading config", + "operationId": "setEnabled", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetEnabledRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseAlertChannelDto" + } + } + } + }, + "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/alert-channels/{id}/test": { "post": { "tags": [ @@ -1659,7 +1783,7 @@ "API Keys" ], "summary": "Update API key", - "operationId": "update_15", + "operationId": "update_16", "parameters": [ { "name": "id", @@ -2005,7 +2129,7 @@ "Audit Log" ], "summary": "List audit events for the current organization", - "operationId": "list_19", + "operationId": "list_20", "parameters": [ { "name": "action", @@ -4545,7 +4669,7 @@ "Incidents" ], "summary": "Get incident details including update timeline", - "operationId": "get_11", + "operationId": "get_9", "parameters": [ { "name": "id", @@ -4649,15 +4773,13 @@ } } } - } - }, - "/api/v1/incidents/{id}/resolve": { - "post": { + }, + "patch": { "tags": [ "Incidents" ], - "summary": "Resolve an incident", - "operationId": "resolve", + "summary": "Update incident title and/or severity", + "operationId": "update_15", "parameters": [ { "name": "id", @@ -4673,10 +4795,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ResolveIncidentRequest" + "$ref": "#/components/schemas/UpdateIncidentRequest" } } - } + }, + "required": true }, "responses": { "200": { @@ -4772,13 +4895,126 @@ } } }, - "/api/v1/incidents/{id}/updates": { + "/api/v1/incidents/{id}/acknowledge": { "post": { "tags": [ "Incidents" ], - "summary": "Add an update to an incident (optionally change status)", - "operationId": "addUpdate", + "summary": "Acknowledge all open notification dispatches for an incident", + "description": "Atomically acknowledges every DELIVERED or ESCALATING dispatch for the incident. Already-acknowledged and non-acknowledgeable dispatches are returned in skipped (not errors). MEMBER+.", + "operationId": "acknowledgeAll", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseAcknowledgeAllIncidentsResponse" + } + } + } + }, + "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/incidents/{id}/resolve": { + "post": { + "tags": [ + "Incidents" + ], + "summary": "Resolve an incident", + "operationId": "resolve", "parameters": [ { "name": "id", @@ -4794,15 +5030,136 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AddIncidentUpdateRequest" + "$ref": "#/components/schemas/ResolveIncidentRequest" } } - }, - "required": true + } }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseIncidentDetailDto" + } + } + } + }, + "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/incidents/{id}/updates": { + "post": { + "tags": [ + "Incidents" + ], + "summary": "Add an update to an incident (optionally change status)", + "operationId": "addUpdate", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddIncidentUpdateRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", "content": { "*/*": { "schema": { @@ -4901,7 +5258,7 @@ ], "summary": "List all supported integration types", "description": "Returns the full static catalog of supported alert channel integration types with their metadata and config field schemas. Used by the frontend to dynamically render the 'Add Alert Channel' form.", - "operationId": "list_18", + "operationId": "list_19", "responses": { "200": { "description": "OK", @@ -4996,6 +5353,108 @@ } } }, + "/api/v1/integrations/voice-languages": { + "get": { + "tags": [ + "Integrations" + ], + "summary": "List supported voice languages for phone call alerts", + "description": "Returns BCP-47 locale codes and human-readable labels for all TTS languages supported by the phone call alert channel.", + "operationId": "listVoiceLanguages", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultVoiceLanguageDto" + } + } + } + }, + "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/invites": { "get": { "tags": [ @@ -5997,7 +6456,7 @@ "Members" ], "summary": "List organization members", - "operationId": "list_17", + "operationId": "list_18", "parameters": [ { "name": "pageable", @@ -6477,7 +6936,9 @@ "MCP_SERVER", "TCP", "ICMP", - "HEARTBEAT" + "HEARTBEAT", + "BROWSER", + "MULTI_STEP_API" ] } }, @@ -7718,13 +8179,14 @@ } } }, - "/api/v1/monitors/{id}/tags": { + "/api/v1/monitors/{id}/status-pages": { "get": { "tags": [ "Monitors" ], - "summary": "Get all tags applied to a monitor", - "operationId": "getMonitorTags", + "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", @@ -7742,7 +8204,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" + "$ref": "#/components/schemas/TableValueResultStatusPageDto" } } } @@ -7828,13 +8290,15 @@ } } } - }, - "post": { + } + }, + "/api/v1/monitors/{id}/tags": { + "get": { "tags": [ "Monitors" ], - "summary": "Add tags to a monitor; supports existing tag IDs and inline creation of new tags", - "operationId": "addMonitorTags", + "summary": "Get all tags applied to a monitor", + "operationId": "getMonitorTags", "parameters": [ { "name": "id", @@ -7846,16 +8310,6 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AddMonitorTagsRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", @@ -7949,12 +8403,12 @@ } } }, - "delete": { + "post": { "tags": [ "Monitors" ], - "summary": "Remove tags from a monitor by their IDs", - "operationId": "removeMonitorTags", + "summary": "Add tags to a monitor; supports existing tag IDs and inline creation of new tags", + "operationId": "addMonitorTags", "parameters": [ { "name": "id", @@ -7970,15 +8424,135 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RemoveMonitorTagsRequest" + "$ref": "#/components/schemas/AddMonitorTagsRequest" } } }, "required": true }, "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultTagDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Monitors" + ], + "summary": "Remove tags from a monitor by their IDs", + "operationId": "removeMonitorTags", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RemoveMonitorTagsRequest" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -8069,7 +8643,7 @@ "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.", + "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": [ { @@ -8176,14 +8750,14 @@ } } }, - "/api/v1/monitors/{id}/uptime": { - "get": { + "/api/v1/monitors/{id}/test-notifications": { + "post": { "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": "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", @@ -8193,40 +8767,35 @@ "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/TestMonitorNotificationsRequest" + } + } + }, + "required": true + }, "responses": { "200": { - "description": "Uptime statistics", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/UptimeDto" + "$ref": "#/components/schemas/TableValueResultTestChannelResult" } } } }, "400": { - "description": "Invalid window parameter", + "description": "Bad request — the payload failed validation", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseUptimeDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -8242,21 +8811,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" } } } @@ -8304,14 +8873,14 @@ } } }, - "/api/v1/monitors/{id}/versions": { + "/api/v1/monitors/{id}/uptime": { "get": { "tags": [ - "Monitors" + "Check Results" ], - "summary": "List version history for a monitor", - "description": "Returns a paginated list of mutation snapshots for the monitor, newest first. Each version captures the full monitor config at the time of a PUT /monitors/{id} call.", - "operationId": "listVersions", + "summary": "Get uptime statistics", + "description": "Returns uptime percentage and latency statistics for the requested time window, computed from continuous aggregates. Uses hourly aggregates for 24h/7d windows and daily aggregates for 30d/90d windows.", + "operationId": "getUptime", "parameters": [ { "name": "id", @@ -8323,31 +8892,38 @@ } }, { - "name": "pageable", + "name": "window", "in": "query", - "required": true, + "description": "Time window for uptime calculation", + "required": false, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "enum": [ + "24h", + "7d", + "30d", + "90d" + ] } } ], "responses": { "200": { - "description": "OK", + "description": "Uptime statistics", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultMonitorVersionDto" + "$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" } } } @@ -8363,21 +8939,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" } } } @@ -8425,14 +9001,14 @@ } } }, - "/api/v1/monitors/{id}/versions/{version}": { + "/api/v1/monitors/{id}/versions": { "get": { "tags": [ "Monitors" ], - "summary": "Get a specific version snapshot for a monitor", - "description": "Returns the full monitor config snapshot captured at the given version number.", - "operationId": "getVersion", + "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": "id", @@ -8444,12 +9020,11 @@ } }, { - "name": "version", - "in": "path", + "name": "pageable", + "in": "query", "required": true, "schema": { - "type": "integer", - "format": "int32" + "$ref": "#/components/schemas/Pageable" } } ], @@ -8459,7 +9034,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorVersionDto" + "$ref": "#/components/schemas/TableValueResultMonitorVersionDto" } } } @@ -8547,41 +9122,41 @@ } } }, - "/api/v1/monitors/{monitorId}/alert-channels": { - "put": { + "/api/v1/monitors/{id}/versions/{version}": { + "get": { "tags": [ - "Monitor Alert Channels" + "Monitors" ], - "summary": "Replace the linked alert channel set for a monitor", - "operationId": "setChannels", + "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": { "type": "string", "format": "uuid" } + }, + { + "name": "version", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SetAlertChannelsRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseListUUID" + "$ref": "#/components/schemas/SingleValueResponseMonitorVersionDto" } } } @@ -8669,13 +9244,13 @@ } } }, - "/api/v1/monitors/{monitorId}/assertions": { - "post": { + "/api/v1/monitors/{monitorId}/alert-channels": { + "put": { "tags": [ - "Monitor Assertions" + "Monitor Alert Channels" ], - "summary": "Add an assertion to a monitor", - "operationId": "add", + "summary": "Replace the linked alert channel set for a monitor", + "operationId": "setChannels", "parameters": [ { "name": "monitorId", @@ -8691,19 +9266,19 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateAssertionRequest" + "$ref": "#/components/schemas/SetAlertChannelsRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" + "$ref": "#/components/schemas/SingleValueResponseListUUID" } } } @@ -8791,13 +9366,13 @@ } } }, - "/api/v1/monitors/{monitorId}/assertions/{assertionId}": { - "put": { + "/api/v1/monitors/{monitorId}/assertions": { + "post": { "tags": [ "Monitor Assertions" ], - "summary": "Update an assertion on a monitor", - "operationId": "update_10", + "summary": "Add an assertion to a monitor", + "operationId": "add", "parameters": [ { "name": "monitorId", @@ -8807,30 +9382,21 @@ "type": "string", "format": "uuid" } - }, - { - "name": "assertionId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateAssertionRequest" + "$ref": "#/components/schemas/CreateAssertionRequest" } } }, "required": true }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { @@ -8920,13 +9486,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{monitorId}/assertions/{assertionId}": { + "put": { "tags": [ "Monitor Assertions" ], - "summary": "Remove an assertion from a monitor", - "operationId": "remove_1", + "summary": "Update an assertion on a monitor", + "operationId": "update_10", "parameters": [ { "name": "monitorId", @@ -8947,9 +9515,26 @@ } } ], + "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", @@ -9032,15 +9617,13 @@ } } } - } - }, - "/api/v1/monitors/{monitorId}/auth": { - "put": { + }, + "delete": { "tags": [ - "Monitor Auth" + "Monitor Assertions" ], - "summary": "Update authentication config for a monitor", - "operationId": "update_9", + "summary": "Remove an assertion from a monitor", + "operationId": "remove_1", "parameters": [ { "name": "monitorId", @@ -9050,28 +9633,20 @@ "type": "string", "format": "uuid" } + }, + { + "name": "assertionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateMonitorAuthRequest" - } - } - }, - "required": true - }, "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -9154,13 +9729,15 @@ } } } - }, - "post": { + } + }, + "/api/v1/monitors/{monitorId}/auth": { + "put": { "tags": [ "Monitor Auth" ], - "summary": "Set authentication config for a monitor", - "operationId": "set", + "summary": "Update authentication config for a monitor", + "operationId": "update_9", "parameters": [ { "name": "monitorId", @@ -9176,15 +9753,15 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SetMonitorAuthRequest" + "$ref": "#/components/schemas/UpdateMonitorAuthRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { @@ -9275,12 +9852,12 @@ } } }, - "delete": { + "post": { "tags": [ "Monitor Auth" ], - "summary": "Remove authentication config from a monitor", - "operationId": "remove", + "summary": "Set authentication config for a monitor", + "operationId": "set", "parameters": [ { "name": "monitorId", @@ -9292,120 +9869,23 @@ } } ], - "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" - } + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetMonitorAuthRequest" } } }, - "503": { - "description": "Service unavailable — try again shortly", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v1/monitors/{monitorId}/policy": { - "get": { - "tags": [ - "Incident Policies" - ], - "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": "monitorId", - "in": "path", - "description": "Monitor UUID", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], + "required": true + }, "responses": { - "200": { - "description": "Policy found", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/IncidentPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" } } } @@ -9441,11 +9921,228 @@ } }, "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" + } + } + } + }, + "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": [ + "Monitor Auth" + ], + "summary": "Remove authentication config from a monitor", + "operationId": "remove", + "parameters": [ + { + "name": "monitorId", + "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/monitors/{monitorId}/policy": { + "get": { + "tags": [ + "Incident Policies" + ], + "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": "monitorId", + "in": "path", + "description": "Monitor UUID", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Policy found", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/IncidentPolicyDto" + } + } + } + }, + "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": "Monitor or policy not found", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" } } } @@ -9733,7 +10430,7 @@ "Monitors" ], "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.", + "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": { @@ -10179,20 +10876,32 @@ } } }, - "/api/v1/notification-policies": { - "get": { + "/api/v1/notification-dispatches/{id}/unacknowledge": { + "post": { "tags": [ - "Notification Policies" + "Notification Dispatches" + ], + "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": "List all notification policies for the authenticated org", - "operationId": "list_7", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" } } } @@ -10278,30 +10987,131 @@ } } } - }, - "post": { + } + }, + "/api/v1/notification-policies": { + "get": { "tags": [ "Notification Policies" ], - "summary": "Create a notification policy with match rules and escalation chain", - "operationId": "create_8", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateNotificationPolicyRequest" - } - } - }, - "required": true - }, + "summary": "List all notification policies for the authenticated org", + "operationId": "list_7", "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "post": { + "tags": [ + "Notification Policies" + ], + "summary": "Create a notification policy with match rules and escalation chain", + "operationId": "create_8", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateNotificationPolicyRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" } } } @@ -10963,7 +11773,7 @@ "Notifications" ], "summary": "List notifications for the current user", - "operationId": "list_16", + "operationId": "list_17", "parameters": [ { "name": "unreadOnly", @@ -12942,7 +13752,7 @@ "Service Subscriptions" ], "summary": "List all service subscriptions for the organization", - "operationId": "list_15", + "operationId": "list_16", "responses": { "200": { "description": "OK", @@ -13043,7 +13853,7 @@ "Service Subscriptions" ], "summary": "Get a subscription by its ID", - "operationId": "get_10", + "operationId": "get_11", "parameters": [ { "name": "id", @@ -13532,6 +14342,15 @@ "type": "boolean" } }, + { + "name": "slaPublished", + "in": "query", + "description": "Filter by SLA page publication status", + "required": false, + "schema": { + "type": "boolean" + } + }, { "name": "search", "in": "query", @@ -13803,7 +14622,7 @@ "Status Data" ], "summary": "List active components for a service with current status and inline uptime", - "description": "When ``groupId`` is supplied, only direct children of that group are returned — used by the pSEO renderer to lazy-load the leaves under a group that summary mode trimmed. Without ``groupId`` the response includes every active component for the service.", + "description": "When ``groupId`` is supplied, only direct children of that group are returned — used by the pSEO renderer to lazy-load the leaves under a group that summary mode trimmed. Without ``groupId`` the response includes every active component for the service. Supports pagination via ``page``/``size`` and case-insensitive name search via ``search``.", "operationId": "getComponents", "parameters": [ { @@ -13823,6 +14642,35 @@ "type": "string", "format": "uuid" } + }, + { + "name": "search", + "in": "query", + "description": "Case-insensitive substring match on component name", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "Zero-based page index", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "size", + "in": "query", + "description": "Page size (default 25, max 100)", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } } ], "responses": { @@ -15097,14 +15945,14 @@ } } }, - "/api/v1/services/{slugOrId}/uptime": { + "/api/v1/services/{slugOrId}/status-events": { "get": { "tags": [ "Status Data" ], - "summary": "Get uptime statistics for a service", - "description": "Uptime data aggregated across active non-group components.", - "operationId": "getServiceUptime", + "summary": "List curated vendor status events for a service", + "description": "Reverse-chronological merge of vendor incidents, maintenances, and rolled-up component transitions for the Dependencies Detail rail. Optional JWT + x-phelm-org-id annotates incident.opened rows with the caller's linked internal incident.", + "operationId": "listStatusEvents", "parameters": [ { "name": "slugOrId", @@ -15114,36 +15962,67 @@ "type": "string" } }, + { + "name": "types", + "in": "query", + "description": "Comma-separated type buckets: incident, maintenance, component (default: all)", + "required": false, + "schema": { + "type": "string" + } + }, { "name": "period", "in": "query", - "description": "Time window", + "description": "Preset window", "required": false, "schema": { "type": "string", "enum": [ - "24h", "7d", "30d", - "90d", - "1y", - "2y", - "all" + "90d" ] } }, { - "name": "granularity", + "name": "from", "in": "query", - "description": "Bucket granularity", + "description": "Explicit lower bound (ISO 8601); overrides period", "required": false, "schema": { "type": "string", - "enum": [ - "hourly", - "daily", - "monthly" - ] + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "Explicit upper bound (ISO 8601); default now", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor from a previous response", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size (1–100, default 50)", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 50 } } ], @@ -15153,7 +16032,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceUptimeResponse" + "$ref": "#/components/schemas/CursorPageStatusEventDto" } } } @@ -15238,61 +16117,56 @@ } } } - }, - "security": [ - { - "BearerAuth": [] - } - ] + } } }, - "/api/v1/services/incidents": { + "/api/v1/services/{slugOrId}/uptime": { "get": { "tags": [ "Status Data" ], - "summary": "List vendor incidents across all services (paginated)", - "description": "Cross-service vendor incident feed ordered by start date descending.", - "operationId": "listCrossServiceIncidents", + "summary": "Get uptime statistics for a service", + "description": "Uptime data aggregated across active non-group components.", + "operationId": "getServiceUptime", "parameters": [ { - "name": "from", - "in": "query", - "description": "Earliest start date (ISO 8601 date)", - "required": false, + "name": "slugOrId", + "in": "path", + "required": true, "schema": { - "type": "string", - "format": "date" + "type": "string" } }, { - "name": "status", + "name": "period", "in": "query", - "description": "Filter: active (unresolved), resolved, or omit for all", + "description": "Time window", "required": false, "schema": { "type": "string", "enum": [ - "active", - "resolved" + "24h", + "7d", + "30d", + "90d", + "1y", + "2y", + "all" ] } }, { - "name": "category", + "name": "granularity", "in": "query", - "description": "Filter by service category", + "description": "Bucket granularity", "required": false, "schema": { - "type": "string" - } - }, - { - "name": "pageable", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "enum": [ + "hourly", + "daily", + "monthly" + ] } } ], @@ -15302,7 +16176,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseServiceUptimeResponse" } } } @@ -15387,137 +16261,71 @@ } } } - } + }, + "security": [ + { + "BearerAuth": [] + } + ] } }, - "/api/v1/services/summary": { + "/api/v1/services/incidents": { "get": { "tags": [ "Status Data" ], - "summary": "Global status summary across all services", - "description": "Returns aggregate counts of services by status and a list of services currently experiencing issues.", - "operationId": "getGlobalStatusSummary", + "summary": "List vendor incidents across all services (paginated)", + "description": "Cross-service vendor incident feed ordered by start date descending.", + "operationId": "listCrossServiceIncidents", "parameters": [ { - "name": "publishedOnly", + "name": "from", "in": "query", - "description": "Aggregate only published services (curated public pSEO set); default false", + "description": "Earliest start date (ISO 8601 date)", "required": false, "schema": { - "type": "boolean", - "default": false - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseGlobalStatusSummaryDto" - } - } - } - }, - "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" - } - } + "type": "string", + "format": "date" } }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + { + "name": "status", + "in": "query", + "description": "Filter: active (unresolved), resolved, or omit for all", + "required": false, + "schema": { + "type": "string", + "enum": [ + "active", + "resolved" + ] } }, - "502": { - "description": "Bad gateway — an upstream provider returned an error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + { + "name": "category", + "in": "query", + "description": "Filter by service category", + "required": false, + "schema": { + "type": "string" } }, - "503": { - "description": "Service unavailable — try again shortly", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" } } - } - } - }, - "/api/v1/status-pages": { - "get": { - "tags": [ - "Status Pages" ], - "summary": "List status pages for the workspace", - "operationId": "list_4", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageDto" + "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" } } } @@ -15603,30 +16411,35 @@ } } } - }, - "post": { + } + }, + "/api/v1/services/summary": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Create a status page", - "operationId": "create_5", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageRequest" - } + "summary": "Global status summary across all services", + "description": "Returns aggregate counts of services by status and a list of services currently experiencing issues.", + "operationId": "getGlobalStatusSummary", + "parameters": [ + { + "name": "publishedOnly", + "in": "query", + "description": "Aggregate only published services (curated public pSEO set); default false", + "required": false, + "schema": { + "type": "boolean", + "default": false } - }, - "required": true - }, + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + "$ref": "#/components/schemas/SingleValueResponseGlobalStatusSummaryDto" } } } @@ -15714,31 +16527,20 @@ } } }, - "/api/v1/status-pages/{id}": { + "/api/v1/status-pages": { "get": { "tags": [ "Status Pages" ], - "summary": "Get a status page", - "operationId": "get_2", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], + "summary": "List status pages for the workspace", + "operationId": "list_4", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + "$ref": "#/components/schemas/TableValueResultStatusPageDto" } } } @@ -15825,36 +16627,25 @@ } } }, - "put": { + "post": { "tags": [ "Status Pages" ], - "summary": "Update a status page", - "operationId": "update_3", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], + "summary": "Create a status page", + "operationId": "create_5", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateStatusPageRequest" + "$ref": "#/components/schemas/CreateStatusPageRequest" } } }, "required": true }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { @@ -15944,13 +16735,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/status-pages/{id}": { + "get": { "tags": [ "Status Pages" ], - "summary": "Delete a status page", - "operationId": "delete_3", + "summary": "Get a status page", + "operationId": "get_2", "parameters": [ { "name": "id", @@ -15963,8 +16756,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -16047,15 +16847,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/components": { - "get": { + }, + "put": { "tags": [ "Status Pages" ], - "summary": "List all components", - "operationId": "listComponents", + "summary": "Update a status page", + "operationId": "update_3", "parameters": [ { "name": "id", @@ -16067,13 +16865,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageComponentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" } } } @@ -16160,12 +16968,12 @@ } } }, - "post": { + "delete": { "tags": [ "Status Pages" ], - "summary": "Add a component to the status page", - "operationId": "createComponent", + "summary": "Delete a status page", + "operationId": "delete_3", "parameters": [ { "name": "id", @@ -16177,26 +16985,9 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageComponentRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -16281,13 +17072,13 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}": { - "put": { + "/api/v1/status-pages/{id}/components": { + "get": { "tags": [ "Status Pages" ], - "summary": "Update a component", - "operationId": "updateComponent", + "summary": "List all components", + "operationId": "listComponents", "parameters": [ { "name": "id", @@ -16297,34 +17088,15 @@ "type": "string", "format": "uuid" } - }, - { - "name": "componentId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageComponentRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/TableValueResultStatusPageComponentDto" } } } @@ -16411,12 +17183,12 @@ } } }, - "delete": { + "post": { "tags": [ "Status Pages" ], - "summary": "Remove a component from the status page", - "operationId": "deleteComponent", + "summary": "Add a component to the status page", + "operationId": "createComponent", "parameters": [ { "name": "id", @@ -16426,20 +17198,28 @@ "type": "string", "format": "uuid" } - }, - { - "name": "componentId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageComponentRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -16524,13 +17304,13 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}/uptime": { - "get": { + "/api/v1/status-pages/{id}/components/{componentId}": { + "put": { "tags": [ "Status Pages" ], - "summary": "Get component uptime history (daily rollups)", - "operationId": "componentUptime_1", + "summary": "Update a component", + "operationId": "updateComponent", "parameters": [ { "name": "id", @@ -16549,25 +17329,25 @@ "type": "string", "format": "uuid" } - }, - { - "name": "days", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 90 - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageComponentRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" } } } @@ -16653,15 +17433,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/components/reorder": { - "put": { + }, + "delete": { "tags": [ "Status Pages" ], - "summary": "Batch reorder components (and optionally move between groups)", - "operationId": "reorderComponents", + "summary": "Remove a component from the status page", + "operationId": "deleteComponent", "parameters": [ { "name": "id", @@ -16671,18 +17449,17 @@ "type": "string", "format": "uuid" } + }, + { + "name": "componentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ReorderComponentsRequest" - } - } - }, - "required": true - }, "responses": { "204": { "description": "No Content" @@ -16770,13 +17547,13 @@ } } }, - "/api/v1/status-pages/{id}/domains": { + "/api/v1/status-pages/{id}/components/{componentId}/uptime": { "get": { "tags": [ "Status Pages" ], - "summary": "List custom domains", - "operationId": "listDomains", + "summary": "Get component uptime history (daily rollups)", + "operationId": "componentUptime_1", "parameters": [ { "name": "id", @@ -16786,6 +17563,25 @@ "type": "string", "format": "uuid" } + }, + { + "name": "componentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "days", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 90 + } } ], "responses": { @@ -16794,7 +17590,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageCustomDomainDto" + "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" } } } @@ -16880,13 +17676,15 @@ } } } - }, - "post": { + } + }, + "/api/v1/status-pages/{id}/components/reorder": { + "put": { "tags": [ "Status Pages" ], - "summary": "Add a custom domain", - "operationId": "addDomain", + "summary": "Batch reorder components (and optionally move between groups)", + "operationId": "reorderComponents", "parameters": [ { "name": "id", @@ -16902,22 +17700,15 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AddCustomDomainRequest" + "$ref": "#/components/schemas/ReorderComponentsRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -17002,13 +17793,13 @@ } } }, - "/api/v1/status-pages/{id}/domains/{domainId}": { - "delete": { + "/api/v1/status-pages/{id}/domains": { + "get": { "tags": [ "Status Pages" ], - "summary": "Remove a custom domain", - "operationId": "removeDomain", + "summary": "List custom domains", + "operationId": "listDomains", "parameters": [ { "name": "id", @@ -17018,20 +17809,18 @@ "type": "string", "format": "uuid" } - }, - { - "name": "domainId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageCustomDomainDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -17114,15 +17903,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/domains/{domainId}/primary": { + }, "post": { "tags": [ "Status Pages" ], - "summary": "Mark a verified custom domain as the page's primary host", - "operationId": "setPrimaryDomain", + "summary": "Add a custom domain", + "operationId": "addDomain", "parameters": [ { "name": "id", @@ -17132,20 +17919,21 @@ "type": "string", "format": "uuid" } - }, - { - "name": "domainId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddCustomDomainRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { @@ -17237,13 +18025,13 @@ } } }, - "/api/v1/status-pages/{id}/domains/{domainId}/verify": { - "post": { + "/api/v1/status-pages/{id}/domains/{domainId}": { + "delete": { "tags": [ "Status Pages" ], - "summary": "Trigger domain verification check", - "operationId": "verifyDomain", + "summary": "Remove a custom domain", + "operationId": "removeDomain", "parameters": [ { "name": "id", @@ -17265,15 +18053,8 @@ } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -17358,13 +18139,13 @@ } } }, - "/api/v1/status-pages/{id}/groups": { - "get": { + "/api/v1/status-pages/{id}/domains/{domainId}/primary": { + "post": { "tags": [ "Status Pages" ], - "summary": "List component groups with nested components", - "operationId": "listGroups", + "summary": "Mark a verified custom domain as the page's primary host", + "operationId": "setPrimaryDomain", "parameters": [ { "name": "id", @@ -17374,6 +18155,15 @@ "type": "string", "format": "uuid" } + }, + { + "name": "domainId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], "responses": { @@ -17382,7 +18172,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageComponentGroupDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" } } } @@ -17468,13 +18258,15 @@ } } } - }, + } + }, + "/api/v1/status-pages/{id}/domains/{domainId}/verify": { "post": { "tags": [ "Status Pages" ], - "summary": "Create a component group", - "operationId": "createGroup", + "summary": "Trigger domain verification check", + "operationId": "verifyDomain", "parameters": [ { "name": "id", @@ -17484,25 +18276,24 @@ "type": "string", "format": "uuid" } + }, + { + "name": "domainId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageComponentGroupRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" } } } @@ -17590,13 +18381,13 @@ } } }, - "/api/v1/status-pages/{id}/groups/{groupId}": { - "put": { + "/api/v1/status-pages/{id}/groups": { + "get": { "tags": [ "Status Pages" ], - "summary": "Update a component group", - "operationId": "updateGroup", + "summary": "List component groups with nested components", + "operationId": "listGroups", "parameters": [ { "name": "id", @@ -17606,9 +18397,110 @@ "type": "string", "format": "uuid" } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageComponentGroupDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "post": { + "tags": [ + "Status Pages" + ], + "summary": "Create a component group", + "operationId": "createGroup", + "parameters": [ { - "name": "groupId", + "name": "id", "in": "path", "required": true, "schema": { @@ -17621,15 +18513,15 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateStatusPageComponentGroupRequest" + "$ref": "#/components/schemas/CreateStatusPageComponentGroupRequest" } } }, "required": true }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { @@ -17719,13 +18611,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/status-pages/{id}/groups/{groupId}": { + "put": { "tags": [ "Status Pages" ], - "summary": "Delete a component group (components become ungrouped)", - "operationId": "deleteGroup", + "summary": "Update a component group", + "operationId": "updateGroup", "parameters": [ { "name": "id", @@ -17746,9 +18640,26 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageComponentGroupRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -17831,15 +18742,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/incidents": { - "get": { + }, + "delete": { "tags": [ "Status Pages" ], - "summary": "List incidents for this status page (filterable by status, paginated)", - "operationId": "listIncidents", + "summary": "Delete a component group (components become ungrouped)", + "operationId": "deleteGroup", "parameters": [ { "name": "id", @@ -17851,41 +18760,155 @@ } }, { - "name": "status", - "in": "query", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] - } - } - }, - { - "name": "pageable", - "in": "query", + "name": "groupId", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" - } - } - } + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/incidents": { + "get": { + "tags": [ + "Status Pages" + ], + "summary": "List incidents for this status page (filterable by status, paginated)", + "operationId": "listIncidents", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" + ] + } + } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -21613,6 +22636,30 @@ }, "components": { "schemas": { + "AcknowledgeAllIncidentsResponse": { + "required": [ + "acknowledged", + "skipped" + ], + "type": "object", + "properties": { + "acknowledged": { + "type": "array", + "description": "Dispatches successfully acknowledged in this request", + "items": { + "$ref": "#/components/schemas/NotificationDispatchDto" + } + }, + "skipped": { + "type": "array", + "description": "Dispatches skipped (already acked or not in an acknowledgeable state)", + "items": { + "$ref": "#/components/schemas/SkippedDispatch" + } + } + }, + "description": "Result of acknowledging all acknowledgeable dispatches for an incident" + }, "AcquireDeployLockRequest": { "required": [ "lockedBy" @@ -21848,6 +22895,36 @@ "type": "string", "description": "Jira project key", "nullable": true + }, + "phoneNumber": { + "type": "string", + "description": "Recipient phone number in E.164 format (SMS / phone-call channels)", + "nullable": true + }, + "verifiedPhoneNumberId": { + "type": "integer", + "description": "Id of the org verified_phone_number row bound to this channel", + "format": "int64", + "nullable": true + }, + "phoneNumbers": { + "type": "array", + "description": "Deprecated mirror of phoneNumber as a length-1 list for older clients", + "nullable": true, + "items": { + "type": "string", + "description": "Deprecated mirror of phoneNumber as a length-1 list for older clients" + } + }, + "voiceLanguage": { + "type": "string", + "description": "BCP-47 voice language for phone-call TTS (e.g. en-US, de-DE)", + "nullable": true + }, + "preferredLanguage": { + "type": "string", + "description": "Preferred language for SMS/voice (BCP-47, e.g. en-US, de-DE)", + "nullable": true } }, "description": "Non-sensitive alert channel configuration metadata" @@ -21856,6 +22933,7 @@ "required": [ "channelType", "createdAt", + "enabled", "id", "name", "updatedAt" @@ -21894,7 +22972,9 @@ "zapier", "datadog", "jira", - "gitlab" + "gitlab", + "sms", + "phone_call" ] }, "displayConfig": { @@ -21905,6 +22985,10 @@ } ] }, + "enabled": { + "type": "boolean", + "description": "Whether this channel is enabled and will receive alerts" + }, "createdAt": { "type": "string", "description": "Timestamp when the channel was created", @@ -21998,7 +23082,11 @@ "DELIVERED", "RETRY_PENDING", "FAILED", - "CANCELLED" + "CANCELLED", + "SKIPPED_NO_CREDIT", + "SKIPPED_UNVERIFIED", + "SKIPPED_OPTED_OUT", + "SKIPPED_RATE_LIMITED" ] }, "eventType": { @@ -22845,7 +23933,8 @@ "tcp": "#/components/schemas/Tcp", "icmp": "#/components/schemas/Icmp", "dns": "#/components/schemas/Dns", - "mcp_server": "#/components/schemas/McpServer" + "mcp_server": "#/components/schemas/McpServer", + "code": "#/components/schemas/Code" } }, "oneOf": [ @@ -22863,9 +23952,95 @@ }, { "$ref": "#/components/schemas/McpServer" + }, + { + "$ref": "#/components/schemas/Code" } ] }, + "Code": { + "type": "object", + "description": "Code check (browser / multi-step API) specific details", + "properties": { + "check_type": { + "type": "string", + "enum": [ + "code" + ] + }, + "exitCode": { + "type": "integer", + "description": "Container exit code (0 = pass)", + "format": "int32" + }, + "stdoutSnippet": { + "type": "string", + "description": "Truncated stdout from the container", + "nullable": true + }, + "stderrSnippet": { + "type": "string", + "description": "Truncated stderr from the container", + "nullable": true + }, + "steps": { + "type": "array", + "description": "Named steps extracted from Playwright test output", + "nullable": true, + "items": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CodeCheckStep" + } + ] + } + }, + "failureKind": { + "type": "string", + "description": "Failure classification: timeout, assertion, or error", + "nullable": true + }, + "timedOut": { + "type": "boolean", + "description": "Whether the run hit a step/total/run-budget timeout", + "nullable": true + } + }, + "required": [ + "check_type", + "exitCode" + ] + }, + "CodeCheckStep": { + "required": [ + "name", + "status" + ], + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Step name from test.step() or test() call" + }, + "status": { + "type": "string", + "description": "Step outcome: passed, failed, skipped, or timedOut" + }, + "durationMs": { + "type": "integer", + "description": "Step duration in milliseconds", + "format": "int32", + "nullable": true + }, + "error": { + "type": "string", + "description": "Error message if the step failed", + "nullable": true + } + }, + "description": "A single named step within a code check execution" + }, "ComponentImpact": { "required": [ "componentId", @@ -22934,6 +24109,35 @@ }, "description": "A single component position" }, + "ComponentSample": { + "required": [ + "componentId", + "newStatus" + ], + "type": "object", + "properties": { + "componentId": { + "type": "string", + "description": "Component ID", + "format": "uuid" + }, + "componentName": { + "type": "string", + "description": "Component display name", + "nullable": true + }, + "oldStatus": { + "type": "string", + "description": "Previous status before the flip", + "nullable": true + }, + "newStatus": { + "type": "string", + "description": "New status after the flip" + } + }, + "description": "One component sample inside a transition rollup" + }, "ComponentsSummaryDto": { "required": [ "groupComponentCounts", @@ -22986,6 +24190,33 @@ }, "description": "Current status of each active component" }, + "ComponentTransitionEventDto": { + "required": [ + "componentSample", + "newStatus", + "componentCount" + ], + "type": "object", + "properties": { + "newStatus": { + "type": "string", + "description": "New status that defines this rollup bucket" + }, + "componentCount": { + "type": "integer", + "description": "Total components in the 5-minute rollup bucket", + "format": "int32" + }, + "componentSample": { + "type": "array", + "description": "Up to 5 sample components from the bucket", + "items": { + "$ref": "#/components/schemas/ComponentSample" + } + } + }, + "description": "Rolled-up component status transitions for a status-events rail row" + }, "ComponentUptimeDayDto": { "required": [ "date", @@ -23143,6 +24374,9 @@ { "$ref": "#/components/schemas/PagerDutyChannelConfig" }, + { + "$ref": "#/components/schemas/PhoneCallChannelConfig" + }, { "$ref": "#/components/schemas/PushbulletChannelConfig" }, @@ -23155,6 +24389,9 @@ { "$ref": "#/components/schemas/SlackChannelConfig" }, + { + "$ref": "#/components/schemas/SmsChannelConfig" + }, { "$ref": "#/components/schemas/SplunkOnCallChannelConfig" }, @@ -23491,6 +24728,18 @@ "type": "string", "description": "Detailed description or context for the incident", "nullable": true + }, + "serviceId": { + "type": "string", + "description": "Vendor service to link; optional for Dependencies create CTA", + "format": "uuid", + "nullable": true + }, + "serviceIncidentId": { + "type": "string", + "description": "Vendor incident to link; idempotent if an active org incident already links it", + "format": "uuid", + "nullable": true } } }, @@ -23517,7 +24766,9 @@ "MCP_SERVER", "TCP", "ICMP", - "HEARTBEAT" + "HEARTBEAT", + "BROWSER", + "MULTI_STEP_API" ] }, "config": { @@ -23537,6 +24788,9 @@ { "$ref": "#/components/schemas/McpServerMonitorConfig" }, + { + "$ref": "#/components/schemas/ScriptMonitorConfig" + }, { "$ref": "#/components/schemas/TcpMonitorConfig" } @@ -24175,6 +25429,72 @@ }, "description": "Create a new workspace within the organization" }, + "CreditPolicy": { + "type": "object", + "properties": { + "summary": { + "type": "string", + "description": "Brief summary of credit policy", + "nullable": true + }, + "maxCreditPercent": { + "type": "integer", + "description": "Max credit as percent of monthly fee", + "format": "int32", + "nullable": true + }, + "claimWindowDays": { + "type": "integer", + "description": "Days to submit a credit claim after eligibility", + "format": "int32", + "nullable": true + }, + "creditApplicationDays": { + "type": "integer", + "description": "Days for credit to be applied after approval", + "format": "int32", + "nullable": true + }, + "tiers": { + "type": "array", + "description": "Credit tiers by uptime threshold", + "nullable": true, + "items": { + "$ref": "#/components/schemas/CreditTier" + } + } + }, + "description": "Service credit policy for SLA violations" + }, + "CreditTier": { + "required": [ + "uptimeRange" + ], + "type": "object", + "properties": { + "uptimeRange": { + "type": "string", + "description": "Uptime range, e.g. '99.1% – 99.98%'" + }, + "creditPercent": { + "type": "integer", + "description": "Credit percent of monthly fee", + "format": "int32", + "nullable": true + }, + "formula": { + "type": "string", + "description": "Credit formula when percent is not a fixed number", + "nullable": true + }, + "notes": { + "type": "string", + "description": "Additional notes on this credit tier", + "nullable": true + } + }, + "description": "Credit tiers by uptime threshold" + }, "CursorPageCheckResultDto": { "required": [ "data", @@ -24253,6 +25573,32 @@ }, "description": "Cursor-paginated response for time-series and append-only data" }, + "CursorPageStatusEventDto": { + "required": [ + "data", + "hasMore" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "description": "Items on this page", + "items": { + "$ref": "#/components/schemas/StatusEventDto" + } + }, + "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" + }, "DashboardOverviewDto": { "required": [ "incidents", @@ -25828,6 +27174,14 @@ "items": { "$ref": "#/components/schemas/LinkedStatusPageIncidentDto" } + }, + "trigger": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/IncidentTriggerDto" + } + ] } } }, @@ -25842,7 +27196,8 @@ "updatedAt", "organizationId", "reopenCount", - "statusPageVisible" + "statusPageVisible", + "suppressDispatch" ], "type": "object", "properties": { @@ -25925,6 +27280,10 @@ "type": "boolean", "description": "Whether this incident is visible on the status page" }, + "suppressDispatch": { + "type": "boolean", + "description": "When true, alert channels are suppressed (AWARENESS silent tracking); false means Alerted" + }, "serviceIncidentId": { "type": "string", "description": "Linked vendor service incident ID; null for monitor incidents", @@ -25966,6 +27325,11 @@ "AUTO_RESOLVED" ] }, + "resolutionNote": { + "type": "string", + "description": "Body from the most recent resolve update; null when not currently resolved, auto-resolved without a note, or no resolve update body was provided", + "nullable": true + }, "startedAt": { "type": "string", "description": "Timestamp when the incident was detected or created", @@ -26052,10 +27416,99 @@ "type": "string", "description": "Detection engine semver that evaluated the rule. Omitted from JSON when null, treat missing as null.", "nullable": true + }, + "displayKey": { + "type": "string", + "description": "Org-scoped human-readable incident code, e.g. \"ABC-42\". Null on incidents created by pre-INC-keys API pods before the sweep; treat missing as unknown and fall back to the id", + "nullable": true } }, "description": "Incident triggered by a monitor check failure or manual creation" }, + "IncidentEventDto": { + "required": [ + "incidentId", + "title" + ], + "type": "object", + "properties": { + "incidentId": { + "type": "string", + "description": "Vendor catalog incident ID", + "format": "uuid" + }, + "externalId": { + "type": "string", + "description": "Vendor-supplied external incident ID", + "nullable": true + }, + "title": { + "type": "string", + "description": "Incident title from the vendor status page" + }, + "impact": { + "type": "string", + "description": "Vendor impact level (major, minor, none)", + "nullable": true + }, + "status": { + "type": "string", + "description": "Vendor lifecycle status (only set on incident.update rows)", + "nullable": true + }, + "body": { + "type": "string", + "description": "Update body text (only set on incident.update rows)", + "nullable": true + }, + "shortlink": { + "type": "string", + "description": "Short public URL for the vendor incident", + "nullable": true + }, + "startedAt": { + "type": "string", + "description": "When the vendor incident started", + "format": "date-time", + "nullable": true + }, + "resolvedAt": { + "type": "string", + "description": "When the vendor incident resolved", + "format": "date-time", + "nullable": true + }, + "detectedAt": { + "type": "string", + "description": "When DevHelm first detected the incident", + "format": "date-time", + "nullable": true + }, + "vendorCreatedAt": { + "type": "string", + "description": "Vendor-reported creation timestamp", + "format": "date-time", + "nullable": true + }, + "durationSeconds": { + "type": "integer", + "description": "Total duration in seconds (set on incident.resolved)", + "format": "int64", + "nullable": true + }, + "affectedComponentIds": { + "type": "array", + "description": "Affected component IDs from the vendor incident join", + "nullable": true, + "items": { + "type": "string", + "description": "Affected component IDs from the vendor incident join", + "format": "uuid" + } + } + }, + "description": "Vendor incident fields for a status-events rail row" + }, "IncidentFilterParams": { "type": "object", "properties": { @@ -26414,6 +27867,59 @@ } } }, + "IncidentTriggerDto": { + "required": [ + "source" + ], + "type": "object", + "properties": { + "ruleType": { + "type": "string", + "description": "Trigger rule type (consecutive_failures, failures_in_window, response_time); null when unknown", + "nullable": true + }, + "ruleIndex": { + "type": "integer", + "description": "0-based index into the policy trigger_rules array; null when unknown", + "format": "int32", + "nullable": true + }, + "count": { + "type": "integer", + "description": "Observed failing_streak or failures_in_window from forensics; null when unavailable", + "format": "int32", + "nullable": true + }, + "threshold": { + "type": "integer", + "description": "Rule required count or threshold_ms from forensics; null when unavailable", + "format": "int32", + "nullable": true + }, + "lastError": { + "type": "string", + "description": "failure_reason from the triggering check result; null when unavailable", + "nullable": true + }, + "firstFailedCheckAt": { + "type": "string", + "description": "Earliest failing check timestamp in the confirm window when computable; null otherwise", + "format": "date-time", + "nullable": true + }, + "source": { + "minLength": 1, + "type": "string", + "description": "Where the enrichment came from: forensics, checks, or none (STATUS_DATA/manual/no data)", + "enum": [ + "forensics", + "checks", + "none" + ] + } + }, + "description": "Honest trigger metadata for the incident origin tooltip / TTD strip" + }, "IncidentUpdateDto": { "required": [ "createdAt", @@ -26592,6 +28098,7 @@ }, "InviteDto": { "required": [ + "createdAt", "email", "expiresAt", "roleOffered", @@ -26617,6 +28124,11 @@ "MEMBER" ] }, + "createdAt": { + "type": "string", + "description": "Timestamp when the invite was created", + "format": "date-time" + }, "expiresAt": { "type": "string", "description": "Timestamp when the invite expires", @@ -26869,6 +28381,79 @@ }, "description": "A component affected by a scheduled maintenance window" }, + "MaintenanceEventDto": { + "required": [ + "externalId", + "maintenanceId", + "status", + "title" + ], + "type": "object", + "properties": { + "maintenanceId": { + "type": "string", + "description": "Vendor catalog maintenance ID", + "format": "uuid" + }, + "externalId": { + "type": "string", + "description": "Vendor-supplied external maintenance ID" + }, + "title": { + "type": "string", + "description": "Maintenance title from the vendor status page" + }, + "status": { + "type": "string", + "description": "Lifecycle status: scheduled, in_progress, verifying, completed" + }, + "impact": { + "type": "string", + "description": "Vendor impact level", + "nullable": true + }, + "shortlink": { + "type": "string", + "description": "Short public URL for the vendor maintenance", + "nullable": true + }, + "scheduledFor": { + "type": "string", + "description": "Scheduled start; null for undated maintenance", + "format": "date-time", + "nullable": true + }, + "scheduledUntil": { + "type": "string", + "description": "Scheduled end", + "format": "date-time", + "nullable": true + }, + "startedAt": { + "type": "string", + "description": "When maintenance actually started", + "format": "date-time", + "nullable": true + }, + "completedAt": { + "type": "string", + "description": "When maintenance completed", + "format": "date-time", + "nullable": true + }, + "affectedComponentIds": { + "type": "array", + "description": "Affected component IDs", + "nullable": true, + "items": { + "type": "string", + "description": "Affected component IDs", + "format": "uuid" + } + } + }, + "description": "Vendor maintenance fields for a status-events rail row" + }, "MaintenanceUpdateDto": { "required": [ "id", @@ -27686,7 +29271,9 @@ "MCP_SERVER", "TCP", "ICMP", - "HEARTBEAT" + "HEARTBEAT", + "BROWSER", + "MULTI_STEP_API" ] }, "config": { @@ -27706,6 +29293,9 @@ { "$ref": "#/components/schemas/McpServerMonitorConfig" }, + { + "$ref": "#/components/schemas/ScriptMonitorConfig" + }, { "$ref": "#/components/schemas/TcpMonitorConfig" } @@ -27904,7 +29494,9 @@ "MCP_SERVER", "TCP", "ICMP", - "HEARTBEAT" + "HEARTBEAT", + "BROWSER", + "MULTI_STEP_API" ] }, "config": { @@ -27924,6 +29516,9 @@ { "$ref": "#/components/schemas/McpServerMonitorConfig" }, + { + "$ref": "#/components/schemas/ScriptMonitorConfig" + }, { "$ref": "#/components/schemas/TcpMonitorConfig" } @@ -28087,6 +29682,32 @@ }, "description": "Inline tag creation — creates the tag if it does not already exist" }, + "NoSlaContext": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "description": "Reason no SLA is published", + "nullable": true + }, + "historicalClaim": { + "type": "string", + "description": "Non-binding historical uptime claim", + "nullable": true + }, + "supportSla": { + "type": "string", + "description": "Support response time SLA if different from uptime SLA", + "nullable": true + }, + "enterpriseNote": { + "type": "string", + "description": "Note about enterprise/custom SLA availability", + "nullable": true + } + }, + "description": "Context for vendors with no public SLA" + }, "NotificationDispatchDto": { "required": [ "createdAt", @@ -28159,6 +29780,25 @@ "format": "date-time", "nullable": true }, + "acknowledgedBy": { + "type": "string", + "description": "Actor who acknowledged this dispatch (user email, api-key:, voice:, etc.); null if not acknowledged", + "nullable": true + }, + "acknowledgedVia": { + "type": "string", + "description": "Channel used to acknowledge (DASHBOARD, API, PHONE_CALL, INTERNAL, etc.); null if not acknowledged", + "nullable": true + }, + "matchedRules": { + "type": "array", + "description": "Labels of match rules that caused this dispatch (same wording as TestMatchResult); null on pre-V138 rows; catch-all is [\"(catch-all: no rules defined)\"]", + "nullable": true, + "items": { + "type": "string", + "description": "Labels of match rules that caused this dispatch (same wording as TestMatchResult); null on pre-V138 rows; catch-all is [\"(catch-all: no rules defined)\"]" + } + }, "nextEscalationAt": { "type": "string", "description": "Timestamp when the next escalation step will fire (null if not scheduled)", @@ -28302,6 +29942,46 @@ }, "description": "Org-level notification policy with match rules and escalation chain" }, + "OfficialSla": { + "type": "object", + "properties": { + "percentage": { + "type": "string", + "description": "Advertised uptime percentage, e.g. '99.99%'", + "nullable": true + }, + "scope": { + "type": "string", + "description": "Scope of the SLA, e.g. 'Monthly uptime per region'", + "nullable": true + }, + "measurement": { + "type": "string", + "description": "How the vendor measures uptime for SLA purposes", + "nullable": true + }, + "exclusions": { + "type": "string", + "description": "Summary of exclusions from SLA calculation", + "nullable": true + }, + "appliesToPlans": { + "type": "array", + "description": "Plan names this SLA applies to, e.g. ['Enterprise']", + "nullable": true, + "items": { + "type": "string", + "description": "Plan names this SLA applies to, e.g. ['Enterprise']" + } + }, + "notCovered": { + "type": "string", + "description": "Services/components NOT covered by the SLA", + "nullable": true + } + }, + "description": "The vendor's officially advertised SLA commitment" + }, "OpsGenieChannelConfig": { "required": [ "channelType", @@ -28367,6 +30047,57 @@ }, "description": "Organization account details" }, + "OrgIncidentAnnotationDto": { + "required": [ + "incidentId", + "severity", + "status", + "alerted" + ], + "type": "object", + "properties": { + "incidentId": { + "type": "string", + "description": "Internal org incident ID", + "format": "uuid" + }, + "displayKey": { + "type": "string", + "description": "Human display key (e.g. DEV-42); null until platform INC codes ship", + "nullable": true + }, + "status": { + "type": "string", + "description": "Internal incident lifecycle status", + "enum": [ + "WATCHING", + "TRIGGERED", + "CONFIRMED", + "RESOLVED" + ] + }, + "severity": { + "type": "string", + "description": "Internal incident severity", + "enum": [ + "DOWN", + "DEGRADED", + "MAINTENANCE" + ] + }, + "alerted": { + "type": "boolean", + "description": "Whether alert channels were eligible to fire (false for AWARENESS silent tracking)" + }, + "startedAt": { + "type": "string", + "description": "When the internal incident started", + "format": "date-time", + "nullable": true + } + }, + "description": "Linked internal incident annotation on a vendor status-event row" + }, "OrgInfo": { "required": [ "name", @@ -28463,6 +30194,51 @@ "pageOrder" ] }, + "PhoneCallChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "phone_call" + ] + }, + "phoneNumber": { + "type": "string", + "description": "Recipient phone number in E.164 format, e.g. +14155550123", + "nullable": true + }, + "verifiedPhoneNumberId": { + "type": "integer", + "description": "Id of an org verified_phone_number row; alternative to phoneNumber", + "format": "int64", + "nullable": true + }, + "phoneNumbers": { + "type": "array", + "description": "Deprecated: use phoneNumber. Accepted as a length-1 list for one release; ignored when phoneNumber or id is set", + "nullable": true, + "items": { + "type": "string", + "description": "Deprecated: use phoneNumber. Accepted as a length-1 list for one release; ignored when phoneNumber or id is set", + "nullable": true + } + }, + "voiceLanguage": { + "type": "string", + "description": "TTS voice language/locale (default: en-US). See VoiceLanguage for supported values", + "nullable": true + }, + "preferredLanguage": { + "type": "string", + "description": "Preferred language for TTS and notifications (BCP-47, e.g. en-US, de-DE). Alias for voiceLanguage", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, "PlanInfo": { "required": [ "entitlements", @@ -28595,6 +30371,29 @@ }, "description": "Aggregated poll metrics for a time bucket" }, + "PricingTier": { + "required": [ + "name" + ], + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Tier name, e.g. 'Free', 'Pro', 'Enterprise'" + }, + "slaPercentage": { + "type": "string", + "description": "SLA percentage for this tier, e.g. '99.9%'", + "nullable": true + }, + "priceFrom": { + "type": "string", + "description": "Starting price, e.g. '$0', '$25/mo', 'Custom'", + "nullable": true + } + }, + "description": "Pricing tiers with associated SLA levels" + }, "PublishStatusPageIncidentRequest": { "type": "object", "properties": { @@ -29601,6 +31400,28 @@ }, "description": "A scheduled maintenance window from a vendor status page" }, + "ScriptMonitorConfig": { + "required": [ + "script" + ], + "type": "object", + "properties": { + "script": { + "maxLength": 65536, + "minLength": 1, + "type": "string", + "description": "Playwright test script source code" + }, + "timeoutSeconds": { + "maximum": 120, + "minimum": 5, + "type": "integer", + "description": "Maximum execution time in seconds (5–120)", + "format": "int32", + "nullable": true + } + } + }, "SecretDto": { "required": [ "createdAt", @@ -29672,6 +31493,34 @@ }, "description": "Admin-editable SEO metadata for pSEO pages" }, + "ServiceBreakdown": { + "required": [ + "service" + ], + "type": "object", + "properties": { + "service": { + "type": "string", + "description": "Sub-service name, e.g. 'EC2', 'S3'" + }, + "slaPercentage": { + "type": "string", + "description": "SLA percentage for this sub-service", + "nullable": true + }, + "scope": { + "type": "string", + "description": "Scope qualifier, e.g. 'Region (Multi-AZ)'", + "nullable": true + }, + "notes": { + "type": "string", + "description": "Additional notes on measurement or conditions", + "nullable": true + } + }, + "description": "Per-service breakdown for vendors with per_service SLA type" + }, "ServiceCatalogDto": { "required": [ "adapterType", @@ -29685,6 +31534,7 @@ "pollingIntervalSeconds", "enabled", "published", + "slaPublished", "componentCount", "activeIncidentCount" ], @@ -29739,6 +31589,10 @@ "published": { "type": "boolean" }, + "slaPublished": { + "type": "boolean", + "description": "Whether the service's SLA page is publicly visible" + }, "overallStatus": { "type": "string", "nullable": true @@ -29959,7 +31813,8 @@ "slug", "updatedAt", "pollingIntervalSeconds", - "enabled" + "enabled", + "slaPublished" ], "type": "object", "properties": { @@ -30062,6 +31917,10 @@ "dataCompleteness": { "type": "string" }, + "slaPublished": { + "type": "boolean", + "description": "Whether the service's SLA page is publicly visible" + }, "seoMetadata": { "nullable": true, "allOf": [ @@ -30070,6 +31929,14 @@ } ] }, + "slaData": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/SlaDataDto" + } + ] + }, "relatedServices": { "type": "array", "nullable": true, @@ -30128,6 +31995,13 @@ "type": "string" } }, + "affectedRegions": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + } + }, "updates": { "type": "array", "items": { @@ -30203,6 +32077,13 @@ "type": "string", "format": "date-time", "nullable": true + }, + "affectedRegions": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + } } } }, @@ -30566,6 +32447,19 @@ }, "description": "Replace the alert channels linked to a monitor" }, + "SetEnabledRequest": { + "required": [ + "enabled" + ], + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether the resource should be enabled" + } + }, + "description": "Request body for toggling a resource's enabled state" + }, "SetMonitorAuthRequest": { "required": [ "config" @@ -30590,6 +32484,17 @@ } } }, + "SingleValueResponseAcknowledgeAllIncidentsResponse": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/AcknowledgeAllIncidentsResponse" + } + } + }, "SingleValueResponseAlertChannelDto": { "required": [ "data" @@ -31211,6 +33116,39 @@ } } }, + "SkippedDispatch": { + "required": [ + "id", + "reason", + "status" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Dispatch identifier", + "format": "uuid" + }, + "status": { + "type": "string", + "description": "Current dispatch status", + "enum": [ + "PENDING", + "DISPATCHING", + "DELIVERED", + "ESCALATING", + "ACKNOWLEDGED", + "COMPLETED" + ] + }, + "reason": { + "minLength": 1, + "type": "string", + "description": "Why this dispatch was skipped" + } + }, + "description": "A dispatch that was not acknowledged by ack-all" + }, "SlackChannelConfig": { "required": [ "channelType", @@ -31236,6 +33174,146 @@ } } }, + "SlaDataDto": { + "type": "object", + "properties": { + "slaType": { + "type": "string", + "description": "SLA pattern: plan_gated, per_service, no_public_sla, or universal", + "nullable": true + }, + "officialSla": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/OfficialSla" + } + ] + }, + "serviceBreakdown": { + "type": "array", + "description": "Per-service breakdown for vendors with per_service SLA type", + "nullable": true, + "items": { + "$ref": "#/components/schemas/ServiceBreakdown" + } + }, + "pricingTiers": { + "type": "array", + "description": "Pricing tiers with associated SLA levels", + "nullable": true, + "items": { + "$ref": "#/components/schemas/PricingTier" + } + }, + "creditPolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CreditPolicy" + } + ] + }, + "noSlaContext": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/NoSlaContext" + } + ] + }, + "sourceUrls": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/SourceUrls" + } + ] + }, + "lastResearched": { + "type": "string", + "description": "ISO date when this data was last manually researched", + "nullable": true + }, + "researchNotes": { + "type": "string", + "description": "Freeform operator notes about the research", + "nullable": true + } + }, + "description": "Researched vendor SLA/pricing data for pSEO SLA report pages" + }, + "SmsChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "sms" + ] + }, + "phoneNumber": { + "type": "string", + "description": "Recipient phone number in E.164 format, e.g. +14155550123", + "nullable": true + }, + "verifiedPhoneNumberId": { + "type": "integer", + "description": "Id of an org verified_phone_number row; alternative to phoneNumber", + "format": "int64", + "nullable": true + }, + "phoneNumbers": { + "type": "array", + "description": "Deprecated: use phoneNumber. Accepted as a length-1 list for one release; ignored when phoneNumber or id is set", + "nullable": true, + "items": { + "type": "string", + "description": "Deprecated: use phoneNumber. Accepted as a length-1 list for one release; ignored when phoneNumber or id is set", + "nullable": true + } + }, + "preferredLanguage": { + "type": "string", + "description": "Preferred language for SMS body (BCP-47, e.g. en-US, de-DE). Default: en-US", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, + "SourceUrls": { + "type": "object", + "properties": { + "slaPage": { + "type": "string", + "description": "URL to vendor's SLA page", + "nullable": true + }, + "pricingPage": { + "type": "string", + "description": "URL to vendor's pricing page", + "nullable": true + }, + "tosPage": { + "type": "string", + "description": "URL to vendor's Terms of Service", + "nullable": true + }, + "statusPage": { + "type": "string", + "description": "URL to vendor's status page", + "nullable": true + }, + "allSlasPage": { + "type": "string", + "description": "URL to vendor's all-services SLA listing", + "nullable": true + } + }, + "description": "Source URLs for SLA, pricing, and ToS pages" + }, "SplunkOnCallChannelConfig": { "required": [ "channelType", @@ -31332,6 +33410,72 @@ } } }, + "StatusEventDto": { + "required": [ + "at", + "id", + "type" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Stable row ID (incident/update/maintenance UUID or transition bucket key)", + "format": "uuid" + }, + "type": { + "type": "string", + "description": "Status event row type on the Dependencies Detail rail", + "enum": [ + "incident.opened", + "incident.update", + "incident.resolved", + "maintenance.scheduled", + "maintenance.started", + "maintenance.completed", + "component.transition" + ] + }, + "at": { + "type": "string", + "description": "Canonical timestamp used for reverse-chronological ordering", + "format": "date-time" + }, + "incident": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/IncidentEventDto" + } + ] + }, + "maintenance": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/MaintenanceEventDto" + } + ] + }, + "component": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/ComponentTransitionEventDto" + } + ] + }, + "orgAnnotation": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/OrgIncidentAnnotationDto" + } + ] + } + }, + "description": "Curated vendor status-event row for the Dependencies Detail rail" + }, "StatusPageBranding": { "type": "object", "properties": { @@ -33072,6 +35216,70 @@ } } }, + "TableValueResultTestChannelResult": { + "required": [ + "data", + "hasNext", + "hasPrev" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TestChannelResult" + } + }, + "hasNext": { + "type": "boolean" + }, + "hasPrev": { + "type": "boolean" + }, + "totalElements": { + "type": "integer", + "format": "int64", + "nullable": true + }, + "totalPages": { + "type": "integer", + "format": "int32", + "nullable": true + } + } + }, + "TableValueResultVoiceLanguageDto": { + "required": [ + "data", + "hasNext", + "hasPrev" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VoiceLanguageDto" + } + }, + "hasNext": { + "type": "boolean" + }, + "hasPrev": { + "type": "boolean" + }, + "totalElements": { + "type": "integer", + "format": "int64", + "nullable": true + }, + "totalPages": { + "type": "integer", + "format": "int32", + "nullable": true + } + } + }, "TableValueResultWebhookDeliveryDto": { "required": [ "data", @@ -33413,6 +35621,9 @@ { "$ref": "#/components/schemas/PagerDutyChannelConfig" }, + { + "$ref": "#/components/schemas/PhoneCallChannelConfig" + }, { "$ref": "#/components/schemas/PushbulletChannelConfig" }, @@ -33425,6 +35636,9 @@ { "$ref": "#/components/schemas/SlackChannelConfig" }, + { + "$ref": "#/components/schemas/SmsChannelConfig" + }, { "$ref": "#/components/schemas/SplunkOnCallChannelConfig" }, @@ -33491,6 +35705,29 @@ }, "description": "Result of a dry-run match evaluation against a notification policy" }, + "TestMonitorNotificationsRequest": { + "type": "object", + "properties": { + "channelIds": { + "type": "array", + "description": "Channel IDs to test; null or empty tests all channels attached to the monitor", + "nullable": true, + "items": { + "type": "string", + "description": "Channel IDs to test; null or empty tests all channels attached to the monitor", + "format": "uuid" + } + }, + "includeResolved": { + "type": "boolean", + "description": "Whether to include a resolved notification in the test (default: false)" + } + }, + "description": "Request to send test notifications through a monitor's alert channels", + "required": [ + "includeResolved" + ] + }, "TestNotificationPolicyRequest": { "type": "object", "properties": { @@ -33564,7 +35801,7 @@ "properties": { "dns_ms": { "type": "integer", - "description": "DNS resolution time in milliseconds", + "description": "Legacy DNS phase; null for new checks (no longer measured)", "format": "int32", "nullable": true, "example": 12 @@ -33753,64 +35990,70 @@ "config": { "oneOf": [ { - "$ref": "#/components/schemas/DatadogChannelConfig" + "$ref": "#/components/schemas/UpdateDatadogChannelConfig" }, { - "$ref": "#/components/schemas/DiscordChannelConfig" + "$ref": "#/components/schemas/UpdateDiscordChannelConfig" }, { - "$ref": "#/components/schemas/EmailChannelConfig" + "$ref": "#/components/schemas/UpdateEmailChannelConfig" }, { - "$ref": "#/components/schemas/GitLabChannelConfig" + "$ref": "#/components/schemas/UpdateGitLabChannelConfig" }, { - "$ref": "#/components/schemas/GoogleChatChannelConfig" + "$ref": "#/components/schemas/UpdateGoogleChatChannelConfig" }, { - "$ref": "#/components/schemas/IncidentIoChannelConfig" + "$ref": "#/components/schemas/UpdateIncidentIoChannelConfig" }, { - "$ref": "#/components/schemas/JiraChannelConfig" + "$ref": "#/components/schemas/UpdateJiraChannelConfig" }, { - "$ref": "#/components/schemas/LinearChannelConfig" + "$ref": "#/components/schemas/UpdateLinearChannelConfig" }, { - "$ref": "#/components/schemas/MattermostChannelConfig" + "$ref": "#/components/schemas/UpdateMattermostChannelConfig" }, { - "$ref": "#/components/schemas/OpsGenieChannelConfig" + "$ref": "#/components/schemas/UpdateOpsGenieChannelConfig" }, { - "$ref": "#/components/schemas/PagerDutyChannelConfig" + "$ref": "#/components/schemas/UpdatePagerDutyChannelConfig" }, { - "$ref": "#/components/schemas/PushbulletChannelConfig" + "$ref": "#/components/schemas/UpdatePhoneCallChannelConfig" }, { - "$ref": "#/components/schemas/PushoverChannelConfig" + "$ref": "#/components/schemas/UpdatePushbulletChannelConfig" }, { - "$ref": "#/components/schemas/RootlyChannelConfig" + "$ref": "#/components/schemas/UpdatePushoverChannelConfig" }, { - "$ref": "#/components/schemas/SlackChannelConfig" + "$ref": "#/components/schemas/UpdateRootlyChannelConfig" }, { - "$ref": "#/components/schemas/SplunkOnCallChannelConfig" + "$ref": "#/components/schemas/UpdateSlackChannelConfig" }, { - "$ref": "#/components/schemas/TeamsChannelConfig" + "$ref": "#/components/schemas/UpdateSmsChannelConfig" }, { - "$ref": "#/components/schemas/TelegramChannelConfig" + "$ref": "#/components/schemas/UpdateSplunkOnCallChannelConfig" }, { - "$ref": "#/components/schemas/WebhookChannelConfig" + "$ref": "#/components/schemas/UpdateTeamsChannelConfig" }, { - "$ref": "#/components/schemas/ZapierChannelConfig" + "$ref": "#/components/schemas/UpdateTelegramChannelConfig" + }, + { + "$ref": "#/components/schemas/UpdateWebhookChannelConfig" + }, + { + "$ref": "#/components/schemas/UpdateZapierChannelConfig" } ] }, @@ -33825,6 +36068,11 @@ "MCP", "API" ] + }, + "enabled": { + "type": "boolean", + "description": "Whether this channel is enabled (default: true); null preserves current value", + "nullable": true } } }, @@ -34004,6 +36252,84 @@ } } }, + "UpdateDatadogChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "datadog" + ] + }, + "apiKey": { + "type": "string", + "description": "Datadog API key", + "nullable": true + }, + "site": { + "type": "string", + "description": "Datadog site region (e.g. datadoghq.com, datadoghq.eu, us3.datadoghq.com)", + "nullable": true + }, + "tags": { + "type": "string", + "description": "Comma-separated tags to attach to events", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, + "UpdateDiscordChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "discord" + ] + }, + "webhookUrl": { + "type": "string", + "description": "Discord webhook URL", + "nullable": true + }, + "mentionRoleId": { + "type": "string", + "description": "Optional Discord role ID to mention in notifications", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, + "UpdateEmailChannelConfig": { + "required": [ + "channelType", + "recipients" + ], + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "email" + ] + }, + "recipients": { + "minItems": 1, + "type": "array", + "description": "Email addresses to send notifications to", + "items": { + "type": "string", + "description": "Email addresses to send notifications to", + "format": "email" + } + } + } + }, "UpdateEnvironmentRequest": { "type": "object", "properties": { @@ -34031,6 +36357,79 @@ } } }, + "UpdateGitLabChannelConfig": { + "required": [ + "channelType", + "endpointUrl" + ], + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "gitlab" + ] + }, + "endpointUrl": { + "minLength": 1, + "type": "string", + "description": "GitLab alert integration endpoint URL" + }, + "authorizationKey": { + "type": "string", + "description": "Authorization key from GitLab alert integration settings", + "nullable": true + } + } + }, + "UpdateGoogleChatChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "google_chat" + ] + }, + "webhookUrl": { + "type": "string", + "description": "Google Chat space webhook URL", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, + "UpdateIncidentIoChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "incident_io" + ] + }, + "apiKey": { + "type": "string", + "description": "incident.io API key with 'Create incidents' permission", + "nullable": true + }, + "severityId": { + "type": "string", + "description": "Severity ID for created incidents (from List Severities API)", + "nullable": true + }, + "visibility": { + "type": "string", + "description": "Incident visibility: public or private (default: public)", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, "UpdateIncidentPolicyRequest": { "required": [ "confirmation", @@ -34056,6 +36455,100 @@ }, "description": "Request body for updating an incident policy" }, + "UpdateIncidentRequest": { + "type": "object", + "properties": { + "title": { + "maxLength": 2147483647, + "minLength": 1, + "type": "string", + "description": "New title; null preserves current (min 1 char if present)", + "nullable": true + }, + "severity": { + "type": "string", + "description": "New severity: DOWN, DEGRADED, or MAINTENANCE; null preserves current", + "nullable": true, + "enum": [ + "DOWN", + "DEGRADED", + "MAINTENANCE" + ] + } + } + }, + "UpdateJiraChannelConfig": { + "required": [ + "channelType", + "domain", + "email", + "projectKey" + ], + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "jira" + ] + }, + "domain": { + "minLength": 1, + "type": "string", + "description": "Atlassian instance domain (e.g. yourteam.atlassian.net)" + }, + "email": { + "minLength": 1, + "type": "string", + "description": "Atlassian account email for API authentication" + }, + "apiToken": { + "type": "string", + "description": "Atlassian API token", + "nullable": true + }, + "projectKey": { + "minLength": 1, + "type": "string", + "description": "Jira project key where issues are created (e.g. OPS)" + }, + "issueType": { + "type": "string", + "description": "Issue type name (e.g. Bug, Task, Incident)", + "nullable": true + } + } + }, + "UpdateLinearChannelConfig": { + "required": [ + "channelType", + "teamId" + ], + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "linear" + ] + }, + "apiKey": { + "type": "string", + "description": "Linear API key", + "nullable": true + }, + "teamId": { + "minLength": 1, + "type": "string", + "description": "Team ID to create issues in" + }, + "labelId": { + "type": "string", + "description": "Label ID to attach to created issues", + "nullable": true + } + } + }, "UpdateMaintenanceWindowRequest": { "required": [ "endsAt", @@ -34100,6 +36593,35 @@ } } }, + "UpdateMattermostChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "mattermost" + ] + }, + "webhookUrl": { + "type": "string", + "description": "Mattermost incoming webhook URL", + "nullable": true + }, + "channel": { + "type": "string", + "description": "Override channel (if webhook allows)", + "nullable": true + }, + "iconUrl": { + "type": "string", + "description": "Custom bot icon URL", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, "UpdateMonitorAuthRequest": { "required": [ "config" @@ -34152,6 +36674,9 @@ { "$ref": "#/components/schemas/McpServerMonitorConfig" }, + { + "$ref": "#/components/schemas/ScriptMonitorConfig" + }, { "$ref": "#/components/schemas/TcpMonitorConfig" } @@ -34291,6 +36816,30 @@ }, "description": "Request body for updating a notification policy (null fields are preserved)" }, + "UpdateOpsGenieChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "opsgenie" + ] + }, + "apiKey": { + "type": "string", + "description": "OpsGenie API key for alert creation", + "nullable": true + }, + "region": { + "type": "string", + "description": "OpsGenie API region: us or eu", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, "UpdateOrgDetailsRequest": { "required": [ "email", @@ -34333,6 +36882,133 @@ } } }, + "UpdatePagerDutyChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "pagerduty" + ] + }, + "routingKey": { + "type": "string", + "description": "PagerDuty Events API v2 routing (integration) key", + "nullable": true + }, + "severityOverride": { + "type": "string", + "description": "Override PagerDuty severity mapping", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, + "UpdatePhoneCallChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "phone_call" + ] + }, + "phoneNumber": { + "type": "string", + "description": "Recipient phone number in E.164 format; null preserves current", + "nullable": true + }, + "verifiedPhoneNumberId": { + "type": "integer", + "description": "Id of an org verified_phone_number row; null preserves current when phoneNumber also null", + "format": "int64", + "nullable": true + }, + "phoneNumbers": { + "type": "array", + "description": "Deprecated: use phoneNumber", + "nullable": true, + "items": { + "type": "string", + "description": "Deprecated: use phoneNumber", + "nullable": true + } + }, + "voiceLanguage": { + "type": "string", + "description": "TTS voice language/locale (default: en-US). See VoiceLanguage for supported values", + "nullable": true + }, + "preferredLanguage": { + "type": "string", + "description": "Preferred language for TTS and notifications (BCP-47, e.g. en-US, de-DE). Alias for voiceLanguage", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, + "UpdatePushbulletChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "pushbullet" + ] + }, + "accessToken": { + "type": "string", + "description": "Pushbullet access token", + "nullable": true + }, + "deviceIden": { + "type": "string", + "description": "Target device identifier (broadcasts to all if empty)", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, + "UpdatePushoverChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "pushover" + ] + }, + "userKey": { + "type": "string", + "description": "Pushover user or group key", + "nullable": true + }, + "appToken": { + "type": "string", + "description": "Pushover application API token", + "nullable": true + }, + "priority": { + "type": "string", + "description": "Notification priority override (-2 to 2)", + "nullable": true + }, + "sound": { + "type": "string", + "description": "Notification sound override", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, "UpdateResourceGroupRequest": { "required": [ "name" @@ -34451,6 +37127,30 @@ }, "description": "Request body for updating a resource group" }, + "UpdateRootlyChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "rootly" + ] + }, + "apiKey": { + "type": "string", + "description": "Rootly API token with incident creation permission", + "nullable": true + }, + "severity": { + "type": "string", + "description": "Severity slug override (e.g. sev0, sev1)", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, "UpdateSecretRequest": { "required": [ "value" @@ -34465,6 +37165,95 @@ } } }, + "UpdateSlackChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "slack" + ] + }, + "webhookUrl": { + "type": "string", + "description": "Slack incoming webhook URL", + "nullable": true + }, + "mentionText": { + "type": "string", + "description": "Optional mention text included in notifications, e.g. @channel", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, + "UpdateSmsChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "sms" + ] + }, + "phoneNumber": { + "type": "string", + "description": "Recipient phone number in E.164 format; null preserves current", + "nullable": true + }, + "verifiedPhoneNumberId": { + "type": "integer", + "description": "Id of an org verified_phone_number row; null preserves current when phoneNumber also null", + "format": "int64", + "nullable": true + }, + "phoneNumbers": { + "type": "array", + "description": "Deprecated: use phoneNumber", + "nullable": true, + "items": { + "type": "string", + "description": "Deprecated: use phoneNumber", + "nullable": true + } + }, + "preferredLanguage": { + "type": "string", + "description": "Preferred language for SMS body (BCP-47, e.g. en-US, de-DE). Default: en-US", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, + "UpdateSplunkOnCallChannelConfig": { + "required": [ + "channelType", + "routingKey" + ], + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "splunk_oncall" + ] + }, + "apiKey": { + "type": "string", + "description": "Splunk On-Call REST API key", + "nullable": true + }, + "routingKey": { + "minLength": 1, + "type": "string", + "description": "Routing key for alert routing" + } + } + }, "UpdateStatusPageComponentGroupRequest": { "type": "object", "properties": { @@ -34685,6 +37474,84 @@ }, "description": "Request body for updating a tag; null fields are left unchanged" }, + "UpdateTeamsChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "teams" + ] + }, + "webhookUrl": { + "type": "string", + "description": "Microsoft Teams incoming webhook URL", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, + "UpdateTelegramChannelConfig": { + "required": [ + "channelType", + "chatId" + ], + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "telegram" + ] + }, + "botToken": { + "type": "string", + "description": "Telegram bot token from @BotFather", + "nullable": true + }, + "chatId": { + "minLength": 1, + "type": "string", + "description": "Chat, group, or channel ID to send alerts to" + } + } + }, + "UpdateWebhookChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "webhook" + ] + }, + "url": { + "type": "string", + "description": "Webhook endpoint URL that receives alert payloads", + "nullable": true + }, + "signingSecret": { + "type": "string", + "description": "HMAC secret for X-DevHelm-Signature header; omit for unsigned delivery", + "nullable": true + }, + "customHeaders": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Additional HTTP headers to include in webhook requests", + "nullable": true + }, + "description": "Additional HTTP headers to include in webhook requests", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, "UpdateWebhookEndpointRequest": { "type": "object", "properties": { @@ -34745,6 +37612,25 @@ }, "description": "Update workspace details" }, + "UpdateZapierChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "zapier" + ] + }, + "webhookUrl": { + "type": "string", + "description": "Zapier/n8n/Make catch webhook URL", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, "UptimeBucketDto": { "required": [ "timestamp", @@ -34809,14 +37695,48 @@ "format": "double", "nullable": true, "example": 312 + }, + "p50LatencyMs": { + "type": "number", + "description": "50th-percentile (median) latency in milliseconds; null when no data", + "format": "double", + "nullable": true, + "example": 128 + }, + "incidentCount": { + "type": "integer", + "description": "Number of incidents that started within the requested window", + "format": "int64", + "example": 2 } }, "description": "Uptime statistics aggregated from continuous aggregates", "required": [ "totalChecks", - "passedChecks" + "passedChecks", + "incidentCount" ] }, + "VoiceLanguageDto": { + "required": [ + "code", + "label" + ], + "type": "object", + "properties": { + "code": { + "minLength": 1, + "type": "string", + "description": "BCP-47 locale code, e.g. en-US" + }, + "label": { + "minLength": 1, + "type": "string", + "description": "Human-readable label, e.g. English (US)" + } + }, + "description": "Supported TTS voice language for phone call alerts" + }, "WebhookChannelConfig": { "required": [ "channelType", @@ -34837,7 +37757,7 @@ }, "signingSecret": { "type": "string", - "description": "Optional HMAC signing secret for payload verification", + "description": "HMAC secret for X-DevHelm-Signature header; omit for unsigned delivery", "nullable": true }, "customHeaders": { diff --git a/src/devhelm/_generated.py b/src/devhelm/_generated.py index 0b19ffa..ff92d68 100644 --- a/src/devhelm/_generated.py +++ b/src/devhelm/_generated.py @@ -173,6 +173,41 @@ class AlertChannelDisplayConfig(BaseModel): project_key: Annotated[ str | None, Field(alias="projectKey", description="Jira project key") ] = None + phone_number: Annotated[ + str | None, + Field( + alias="phoneNumber", + description="Recipient phone number in E.164 format (SMS / phone-call channels)", + ), + ] = None + verified_phone_number_id: Annotated[ + int | None, + Field( + alias="verifiedPhoneNumberId", + description="Id of the org verified_phone_number row bound to this channel", + ), + ] = None + phone_numbers: Annotated[ + list[str] | None, + Field( + alias="phoneNumbers", + description="Deprecated mirror of phoneNumber as a length-1 list for older clients", + ), + ] = None + voice_language: Annotated[ + str | None, + Field( + alias="voiceLanguage", + description="BCP-47 voice language for phone-call TTS (e.g. en-US, de-DE)", + ), + ] = None + preferred_language: Annotated[ + str | None, + Field( + alias="preferredLanguage", + description="Preferred language for SMS/voice (BCP-47, e.g. en-US, de-DE)", + ), + ] = None class AlertChannelDto(BaseModel): @@ -189,6 +224,10 @@ class AlertChannelDto(BaseModel): display_config: Annotated[ AlertChannelDisplayConfig | None, Field(alias="displayConfig") ] = None + enabled: Annotated[ + bool, + Field(description="Whether this channel is enabled and will receive alerts"), + ] created_at: Annotated[ AwareDatetime, Field(alias="createdAt", description="Timestamp when the channel was created"), @@ -549,6 +588,21 @@ class ChartBucketDto(BaseModel): ] = None +class CodeCheckStep(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + name: Annotated[str, Field(description="Step name from test.step() or test() call")] + status: Annotated[ + str, Field(description="Step outcome: passed, failed, skipped, or timedOut") + ] + duration_ms: Annotated[ + int | None, + Field(alias="durationMs", description="Step duration in milliseconds"), + ] = None + error: Annotated[ + str | None, Field(description="Error message if the step failed") + ] = None + + class ComponentImpact(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) component_id: Annotated[ @@ -601,6 +655,23 @@ class ComponentPosition(BaseModel): ] = None +class ComponentSample(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + component_id: Annotated[ + UUID, Field(alias="componentId", description="Component ID") + ] + component_name: Annotated[ + str | None, Field(alias="componentName", description="Component display name") + ] = None + old_status: Annotated[ + str | None, + Field(alias="oldStatus", description="Previous status before the flip"), + ] = None + new_status: Annotated[ + str, Field(alias="newStatus", description="New status after the flip") + ] + + class ComponentsSummaryDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) total_count: Annotated[ @@ -638,6 +709,30 @@ class ComponentStatusDto(BaseModel): ] +class ComponentTransitionEventDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + new_status: Annotated[ + str, + Field( + alias="newStatus", description="New status that defines this rollup bucket" + ), + ] + component_count: Annotated[ + int, + Field( + alias="componentCount", + description="Total components in the 5-minute rollup bucket", + ), + ] + component_sample: Annotated[ + list[ComponentSample], + Field( + alias="componentSample", + description="Up to 5 sample components from the bucket", + ), + ] + + class ComponentUptimeSummaryDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) day: Annotated[ @@ -834,6 +929,20 @@ class CreateManualIncidentRequest(BaseModel): str | None, Field(description="Detailed description or context for the incident"), ] = None + service_id: Annotated[ + UUID | None, + Field( + alias="serviceId", + description="Vendor service to link; optional for Dependencies create CTA", + ), + ] = None + service_incident_id: Annotated[ + UUID | None, + Field( + alias="serviceIncidentId", + description="Vendor incident to link; idempotent if an active org incident already links it", + ), + ] = None class Type(StrEnum): @@ -843,6 +952,8 @@ class Type(StrEnum): tcp = "TCP" icmp = "ICMP" heartbeat = "HEARTBEAT" + browser = "BROWSER" + multi_step_api = "MULTI_STEP_API" class HealthThresholdType(StrEnum): @@ -1121,6 +1232,25 @@ class CreateWorkspaceRequest(BaseModel): name: Annotated[str, Field(description="Workspace name", min_length=1)] +class CreditTier(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + uptime_range: Annotated[ + str, + Field(alias="uptimeRange", description="Uptime range, e.g. '99.1% – 99.98%'"), + ] + credit_percent: Annotated[ + int | None, + Field(alias="creditPercent", description="Credit percent of monthly fee"), + ] = None + formula: Annotated[ + str | None, + Field(description="Credit formula when percent is not a fixed number"), + ] = None + notes: Annotated[ + str | None, Field(description="Additional notes on this credit tier") + ] = None + + class DatadogChannelConfig(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) channel_type: Annotated[Literal["datadog"], Field(alias="channelType")] = "datadog" @@ -2116,6 +2246,13 @@ class IncidentDto(BaseModel): description="Whether this incident is visible on the status page", ), ] + suppress_dispatch: Annotated[ + bool, + Field( + alias="suppressDispatch", + description="When true, alert channels are suppressed (AWARENESS silent tracking); false means Alerted", + ), + ] service_incident_id: Annotated[ UUID | None, Field( @@ -2154,6 +2291,13 @@ class IncidentDto(BaseModel): description="How the incident was resolved (AUTO_RECOVERED, MANUAL, etc.)", ), ] = None + resolution_note: Annotated[ + str | None, + Field( + alias="resolutionNote", + description="Body from the most recent resolve update; null when not currently resolved, auto-resolved without a note, or no resolve update body was provided", + ), + ] = None started_at: Annotated[ AwareDatetime | None, Field( @@ -2265,6 +2409,75 @@ class IncidentDto(BaseModel): description="Detection engine semver that evaluated the rule. Omitted from JSON when null, treat missing as null.", ), ] = None + display_key: Annotated[ + str | None, + Field( + alias="displayKey", + description='Org-scoped human-readable incident code, e.g. "ABC-42". Null on incidents created by pre-INC-keys API pods before the sweep; treat missing as unknown and fall back to the id', + ), + ] = None + + +class IncidentEventDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + incident_id: Annotated[ + UUID, Field(alias="incidentId", description="Vendor catalog incident ID") + ] + external_id: Annotated[ + str | None, + Field(alias="externalId", description="Vendor-supplied external incident ID"), + ] = None + title: Annotated[ + str, Field(description="Incident title from the vendor status page") + ] + impact: Annotated[ + str | None, Field(description="Vendor impact level (major, minor, none)") + ] = None + status: Annotated[ + str | None, + Field(description="Vendor lifecycle status (only set on incident.update rows)"), + ] = None + body: Annotated[ + str | None, + Field(description="Update body text (only set on incident.update rows)"), + ] = None + shortlink: Annotated[ + str | None, Field(description="Short public URL for the vendor incident") + ] = None + started_at: Annotated[ + AwareDatetime | None, + Field(alias="startedAt", description="When the vendor incident started"), + ] = None + resolved_at: Annotated[ + AwareDatetime | None, + Field(alias="resolvedAt", description="When the vendor incident resolved"), + ] = None + detected_at: Annotated[ + AwareDatetime | None, + Field( + alias="detectedAt", description="When DevHelm first detected the incident" + ), + ] = None + vendor_created_at: Annotated[ + AwareDatetime | None, + Field( + alias="vendorCreatedAt", description="Vendor-reported creation timestamp" + ), + ] = None + duration_seconds: Annotated[ + int | None, + Field( + alias="durationSeconds", + description="Total duration in seconds (set on incident.resolved)", + ), + ] = None + affected_component_ids: Annotated[ + list[UUID] | None, + Field( + alias="affectedComponentIds", + description="Affected component IDs from the vendor incident join", + ), + ] = None class Status5(StrEnum): @@ -2415,6 +2628,57 @@ class IncidentsSummaryDto(BaseModel): mttr30d: float | None = None +class IncidentTriggerDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + rule_type: Annotated[ + str | None, + Field( + alias="ruleType", + description="Trigger rule type (consecutive_failures, failures_in_window, response_time); null when unknown", + ), + ] = None + rule_index: Annotated[ + int | None, + Field( + alias="ruleIndex", + description="0-based index into the policy trigger_rules array; null when unknown", + ), + ] = None + count: Annotated[ + int | None, + Field( + description="Observed failing_streak or failures_in_window from forensics; null when unavailable" + ), + ] = None + threshold: Annotated[ + int | None, + Field( + description="Rule required count or threshold_ms from forensics; null when unavailable" + ), + ] = None + last_error: Annotated[ + str | None, + Field( + alias="lastError", + description="failure_reason from the triggering check result; null when unavailable", + ), + ] = None + first_failed_check_at: Annotated[ + AwareDatetime | None, + Field( + alias="firstFailedCheckAt", + description="Earliest failing check timestamp in the confirm window when computable; null otherwise", + ), + ] = None + source: Annotated[ + str, + Field( + description="Where the enrichment came from: forensics, checks, or none (STATUS_DATA/manual/no data)", + min_length=1, + ), + ] + + class IncidentUpdateDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: UUID @@ -2453,6 +2717,10 @@ class InviteDto(BaseModel): description="Role that will be assigned to the invitee on acceptance", ), ] + created_at: Annotated[ + AwareDatetime, + Field(alias="createdAt", description="Timestamp when the invite was created"), + ] expires_at: Annotated[ AwareDatetime, Field(alias="expiresAt", description="Timestamp when the invite expires"), @@ -2584,6 +2852,54 @@ class MaintenanceComponentRef(BaseModel): ] +class MaintenanceEventDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + maintenance_id: Annotated[ + UUID, Field(alias="maintenanceId", description="Vendor catalog maintenance ID") + ] + external_id: Annotated[ + str, + Field( + alias="externalId", description="Vendor-supplied external maintenance ID" + ), + ] + title: Annotated[ + str, Field(description="Maintenance title from the vendor status page") + ] + status: Annotated[ + str, + Field( + description="Lifecycle status: scheduled, in_progress, verifying, completed" + ), + ] + impact: Annotated[str | None, Field(description="Vendor impact level")] = None + shortlink: Annotated[ + str | None, Field(description="Short public URL for the vendor maintenance") + ] = None + scheduled_for: Annotated[ + AwareDatetime | None, + Field( + alias="scheduledFor", + description="Scheduled start; null for undated maintenance", + ), + ] = None + scheduled_until: Annotated[ + AwareDatetime | None, Field(alias="scheduledUntil", description="Scheduled end") + ] = None + started_at: Annotated[ + AwareDatetime | None, + Field(alias="startedAt", description="When maintenance actually started"), + ] = None + completed_at: Annotated[ + AwareDatetime | None, + Field(alias="completedAt", description="When maintenance completed"), + ] = None + affected_component_ids: Annotated[ + list[UUID] | None, + Field(alias="affectedComponentIds", description="Affected component IDs"), + ] = None + + class MaintenanceUpdateDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: Annotated[UUID, Field(description="Unique update identifier")] @@ -2946,6 +3262,8 @@ class Type3(StrEnum): tcp = "TCP" icmp = "ICMP" heartbeat = "HEARTBEAT" + browser = "BROWSER" + multi_step_api = "MULTI_STEP_API" class MonitorTestResultDto(BaseModel): @@ -2979,6 +3297,33 @@ class NewTagRequest(BaseModel): ] = None +class NoSlaContext(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + reason: Annotated[str | None, Field(description="Reason no SLA is published")] = ( + None + ) + historical_claim: Annotated[ + str | None, + Field( + alias="historicalClaim", description="Non-binding historical uptime claim" + ), + ] = None + support_sla: Annotated[ + str | None, + Field( + alias="supportSla", + description="Support response time SLA if different from uptime SLA", + ), + ] = None + enterprise_note: Annotated[ + str | None, + Field( + alias="enterpriseNote", + description="Note about enterprise/custom SLA availability", + ), + ] = None + + class NotificationDispatchDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: Annotated[UUID, Field(description="Unique dispatch record identifier")] @@ -3028,6 +3373,27 @@ class NotificationDispatchDto(BaseModel): description="Timestamp when this dispatch was acknowledged (null if not acknowledged)", ), ] = None + acknowledged_by: Annotated[ + str | None, + Field( + alias="acknowledgedBy", + description="Actor who acknowledged this dispatch (user email, api-key:, voice:, etc.); null if not acknowledged", + ), + ] = None + acknowledged_via: Annotated[ + str | None, + Field( + alias="acknowledgedVia", + description="Channel used to acknowledge (DASHBOARD, API, PHONE_CALL, INTERNAL, etc.); null if not acknowledged", + ), + ] = None + matched_rules: Annotated[ + list[str] | None, + Field( + alias="matchedRules", + description='Labels of match rules that caused this dispatch (same wording as TestMatchResult); null on pre-V138 rows; catch-all is ["(catch-all: no rules defined)"]', + ), + ] = None next_escalation_at: Annotated[ AwareDatetime | None, Field( @@ -3095,21 +3461,51 @@ class NotificationDto(BaseModel): ] -class OpsGenieChannelConfig(BaseModel): +class OfficialSla(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) - channel_type: Annotated[Literal["opsgenie"], Field(alias="channelType")] = ( - "opsgenie" - ) - api_key: Annotated[ - str, - Field( - alias="apiKey", - description="OpsGenie API key for alert creation", - min_length=1, - ), - ] - region: Annotated[ - str | None, Field(description="OpsGenie API region: us or eu") + percentage: Annotated[ + str | None, Field(description="Advertised uptime percentage, e.g. '99.99%'") + ] = None + scope: Annotated[ + str | None, + Field(description="Scope of the SLA, e.g. 'Monthly uptime per region'"), + ] = None + measurement: Annotated[ + str | None, Field(description="How the vendor measures uptime for SLA purposes") + ] = None + exclusions: Annotated[ + str | None, Field(description="Summary of exclusions from SLA calculation") + ] = None + applies_to_plans: Annotated[ + list[str] | None, + Field( + alias="appliesToPlans", + description="Plan names this SLA applies to, e.g. ['Enterprise']", + ), + ] = None + not_covered: Annotated[ + str | None, + Field( + alias="notCovered", description="Services/components NOT covered by the SLA" + ), + ] = None + + +class OpsGenieChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["opsgenie"], Field(alias="channelType")] = ( + "opsgenie" + ) + api_key: Annotated[ + str, + Field( + alias="apiKey", + description="OpsGenie API key for alert creation", + min_length=1, + ), + ] + region: Annotated[ + str | None, Field(description="OpsGenie API region: us or eu") ] = None @@ -3129,6 +3525,32 @@ class OrganizationDto(BaseModel): ] = None +class OrgIncidentAnnotationDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + incident_id: Annotated[ + UUID, Field(alias="incidentId", description="Internal org incident ID") + ] + display_key: Annotated[ + str | None, + Field( + alias="displayKey", + description="Human display key (e.g. DEV-42); null until platform INC codes ship", + ), + ] = None + status: Annotated[str, Field(description="Internal incident lifecycle status")] + severity: Annotated[str, Field(description="Internal incident severity")] + alerted: Annotated[ + bool, + Field( + description="Whether alert channels were eligible to fire (false for AWARENESS silent tracking)" + ), + ] + started_at: Annotated[ + AwareDatetime | None, + Field(alias="startedAt", description="When the internal incident started"), + ] = None + + class OrgInfo(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) id: Annotated[int, Field(description="Organization ID")] @@ -3181,6 +3603,48 @@ class PageSection(BaseModel): ] +class PhoneCallChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["phone_call"], Field(alias="channelType")] = ( + "phone_call" + ) + phone_number: Annotated[ + str | None, + Field( + alias="phoneNumber", + description="Recipient phone number in E.164 format, e.g. +14155550123", + ), + ] = None + verified_phone_number_id: Annotated[ + int | None, + Field( + alias="verifiedPhoneNumberId", + description="Id of an org verified_phone_number row; alternative to phoneNumber", + ), + ] = None + phone_numbers: Annotated[ + list[str] | None, + Field( + alias="phoneNumbers", + description="Deprecated: use phoneNumber. Accepted as a length-1 list for one release; ignored when phoneNumber or id is set", + ), + ] = None + voice_language: Annotated[ + str | None, + Field( + alias="voiceLanguage", + description="TTS voice language/locale (default: en-US). See VoiceLanguage for supported values", + ), + ] = None + preferred_language: Annotated[ + str | None, + Field( + alias="preferredLanguage", + description="Preferred language for TTS and notifications (BCP-47, e.g. en-US, de-DE). Alias for voiceLanguage", + ), + ] = None + + class Tier(StrEnum): free = "FREE" starter = "STARTER" @@ -3286,6 +3750,27 @@ class PollChartBucketDto(BaseModel): ] +class PricingTier(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + name: Annotated[ + str, Field(description="Tier name, e.g. 'Free', 'Pro', 'Enterprise'") + ] + sla_percentage: Annotated[ + str | None, + Field( + alias="slaPercentage", + description="SLA percentage for this tier, e.g. '99.9%'", + ), + ] = None + price_from: Annotated[ + str | None, + Field( + alias="priceFrom", + description="Starting price, e.g. '$0', '$25/mo', 'Custom'", + ), + ] = None + + class Status6(StrEnum): investigating = "INVESTIGATING" identified = "IDENTIFIED" @@ -3930,6 +4415,27 @@ class ScheduledMaintenanceDto(BaseModel): ] +class ScriptMonitorConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + script: Annotated[ + str, + Field( + description="Playwright test script source code", + max_length=65536, + min_length=1, + ), + ] + timeout_seconds: Annotated[ + int | None, + Field( + alias="timeoutSeconds", + description="Maximum execution time in seconds (5–120)", + ge=5, + le=120, + ), + ] = None + + class SecretDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: Annotated[UUID, Field(description="Unique secret identifier")] @@ -3986,6 +4492,21 @@ class SeoMetadataDto(BaseModel): ] = None +class ServiceBreakdown(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + service: Annotated[str, Field(description="Sub-service name, e.g. 'EC2', 'S3'")] + sla_percentage: Annotated[ + str | None, + Field(alias="slaPercentage", description="SLA percentage for this sub-service"), + ] = None + scope: Annotated[ + str | None, Field(description="Scope qualifier, e.g. 'Region (Multi-AZ)'") + ] = None + notes: Annotated[ + str | None, Field(description="Additional notes on measurement or conditions") + ] = None + + class ServiceCatalogDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: UUID @@ -4006,6 +4527,13 @@ class ServiceCatalogDto(BaseModel): ] enabled: bool published: bool + sla_published: Annotated[ + bool, + Field( + alias="slaPublished", + description="Whether the service's SLA page is publicly visible", + ), + ] overall_status: Annotated[str | None, Field(alias="overallStatus")] = None created_at: Annotated[AwareDatetime, Field(alias="createdAt")] updated_at: Annotated[AwareDatetime, Field(alias="updatedAt")] @@ -4147,6 +4675,7 @@ class ServiceIncidentDto(BaseModel): vendor_created_at: Annotated[ AwareDatetime | None, Field(alias="vendorCreatedAt") ] = None + affected_regions: Annotated[list[str] | None, Field(alias="affectedRegions")] = None class ServiceIncidentUpdateDto(BaseModel): @@ -4388,6 +4917,13 @@ class SetAlertChannelsRequest(BaseModel): ] +class SetEnabledRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + enabled: Annotated[ + bool, Field(description="Whether the resource should be enabled") + ] + + class SetMonitorAuthRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) config: ApiKeyAuthConfig | BasicAuthConfig | BearerAuthConfig | HeaderAuthConfig @@ -4518,6 +5054,24 @@ class SingleValueResponseString(BaseModel): data: str +class Status7(StrEnum): + pending = "PENDING" + dispatching = "DISPATCHING" + delivered = "DELIVERED" + escalating = "ESCALATING" + acknowledged = "ACKNOWLEDGED" + completed = "COMPLETED" + + +class SkippedDispatch(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + id: Annotated[UUID, Field(description="Dispatch identifier")] + status: Annotated[Status7, Field(description="Current dispatch status")] + reason: Annotated[ + str, Field(description="Why this dispatch was skipped", min_length=1) + ] + + class SlackChannelConfig(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) channel_type: Annotated[Literal["slack"], Field(alias="channelType")] = "slack" @@ -4536,6 +5090,63 @@ class SlackChannelConfig(BaseModel): ] = None +class SmsChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["sms"], Field(alias="channelType")] = "sms" + phone_number: Annotated[ + str | None, + Field( + alias="phoneNumber", + description="Recipient phone number in E.164 format, e.g. +14155550123", + ), + ] = None + verified_phone_number_id: Annotated[ + int | None, + Field( + alias="verifiedPhoneNumberId", + description="Id of an org verified_phone_number row; alternative to phoneNumber", + ), + ] = None + phone_numbers: Annotated[ + list[str] | None, + Field( + alias="phoneNumbers", + description="Deprecated: use phoneNumber. Accepted as a length-1 list for one release; ignored when phoneNumber or id is set", + ), + ] = None + preferred_language: Annotated[ + str | None, + Field( + alias="preferredLanguage", + description="Preferred language for SMS body (BCP-47, e.g. en-US, de-DE). Default: en-US", + ), + ] = None + + +class SourceUrls(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + sla_page: Annotated[ + str | None, Field(alias="slaPage", description="URL to vendor's SLA page") + ] = None + pricing_page: Annotated[ + str | None, + Field(alias="pricingPage", description="URL to vendor's pricing page"), + ] = None + tos_page: Annotated[ + str | None, + Field(alias="tosPage", description="URL to vendor's Terms of Service"), + ] = None + status_page: Annotated[ + str | None, Field(alias="statusPage", description="URL to vendor's status page") + ] = None + all_slas_page: Annotated[ + str | None, + Field( + alias="allSlasPage", description="URL to vendor's all-services SLA listing" + ), + ] = None + + class SplunkOnCallChannelConfig(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) channel_type: Annotated[Literal["splunk_oncall"], Field(alias="channelType")] = ( @@ -4600,6 +5211,31 @@ class StatusCodeAssertion(BaseModel): ] +class StatusEventDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[ + UUID, + Field( + description="Stable row ID (incident/update/maintenance UUID or transition bucket key)" + ), + ] + type: Annotated[ + str, Field(description="Status event row type on the Dependencies Detail rail") + ] + at: Annotated[ + AwareDatetime, + Field( + description="Canonical timestamp used for reverse-chronological ordering" + ), + ] + incident: IncidentEventDto | None = None + maintenance: MaintenanceEventDto | None = None + component: ComponentTransitionEventDto | None = None + org_annotation: Annotated[ + OrgIncidentAnnotationDto | None, Field(alias="orgAnnotation") + ] = None + + class StatusPageBranding(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) logo_url: Annotated[ @@ -5188,6 +5824,24 @@ class TestMatchResult(BaseModel): ] +class TestMonitorNotificationsRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_ids: Annotated[ + list[UUID] | None, + Field( + alias="channelIds", + description="Channel IDs to test; null or empty tests all channels attached to the monitor", + ), + ] = None + include_resolved: Annotated[ + bool, + Field( + alias="includeResolved", + description="Whether to include a resolved notification in the test (default: false)", + ), + ] + + class TestNotificationPolicyRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) severity: Annotated[ @@ -5261,7 +5915,10 @@ class TimingPhasesDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) dns_ms: Annotated[ int | None, - Field(description="DNS resolution time in milliseconds", examples=[12]), + Field( + description="Legacy DNS phase; null for new checks (no longer measured)", + examples=[12], + ), ] = None tcp_ms: Annotated[ int | None, Field(description="TCP connect time in milliseconds", examples=[18]) @@ -5489,6 +6146,47 @@ class UpdateAssertionRequest(BaseModel): ] = None +class UpdateDatadogChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["datadog"], Field(alias="channelType")] = "datadog" + api_key: Annotated[ + str | None, Field(alias="apiKey", description="Datadog API key") + ] = None + site: Annotated[ + str | None, + Field( + description="Datadog site region (e.g. datadoghq.com, datadoghq.eu, us3.datadoghq.com)" + ), + ] = None + tags: Annotated[ + str | None, Field(description="Comma-separated tags to attach to events") + ] = None + + +class UpdateDiscordChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["discord"], Field(alias="channelType")] = "discord" + webhook_url: Annotated[ + str | None, Field(alias="webhookUrl", description="Discord webhook URL") + ] = None + mention_role_id: Annotated[ + str | None, + Field( + alias="mentionRoleId", + description="Optional Discord role ID to mention in notifications", + ), + ] = None + + +class UpdateEmailChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["email"], Field(alias="channelType")] = "email" + recipients: Annotated[ + list[EmailStr], + Field(description="Email addresses to send notifications to", min_length=1), + ] + + class UpdateEnvironmentRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) name: Annotated[ @@ -5512,35 +6210,166 @@ class UpdateEnvironmentRequest(BaseModel): ] = None -class UpdateIncidentPolicyRequest(BaseModel): +class UpdateGitLabChannelConfig(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) - trigger_rules: Annotated[ - list[TriggerRule], + channel_type: Annotated[Literal["gitlab"], Field(alias="channelType")] = "gitlab" + endpoint_url: Annotated[ + str, Field( - alias="triggerRules", - description="Array of trigger rules; at least one required", + alias="endpointUrl", + description="GitLab alert integration endpoint URL", min_length=1, ), ] - confirmation: ConfirmationPolicy - recovery: RecoveryPolicy + authorization_key: Annotated[ + str | None, + Field( + alias="authorizationKey", + description="Authorization key from GitLab alert integration settings", + ), + ] = None -class UpdateMaintenanceWindowRequest(BaseModel): +class UpdateGoogleChatChannelConfig(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) - monitor_id: Annotated[ - UUID | None, - Field( - alias="monitorId", - description="Monitor this window applies to; null switches the window to org-wide", - ), + channel_type: Annotated[Literal["google_chat"], Field(alias="channelType")] = ( + "google_chat" + ) + webhook_url: Annotated[ + str | None, + Field(alias="webhookUrl", description="Google Chat space webhook URL"), ] = None - starts_at: Annotated[ - AwareDatetime, - Field(alias="startsAt", description="Updated start time (ISO 8601)"), - ] - ends_at: Annotated[ - AwareDatetime, Field(alias="endsAt", description="Updated end time (ISO 8601)") + + +class UpdateIncidentIoChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["incident_io"], Field(alias="channelType")] = ( + "incident_io" + ) + api_key: Annotated[ + str | None, + Field( + alias="apiKey", + description="incident.io API key with 'Create incidents' permission", + ), + ] = None + severity_id: Annotated[ + str | None, + Field( + alias="severityId", + description="Severity ID for created incidents (from List Severities API)", + ), + ] = None + visibility: Annotated[ + str | None, + Field(description="Incident visibility: public or private (default: public)"), + ] = None + + +class UpdateIncidentPolicyRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + trigger_rules: Annotated[ + list[TriggerRule], + Field( + alias="triggerRules", + description="Array of trigger rules; at least one required", + min_length=1, + ), + ] + confirmation: ConfirmationPolicy + recovery: RecoveryPolicy + + +class Severity5(StrEnum): + down = "DOWN" + degraded = "DEGRADED" + maintenance = "MAINTENANCE" + + +class UpdateIncidentRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + title: Annotated[ + str | None, + Field( + description="New title; null preserves current (min 1 char if present)", + max_length=2147483647, + min_length=1, + ), + ] = None + severity: Annotated[ + Severity5 | None, + Field( + description="New severity: DOWN, DEGRADED, or MAINTENANCE; null preserves current" + ), + ] = None + + +class UpdateJiraChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["jira"], Field(alias="channelType")] = "jira" + domain: Annotated[ + str, + Field( + description="Atlassian instance domain (e.g. yourteam.atlassian.net)", + min_length=1, + ), + ] + email: Annotated[ + str, + Field( + description="Atlassian account email for API authentication", min_length=1 + ), + ] + api_token: Annotated[ + str | None, Field(alias="apiToken", description="Atlassian API token") + ] = None + project_key: Annotated[ + str, + Field( + alias="projectKey", + description="Jira project key where issues are created (e.g. OPS)", + min_length=1, + ), + ] + issue_type: Annotated[ + str | None, + Field( + alias="issueType", description="Issue type name (e.g. Bug, Task, Incident)" + ), + ] = None + + +class UpdateLinearChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["linear"], Field(alias="channelType")] = "linear" + api_key: Annotated[ + str | None, Field(alias="apiKey", description="Linear API key") + ] = None + team_id: Annotated[ + str, + Field(alias="teamId", description="Team ID to create issues in", min_length=1), + ] + label_id: Annotated[ + str | None, + Field(alias="labelId", description="Label ID to attach to created issues"), + ] = None + + +class UpdateMaintenanceWindowRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + monitor_id: Annotated[ + UUID | None, + Field( + alias="monitorId", + description="Monitor this window applies to; null switches the window to org-wide", + ), + ] = None + starts_at: Annotated[ + AwareDatetime, + Field(alias="startsAt", description="Updated start time (ISO 8601)"), + ] + ends_at: Annotated[ + AwareDatetime, Field(alias="endsAt", description="Updated end time (ISO 8601)") ] repeat_rule: Annotated[ str | None, @@ -5568,11 +6397,42 @@ class UpdateMaintenanceWindowRequest(BaseModel): ] = None +class UpdateMattermostChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["mattermost"], Field(alias="channelType")] = ( + "mattermost" + ) + webhook_url: Annotated[ + str | None, + Field(alias="webhookUrl", description="Mattermost incoming webhook URL"), + ] = None + channel: Annotated[ + str | None, Field(description="Override channel (if webhook allows)") + ] = None + icon_url: Annotated[ + str | None, Field(alias="iconUrl", description="Custom bot icon URL") + ] = None + + class UpdateMonitorAuthRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) config: ApiKeyAuthConfig | BasicAuthConfig | BearerAuthConfig | HeaderAuthConfig +class UpdateOpsGenieChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["opsgenie"], Field(alias="channelType")] = ( + "opsgenie" + ) + api_key: Annotated[ + str | None, + Field(alias="apiKey", description="OpsGenie API key for alert creation"), + ] = None + region: Annotated[ + str | None, Field(description="OpsGenie API region: us or eu") + ] = None + + class UpdateOrgDetailsRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) name: Annotated[ @@ -5614,6 +6474,102 @@ class UpdateOrgDetailsRequest(BaseModel): ] = None +class UpdatePagerDutyChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["pagerduty"], Field(alias="channelType")] = ( + "pagerduty" + ) + routing_key: Annotated[ + str | None, + Field( + alias="routingKey", + description="PagerDuty Events API v2 routing (integration) key", + ), + ] = None + severity_override: Annotated[ + str | None, + Field( + alias="severityOverride", description="Override PagerDuty severity mapping" + ), + ] = None + + +class UpdatePhoneCallChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["phone_call"], Field(alias="channelType")] = ( + "phone_call" + ) + phone_number: Annotated[ + str | None, + Field( + alias="phoneNumber", + description="Recipient phone number in E.164 format; null preserves current", + ), + ] = None + verified_phone_number_id: Annotated[ + int | None, + Field( + alias="verifiedPhoneNumberId", + description="Id of an org verified_phone_number row; null preserves current when phoneNumber also null", + ), + ] = None + phone_numbers: Annotated[ + list[str] | None, + Field(alias="phoneNumbers", description="Deprecated: use phoneNumber"), + ] = None + voice_language: Annotated[ + str | None, + Field( + alias="voiceLanguage", + description="TTS voice language/locale (default: en-US). See VoiceLanguage for supported values", + ), + ] = None + preferred_language: Annotated[ + str | None, + Field( + alias="preferredLanguage", + description="Preferred language for TTS and notifications (BCP-47, e.g. en-US, de-DE). Alias for voiceLanguage", + ), + ] = None + + +class UpdatePushbulletChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["pushbullet"], Field(alias="channelType")] = ( + "pushbullet" + ) + access_token: Annotated[ + str | None, Field(alias="accessToken", description="Pushbullet access token") + ] = None + device_iden: Annotated[ + str | None, + Field( + alias="deviceIden", + description="Target device identifier (broadcasts to all if empty)", + ), + ] = None + + +class UpdatePushoverChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["pushover"], Field(alias="channelType")] = ( + "pushover" + ) + user_key: Annotated[ + str | None, Field(alias="userKey", description="Pushover user or group key") + ] = None + app_token: Annotated[ + str | None, + Field(alias="appToken", description="Pushover application API token"), + ] = None + priority: Annotated[ + str | None, Field(description="Notification priority override (-2 to 2)") + ] = None + sound: Annotated[str | None, Field(description="Notification sound override")] = ( + None + ) + + class UpdateResourceGroupRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) name: Annotated[ @@ -5718,6 +6674,21 @@ class UpdateResourceGroupRequest(BaseModel): ] = None +class UpdateRootlyChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["rootly"], Field(alias="channelType")] = "rootly" + api_key: Annotated[ + str | None, + Field( + alias="apiKey", + description="Rootly API token with incident creation permission", + ), + ] = None + severity: Annotated[ + str | None, Field(description="Severity slug override (e.g. sev0, sev1)") + ] = None + + class UpdateSecretRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) value: Annotated[ @@ -5730,6 +6701,69 @@ class UpdateSecretRequest(BaseModel): ] +class UpdateSlackChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["slack"], Field(alias="channelType")] = "slack" + webhook_url: Annotated[ + str | None, Field(alias="webhookUrl", description="Slack incoming webhook URL") + ] = None + mention_text: Annotated[ + str | None, + Field( + alias="mentionText", + description="Optional mention text included in notifications, e.g. @channel", + ), + ] = None + + +class UpdateSmsChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["sms"], Field(alias="channelType")] = "sms" + phone_number: Annotated[ + str | None, + Field( + alias="phoneNumber", + description="Recipient phone number in E.164 format; null preserves current", + ), + ] = None + verified_phone_number_id: Annotated[ + int | None, + Field( + alias="verifiedPhoneNumberId", + description="Id of an org verified_phone_number row; null preserves current when phoneNumber also null", + ), + ] = None + phone_numbers: Annotated[ + list[str] | None, + Field(alias="phoneNumbers", description="Deprecated: use phoneNumber"), + ] = None + preferred_language: Annotated[ + str | None, + Field( + alias="preferredLanguage", + description="Preferred language for SMS body (BCP-47, e.g. en-US, de-DE). Default: en-US", + ), + ] = None + + +class UpdateSplunkOnCallChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["splunk_oncall"], Field(alias="channelType")] = ( + "splunk_oncall" + ) + api_key: Annotated[ + str | None, Field(alias="apiKey", description="Splunk On-Call REST API key") + ] = None + routing_key: Annotated[ + str, + Field( + alias="routingKey", + description="Routing key for alert routing", + min_length=1, + ), + ] + + class UpdateStatusPageComponentGroupRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) name: Annotated[ @@ -5826,6 +6860,13 @@ class UpdateStatusPageComponentRequest(BaseModel): ] = None +class Status8(StrEnum): + investigating = "INVESTIGATING" + identified = "IDENTIFIED" + monitoring = "MONITORING" + resolved = "RESOLVED" + + class UpdateStatusPageIncidentRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) title: Annotated[ @@ -5837,7 +6878,7 @@ class UpdateStatusPageIncidentRequest(BaseModel): ), ] = None status: Annotated[ - Status6 | None, Field(description="New status; null preserves current") + Status8 | None, Field(description="New status; null preserves current") ] = None impact: Annotated[ Impact | None, Field(description="New impact level; null preserves current") @@ -5916,8 +6957,59 @@ class UpdateTagRequest(BaseModel): color: Annotated[ str | None, Field( - description="New hex color code", - pattern="^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$", + description="New hex color code", + pattern="^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$", + ), + ] = None + + +class UpdateTeamsChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["teams"], Field(alias="channelType")] = "teams" + webhook_url: Annotated[ + str | None, + Field(alias="webhookUrl", description="Microsoft Teams incoming webhook URL"), + ] = None + + +class UpdateTelegramChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["telegram"], Field(alias="channelType")] = ( + "telegram" + ) + bot_token: Annotated[ + str | None, + Field(alias="botToken", description="Telegram bot token from @BotFather"), + ] = None + chat_id: Annotated[ + str, + Field( + alias="chatId", + description="Chat, group, or channel ID to send alerts to", + min_length=1, + ), + ] + + +class UpdateWebhookChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["webhook"], Field(alias="channelType")] = "webhook" + url: Annotated[ + str | None, + Field(description="Webhook endpoint URL that receives alert payloads"), + ] = None + signing_secret: Annotated[ + str | None, + Field( + alias="signingSecret", + description="HMAC secret for X-DevHelm-Signature header; omit for unsigned delivery", + ), + ] = None + custom_headers: Annotated[ + dict[str, str] | None, + Field( + alias="customHeaders", + description="Additional HTTP headers to include in webhook requests", ), ] = None @@ -5960,6 +7052,15 @@ class UpdateWorkspaceRequest(BaseModel): ] +class UpdateZapierChannelConfig(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + channel_type: Annotated[Literal["zapier"], Field(alias="channelType")] = "zapier" + webhook_url: Annotated[ + str | None, + Field(alias="webhookUrl", description="Zapier/n8n/Make catch webhook URL"), + ] = None + + class UptimeBucketDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) timestamp: Annotated[ @@ -6029,6 +7130,32 @@ class UptimeDto(BaseModel): examples=[312], ), ] = None + p50_latency_ms: Annotated[ + float | None, + Field( + alias="p50LatencyMs", + description="50th-percentile (median) latency in milliseconds; null when no data", + examples=[128], + ), + ] = None + incident_count: Annotated[ + int, + Field( + alias="incidentCount", + description="Number of incidents that started within the requested window", + examples=[2], + ), + ] + + +class VoiceLanguageDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + code: Annotated[ + str, Field(description="BCP-47 locale code, e.g. en-US", min_length=1) + ] + label: Annotated[ + str, Field(description="Human-readable label, e.g. English (US)", min_length=1) + ] class WebhookChannelConfig(BaseModel): @@ -6045,7 +7172,7 @@ class WebhookChannelConfig(BaseModel): str | None, Field( alias="signingSecret", - description="Optional HMAC signing secret for payload verification", + description="HMAC secret for X-DevHelm-Signature header; omit for unsigned delivery", ), ] = None custom_headers: Annotated[ @@ -6201,6 +7328,20 @@ class ZapierChannelConfig(BaseModel): ] +class AcknowledgeAllIncidentsResponse(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + acknowledged: Annotated[ + list[NotificationDispatchDto], + Field(description="Dispatches successfully acknowledged in this request"), + ] + skipped: Annotated[ + list[SkippedDispatch], + Field( + description="Dispatches skipped (already acked or not in an acknowledgeable state)" + ), + ] + + class AddMonitorTagsRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) tag_ids: Annotated[ @@ -6278,6 +7419,40 @@ class BulkMonitorActionResult(BaseModel): ] +class Code(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + check_type: Literal["code"] = "code" + exit_code: Annotated[ + int, Field(alias="exitCode", description="Container exit code (0 = pass)") + ] + stdout_snippet: Annotated[ + str | None, + Field(alias="stdoutSnippet", description="Truncated stdout from the container"), + ] = None + stderr_snippet: Annotated[ + str | None, + Field(alias="stderrSnippet", description="Truncated stderr from the container"), + ] = None + steps: Annotated[ + list[CodeCheckStep] | None, + Field(description="Named steps extracted from Playwright test output"), + ] = None + failure_kind: Annotated[ + str | None, + Field( + alias="failureKind", + description="Failure classification: timeout, assertion, or error", + ), + ] = None + timed_out: Annotated[ + bool | None, + Field( + alias="timedOut", + description="Whether the run hit a step/total/run-budget timeout", + ), + ] = None + + class ComponentUptimeDayDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) date: Annotated[ @@ -6342,10 +7517,12 @@ class CreateAlertChannelRequest(BaseModel): | MattermostChannelConfig | OpsGenieChannelConfig | PagerDutyChannelConfig + | PhoneCallChannelConfig | PushbulletChannelConfig | PushoverChannelConfig | RootlyChannelConfig | SlackChannelConfig + | SmsChannelConfig | SplunkOnCallChannelConfig | TeamsChannelConfig | TelegramChannelConfig @@ -6434,6 +7611,7 @@ class CreateMonitorRequest(BaseModel): | HttpMonitorConfig | IcmpMonitorConfig | McpServerMonitorConfig + | ScriptMonitorConfig | TcpMonitorConfig ) frequency_seconds: Annotated[ @@ -6640,6 +7818,36 @@ class CreateStatusPageRequest(BaseModel): ] = None +class CreditPolicy(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + summary: Annotated[ + str | None, Field(description="Brief summary of credit policy") + ] = None + max_credit_percent: Annotated[ + int | None, + Field( + alias="maxCreditPercent", description="Max credit as percent of monthly fee" + ), + ] = None + claim_window_days: Annotated[ + int | None, + Field( + alias="claimWindowDays", + description="Days to submit a credit claim after eligibility", + ), + ] = None + credit_application_days: Annotated[ + int | None, + Field( + alias="creditApplicationDays", + description="Days for credit to be applied after approval", + ), + ] = None + tiers: Annotated[ + list[CreditTier] | None, Field(description="Credit tiers by uptime threshold") + ] = None + + class CursorPageServiceCatalogDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: Annotated[list[ServiceCatalogDto], Field(description="Items on this page")] @@ -6676,6 +7884,24 @@ class CursorPageServicePollResultDto(BaseModel): ] +class CursorPageStatusEventDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: Annotated[list[StatusEventDto], 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 DashboardOverviewDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) monitors: MonitorsSummaryDto @@ -6784,6 +8010,7 @@ class IncidentDetailDto(BaseModel): status_page_incidents: Annotated[ list[LinkedStatusPageIncidentDto] | None, Field(alias="statusPageIncidents") ] = None + trigger: IncidentTriggerDto | None = None class IncidentPolicyDto(BaseModel): @@ -7004,9 +8231,6 @@ class MonitorDto(BaseModel): """Note: ``currentStatus`` was removed from this DTO. Inspect ``enabled`` and the incident-policy API to derive a live status for a monitor instead.""" model_config = ConfigDict(extra="ignore", populate_by_name=True) - """Note: ``currentStatus`` was removed from this DTO. Inspect ``enabled`` and the incident-policy API to derive a live status for a monitor instead.""" - - model_config = ConfigDict(extra="forbid", populate_by_name=True) id: Annotated[UUID, Field(description="Unique monitor identifier")] organization_id: Annotated[ int, @@ -7024,6 +8248,7 @@ class MonitorDto(BaseModel): | HttpMonitorConfig | IcmpMonitorConfig | McpServerMonitorConfig + | ScriptMonitorConfig | TcpMonitorConfig ) frequency_seconds: Annotated[ @@ -7100,6 +8325,7 @@ class MonitorTestRequest(BaseModel): | HttpMonitorConfig | IcmpMonitorConfig | McpServerMonitorConfig + | ScriptMonitorConfig | TcpMonitorConfig ) assertions: Annotated[ @@ -7287,48 +8513,6 @@ class ResourceGroupDto(BaseModel): ] -class ServiceDetailDto(BaseModel): - model_config = ConfigDict(extra="ignore", populate_by_name=True) - id: UUID - slug: str - name: str - category: str | None = None - official_status_url: Annotated[str | None, Field(alias="officialStatusUrl")] = None - developer_context: Annotated[str | None, Field(alias="developerContext")] = None - logo_url: Annotated[str | None, Field(alias="logoUrl")] = None - adapter_type: Annotated[str, Field(alias="adapterType")] - polling_interval_seconds: Annotated[int, Field(alias="pollingIntervalSeconds")] - lifecycle_status: Annotated[ - str, - Field( - alias="lifecycleStatus", - description="Service lifecycle state: ACTIVE, DEGRADED, DEPRECATED, or RETIRED", - ), - ] - enabled: bool - created_at: Annotated[AwareDatetime, Field(alias="createdAt")] - updated_at: Annotated[AwareDatetime, Field(alias="updatedAt")] - current_status: Annotated[ServiceStatusDto | None, Field(alias="currentStatus")] = ( - None - ) - recent_incidents: Annotated[ - list[ServiceIncidentDto], Field(alias="recentIncidents") - ] - components: list[ServiceComponentDto] - components_summary: Annotated[ - ComponentsSummaryDto | None, Field(alias="componentsSummary") - ] = None - uptime: ComponentUptimeSummaryDto | None = None - active_maintenances: Annotated[ - list[ScheduledMaintenanceDto], Field(alias="activeMaintenances") - ] - data_completeness: Annotated[str, Field(alias="dataCompleteness")] - seo_metadata: Annotated[SeoMetadataDto | None, Field(alias="seoMetadata")] = None - related_services: Annotated[ - list[ServiceCatalogDto] | None, Field(alias="relatedServices") - ] = None - - class ServiceIncidentDetailDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: UUID @@ -7342,6 +8526,7 @@ class ServiceIncidentDetailDto(BaseModel): affected_components: Annotated[ list[str] | None, Field(alias="affectedComponents") ] = None + affected_regions: Annotated[list[str] | None, Field(alias="affectedRegions")] = None updates: list[ServiceIncidentUpdateDto] @@ -7372,6 +8557,11 @@ class ServiceUptimeResponse(BaseModel): ] = None +class SingleValueResponseAcknowledgeAllIncidentsResponse(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: AcknowledgeAllIncidentsResponse + + class SingleValueResponseAuthMeResponse(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: AuthMeResponse @@ -7432,11 +8622,6 @@ class SingleValueResponseResourceGroupDto(BaseModel): data: ResourceGroupDto -class SingleValueResponseServiceDetailDto(BaseModel): - model_config = ConfigDict(extra="ignore", populate_by_name=True) - data: ServiceDetailDto - - class SingleValueResponseServiceIncidentDetailDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: ServiceIncidentDetailDto @@ -7512,6 +8697,48 @@ class SingleValueResponseWorkspaceDto(BaseModel): data: WorkspaceDto +class SlaDataDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + sla_type: Annotated[ + str | None, + Field( + alias="slaType", + description="SLA pattern: plan_gated, per_service, no_public_sla, or universal", + ), + ] = None + official_sla: Annotated[OfficialSla | None, Field(alias="officialSla")] = None + service_breakdown: Annotated[ + list[ServiceBreakdown] | None, + Field( + alias="serviceBreakdown", + description="Per-service breakdown for vendors with per_service SLA type", + ), + ] = None + pricing_tiers: Annotated[ + list[PricingTier] | None, + Field( + alias="pricingTiers", description="Pricing tiers with associated SLA levels" + ), + ] = None + credit_policy: Annotated[CreditPolicy | None, Field(alias="creditPolicy")] = None + no_sla_context: Annotated[NoSlaContext | None, Field(alias="noSlaContext")] = None + source_urls: Annotated[SourceUrls | None, Field(alias="sourceUrls")] = None + last_researched: Annotated[ + str | None, + Field( + alias="lastResearched", + description="ISO date when this data was last manually researched", + ), + ] = None + research_notes: Annotated[ + str | None, + Field( + alias="researchNotes", + description="Freeform operator notes about the research", + ), + ] = None + + class StatusPageIncidentDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: UUID @@ -7621,6 +8848,24 @@ class TableValueResultTagDto(BaseModel): total_pages: Annotated[int | None, Field(alias="totalPages")] = None +class TableValueResultTestChannelResult(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: list[TestChannelResult] + has_next: Annotated[bool, Field(alias="hasNext")] + 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 + + +class TableValueResultVoiceLanguageDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: list[VoiceLanguageDto] + has_next: Annotated[bool, Field(alias="hasNext")] + 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 + + class TableValueResultWebhookDeliveryDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: list[WebhookDeliveryDto] @@ -7662,10 +8907,12 @@ class TestAlertChannelRequest(BaseModel): | MattermostChannelConfig | OpsGenieChannelConfig | PagerDutyChannelConfig + | PhoneCallChannelConfig | PushbulletChannelConfig | PushoverChannelConfig | RootlyChannelConfig | SlackChannelConfig + | SmsChannelConfig | SplunkOnCallChannelConfig | TeamsChannelConfig | TelegramChannelConfig @@ -7686,26 +8933,28 @@ class UpdateAlertChannelRequest(BaseModel): ), ] config: Annotated[ - DatadogChannelConfig - | DiscordChannelConfig - | EmailChannelConfig - | GitLabChannelConfig - | GoogleChatChannelConfig - | IncidentIoChannelConfig - | JiraChannelConfig - | LinearChannelConfig - | MattermostChannelConfig - | OpsGenieChannelConfig - | PagerDutyChannelConfig - | PushbulletChannelConfig - | PushoverChannelConfig - | RootlyChannelConfig - | SlackChannelConfig - | SplunkOnCallChannelConfig - | TeamsChannelConfig - | TelegramChannelConfig - | WebhookChannelConfig - | ZapierChannelConfig, + UpdateDatadogChannelConfig + | UpdateDiscordChannelConfig + | UpdateEmailChannelConfig + | UpdateGitLabChannelConfig + | UpdateGoogleChatChannelConfig + | UpdateIncidentIoChannelConfig + | UpdateJiraChannelConfig + | UpdateLinearChannelConfig + | UpdateMattermostChannelConfig + | UpdateOpsGenieChannelConfig + | UpdatePagerDutyChannelConfig + | UpdatePhoneCallChannelConfig + | UpdatePushbulletChannelConfig + | UpdatePushoverChannelConfig + | UpdateRootlyChannelConfig + | UpdateSlackChannelConfig + | UpdateSmsChannelConfig + | UpdateSplunkOnCallChannelConfig + | UpdateTeamsChannelConfig + | UpdateTelegramChannelConfig + | UpdateWebhookChannelConfig + | UpdateZapierChannelConfig, Field(discriminator="channel_type"), ] managed_by: Annotated[ @@ -7715,6 +8964,12 @@ class UpdateAlertChannelRequest(BaseModel): description="New attribution source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value.", ), ] = None + enabled: Annotated[ + bool | None, + Field( + description="Whether this channel is enabled (default: true); null preserves current value" + ), + ] = None class UpdateMonitorRequest(BaseModel): @@ -7733,6 +8988,7 @@ class UpdateMonitorRequest(BaseModel): | HttpMonitorConfig | IcmpMonitorConfig | McpServerMonitorConfig + | ScriptMonitorConfig | TcpMonitorConfig | None ) = None @@ -7906,9 +9162,9 @@ class CheckTraceDto(BaseModel): ] = None -class CheckTypeDetailsDto(RootModel[Http | Tcp | Icmp | Dns | McpServer]): +class CheckTypeDetailsDto(RootModel[Http | Tcp | Icmp | Dns | McpServer | Code]): root: Annotated[ - Http | Tcp | Icmp | Dns | McpServer, + Http | Tcp | Icmp | Dns | McpServer | Code, Field( description="Check-type-specific details — polymorphic by check_type discriminator", discriminator="check_type", @@ -7945,6 +9201,56 @@ class CreateNotificationPolicyRequest(BaseModel): ] = 0 +class ServiceDetailDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: UUID + slug: str + name: str + category: str | None = None + official_status_url: Annotated[str | None, Field(alias="officialStatusUrl")] = None + developer_context: Annotated[str | None, Field(alias="developerContext")] = None + logo_url: Annotated[str | None, Field(alias="logoUrl")] = None + adapter_type: Annotated[str, Field(alias="adapterType")] + polling_interval_seconds: Annotated[int, Field(alias="pollingIntervalSeconds")] + lifecycle_status: Annotated[ + str, + Field( + alias="lifecycleStatus", + description="Service lifecycle state: ACTIVE, DEGRADED, DEPRECATED, or RETIRED", + ), + ] + enabled: bool + created_at: Annotated[AwareDatetime, Field(alias="createdAt")] + updated_at: Annotated[AwareDatetime, Field(alias="updatedAt")] + current_status: Annotated[ServiceStatusDto | None, Field(alias="currentStatus")] = ( + None + ) + recent_incidents: Annotated[ + list[ServiceIncidentDto], Field(alias="recentIncidents") + ] + components: list[ServiceComponentDto] + components_summary: Annotated[ + ComponentsSummaryDto | None, Field(alias="componentsSummary") + ] = None + uptime: ComponentUptimeSummaryDto | None = None + active_maintenances: Annotated[ + list[ScheduledMaintenanceDto], Field(alias="activeMaintenances") + ] + data_completeness: Annotated[str, Field(alias="dataCompleteness")] + sla_published: Annotated[ + bool, + Field( + alias="slaPublished", + description="Whether the service's SLA page is publicly visible", + ), + ] + seo_metadata: Annotated[SeoMetadataDto | None, Field(alias="seoMetadata")] = None + sla_data: Annotated[SlaDataDto | None, Field(alias="slaData")] = None + related_services: Annotated[ + list[ServiceCatalogDto] | None, Field(alias="relatedServices") + ] = None + + class SingleValueResponseBatchComponentUptimeDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: BatchComponentUptimeDto @@ -7955,6 +9261,11 @@ class SingleValueResponseCheckTraceDto(BaseModel): data: CheckTraceDto +class SingleValueResponseServiceDetailDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: ServiceDetailDto + + class SingleValueResponseStatusPageIncidentDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: StatusPageIncidentDto