diff --git a/docs/openapi/monitoring-api.json b/docs/openapi/monitoring-api.json index 146f30f..6c75f54 100644 --- a/docs/openapi/monitoring-api.json +++ b/docs/openapi/monitoring-api.json @@ -38,6 +38,10 @@ "name": "API Keys", "description": "Organization API key management" }, + { + "name": "Artifacts", + "description": "Run evidence file content" + }, { "name": "Audit Log", "description": "Organization audit trail" @@ -50,6 +54,10 @@ "name": "Dashboard", "description": "Overview dashboard aggregates" }, + { + "name": "Definitions", + "description": "Code-monitor definition catalog and revisions" + }, { "name": "Deploy Lock", "description": "Mutex for CLI deploy operations" @@ -102,6 +110,22 @@ "name": "Monitor Auth", "description": "Manage authentication configuration for a monitor" }, + { + "name": "Monitor definitions", + "description": "Publish, rollback, and revision history for code monitors" + }, + { + "name": "Monitor Runs", + "description": "Per-monitor code run history and run-now" + }, + { + "name": "Monitor secret requests", + "description": "Secret keys a monitor requires and how they are fulfilled" + }, + { + "name": "Monitor session", + "description": "Cached sign-in session for a monitor" + }, { "name": "Monitors", "description": "Monitor CRUD and lifecycle management" @@ -126,6 +150,14 @@ "name": "Resource Groups", "description": "Resource group CRUD and member management" }, + { + "name": "Revisions", + "description": "Definition revision packages" + }, + { + "name": "Runs", + "description": "Code-monitor run list, snapshot, cases, events, and cancel" + }, { "name": "Secrets", "description": "Organization environment secret management" @@ -2123,13 +2155,122 @@ } } }, + "/api/v1/artifacts/{id}/content": { + "get": { + "tags": [ + "Artifacts" + ], + "summary": "Redirect to signed artifact download", + "description": "Returns 302 Location with a signed GET URL. 410 after the 14-day file clock.", + "operationId": "getArtifactContent", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "302": { + "description": "Signed download Location" + }, + "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" + } + } + } + }, + "410": { + "description": "Artifact bytes expired" + }, + "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/audit-log": { "get": { "tags": [ "Audit Log" ], "summary": "List audit events for the current organization", - "operationId": "list_20", + "operationId": "list_22", "parameters": [ { "name": "action", @@ -2606,21 +2747,20 @@ } } }, - "/api/v1/deploy/lock": { + "/api/v1/definitions": { "get": { "tags": [ - "Deploy Lock" + "Definitions" ], - "summary": "Get current deploy lock", - "description": "Returns the active deploy lock for the current workspace, if any.", - "operationId": "current", + "summary": "List definitions", + "operationId": "list_21", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseDeployLockDto" + "$ref": "#/components/schemas/TableValueResultDefinitionDto" } } } @@ -2706,31 +2846,145 @@ } } } - }, - "post": { + } + }, + "/api/v1/definitions/{id}": { + "get": { "tags": [ - "Deploy Lock" + "Definitions" ], - "summary": "Acquire deploy lock", - "description": "Acquires an exclusive deploy lock for the current workspace. Returns 409 Conflict if the workspace is already locked by another session.", - "operationId": "acquire", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AcquireDeployLockRequest" + "summary": "Get definition with Heads", + "operationId": "get_13", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseDefinitionDetailDto" + } } } }, - "required": true - }, + "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/definitions/{id}/revisions": { + "get": { + "tags": [ + "Definitions" + ], + "summary": "List all revisions for a definition", + "operationId": "listRevisions_1", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseDeployLockDto" + "$ref": "#/components/schemas/TableValueResultRevisionDto" } } } @@ -2818,28 +3072,134 @@ } } }, - "/api/v1/deploy/lock/{lockId}": { - "delete": { + "/api/v1/deploy/lock": { + "get": { "tags": [ "Deploy Lock" ], - "summary": "Release deploy lock", - "description": "Releases a deploy lock by ID. Only the lock holder should call this.", - "operationId": "release", - "parameters": [ - { - "name": "lockId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" + "summary": "Get current deploy lock", + "description": "Returns the active deploy lock for the current workspace, if any.", + "operationId": "current", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseDeployLockDto" + } + } + } + }, + "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": [ + "Deploy Lock" ], + "summary": "Acquire deploy lock", + "description": "Acquires an exclusive deploy lock for the current workspace. Returns 409 Conflict if the workspace is already locked by another session.", + "operationId": "acquire", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AcquireDeployLockRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseDeployLockDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -2924,14 +3284,25 @@ } } }, - "/api/v1/deploy/lock/force": { + "/api/v1/deploy/lock/{lockId}": { "delete": { "tags": [ "Deploy Lock" ], - "summary": "Force-release deploy lock", - "description": "Forcibly removes any deploy lock on the current workspace. Use to break stale locks.", - "operationId": "forceRelease", + "summary": "Release deploy lock", + "description": "Releases a deploy lock by ID. Only the lock holder should call this.", + "operationId": "release", + "parameters": [ + { + "name": "lockId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], "responses": { "204": { "description": "No Content" @@ -3019,23 +3390,17 @@ } } }, - "/api/v1/environments": { - "get": { + "/api/v1/deploy/lock/force": { + "delete": { "tags": [ - "Environments" + "Deploy Lock" ], - "summary": "List environments", - "operationId": "list_12", + "summary": "Force-release deploy lock", + "description": "Forcibly removes any deploy lock on the current workspace. Use to break stale locks.", + "operationId": "forceRelease", "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultEnvironmentDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -3118,30 +3483,22 @@ } } } - }, - "post": { + } + }, + "/api/v1/environments": { + "get": { "tags": [ "Environments" ], - "summary": "Create environment", - "operationId": "create_13", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateEnvironmentRequest" - } - } - }, - "required": true - }, + "summary": "List environments", + "operationId": "list_12", "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseEnvironmentDto" + "$ref": "#/components/schemas/TableValueResultEnvironmentDto" } } } @@ -3227,28 +3584,26 @@ } } } - } - }, - "/api/v1/environments/{slug}": { - "get": { + }, + "post": { "tags": [ "Environments" ], - "summary": "Get environment by slug", - "operationId": "get_7", - "parameters": [ - { - "name": "slug", - "in": "path", - "required": true, - "schema": { - "type": "string" + "summary": "Create environment", + "operationId": "create_13", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateEnvironmentRequest" + } } - } - ], + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { @@ -3338,13 +3693,15 @@ } } } - }, - "put": { + } + }, + "/api/v1/environments/{slug}": { + "get": { "tags": [ "Environments" ], - "summary": "Update environment", - "operationId": "update_13", + "summary": "Get environment by slug", + "operationId": "get_7", "parameters": [ { "name": "slug", @@ -3355,16 +3712,6 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateEnvironmentRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", @@ -3458,12 +3805,12 @@ } } }, - "delete": { + "put": { "tags": [ "Environments" ], - "summary": "Delete environment", - "operationId": "delete_9", + "summary": "Update environment", + "operationId": "update_13", "parameters": [ { "name": "slug", @@ -3474,9 +3821,26 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateEnvironmentRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseEnvironmentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -3559,37 +3923,26 @@ } } } - } - }, - "/api/v1/forensics/incidents/{id}/timeline": { - "get": { + }, + "delete": { "tags": [ - "Forensics" + "Environments" ], - "summary": "Full forensic timeline for an incident", - "description": "Returns every state-machine transition for this incident plus the rule evaluations that caused each transition, plus the policy snapshot that triggered confirmation. Correlate evaluations to transitions via evaluation.triggeringTransitionId == transition.id.", - "operationId": "getTimeline", + "summary": "Delete environment", + "operationId": "delete_9", "parameters": [ { - "name": "id", + "name": "slug", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentTimelineDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -3674,14 +4027,14 @@ } } }, - "/api/v1/forensics/monitors/{id}/rule-evaluations": { + "/api/v1/forensics/incidents/{id}/timeline": { "get": { "tags": [ "Forensics" ], - "summary": "Paged list of rule evaluations for a monitor", - "description": "Filter by ruleType (e.g. consecutive_failures), region, onlyMatched=true to narrow to firing evaluations. Time window defaults to the last 7 days when from/to are omitted; windows wider than 30 days are clamped.", - "operationId": "listMonitorRuleEvaluations", + "summary": "Full forensic timeline for an incident", + "description": "Returns every state-machine transition for this incident plus the rule evaluations that caused each transition, plus the policy snapshot that triggered confirmation. Correlate evaluations to transitions via evaluation.triggeringTransitionId == transition.id.", + "operationId": "getTimeline", "parameters": [ { "name": "id", @@ -3691,56 +4044,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "ruleType", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "region", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "onlyMatched", - "in": "query", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "from", - "in": "query", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "pageable", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/Pageable" - } } ], "responses": { @@ -3749,7 +4052,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultRuleEvaluationDto" + "$ref": "#/components/schemas/SingleValueResponseIncidentTimelineDto" } } } @@ -3837,14 +4140,14 @@ } } }, - "/api/v1/forensics/monitors/{id}/transitions": { + "/api/v1/forensics/monitors/{id}/rule-evaluations": { "get": { "tags": [ "Forensics" ], - "summary": "Paged list of state transitions for a monitor", - "description": "Time window defaults to the last 30 days when from/to are omitted; windows wider than 90 days are clamped.", - "operationId": "listMonitorTransitions", + "summary": "Paged list of rule evaluations for a monitor", + "description": "Filter by ruleType (e.g. consecutive_failures), region, onlyMatched=true to narrow to firing evaluations. Time window defaults to the last 7 days when from/to are omitted; windows wider than 30 days are clamped.", + "operationId": "listMonitorRuleEvaluations", "parameters": [ { "name": "id", @@ -3855,6 +4158,30 @@ "format": "uuid" } }, + { + "name": "ruleType", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "region", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "onlyMatched", + "in": "query", + "required": false, + "schema": { + "type": "boolean" + } + }, { "name": "from", "in": "query", @@ -3888,7 +4215,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultIncidentStateTransitionDto" + "$ref": "#/components/schemas/TableValueResultRuleEvaluationDto" } } } @@ -3976,134 +4303,48 @@ } } }, - "/api/v1/forensics/policy-snapshots/{hashHex}": { + "/api/v1/forensics/monitors/{id}/transitions": { "get": { "tags": [ "Forensics" ], - "summary": "Fetch a policy snapshot by its content hash", - "description": "Hash is SHA-256 over canonical policy JSON, hex-encoded. Access is gated: caller's org must have evaluated against this hash at least once.", - "operationId": "getPolicySnapshot", + "summary": "Paged list of state transitions for a monitor", + "description": "Time window defaults to the last 30 days when from/to are omitted; windows wider than 90 days are clamped.", + "operationId": "listMonitorTransitions", "parameters": [ { - "name": "hashHex", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponsePolicySnapshotDto" - } - } - } - }, - "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": "uuid" } }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + { + "name": "from", + "in": "query", + "required": false, + "schema": { + "type": "string", + "format": "date-time" } }, - "502": { - "description": "Bad gateway — an upstream provider returned an error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + { + "name": "to", + "in": "query", + "required": false, + "schema": { + "type": "string", + "format": "date-time" } }, - "503": { - "description": "Service unavailable — try again shortly", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v1/forensics/traces/{checkId}": { - "get": { - "tags": [ - "Forensics" - ], - "summary": "Replay a single check execution", - "description": "Returns every rule evaluation and state transition emitted for this scheduler-minted check_id (V92), plus the policy snapshot that governed them.", - "operationId": "getTrace", - "parameters": [ { - "name": "checkId", - "in": "path", + "name": "pageable", + "in": "query", "required": true, "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/Pageable" } } ], @@ -4113,7 +4354,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseCheckTraceDto" + "$ref": "#/components/schemas/TableValueResultIncidentStateTransitionDto" } } } @@ -4201,19 +4442,18 @@ } } }, - "/api/v1/heartbeat/{token}": { + "/api/v1/forensics/policy-snapshots/{hashHex}": { "get": { "tags": [ - "Heartbeat" + "Forensics" ], - "summary": "Record a heartbeat ping (GET)", - "description": "Called by external systems (cron jobs, scheduled tasks) to signal liveness. Always returns 200 OK.", - "operationId": "pingGet", + "summary": "Fetch a policy snapshot by its content hash", + "description": "Hash is SHA-256 over canonical policy JSON, hex-encoded. Access is gated: caller's org must have evaluated against this hash at least once.", + "operationId": "getPolicySnapshot", "parameters": [ { - "name": "token", + "name": "hashHex", "in": "path", - "description": "Ping endpoint token for the heartbeat monitor", "required": true, "schema": { "type": "string" @@ -4226,7 +4466,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/HeartbeatPingResponse" + "$ref": "#/components/schemas/SingleValueResponsePolicySnapshotDto" } } } @@ -4312,51 +4552,34 @@ } } } - }, - "post": { + } + }, + "/api/v1/forensics/traces/{checkId}": { + "get": { "tags": [ - "Heartbeat" + "Forensics" ], - "summary": "Record a heartbeat ping (POST)", - "description": "Called by external systems to signal liveness with an optional JSON payload. The payload can be inspected by heartbeat_payload_contains assertions. Always returns 200 OK.", - "operationId": "pingPost", + "summary": "Replay a single check execution", + "description": "Returns every rule evaluation and state transition emitted for this scheduler-minted check_id (V92), plus the policy snapshot that governed them.", + "operationId": "getTrace", "parameters": [ { - "name": "token", + "name": "checkId", "in": "path", - "description": "Ping endpoint token for the heartbeat monitor", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "string" - } - }, - "text/plain": { - "schema": { - "type": "string" - } - }, - "*/*": { - "schema": { - "type": "string" - } - } - } - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/HeartbeatPingResponse" + "$ref": "#/components/schemas/SingleValueResponseCheckTraceDto" } } } @@ -4444,20 +4667,22 @@ } } }, - "/api/v1/incidents": { + "/api/v1/heartbeat/{token}": { "get": { "tags": [ - "Incidents" + "Heartbeat" ], - "summary": "List incidents for the authenticated org", - "operationId": "list_11", + "summary": "Record a heartbeat ping (GET)", + "description": "Called by external systems (cron jobs, scheduled tasks) to signal liveness. Always returns 200 OK.", + "operationId": "pingGet", "parameters": [ { - "name": "params", - "in": "query", + "name": "token", + "in": "path", + "description": "Ping endpoint token for the heartbeat monitor", "required": true, "schema": { - "$ref": "#/components/schemas/IncidentFilterParams" + "type": "string" } } ], @@ -4467,7 +4692,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultIncidentDto" + "$ref": "#/components/schemas/HeartbeatPingResponse" } } } @@ -4556,27 +4781,48 @@ }, "post": { "tags": [ - "Incidents" + "Heartbeat" + ], + "summary": "Record a heartbeat ping (POST)", + "description": "Called by external systems to signal liveness with an optional JSON payload. The payload can be inspected by heartbeat_payload_contains assertions. Always returns 200 OK.", + "operationId": "pingPost", + "parameters": [ + { + "name": "token", + "in": "path", + "description": "Ping endpoint token for the heartbeat monitor", + "required": true, + "schema": { + "type": "string" + } + } ], - "summary": "Create a manual incident", - "operationId": "create_12", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateManualIncidentRequest" + "type": "string" + } + }, + "text/plain": { + "schema": { + "type": "string" + } + }, + "*/*": { + "schema": { + "type": "string" } } - }, - "required": true + } }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentDetailDto" + "$ref": "#/components/schemas/HeartbeatPingResponse" } } } @@ -4664,22 +4910,20 @@ } } }, - "/api/v1/incidents/{id}": { + "/api/v1/incidents": { "get": { "tags": [ "Incidents" ], - "summary": "Get incident details including update timeline", - "description": "Shell payload: incident row, updates, and linked status-page incidents. Trigger enrichment (forensics / check_results) is GET /{id}/trigger so first paint is not blocked on hypertable reads.", - "operationId": "get_9", + "summary": "List incidents for the authenticated org", + "operationId": "list_11", "parameters": [ { - "name": "id", - "in": "path", + "name": "params", + "in": "query", "required": true, "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/IncidentFilterParams" } } ], @@ -4689,7 +4933,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentDetailDto" + "$ref": "#/components/schemas/TableValueResultIncidentDto" } } } @@ -4776,12 +5020,124 @@ } } }, - "patch": { + "post": { "tags": [ "Incidents" ], - "summary": "Update incident title and/or severity", - "operationId": "update_15", + "summary": "Create a manual incident", + "operationId": "create_12", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateManualIncidentRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "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}": { + "get": { + "tags": [ + "Incidents" + ], + "summary": "Get incident details including update timeline", + "description": "Shell payload: incident row, updates, and linked status-page incidents. Trigger enrichment (forensics / check_results) is GET /{id}/trigger so first paint is not blocked on hypertable reads.", + "operationId": "get_9", "parameters": [ { "name": "id", @@ -4793,16 +5149,126 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateIncidentRequest" - } - } - }, - "required": true - }, + "responses": { + "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" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Incidents" + ], + "summary": "Update incident title and/or severity", + "operationId": "update_15", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateIncidentRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", @@ -5637,7 +6103,7 @@ ], "summary": "List all supported integration types", "description": "Returns the full static catalog of supported alert channel integration types with their metadata and config field schemas. Used by the frontend to dynamically render the 'Add Alert Channel' form.", - "operationId": "list_19", + "operationId": "list_20", "responses": { "200": { "description": "OK", @@ -6835,7 +7301,7 @@ "Members" ], "summary": "List organization members", - "operationId": "list_18", + "operationId": "list_19", "parameters": [ { "name": "pageable", @@ -7921,13 +8387,13 @@ } } }, - "/api/v1/monitors/{id}/pause": { + "/api/v1/monitors/{id}/mute": { "post": { "tags": [ "Monitors" ], - "summary": "Pause a monitor (set enabled=false)", - "operationId": "pause", + "summary": "Mute alert delivery without flipping enabled", + "operationId": "mute", "parameters": [ { "name": "id", @@ -7939,6 +8405,15 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MonitorOverlayRequest" + } + } + } + }, "responses": { "200": { "description": "OK", @@ -8033,14 +8508,14 @@ } } }, - "/api/v1/monitors/{id}/results": { + "/api/v1/monitors/{id}/overview/steps": { "get": { "tags": [ "Check Results" ], - "summary": "List raw check results", - "description": "Returns check results for the given monitor with optional time-range, region, and pass/fail filtering. Uses cursor-based pagination — pass the returned `cursor` value on subsequent requests to retrieve the next page. The cursor encodes the original time bounds, so `from`/`to` are ignored when a cursor is present.", - "operationId": "getResults", + "summary": "Overview step catalog", + "description": "Step catalog from finished runs of the Head revision in the window, with first-try and flake aggregates. Empty when the monitor has no step catalog.", + "operationId": "getMonitorOverviewSteps", "parameters": [ { "name": "id", @@ -8052,82 +8527,38 @@ } }, { - "name": "from", - "in": "query", - "description": "Start of time range (ISO 8601, inclusive); defaults to 24 hours ago", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", + "name": "window", "in": "query", - "description": "End of time range (ISO 8601, inclusive); defaults to now", + "description": "Time window for step aggregates", "required": false, "schema": { "type": "string", - "format": "date-time" - } - }, - { - "name": "cursor", - "in": "query", - "description": "Opaque cursor from a previous response for pagination", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "Maximum results per page (1–200)", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 50 - }, - "example": 50 - }, - { - "name": "region", - "in": "query", - "description": "Filter by region (e.g. us-east)", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "passed", - "in": "query", - "description": "Filter by pass/fail status", - "required": false, - "schema": { - "type": "boolean" + "enum": [ + "24h", + "7d", + "30d", + "90d" + ] } } ], "responses": { "200": { - "description": "Paginated check results", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/CursorPageCheckResultDto" + "$ref": "#/components/schemas/SingleValueResponseOverviewStepsDto" } } } }, "400": { - "description": "Invalid query parameters", + "description": "Bad request — the payload failed validation", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/CursorPageCheckResultDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -8143,21 +8574,21 @@ } }, "403": { - "description": "Monitor does not belong to the caller's org", + "description": "Forbidden — the actor lacks permission for this resource", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/CursorPageCheckResultDto" + "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { - "description": "Monitor not found", + "description": "Not found — the requested resource does not exist", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/CursorPageCheckResultDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -8205,14 +8636,13 @@ } } }, - "/api/v1/monitors/{id}/results/summary": { - "get": { + "/api/v1/monitors/{id}/pause": { + "post": { "tags": [ - "Check Results" + "Monitors" ], - "summary": "Get results summary", - "description": "Returns a dashboard summary for the monitor: current status derived from the latest result per region, time-bucketed chart data, the 24-hour uptime percentage, and the selected window's uptime percentage.", - "operationId": "getSummary", + "summary": "Pause a monitor", + "operationId": "pause", "parameters": [ { "name": "id", @@ -8222,40 +8652,34 @@ "type": "string", "format": "uuid" } - }, - { - "name": "chartWindow", - "in": "query", - "description": "Chart window: 24h returns hourly buckets, 7d/30d/90d return daily buckets", - "required": false, - "schema": { - "type": "string", - "enum": [ - "24h", - "7d", - "30d", - "90d" - ] - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MonitorOverlayRequest" + } + } + } + }, "responses": { "200": { - "description": "Results summary", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/ResultSummaryDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } }, "400": { - "description": "Invalid chartWindow parameter", + "description": "Bad request — the payload failed validation", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -8271,21 +8695,21 @@ } }, "403": { - "description": "Monitor does not belong to the caller's org", + "description": "Forbidden — the actor lacks permission for this resource", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" + "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { - "description": "Monitor not found", + "description": "Not found — the requested resource does not exist", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -8333,13 +8757,14 @@ } } }, - "/api/v1/monitors/{id}/resume": { + "/api/v1/monitors/{id}/publish": { "post": { "tags": [ - "Monitors" + "Monitor definitions" ], - "summary": "Resume a monitor (set enabled=true)", - "operationId": "resume", + "summary": "Publish a revision as Head for this monitor's environment", + "description": "Retargets the shared Head for (definition, environment). Does not clone package bytes.", + "operationId": "publish", "parameters": [ { "name": "id", @@ -8351,13 +8776,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublishRevisionRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorDto" + "$ref": "#/components/schemas/SingleValueResponseDefinitionHeadDto" } } } @@ -8445,14 +8880,13 @@ } } }, - "/api/v1/monitors/{id}/rotate-token": { + "/api/v1/monitors/{id}/quarantine": { "post": { "tags": [ "Monitors" ], - "summary": "Rotate the ping token for a heartbeat monitor", - "description": "Generates a new ping token. The old token remains valid for 24 hours to allow cron jobs to be updated without downtime. Only supported for HEARTBEAT monitors.", - "operationId": "rotateToken", + "summary": "Quarantine a monitor", + "operationId": "quarantine", "parameters": [ { "name": "id", @@ -8464,6 +8898,16 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QuarantineMonitorRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", @@ -8558,14 +9002,13 @@ } } }, - "/api/v1/monitors/{id}/status-pages": { - "get": { + "/api/v1/monitors/{id}/release-quarantine": { + "post": { "tags": [ "Monitors" ], - "summary": "List status pages that contain this monitor as a component", - "description": "Returns all status pages where this monitor appears as a component, enabling the detail page to show 'Appears On' cross-links.", - "operationId": "listStatusPagesForMonitor", + "summary": "Release quarantine", + "operationId": "releaseQuarantine", "parameters": [ { "name": "id", @@ -8583,7 +9026,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -8671,13 +9114,14 @@ } } }, - "/api/v1/monitors/{id}/tags": { + "/api/v1/monitors/{id}/results": { "get": { "tags": [ - "Monitors" + "Check Results" ], - "summary": "Get all tags applied to a monitor", - "operationId": "getMonitorTags", + "summary": "List raw check results", + "description": "Returns check results for the given monitor with optional time-range, region, and pass/fail filtering. Uses cursor-based pagination — pass the returned `cursor` value on subsequent requests to retrieve the next page. The cursor encodes the original time bounds, so `from`/`to` are ignored when a cursor is present.", + "operationId": "getResults", "parameters": [ { "name": "id", @@ -8687,25 +9131,84 @@ "type": "string", "format": "uuid" } + }, + { + "name": "from", + "in": "query", + "description": "Start of time range (ISO 8601, inclusive); defaults to 24 hours ago", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "to", + "in": "query", + "description": "End of time range (ISO 8601, inclusive); defaults to now", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor from a previous response for pagination", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Maximum results per page (1–200)", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 50 + }, + "example": 50 + }, + { + "name": "region", + "in": "query", + "description": "Filter by region (e.g. us-east)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "passed", + "in": "query", + "description": "Filter by pass/fail status", + "required": false, + "schema": { + "type": "boolean" + } } ], "responses": { "200": { - "description": "OK", + "description": "Paginated check results", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" + "$ref": "#/components/schemas/CursorPageCheckResultDto" } } } }, "400": { - "description": "Bad request — the payload failed validation", + "description": "Invalid query parameters", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/CursorPageCheckResultDto" } } } @@ -8721,7 +9224,27 @@ } }, "403": { - "description": "Forbidden — the actor lacks permission for this resource", + "description": "Monitor does not belong to the caller's org", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/CursorPageCheckResultDto" + } + } + } + }, + "404": { + "description": "Monitor not found", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/CursorPageCheckResultDto" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", "content": { "application/json": { "schema": { @@ -8730,8 +9253,96 @@ } } }, - "404": { - "description": "Not found — the requested resource does not exist", + "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/{id}/results/summary": { + "get": { + "tags": [ + "Check Results" + ], + "summary": "Get results summary", + "description": "Returns a dashboard summary for the monitor: current status derived from the latest result per region, time-bucketed chart data, the 24-hour uptime percentage, and the selected window's uptime percentage.", + "operationId": "getSummary", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "chartWindow", + "in": "query", + "description": "Chart window: 24h returns hourly buckets, 7d/30d/90d return daily buckets", + "required": false, + "schema": { + "type": "string", + "enum": [ + "24h", + "7d", + "30d", + "90d" + ] + } + } + ], + "responses": { + "200": { + "description": "Results summary", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ResultSummaryDto" + } + } + } + }, + "400": { + "description": "Invalid chartWindow parameter", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", "content": { "application/json": { "schema": { @@ -8740,6 +9351,26 @@ } } }, + "403": { + "description": "Monitor does not belong to the caller's org", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" + } + } + } + }, + "404": { + "description": "Monitor not found", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseResultSummaryDto" + } + } + } + }, "409": { "description": "Conflict — the request collides with current resource state", "content": { @@ -8781,13 +9412,15 @@ } } } - }, + } + }, + "/api/v1/monitors/{id}/resume": { "post": { "tags": [ "Monitors" ], - "summary": "Add tags to a monitor; supports existing tag IDs and inline creation of new tags", - "operationId": "addMonitorTags", + "summary": "Resume a paused monitor", + "operationId": "resume", "parameters": [ { "name": "id", @@ -8799,23 +9432,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AddMonitorTagsRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -8901,13 +9524,16 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{id}/revisions": { + "get": { "tags": [ - "Monitors" + "Monitor definitions" ], - "summary": "Remove tags from a monitor by their IDs", - "operationId": "removeMonitorTags", + "summary": "List revisions published in this monitor's environment", + "description": "Omits drafts never published here. Page size default 25.", + "operationId": "listRevisions", "parameters": [ { "name": "id", @@ -8917,22 +9543,27 @@ "type": "string", "format": "uuid" } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RemoveMonitorTagsRequest" + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultRevisionDto" + } } } }, - "required": true - }, - "responses": { - "204": { - "description": "No Content" - }, "400": { "description": "Bad request — the payload failed validation", "content": { @@ -9016,14 +9647,14 @@ } } }, - "/api/v1/monitors/{id}/test": { + "/api/v1/monitors/{id}/revisions/{revisionId}/test": { "post": { "tags": [ - "Monitors" + "Monitor definitions" ], - "summary": "Test an existing monitor", - "description": "Runs the saved config and assertions of an existing monitor once, without persisting any result. Runs synchronously and returns the same shape as the ad-hoc test. MULTI_STEP_API and BROWSER are rejected with MONITOR_CODE_CHECK_TEST_UNAVAILABLE until fleet dry-run is available.", - "operationId": "testExisting", + "summary": "Run remote validation against a revision without moving Head", + "description": "Creates a Run with source=remote_validation. Does not signal.", + "operationId": "testRevision", "parameters": [ { "name": "id", @@ -9033,15 +9664,24 @@ "type": "string", "format": "uuid" } + }, + { + "name": "revisionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], "responses": { - "200": { - "description": "OK", + "202": { + "description": "Accepted", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" + "$ref": "#/components/schemas/SingleValueResponseRunDto" } } } @@ -9129,14 +9769,14 @@ } } }, - "/api/v1/monitors/{id}/test-notifications": { + "/api/v1/monitors/{id}/rollback": { "post": { "tags": [ - "Monitors" + "Monitor definitions" ], - "summary": "Send test notifications through the monitor's alert channels", - "description": "Sends a test alert to all specified channel IDs (must be channels attached to this monitor). If no channelIds are provided, tests all attached channels. Returns per-channel results.", - "operationId": "testNotifications", + "summary": "Roll back Head to a prior revision", + "description": "Same Head UPDATE as publish; stores reason on the Head.", + "operationId": "rollback", "parameters": [ { "name": "id", @@ -9152,7 +9792,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TestMonitorNotificationsRequest" + "$ref": "#/components/schemas/RollbackRevisionRequest" } } }, @@ -9164,7 +9804,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTestChannelResult" + "$ref": "#/components/schemas/SingleValueResponseDefinitionHeadDto" } } } @@ -9252,14 +9892,13 @@ } } }, - "/api/v1/monitors/{id}/uptime": { + "/api/v1/monitors/{id}/rollback-preview": { "get": { "tags": [ - "Check Results" + "Monitor definitions" ], - "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": "Preview rollback consequences for this environment", + "operationId": "rollbackPreview", "parameters": [ { "name": "id", @@ -9271,140 +9910,13 @@ } }, { - "name": "window", + "name": "revisionId", "in": "query", - "description": "Time window for uptime calculation", - "required": false, - "schema": { - "type": "string", - "enum": [ - "24h", - "7d", - "30d", - "90d" - ] - } - } - ], - "responses": { - "200": { - "description": "Uptime statistics", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/UptimeDto" - } - } - } - }, - "400": { - "description": "Invalid window parameter", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseUptimeDto" - } - } - } - }, - "401": { - "description": "Unauthorized — missing or invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "403": { - "description": "Monitor does not belong to the caller's org", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseUptimeDto" - } - } - } - }, - "404": { - "description": "Monitor not found", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseUptimeDto" - } - } - } - }, - "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/{id}/versions": { - "get": { - "tags": [ - "Monitors" - ], - "summary": "List version history for a monitor", - "description": "Returns a paginated list of mutation snapshots for the monitor, newest first. Each version captures the full monitor config at the time of a PUT /monitors/{id} call.", - "operationId": "listVersions", - "parameters": [ - { - "name": "id", - "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } - }, - { - "name": "pageable", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/Pageable" - } } ], "responses": { @@ -9413,7 +9925,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultMonitorVersionDto" + "$ref": "#/components/schemas/SingleValueResponseRollbackPreviewDto" } } } @@ -9501,14 +10013,14 @@ } } }, - "/api/v1/monitors/{id}/versions/{version}": { - "get": { + "/api/v1/monitors/{id}/rotate-token": { + "post": { "tags": [ "Monitors" ], - "summary": "Get a specific version snapshot for a monitor", - "description": "Returns the full monitor config snapshot captured at the given version number.", - "operationId": "getVersion", + "summary": "Rotate the ping token for a heartbeat monitor", + "description": "Generates a new ping token. The old token remains valid for 24 hours to allow cron jobs to be updated without downtime. Only supported for HEARTBEAT monitors.", + "operationId": "rotateToken", "parameters": [ { "name": "id", @@ -9518,15 +10030,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "version", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } } ], "responses": { @@ -9535,7 +10038,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorVersionDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -9623,41 +10126,40 @@ } } }, - "/api/v1/monitors/{monitorId}/alert-channels": { - "put": { + "/api/v1/monitors/{id}/runs": { + "get": { "tags": [ - "Monitor Alert Channels" + "Monitor Runs" ], - "summary": "Replace the linked alert channel set for a monitor", - "operationId": "setChannels", + "summary": "List runs for a code monitor", + "description": "Cursor page. Default limit 25.", + "operationId": "listMonitorRuns", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + }, + { + "name": "params", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/MonitorRunListParams" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SetAlertChannelsRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseListUUID" + "$ref": "#/components/schemas/CursorPageRunDto" } } } @@ -9743,18 +10245,17 @@ } } } - } - }, - "/api/v1/monitors/{monitorId}/assertions": { + }, "post": { "tags": [ - "Monitor Assertions" + "Monitor Runs" ], - "summary": "Add an assertion to a monitor", - "operationId": "add", + "summary": "Run now", + "description": "Persists a run in queued phase. 409 if no Head or any secret key is missing.", + "operationId": "runNow", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -9763,23 +10264,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateAssertionRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "202": { + "description": "Accepted", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" + "$ref": "#/components/schemas/SingleValueResponseRunDto" } } } @@ -9867,38 +10358,149 @@ } } }, - "/api/v1/monitors/{monitorId}/assertions/{assertionId}": { - "put": { + "/api/v1/monitors/{id}/secret-requests": { + "get": { "tags": [ - "Monitor Assertions" + "Monitor secret requests" ], - "summary": "Update an assertion on a monitor", - "operationId": "update_10", + "summary": "List secret requests for a monitor", + "operationId": "list_18", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseMonitorSecretRequestsDto" + } + } + } + }, + "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/{id}/secret-requests/{key}": { + "put": { + "tags": [ + "Monitor secret requests" + ], + "summary": "Attach or clear a remapped secret for a key", + "operationId": "remap", + "parameters": [ { - "name": "assertionId", + "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + }, + { + "name": "key", + "in": "path", + "required": true, + "schema": { + "type": "string" + } } ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateAssertionRequest" + "$ref": "#/components/schemas/RemapSecretRequest" } } }, @@ -9910,7 +10512,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorSecretRequestsDto" } } } @@ -9996,25 +10598,18 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{id}/secret-requests/rescan": { + "post": { "tags": [ - "Monitor Assertions" + "Monitor secret requests" ], - "summary": "Remove an assertion from a monitor", - "operationId": "remove_1", + "summary": "Rescan secret requests from the active package", + "operationId": "rescan", "parameters": [ { - "name": "monitorId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "assertionId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10024,8 +10619,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseMonitorSecretRequestsDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -10110,16 +10712,16 @@ } } }, - "/api/v1/monitors/{monitorId}/auth": { - "put": { + "/api/v1/monitors/{id}/session": { + "get": { "tags": [ - "Monitor Auth" + "Monitor session" ], - "summary": "Update authentication config for a monitor", - "operationId": "update_9", + "summary": "Get the monitor session", + "operationId": "getSession", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10128,23 +10730,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateMonitorAuthRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorSessionDto" } } } @@ -10231,15 +10823,15 @@ } } }, - "post": { + "put": { "tags": [ - "Monitor Auth" + "Monitor session" ], - "summary": "Set authentication config for a monitor", - "operationId": "set", + "summary": "Create or update the monitor session", + "operationId": "putSession", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10252,19 +10844,19 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SetMonitorAuthRequest" + "$ref": "#/components/schemas/UpsertMonitorSessionRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorSessionDto" } } } @@ -10350,16 +10942,18 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{id}/session/renew": { + "post": { "tags": [ - "Monitor Auth" + "Monitor session" ], - "summary": "Remove authentication config from a monitor", - "operationId": "remove", + "summary": "Renew the monitor session", + "operationId": "renewSession", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10369,8 +10963,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "202": { + "description": "Accepted", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseRunDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -10455,19 +11056,17 @@ } } }, - "/api/v1/monitors/{monitorId}/policy": { - "get": { + "/api/v1/monitors/{id}/session/revoke": { + "post": { "tags": [ - "Incident Policies" + "Monitor session" ], - "summary": "Get incident policy for a monitor", - "description": "Returns the trigger rules, confirmation settings, and recovery settings for the given monitor.", - "operationId": "get_5", + "summary": "Revoke the monitor session", + "operationId": "revokeSession", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", - "description": "Monitor UUID", "required": true, "schema": { "type": "string", @@ -10477,11 +11076,11 @@ ], "responses": { "200": { - "description": "Policy found", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/IncidentPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorSessionDto" } } } @@ -10517,11 +11116,11 @@ } }, "404": { - "description": "Monitor or policy not found", + "description": "Not found — the requested resource does not exist", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -10567,19 +11166,20 @@ } } } - }, - "put": { + } + }, + "/api/v1/monitors/{id}/status-pages": { + "get": { "tags": [ - "Incident Policies" + "Monitors" ], - "summary": "Update incident policy for a monitor", - "description": "Replaces the trigger rules, confirmation settings, and recovery settings. All fields are validated before saving.", - "operationId": "update_8", + "summary": "List status pages that contain this monitor as a component", + "description": "Returns all status pages where this monitor appears as a component, enabling the detail page to show 'Appears On' cross-links.", + "operationId": "listStatusPagesForMonitor", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", - "description": "Monitor UUID", "required": true, "schema": { "type": "string", @@ -10587,33 +11187,23 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateIncidentPolicyRequest" - } - } - }, - "required": true - }, "responses": { "200": { - "description": "Policy updated", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/IncidentPolicyDto" + "$ref": "#/components/schemas/TableValueResultStatusPageDto" } } } }, "400": { - "description": "Validation error in JSONB shape", + "description": "Bad request — the payload failed validation", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -10639,11 +11229,11 @@ } }, "404": { - "description": "Monitor or policy not found", + "description": "Not found — the requested resource does not exist", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -10691,31 +11281,31 @@ } } }, - "/api/v1/monitors/bulk": { - "post": { + "/api/v1/monitors/{id}/tags": { + "get": { "tags": [ "Monitors" ], - "summary": "Bulk action on monitors", - "description": "Applies PAUSE, RESUME, DELETE, ADD_TAG, or REMOVE_TAG to a list of monitors. Returns a partial-success response indicating which monitors succeeded and which failed.", - "operationId": "bulkAction", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BulkMonitorActionRequest" - } + "summary": "Get all tags applied to a monitor", + "operationId": "getMonitorTags", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } - }, - "required": true - }, + } + ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseBulkMonitorActionResult" + "$ref": "#/components/schemas/TableValueResultTagDto" } } } @@ -10801,21 +11391,29 @@ } } } - } - }, - "/api/v1/monitors/test": { + }, "post": { "tags": [ "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. MULTI_STEP_API and BROWSER are rejected with MONITOR_CODE_CHECK_TEST_UNAVAILABLE until fleet dry-run is available.", - "operationId": "testAdHoc", + "summary": "Add tags to a monitor; supports existing tag IDs and inline creation of new tags", + "operationId": "addMonitorTags", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/MonitorTestRequest" + "$ref": "#/components/schemas/AddMonitorTagsRequest" } } }, @@ -10827,7 +11425,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" + "$ref": "#/components/schemas/TableValueResultTagDto" } } } @@ -10913,21 +11511,17 @@ } } } - } - }, - "/api/v1/notification-dispatches": { - "get": { + }, + "delete": { "tags": [ - "Notification Dispatches" + "Monitors" ], - "summary": "List all dispatches for an incident", - "description": "Returns all notification dispatches for the given incident that belong to the authenticated org's policies. Each dispatch includes delivery records for all associated channels.", - "operationId": "listByIncident", + "summary": "Remove tags from a monitor by their IDs", + "operationId": "removeMonitorTags", "parameters": [ { - "name": "incident_id", - "in": "query", - "description": "UUID of the incident to inspect", + "name": "id", + "in": "path", "required": true, "schema": { "type": "string", @@ -10935,17 +11529,20 @@ } } ], - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" - } + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RemoveMonitorTagsRequest" } } }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, "400": { "description": "Bad request — the payload failed validation", "content": { @@ -11029,14 +11626,14 @@ } } }, - "/api/v1/notification-dispatches/{id}": { - "get": { + "/api/v1/monitors/{id}/test": { + "post": { "tags": [ - "Notification Dispatches" + "Monitors" ], - "summary": "Get a single dispatch with full escalation and delivery history", - "description": "Returns the dispatch state including current escalation step, acknowledgment info, and all delivery attempts made across every step.", - "operationId": "getById_3", + "summary": "Test an existing monitor", + "description": "Runs the saved config and assertions of an existing monitor once, without persisting any result. Runs synchronously and returns the same shape as the ad-hoc test. MULTI_STEP_API and BROWSER are rejected with MONITOR_CODE_CHECK_TEST_UNAVAILABLE until fleet dry-run is available.", + "operationId": "testExisting", "parameters": [ { "name": "id", @@ -11054,7 +11651,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" } } } @@ -11142,14 +11739,14 @@ } } }, - "/api/v1/notification-dispatches/{id}/acknowledge": { + "/api/v1/monitors/{id}/test-notifications": { "post": { "tags": [ - "Notification Dispatches" + "Monitors" ], - "summary": "Acknowledge a notification dispatch", - "description": "Marks the dispatch as acknowledged. The dispatch must be in DELIVERED or ESCALATING state. Sets acknowledgedAt, acknowledgedBy (actor email), and acknowledgedVia (DASHBOARD).", - "operationId": "acknowledge", + "summary": "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", @@ -11161,13 +11758,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestMonitorNotificationsRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$ref": "#/components/schemas/TableValueResultTestChannelResult" } } } @@ -11255,14 +11862,13 @@ } } }, - "/api/v1/notification-dispatches/{id}/unacknowledge": { + "/api/v1/monitors/{id}/unmute": { "post": { "tags": [ - "Notification Dispatches" + "Monitors" ], - "summary": "Unacknowledge a notification dispatch", - "description": "Reverses a mistaken acknowledgment without reopening the incident. Allowed only from ACKNOWLEDGED. Clears ack fields, stays on the current escalation step, restores nextEscalationAt, and resumes escalation (ESCALATING if more steps remain, else DELIVERED). MEMBER+.", - "operationId": "unacknowledge", + "summary": "Clear mute overlay", + "operationId": "unmute", "parameters": [ { "name": "id", @@ -11280,7 +11886,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -11368,30 +11974,57 @@ } } }, - "/api/v1/notification-policies": { + "/api/v1/monitors/{id}/uptime": { "get": { "tags": [ - "Notification Policies" + "Check Results" + ], + "summary": "Get uptime statistics", + "description": "Returns uptime percentage and latency statistics for the requested time window, computed from continuous aggregates. Uses hourly aggregates for 24h/7d windows and daily aggregates for 30d/90d windows.", + "operationId": "getUptime", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "window", + "in": "query", + "description": "Time window for uptime calculation", + "required": false, + "schema": { + "type": "string", + "enum": [ + "24h", + "7d", + "30d", + "90d" + ] + } + } ], - "summary": "List all notification policies for the authenticated org", - "operationId": "list_7", "responses": { "200": { - "description": "OK", + "description": "Uptime statistics", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" + "$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" } } } @@ -11407,21 +12040,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" } } } @@ -11467,30 +12100,42 @@ } } } - }, - "post": { + } + }, + "/api/v1/monitors/{id}/versions": { + "get": { "tags": [ - "Notification Policies" + "Monitors" ], - "summary": "Create a notification policy with match rules and escalation chain", - "operationId": "create_8", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateNotificationPolicyRequest" - } + "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", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "required": true - }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/TableValueResultMonitorVersionDto" } } } @@ -11578,13 +12223,14 @@ } } }, - "/api/v1/notification-policies/{id}": { + "/api/v1/monitors/{id}/versions/{version}": { "get": { "tags": [ - "Notification Policies" + "Monitors" ], - "summary": "Get a notification policy by ID", - "operationId": "getById_1", + "summary": "Get a specific version snapshot for a monitor", + "description": "Returns the full monitor config snapshot captured at the given version number.", + "operationId": "getVersion", "parameters": [ { "name": "id", @@ -11594,6 +12240,15 @@ "type": "string", "format": "uuid" } + }, + { + "name": "version", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } } ], "responses": { @@ -11602,7 +12257,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorVersionDto" } } } @@ -11688,16 +12343,18 @@ } } } - }, + } + }, + "/api/v1/monitors/{monitorId}/alert-channels": { "put": { "tags": [ - "Notification Policies" + "Monitor Alert Channels" ], - "summary": "Update a notification policy", - "operationId": "update_7", + "summary": "Replace the linked alert channel set for a monitor", + "operationId": "setChannels", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { @@ -11710,7 +12367,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateNotificationPolicyRequest" + "$ref": "#/components/schemas/SetAlertChannelsRequest" } } }, @@ -11722,7 +12379,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseListUUID" } } } @@ -11808,16 +12465,18 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{monitorId}/assertions": { + "post": { "tags": [ - "Notification Policies" + "Monitor Assertions" ], - "summary": "Delete a notification policy", - "operationId": "delete_6", + "summary": "Add an assertion to a monitor", + "operationId": "add", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { @@ -11826,9 +12485,26 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateAssertionRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -11913,17 +12589,16 @@ } } }, - "/api/v1/notification-policies/{id}/dispatches": { - "get": { + "/api/v1/monitors/{monitorId}/assertions/{assertionId}": { + "put": { "tags": [ - "Notification Policies" + "Monitor Assertions" ], - "summary": "List dispatches (firing history) for a notification policy", - "description": "Additive optional query params: since/until/cursor/limit. When all are omitted, returns the full history (legacy). When any is set, defaults to a 30-day window and limit 50, and may include nextCursor. Response remains TableValueResult — no CursorPage swap.", - "operationId": "listDispatches", + "summary": "Update an assertion on a monitor", + "operationId": "update_10", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { @@ -11932,52 +12607,32 @@ } }, { - "name": "since", - "in": "query", - "description": "Inclusive lower bound (ISO-8601); defaults to now−30d when windowing", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "until", - "in": "query", - "description": "Exclusive upper bound (ISO-8601); defaults to now when windowing", - "required": false, + "name": "assertionId", + "in": "path", + "required": true, "schema": { "type": "string", - "format": "date-time" - } - }, - { - "name": "cursor", - "in": "query", - "description": "Opaque cursor from a previous nextCursor", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "Page size 1–100 when windowing/paginating (default 50)", - "required": false, - "schema": { - "type": "integer", - "format": "int32" + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateAssertionRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" } } } @@ -12063,45 +12718,36 @@ } } } - } - }, - "/api/v1/notification-policies/{id}/test": { - "post": { + }, + "delete": { "tags": [ - "Notification Policies" + "Monitor Assertions" ], - "summary": "Dry-run: evaluate a policy's match rules against a supplied incident context", - "operationId": "test_1", + "summary": "Remove an assertion from a monitor", + "operationId": "remove_1", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestNotificationPolicyRequest" - } + }, + { + "name": "assertionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } - }, + ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseTestMatchResult" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -12186,51 +12832,41 @@ } } }, - "/api/v1/notifications": { - "get": { + "/api/v1/monitors/{monitorId}/auth": { + "put": { "tags": [ - "Notifications" + "Monitor Auth" ], - "summary": "List notifications for the current user", - "operationId": "list_17", + "summary": "Update authentication config for a monitor", + "operationId": "update_9", "parameters": [ { - "name": "unreadOnly", - "in": "query", - "required": false, - "schema": { - "type": "boolean", - "default": false - } - }, - { - "name": "page", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 0 - } - }, - { - "name": "size", - "in": "query", - "required": false, + "name": "monitorId", + "in": "path", + "required": true, "schema": { - "type": "integer", - "format": "int32", - "default": 20 + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateMonitorAuthRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" } } } @@ -12316,29 +12952,44 @@ } } } - } - }, - "/api/v1/notifications/{id}/read": { - "put": { + }, + "post": { "tags": [ - "Notifications" + "Monitor Auth" ], - "summary": "Mark a notification as read", - "operationId": "markRead", + "summary": "Set authentication config for a monitor", + "operationId": "set", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { - "type": "integer", - "format": "int64" + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetMonitorAuthRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -12421,15 +13072,24 @@ } } } - } - }, - "/api/v1/notifications/read-all": { - "put": { + }, + "delete": { "tags": [ - "Notifications" + "Monitor Auth" + ], + "summary": "Remove authentication config from a monitor", + "operationId": "remove", + "parameters": [ + { + "name": "monitorId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } ], - "summary": "Mark all notifications as read", - "operationId": "markAllRead", "responses": { "204": { "description": "No Content" @@ -12517,20 +13177,33 @@ } } }, - "/api/v1/notifications/unread-count": { + "/api/v1/monitors/{monitorId}/policy": { "get": { "tags": [ - "Notifications" + "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" + } + } ], - "summary": "Get unread notification count", - "operationId": "unreadCount", "responses": { "200": { - "description": "OK", + "description": "Policy found", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseLong" + "$ref": "#/components/schemas/IncidentPolicyDto" } } } @@ -12566,11 +13239,11 @@ } }, "404": { - "description": "Not found — the requested resource does not exist", + "description": "Monitor or policy not found", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" } } } @@ -12616,32 +13289,53 @@ } } } - } - }, - "/api/v1/org": { - "get": { + }, + "put": { "tags": [ - "Organizations" + "Incident Policies" ], - "summary": "Get the current organization", - "operationId": "get_4", + "summary": "Update incident policy for a monitor", + "description": "Replaces the trigger rules, confirmation settings, and recovery settings. All fields are validated before saving.", + "operationId": "update_8", + "parameters": [ + { + "name": "monitorId", + "in": "path", + "description": "Monitor UUID", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateIncidentPolicyRequest" + } + } + }, + "required": true + }, "responses": { "200": { - "description": "OK", + "description": "Policy updated", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" + "$ref": "#/components/schemas/IncidentPolicyDto" } } } }, "400": { - "description": "Bad request — the payload failed validation", + "description": "Validation error in JSONB shape", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" } } } @@ -12667,11 +13361,11 @@ } }, "404": { - "description": "Not found — the requested resource does not exist", + "description": "Monitor or policy not found", "content": { - "application/json": { + "*/*": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" } } } @@ -12717,18 +13411,21 @@ } } } - }, - "put": { + } + }, + "/api/v1/monitors/bulk": { + "post": { "tags": [ - "Organizations" + "Monitors" ], - "summary": "Update the current organization", - "operationId": "update_6", + "summary": "Bulk action on monitors", + "description": "Applies PAUSE, RESUME, DELETE, ADD_TAG, or REMOVE_TAG to a list of monitors. Returns a partial-success response indicating which monitors succeeded and which failed.", + "operationId": "bulkAction", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateOrgDetailsRequest" + "$ref": "#/components/schemas/BulkMonitorActionRequest" } } }, @@ -12740,7 +13437,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" + "$ref": "#/components/schemas/SingleValueResponseBulkMonitorActionResult" } } } @@ -12828,20 +13525,30 @@ } } }, - "/api/v1/resource-groups": { - "get": { + "/api/v1/monitors/package-uploads": { + "post": { "tags": [ - "Resource Groups" + "Monitors" ], - "summary": "List all resource groups for the authenticated org with health summaries", - "operationId": "list_6", + "summary": "Mint a signed package upload URL", + "operationId": "createPackageUpload", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreatePackageUploadRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultResourceGroupDto" + "$ref": "#/components/schemas/SingleValueResponsePackageUploadDto" } } } @@ -12927,30 +13634,33 @@ } } } - }, + } + }, + "/api/v1/monitors/test": { "post": { "tags": [ - "Resource Groups" + "Monitors" ], - "summary": "Create a new resource group", - "operationId": "create_7", + "summary": "Ad-hoc monitor test", + "description": "Executes a one-off check from an inline config without saving the monitor. Runs synchronously and returns status code, response time, assertion results, body preview, and headers. MULTI_STEP_API and BROWSER are rejected with MONITOR_CODE_CHECK_TEST_UNAVAILABLE until fleet dry-run is available.", + "operationId": "testAdHoc", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateResourceGroupRequest" + "$ref": "#/components/schemas/MonitorTestRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" } } } @@ -13038,31 +13748,136 @@ } } }, - "/api/v1/resource-groups/{id}": { + "/api/v1/notification-dispatches": { "get": { "tags": [ - "Resource Groups" + "Notification Dispatches" ], - "summary": "Get a resource group by id with member statuses and inherited settings", - "description": "Pass includeMetrics=true to enrich each member with 24h uptime, chart data, and latency metrics.", - "operationId": "get_3", + "summary": "List all dispatches for an incident", + "description": "Returns all notification dispatches for the given incident that belong to the authenticated org's policies. Each dispatch includes delivery records for all associated channels.", + "operationId": "listByIncident", "parameters": [ { - "name": "id", - "in": "path", + "name": "incident_id", + "in": "query", + "description": "UUID of the incident to inspect", "required": true, "schema": { "type": "string", "format": "uuid" } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" + } + } + } + }, + "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/notification-dispatches/{id}": { + "get": { + "tags": [ + "Notification Dispatches" + ], + "summary": "Get a single dispatch with full escalation and delivery history", + "description": "Returns the dispatch state including current escalation step, acknowledgment info, and all delivery attempts made across every step.", + "operationId": "getById_3", + "parameters": [ { - "name": "includeMetrics", - "in": "query", - "required": false, + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "boolean", - "default": false + "type": "string", + "format": "uuid" } } ], @@ -13072,7 +13887,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" } } } @@ -13158,13 +13973,16 @@ } } } - }, - "put": { + } + }, + "/api/v1/notification-dispatches/{id}/acknowledge": { + "post": { "tags": [ - "Resource Groups" + "Notification Dispatches" ], - "summary": "Update a resource group's name, description, alert policy, inherited settings, and health threshold", - "operationId": "update_5", + "summary": "Acknowledge a notification dispatch", + "description": "Marks the dispatch as acknowledged. The dispatch must be in DELIVERED or ESCALATING state. Sets acknowledgedAt, acknowledgedBy (actor email), and acknowledgedVia (DASHBOARD).", + "operationId": "acknowledge", "parameters": [ { "name": "id", @@ -13176,23 +13994,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateResourceGroupRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" } } } @@ -13278,13 +14086,16 @@ } } } - }, - "delete": { + } + }, + "/api/v1/notification-dispatches/{id}/unacknowledge": { + "post": { "tags": [ - "Resource Groups" + "Notification Dispatches" ], - "summary": "Delete a resource group (cascades to member rows)", - "operationId": "delete_5", + "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", @@ -13297,8 +14108,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -13383,32 +14201,20 @@ } } }, - "/api/v1/resource-groups/{id}/health": { + "/api/v1/notification-policies": { "get": { "tags": [ - "Resource Groups" - ], - "summary": "Get the detailed health breakdown for a resource group", - "description": "Returns member counts, worst-of status, and threshold-based health evaluation. The thresholdStatus field is populated only when a health threshold is configured.", - "operationId": "getHealth", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "Notification Policies" ], + "summary": "List all notification policies for the authenticated org", + "operationId": "list_7", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupHealthDto" + "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" } } } @@ -13494,34 +14300,30 @@ } } } - } - }, - "/api/v1/resource-groups/{id}/matched-policies": { - "get": { + }, + "post": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "List notification policies that match this resource group", - "description": "Policies whose match rules evaluate true for a DEGRADED or DOWN group-origin INCIDENT_CREATED context on this resource group (includes paused)", - "operationId": "listMatchedPolicies", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" + "summary": "Create a notification policy with match rules and escalation chain", + "operationId": "create_8", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateNotificationPolicyRequest" + } } - } - ], + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" } } } @@ -13609,13 +14411,13 @@ } } }, - "/api/v1/resource-groups/{id}/members": { - "post": { + "/api/v1/notification-policies/{id}": { + "get": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "Add a monitor or service member to a resource group", - "operationId": "addMember_1", + "summary": "Get a notification policy by ID", + "operationId": "getById_1", "parameters": [ { "name": "id", @@ -13627,23 +14429,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AddResourceGroupMemberRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupMemberDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" } } } @@ -13729,15 +14521,13 @@ } } } - } - }, - "/api/v1/resource-groups/{id}/members/{memberId}": { - "delete": { + }, + "put": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "Remove a member from a resource group", - "operationId": "removeMember_1", + "summary": "Update a notification policy", + "operationId": "update_7", "parameters": [ { "name": "id", @@ -13747,20 +14537,28 @@ "type": "string", "format": "uuid" } - }, - { - "name": "memberId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateNotificationPolicyRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -13843,25 +14641,27 @@ } } } - } - }, - "/api/v1/secrets": { - "get": { + }, + "delete": { "tags": [ - "Secrets" + "Notification Policies" ], - "summary": "List secrets", - "operationId": "list_5", - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultSecretDto" - } - } + "summary": "Delete a notification policy", + "operationId": "delete_6", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } + } + ], + "responses": { + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -13944,30 +14744,73 @@ } } } - }, - "post": { + } + }, + "/api/v1/notification-policies/{id}/dispatches": { + "get": { "tags": [ - "Secrets" + "Notification Policies" ], - "summary": "Create secret", - "operationId": "create_6", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSecretRequest" - } + "summary": "List dispatches (firing history) for a notification policy", + "description": "Optional query params: since/until/cursor/limit. When all are omitted, returns the full history (legacy). When any is set, defaults to a 30-day window and limit 50. Response is CursorPage (hasMore + nextCursor), the same wrapper used by other append-only history endpoints.", + "operationId": "listDispatches", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "required": true - }, + { + "name": "since", + "in": "query", + "description": "Inclusive lower bound (ISO-8601); defaults to now−30d when windowing", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "until", + "in": "query", + "description": "Exclusive upper bound (ISO-8601); defaults to now when windowing", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor from a previous nextCursor", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size 1–100 when windowing/paginating (default 50)", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseSecretDto" + "$ref": "#/components/schemas/CursorPageNotificationDispatchDto" } } } @@ -14055,20 +14898,21 @@ } } }, - "/api/v1/secrets/{key}": { - "put": { + "/api/v1/notification-policies/{id}/test": { + "post": { "tags": [ - "Secrets" + "Notification Policies" ], - "summary": "Update secret", - "operationId": "update_4", + "summary": "Dry-run: evaluate a policy's match rules against a supplied incident context", + "operationId": "test_1", "parameters": [ { - "name": "key", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } } ], @@ -14076,11 +14920,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateSecretRequest" + "$ref": "#/components/schemas/TestNotificationPolicyRequest" } } - }, - "required": true + } }, "responses": { "200": { @@ -14088,7 +14931,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseSecretDto" + "$ref": "#/components/schemas/SingleValueResponseTestMatchResult" } } } @@ -14174,124 +15017,53 @@ } } } - }, - "delete": { + } + }, + "/api/v1/notifications": { + "get": { "tags": [ - "Secrets" + "Notifications" ], - "summary": "Delete secret", - "operationId": "delete_4", + "summary": "List notifications for the current user", + "operationId": "list_17", "parameters": [ { - "name": "key", - "in": "path", - "required": true, + "name": "unreadOnly", + "in": "query", + "required": false, "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad request — the payload failed validation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "401": { - "description": "Unauthorized — missing or invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "403": { - "description": "Forbidden — the actor lacks permission for this resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "404": { - "description": "Not found — the requested resource does not exist", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "409": { - "description": "Conflict — the request collides with current resource state", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + "type": "boolean", + "default": false } }, - "502": { - "description": "Bad gateway — an upstream provider returned an error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 0 } }, - "503": { - "description": "Service unavailable — try again shortly", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + { + "name": "size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 20 } } - } - } - }, - "/api/v1/service-subscriptions": { - "get": { - "tags": [ - "Service Subscriptions" ], - "summary": "List all service subscriptions for the organization", - "operationId": "list_16", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultServiceSubscriptionDto" + "$ref": "#/components/schemas/TableValueResultNotificationDto" } } } @@ -14379,34 +15151,27 @@ } } }, - "/api/v1/service-subscriptions/{id}": { - "get": { + "/api/v1/notifications/{id}/read": { + "put": { "tags": [ - "Service Subscriptions" + "Notifications" ], - "summary": "Get a subscription by its ID", - "operationId": "get_11", + "summary": "Mark a notification as read", + "operationId": "markRead", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "integer", + "format": "int64" } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -14489,25 +15254,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/notifications/read-all": { + "put": { "tags": [ - "Service Subscriptions" - ], - "summary": "Remove a subscription by its ID", - "description": "Removes a specific subscription (whole-service or component-level). No-op if not found.", - "operationId": "unsubscribe_1", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "Notifications" ], + "summary": "Mark all notifications as read", + "operationId": "markAllRead", "responses": { "204": { "description": "No Content" @@ -14595,42 +15350,20 @@ } } }, - "/api/v1/service-subscriptions/{id}/alert-sensitivity": { - "patch": { + "/api/v1/notifications/unread-count": { + "get": { "tags": [ - "Service Subscriptions" - ], - "summary": "Update alert sensitivity for a subscription", - "description": "Controls which external incidents trigger alerts and whether they page anyone: ALL (any status change, paged), INCIDENTS_ONLY (real vendor incidents, paged), MAJOR_ONLY (only DOWN-level incidents, paged), AWARENESS (real vendor incidents tracked silently — visible on the dashboard but no alert channels fire; default for new subscriptions).", - "operationId": "updateAlertSensitivity", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "Notifications" ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateAlertSensitivityRequest" - } - } - }, - "required": true - }, + "summary": "Get unread notification count", + "operationId": "unreadCount", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + "$ref": "#/components/schemas/SingleValueResponseLong" } } } @@ -14718,40 +15451,20 @@ } } }, - "/api/v1/service-subscriptions/{slug}": { - "post": { + "/api/v1/org": { + "get": { "tags": [ - "Service Subscriptions" - ], - "summary": "Subscribe to a service or a component of a service", - "description": "Idempotent — returns the existing subscription if an identical one exists. Omit the request body or set componentId to null for a whole-service subscription. When alertSensitivity is omitted, new subscriptions default to AWARENESS (silent tracking — the incident appears on the dashboard but no alert channels fire). PATCH /alert-sensitivity to opt in to paging. Free tier: max 10 subscriptions. Paid tier: unlimited.", - "operationId": "subscribe_1", - "parameters": [ - { - "name": "slug", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } + "Organizations" ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ServiceSubscribeRequest" - } - } - } - }, + "summary": "Get the current organization", + "operationId": "get_4", "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" } } } @@ -14837,98 +15550,30 @@ } } } - } - }, - "/api/v1/services": { - "get": { + }, + "put": { "tags": [ - "Status Data" + "Organizations" ], - "summary": "List all enabled services (cursor-paginated)", - "operationId": "listServices", - "parameters": [ - { - "name": "category", - "in": "query", - "description": "Filter by category (exact match)", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "status", - "in": "query", - "description": "Filter by current overall_status (exact match)", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "published", - "in": "query", - "description": "Filter by published status for pSEO pages", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "slaPublished", - "in": "query", - "description": "Filter by SLA page publication status", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "search", - "in": "query", - "description": "Case-insensitive substring match on service name or slug", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sort", - "in": "query", - "description": "Result ordering: 'recent' (default, newest first) or 'curated' (curated/recognizable first)", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "cursor", - "in": "query", - "description": "Opaque cursor from a previous response", - "required": false, - "schema": { - "type": "string" + "summary": "Update the current organization", + "operationId": "update_6", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOrgDetailsRequest" + } } }, - { - "name": "limit", - "in": "query", - "description": "Page size (1–100, default 20)", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 20 - } - } - ], + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/CursorPageServiceCatalogDto" + "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" } } } @@ -15016,51 +15661,20 @@ } } }, - "/api/v1/services/{slugOrId}": { + "/api/v1/resource-groups": { "get": { "tags": [ - "Status Data" - ], - "summary": "Get a single service by slug or UUID with current status, components, and recent incidents", - "description": "When ``summary=true``, the inline ``components`` list is trimmed to groups + showcase leaves + currently-impacted leaves + ungrouped leaves, and a ``componentsSummary`` block is added with the trimmed counts. Powers SSR for vendors with hundreds of components (Snowflake, Cloudflare, DigitalOcean) without OOM-ing the renderer. Default false for full back-compat.", - "operationId": "getService", - "parameters": [ - { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "summary", - "in": "query", - "description": "Return a curated subset of components (groups + showcase + impacted + ungrouped) and a componentsSummary block; default false", - "required": false, - "schema": { - "type": "boolean", - "default": false - } - }, - { - "name": "publishedOnly", - "in": "query", - "description": "Resolve only published services (curated public pSEO set); 404 otherwise. Default false", - "required": false, - "schema": { - "type": "boolean", - "default": false - } - } + "Resource Groups" ], + "summary": "List all resource groups for the authenticated org with health summaries", + "operationId": "list_6", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceDetailDto" + "$ref": "#/components/schemas/TableValueResultResourceGroupDto" } } } @@ -15146,72 +15760,30 @@ } } } - } - }, - "/api/v1/services/{slugOrId}/components": { - "get": { + }, + "post": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "List active components for a service with current status and inline uptime", - "description": "When ``groupId`` is supplied, only direct children of that group are returned — used by the pSEO renderer to lazy-load the leaves under a group that summary mode trimmed. Without ``groupId`` the response includes every active component for the service. Supports pagination via ``page``/``size`` and case-insensitive name search via ``search``.", - "operationId": "getComponents", - "parameters": [ - { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "groupId", - "in": "query", - "description": "Restrict result to direct children of this group component id", - "required": false, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "search", - "in": "query", - "description": "Case-insensitive substring match on component name", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "Zero-based page index", - "required": false, - "schema": { - "type": "integer", - "format": "int32" + "summary": "Create a new resource group", + "operationId": "create_7", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateResourceGroupRequest" + } } }, - { - "name": "size", - "in": "query", - "description": "Page size (default 25, max 100)", - "required": false, - "schema": { - "type": "integer", - "format": "int32" - } - } - ], + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultServiceComponentDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -15299,25 +15871,17 @@ } } }, - "/api/v1/services/{slugOrId}/components/{componentId}/uptime": { + "/api/v1/resource-groups/{id}": { "get": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "Get daily uptime data for a component", - "description": "Pass either ``period`` (preset window) or an explicit ``from``/``to`` calendar window (ISO yyyy-MM-dd, max 730 days, ``to`` defaults to today). When both are supplied, the explicit window wins.", - "operationId": "getComponentUptime", + "summary": "Get a resource group by id with member statuses and inherited settings", + "description": "Pass includeMetrics=true to enrich each member with 24h uptime, chart data, and latency metrics.", + "operationId": "get_3", "parameters": [ { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "componentId", + "name": "id", "in": "path", "required": true, "schema": { @@ -15326,38 +15890,12 @@ } }, { - "name": "period", - "in": "query", - "description": "Preset time window (used when ``from`` is omitted)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "7d", - "30d", - "90d", - "1y" - ] - } - }, - { - "name": "from", - "in": "query", - "description": "Explicit window start (ISO date); overrides ``period``", - "required": false, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "to", + "name": "includeMetrics", "in": "query", - "description": "Explicit window end (ISO date); defaults to today", "required": false, "schema": { - "type": "string", - "format": "date" + "type": "boolean", + "default": false } } ], @@ -15367,7 +15905,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -15453,68 +15991,41 @@ } } } - } - }, - "/api/v1/services/{slugOrId}/components/uptime": { - "get": { + }, + "put": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "Batch daily uptime data for all leaf components", - "description": "Returns daily uptime for every active non-group component with uptime data, keyed by component ID. Replaces N individual per-component uptime calls with a single request. Supports either a preset ``period`` or an explicit ``from``/``to`` window (ISO yyyy-MM-dd, max 730 days). The explicit window wins when both are supplied — this is what powers the sliding 90-day navigator on the public uptime history page.", - "operationId": "getBatchComponentUptime", + "summary": "Update a resource group's name, description, alert policy, inherited settings, and health threshold", + "operationId": "update_5", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "period", - "in": "query", - "description": "Preset time window (used when ``from`` is omitted)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "7d", - "30d", - "90d", - "1y" - ] - } - }, - { - "name": "from", - "in": "query", - "description": "Explicit window start (ISO date); overrides ``period``", - "required": false, "schema": { "type": "string", - "format": "date" - } - }, - { - "name": "to", - "in": "query", - "description": "Explicit window end (ISO date); defaults to today", - "required": false, - "schema": { - "type": "string", - "format": "date" + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateResourceGroupRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseBatchComponentUptimeDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -15600,46 +16111,27 @@ } } } - } - }, - "/api/v1/services/{slugOrId}/days/{date}": { - "get": { + }, + "delete": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "One-day rollup for a service: aggregated uptime, per-component impacts, and overlapping incidents", - "description": "Powers the click/hover-to-expand panel under each uptime bar on the public status page. Single round-trip — components, sums, and overlapping incidents (with affected component names) are returned in one response.", - "operationId": "getServiceDayDetail", + "summary": "Delete a resource group (cascades to member rows)", + "operationId": "delete_5", "parameters": [ { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "date", + "name": "id", "in": "path", - "description": "UTC calendar day in ISO format (YYYY-MM-DD)", "required": true, "schema": { "type": "string", - "format": "date" + "format": "uuid" } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceDayDetailDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -15724,51 +16216,22 @@ } } }, - "/api/v1/services/{slugOrId}/incidents": { + "/api/v1/resource-groups/{id}/health": { "get": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "List incident history for a service (paginated)", - "operationId": "listIncidents_1", + "summary": "Get the detailed health breakdown for a resource group", + "description": "Returns member counts, worst-of status, and threshold-based health evaluation. The thresholdStatus field is populated only when a health threshold is configured.", + "operationId": "getHealth", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "from", - "in": "query", - "description": "Earliest start date (ISO 8601 date)", - "required": false, "schema": { "type": "string", - "format": "date" - } - }, - { - "name": "status", - "in": "query", - "description": "Filter: active (unresolved), resolved, or omit for all", - "required": false, - "schema": { - "type": "string", - "enum": [ - "active", - "resolved" - ] - } - }, - { - "name": "pageable", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/Pageable" + "format": "uuid" } } ], @@ -15778,7 +16241,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupHealthDto" } } } @@ -15866,24 +16329,17 @@ } } }, - "/api/v1/services/{slugOrId}/incidents/{incidentId}": { + "/api/v1/resource-groups/{id}/matched-policies": { "get": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "Get incident detail with full update timeline", - "operationId": "getIncident_1", + "summary": "List notification policies that match this resource group", + "description": "Policies whose match rules evaluate true for a DEGRADED or DOWN group-origin INCIDENT_CREATED context on this resource group (includes paused)", + "operationId": "listMatchedPolicies", "parameters": [ { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "incidentId", + "name": "id", "in": "path", "required": true, "schema": { @@ -15898,7 +16354,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceIncidentDetailDto" + "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" } } } @@ -15986,31 +16442,41 @@ } } }, - "/api/v1/services/{slugOrId}/live-status": { - "get": { + "/api/v1/resource-groups/{id}/members": { + "post": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "Lightweight live-status snapshot for polling", - "description": "Returns only the current overall status, component statuses, and active incident count. Designed for frequent polling with minimal payload.", - "operationId": "getServiceLiveStatus", + "summary": "Add a monitor or service member to a resource group", + "operationId": "addMember_1", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddResourceGroupMemberRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceLiveStatusDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupMemberDto" } } } @@ -16098,45 +16564,36 @@ } } }, - "/api/v1/services/{slugOrId}/maintenances": { - "get": { + "/api/v1/resource-groups/{id}/members/{memberId}": { + "delete": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "List scheduled maintenances for a service", - "operationId": "getScheduledMaintenances", + "summary": "Remove a member from a resource group", + "operationId": "removeMember_1", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } }, { - "name": "status", - "in": "query", - "description": "Filter by status (e.g. scheduled, in_progress, verifying, completed)", - "required": false, + "name": "memberId", + "in": "path", + "required": true, "schema": { - "type": "array", - "items": { - "type": "string" - } + "type": "string", + "format": "uuid" } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultScheduledMaintenanceDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -16221,40 +16678,21 @@ } } }, - "/api/v1/services/{slugOrId}/poll-results": { + "/api/v1/revisions/{id}": { "get": { "tags": [ - "Status Data" + "Revisions" ], - "summary": "List poll results for a service (cursor-paginated)", - "operationId": "listPollResults", + "summary": "Get revision package", + "operationId": "get_12", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" - } - }, - { - "name": "cursor", - "in": "query", - "description": "ISO 8601 timestamp cursor from a previous response", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "Page size (1–100, default 50)", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 50 + "type": "string", + "format": "uuid" } } ], @@ -16264,7 +16702,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/CursorPageServicePollResultDto" + "$ref": "#/components/schemas/SingleValueResponseRevisionDto" } } } @@ -16352,47 +16790,28 @@ } } }, - "/api/v1/services/{slugOrId}/poll-summary": { + "/api/v1/revisions/{id}/bundle": { "get": { "tags": [ - "Status Data" + "Revisions" ], - "summary": "Get aggregated poll metrics and chart data for a service", - "operationId": "getPollSummary", + "summary": "Redirect to signed package download", + "description": "Returns 302 Location with a signed GET URL. 404 after downloadUntil.", + "operationId": "bundle", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "window", - "in": "query", - "description": "Time window", - "required": false, "schema": { "type": "string", - "enum": [ - "24h", - "7d", - "30d" - ] + "format": "uuid" } } ], "responses": { "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseServicePollSummaryDto" - } - } - } + "description": "OK" }, "400": { "description": "Bad request — the payload failed validation", @@ -16477,84 +16896,142 @@ } } }, - "/api/v1/services/{slugOrId}/status-events": { + "/api/v1/revisions/{id}/diff/{other}": { "get": { "tags": [ - "Status Data" + "Revisions" ], - "summary": "List curated vendor status events for a service", - "description": "Reverse-chronological merge of vendor incidents, maintenances, and rolled-up component transitions for the Dependencies Detail rail. Optional JWT + x-phelm-org-id annotates incident.opened rows with the caller's linked internal incident.", - "operationId": "listStatusEvents", + "summary": "Compare two revisions (bounded hunks)", + "operationId": "diff", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } }, { - "name": "types", - "in": "query", - "description": "Comma-separated type buckets: incident, maintenance, component (default: all)", - "required": false, + "name": "other", + "in": "path", + "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseRevisionDiffDto" + } + } } }, - { - "name": "period", - "in": "query", - "description": "Preset window", - "required": false, - "schema": { - "type": "string", - "enum": [ - "7d", - "30d", - "90d" - ] + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } }, - { - "name": "from", - "in": "query", - "description": "Explicit lower bound (ISO 8601); overrides period", - "required": false, - "schema": { - "type": "string", - "format": "date-time" + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } }, - { - "name": "to", - "in": "query", - "description": "Explicit upper bound (ISO 8601); default now", - "required": false, - "schema": { - "type": "string", - "format": "date-time" + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } }, - { - "name": "cursor", - "in": "query", - "description": "Opaque cursor from a previous response", - "required": false, - "schema": { - "type": "string" + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/runs": { + "get": { + "tags": [ + "Runs" + ], + "summary": "List code runs", + "description": "Org index. Default from=now-30m. Page size 50.", + "operationId": "listRuns", + "parameters": [ { - "name": "limit", + "name": "params", "in": "query", - "description": "Page size (1–100, default 50)", - "required": false, + "required": true, "schema": { - "type": "integer", - "format": "int32", - "default": 50 + "$ref": "#/components/schemas/RunListParams" } } ], @@ -16564,7 +17041,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/CursorPageStatusEventDto" + "$ref": "#/components/schemas/TableValueResultRunDto" } } } @@ -16652,53 +17129,21 @@ } } }, - "/api/v1/services/{slugOrId}/uptime": { + "/api/v1/runs/{id}": { "get": { "tags": [ - "Status Data" + "Runs" ], - "summary": "Get uptime statistics for a service", - "description": "Uptime data aggregated across active non-group components.", - "operationId": "getServiceUptime", + "summary": "Get a run", + "operationId": "getRun", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "period", - "in": "query", - "description": "Time window", - "required": false, "schema": { "type": "string", - "enum": [ - "24h", - "7d", - "30d", - "90d", - "1y", - "2y", - "all" - ] - } - }, - { - "name": "granularity", - "in": "query", - "description": "Bucket granularity", - "required": false, - "schema": { - "type": "string", - "enum": [ - "hourly", - "daily", - "monthly" - ] + "format": "uuid" } } ], @@ -16708,7 +17153,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceUptimeResponse" + "$ref": "#/components/schemas/SingleValueResponseRunDto" } } } @@ -16793,61 +17238,25 @@ } } } - }, - "security": [ - { - "BearerAuth": [] - } - ] + } } }, - "/api/v1/services/incidents": { + "/api/v1/runs/{id}/artifacts": { "get": { "tags": [ - "Status Data" + "Runs" ], - "summary": "List vendor incidents across all services (paginated)", - "description": "Cross-service vendor incident feed ordered by start date descending.", - "operationId": "listCrossServiceIncidents", + "summary": "List run artifacts", + "description": "Complete persist manifest for this run.", + "operationId": "listRunArtifacts", "parameters": [ { - "name": "from", - "in": "query", - "description": "Earliest start date (ISO 8601 date)", - "required": false, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "status", - "in": "query", - "description": "Filter: active (unresolved), resolved, or omit for all", - "required": false, - "schema": { - "type": "string", - "enum": [ - "active", - "resolved" - ] - } - }, - { - "name": "category", - "in": "query", - "description": "Filter by service category", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "pageable", - "in": "query", + "name": "id", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" } } ], @@ -16857,7 +17266,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" + "$ref": "#/components/schemas/TableValueResultRunArtifactDto" } } } @@ -16945,23 +17354,22 @@ } } }, - "/api/v1/services/summary": { - "get": { + "/api/v1/runs/{id}/cancel": { + "post": { "tags": [ - "Status Data" + "Runs" ], - "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": "Request run cancel", + "description": "Sets cancel_requested; phase unchanged.", + "operationId": "cancelRun", "parameters": [ { - "name": "publishedOnly", - "in": "query", - "description": "Aggregate only published services (curated public pSEO set); default false", - "required": false, + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "boolean", - "default": false + "type": "string", + "format": "uuid" } } ], @@ -16971,7 +17379,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseGlobalStatusSummaryDto" + "$ref": "#/components/schemas/SingleValueResponseRunDto" } } } @@ -17059,20 +17467,41 @@ } } }, - "/api/v1/status-pages": { + "/api/v1/runs/{id}/captures/{artifactId}/compare": { "get": { "tags": [ - "Status Pages" + "Runs" + ], + "summary": "Compare a screenshot to the last pass of this step", + "description": "Captures viewer baseline: last pass of this step in this region, any revision.", + "operationId": "compareRunCapture", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "artifactId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } ], - "summary": "List status pages for the workspace", - "operationId": "list_4", "responses": { "200": { "description": "OK", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageDto" + "$ref": "#/components/schemas/SingleValueResponseCaptureCompareDto" } } } @@ -17158,30 +17587,41 @@ } } } - }, - "post": { + } + }, + "/api/v1/runs/{id}/cases": { + "get": { "tags": [ - "Status Pages" + "Runs" ], - "summary": "Create a status page", - "operationId": "create_5", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageRequest" - } + "summary": "List run cases with nested steps", + "operationId": "listRunCases", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "required": true - }, + { + "name": "params", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/RunCaseListParams" + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + "$ref": "#/components/schemas/TableValueResultRunCaseDto" } } } @@ -17269,13 +17709,14 @@ } } }, - "/api/v1/status-pages/{id}": { + "/api/v1/runs/{id}/console": { "get": { "tags": [ - "Status Pages" + "Runs" ], - "summary": "Get a status page", - "operationId": "get_2", + "summary": "Download raw console log", + "description": "Ungrouped text/plain console lines.", + "operationId": "getRunConsoleRaw", "parameters": [ { "name": "id", @@ -17285,15 +17726,28 @@ "type": "string", "format": "uuid" } + }, + { + "name": "params", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/RunConsoleParams" + } } ], "responses": { "200": { "description": "OK", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + "$ref": "#/components/schemas/SingleValueResponseRunConsoleDto" + } + }, + "text/plain": { + "schema": { + "type": "string" } } } @@ -17379,13 +17833,16 @@ } } } - }, - "put": { + } + }, + "/api/v1/runs/{id}/diff": { + "get": { "tags": [ - "Status Pages" + "Runs" ], - "summary": "Update a status page", - "operationId": "update_3", + "summary": "Diff this run against a prior pass", + "description": "Default baseline is the last pass of the same revision in this region. Pass baselineRunId to pick another finished run of the same monitor.", + "operationId": "getRunDiff", "parameters": [ { "name": "id", @@ -17395,25 +17852,24 @@ "type": "string", "format": "uuid" } + }, + { + "name": "baselineRunId", + "in": "query", + "required": false, + "schema": { + "type": "string", + "format": "uuid" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + "$ref": "#/components/schemas/SingleValueResponseRunDiffDto" } } } @@ -17499,13 +17955,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/runs/{id}/events": { + "get": { "tags": [ - "Status Pages" + "Runs" ], - "summary": "Delete a status page", - "operationId": "delete_3", + "summary": "Stream run control events", + "operationId": "streamRunEvents", "parameters": [ { "name": "id", @@ -17515,11 +17973,34 @@ "type": "string", "format": "uuid" } + }, + { + "name": "params", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/RunEventParams" + } + }, + { + "name": "Last-Event-ID", + "in": "header", + "required": false, + "schema": { + "type": "string" + } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "Server-sent persist control events", + "content": { + "text/event-stream": { + "schema": { + "$ref": "#/components/schemas/RunEventDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -17604,13 +18085,14 @@ } } }, - "/api/v1/status-pages/{id}/components": { + "/api/v1/runs/{id}/export": { "get": { "tags": [ - "Status Pages" + "Runs" ], - "summary": "List all components", - "operationId": "listComponents", + "summary": "Export run snapshot and available artifacts", + "description": "Zip of snapshot.json plus available artifact bytes. Expired files are omitted.", + "operationId": "exportRun", "parameters": [ { "name": "id", @@ -17624,13 +18106,9 @@ ], "responses": { "200": { - "description": "OK", + "description": "Zip of snapshot.json and available artifacts", "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageComponentDto" - } - } + "application/zip": {} } }, "400": { @@ -17714,13 +18192,16 @@ } } } - }, - "post": { + } + }, + "/api/v1/runs/{id}/network": { + "get": { "tags": [ - "Status Pages" + "Runs" ], - "summary": "Add a component to the status page", - "operationId": "createComponent", + "summary": "List run network rows", + "description": "Waterfall collection. Filters: failed, slow, stepId, xhr, source. 500 per page.", + "operationId": "listRunNetwork", "parameters": [ { "name": "id", @@ -17730,25 +18211,23 @@ "type": "string", "format": "uuid" } + }, + { + "name": "params", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/RunNetworkParams" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageComponentRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/RunNetworkDto" } } } @@ -17836,13 +18315,14 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}": { - "put": { + "/api/v1/runs/{id}/network/{rowId}": { + "get": { "tags": [ - "Status Pages" + "Runs" ], - "summary": "Update a component", - "operationId": "updateComponent", + "summary": "Get one network row", + "description": "Includes redacted headers, bodies, and copy-as-cURL.", + "operationId": "getRunNetworkRow", "parameters": [ { "name": "id", @@ -17854,32 +18334,21 @@ } }, { - "name": "componentId", + "name": "rowId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageComponentRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/SingleValueResponseNetworkRowDto" } } } @@ -17965,13 +18434,16 @@ } } } - }, - "delete": { + } + }, + "/api/v1/runs/{id}/runner-log": { + "get": { "tags": [ - "Status Pages" + "Runs" ], - "summary": "Remove a component from the status page", - "operationId": "deleteComponent", + "summary": "Snapshot in-flight runner log", + "description": "Hot Loki snapshot (text/plain) of lines so far. This is not live tail — poll this endpoint or use GET /runner-log/live (SSE). After finish, the cold file is the runner_log artifact (GET /artifacts/{id}/content). Empty while no lines have been pushed.", + "operationId": "getRunRunnerLog", "parameters": [ { "name": "id", @@ -17981,20 +18453,23 @@ "type": "string", "format": "uuid" } - }, - { - "name": "componentId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + }, + "*/*": { + "schema": { + "type": "string" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -18079,14 +18554,14 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}/measured-uptime": { + "/api/v1/runs/{id}/runner-log/live": { "get": { "tags": [ - "Status Pages" + "Runs" ], - "summary": "Get measured (check-based) component uptime history", - "description": "Additive measured daily uptime for MONITOR components (ASK-SP-2 / CHG-2). Reads time-bounded check_results_daily rollups for the linked monitor. Response source is always measured. Does not change legacy GET …/uptime incident-window semantics. days default 90, max 365.", - "operationId": "componentMeasuredUptime", + "summary": "Live tail runner log", + "description": "SSE live tail of in-flight Loki lines. Same ACL as the snapshot (runs.get). Each event data is JSON {ts,line} (ts is Loki nanoseconds, line is one log line). Loki stays internal. Closes on client disconnect, idle/run-finished, or the same SSE timeout as GET /events. Cold file after finish is the runner_log artifact.", + "operationId": "streamRunRunnerLog", "parameters": [ { "name": "id", @@ -18096,34 +18571,15 @@ "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": { "200": { - "description": "OK", + "description": "Server-sent runner-log lines", "content": { - "*/*": { + "text/event-stream": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageMeasuredComponentUptimeDto" + "$ref": "#/components/schemas/RunnerLogLiveEvent" } } } @@ -18211,51 +18667,20 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}/override": { - "put": { + "/api/v1/secrets": { + "get": { "tags": [ - "Status Pages" - ], - "summary": "Set a timed human status override on a component", - "description": "ASK-SP-1 / CHG-1. Effective currentStatus reflects the override until expiry or clear, unless an active incident takes precedence (incident > override > binding). Max expiry horizon is 24 hours.", - "operationId": "setComponentOverride", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "componentId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "Secrets" ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SetStatusPageComponentOverrideRequest" - } - } - }, - "required": true - }, + "summary": "List organization secrets", + "operationId": "list_5", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/TableValueResultSecretDto" } } } @@ -18342,39 +18767,29 @@ } } }, - "delete": { + "post": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "Clear a timed human status override on a component", - "operationId": "clearComponentOverride", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" + "summary": "Create secret", + "operationId": "create_6", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSecretRequest" + } } }, - { - "name": "componentId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/SingleValueResponseSecretDto" } } } @@ -18462,51 +18877,40 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}/uptime": { - "get": { + "/api/v1/secrets/{key}": { + "put": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "Get component uptime history from published incident windows", - "description": "Legacy incident-window rollup (source semantics: incident_window). Daily % is derived from published status-page incident windows, not probe checks. For measured check-based uptime use GET …/measured-uptime (ASK-SP-2 / CHG-2).", - "operationId": "componentUptime_1", + "summary": "Update secret", + "operationId": "update_4", "parameters": [ { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "componentId", + "name": "key", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "days", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 90 + "type": "string" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSecretRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" + "$ref": "#/components/schemas/SingleValueResponseSecretDto" } } } @@ -18592,36 +18996,23 @@ } } } - } - }, - "/api/v1/status-pages/{id}/components/reorder": { - "put": { + }, + "delete": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "Batch reorder components (and optionally move between groups)", - "operationId": "reorderComponents", + "summary": "Delete secret", + "operationId": "delete_4", "parameters": [ { - "name": "id", + "name": "key", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ReorderComponentsRequest" - } - } - }, - "required": true - }, "responses": { "204": { "description": "No Content" @@ -18709,21 +19100,20 @@ } } }, - "/api/v1/status-pages/{id}/domains": { + "/api/v1/secrets/{key}/audit": { "get": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "List custom domains", - "operationId": "listDomains", + "summary": "Last update metadata for a secret", + "operationId": "audit", "parameters": [ { - "name": "id", + "name": "key", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } } ], @@ -18733,7 +19123,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageCustomDomainDto" + "$ref": "#/components/schemas/SingleValueResponseSecretAuditDto" } } } @@ -18819,16 +19209,26 @@ } } } - }, - "post": { + } + }, + "/api/v1/secrets/{key}/environments/{environmentId}": { + "put": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "Add a custom domain", - "operationId": "addDomain", + "summary": "Write a secret value for one environment", + "operationId": "writeEnvironmentValue", "parameters": [ { - "name": "id", + "name": "key", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "environmentId", "in": "path", "required": true, "schema": { @@ -18841,22 +19241,15 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AddCustomDomainRequest" + "$ref": "#/components/schemas/WriteSecretEnvironmentValueRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -18941,36 +19334,134 @@ } } }, - "/api/v1/status-pages/{id}/domains/{domainId}": { - "delete": { + "/api/v1/secrets/{key}/usage": { + "get": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "Remove a custom domain", - "operationId": "removeDomain", + "summary": "Secret usage across monitors", + "operationId": "usage", "parameters": [ { - "name": "id", + "name": "key", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseSecretUsageDto" + } + } } }, - { - "name": "domainId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } } + } + } + }, + "/api/v1/service-subscriptions": { + "get": { + "tags": [ + "Service Subscriptions" ], + "summary": "List all service subscriptions for the organization", + "operationId": "list_16", "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultServiceSubscriptionDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -19055,13 +19546,13 @@ } } }, - "/api/v1/status-pages/{id}/domains/{domainId}/primary": { - "post": { + "/api/v1/service-subscriptions/{id}": { + "get": { "tags": [ - "Status Pages" + "Service Subscriptions" ], - "summary": "Mark a verified custom domain as the page's primary host", - "operationId": "setPrimaryDomain", + "summary": "Get a subscription by its ID", + "operationId": "get_11", "parameters": [ { "name": "id", @@ -19071,15 +19562,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "domainId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], "responses": { @@ -19088,7 +19570,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" } } } @@ -19174,15 +19656,14 @@ } } } - } - }, - "/api/v1/status-pages/{id}/domains/{domainId}/verify": { - "post": { + }, + "delete": { "tags": [ - "Status Pages" + "Service Subscriptions" ], - "summary": "Trigger domain verification check", - "operationId": "verifyDomain", + "summary": "Remove a subscription by its ID", + "description": "Removes a specific subscription (whole-service or component-level). No-op if not found.", + "operationId": "unsubscribe_1", "parameters": [ { "name": "id", @@ -19192,27 +19673,11 @@ "type": "string", "format": "uuid" } - }, - { - "name": "domainId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -19297,13 +19762,14 @@ } } }, - "/api/v1/status-pages/{id}/groups": { - "get": { + "/api/v1/service-subscriptions/{id}/alert-sensitivity": { + "patch": { "tags": [ - "Status Pages" + "Service Subscriptions" ], - "summary": "List component groups with nested components", - "operationId": "listGroups", + "summary": "Update alert sensitivity for a subscription", + "description": "Controls which external incidents trigger alerts and whether they page anyone: ALL (any status change, paged), INCIDENTS_ONLY (real vendor incidents, paged), MAJOR_ONLY (only DOWN-level incidents, paged), AWARENESS (real vendor incidents tracked silently — visible on the dashboard but no alert channels fire; default for new subscriptions).", + "operationId": "updateAlertSensitivity", "parameters": [ { "name": "id", @@ -19315,13 +19781,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateAlertSensitivityRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageComponentGroupDto" + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" } } } @@ -19407,21 +19883,23 @@ } } } - }, + } + }, + "/api/v1/service-subscriptions/{slug}": { "post": { "tags": [ - "Status Pages" + "Service Subscriptions" ], - "summary": "Create a component group", - "operationId": "createGroup", + "summary": "Subscribe to a service or a component of a service", + "description": "Idempotent — returns the existing subscription if an identical one exists. Omit the request body or set componentId to null for a whole-service subscription. When alertSensitivity is omitted, new subscriptions default to AWARENESS (silent tracking — the incident appears on the dashboard but no alert channels fire). PATCH /alert-sensitivity to opt in to paging. Free tier: max 10 subscriptions. Paid tier: unlimited.", + "operationId": "subscribe_1", "parameters": [ { - "name": "id", + "name": "slug", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } } ], @@ -19429,11 +19907,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateStatusPageComponentGroupRequest" + "$ref": "#/components/schemas/ServiceSubscribeRequest" } } - }, - "required": true + } }, "responses": { "201": { @@ -19441,7 +19918,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" } } } @@ -19529,50 +20006,96 @@ } } }, - "/api/v1/status-pages/{id}/groups/{groupId}": { - "put": { + "/api/v1/services": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Update a component group", - "operationId": "updateGroup", + "summary": "List all enabled services (cursor-paginated)", + "operationId": "listServices", "parameters": [ { - "name": "id", - "in": "path", - "required": true, + "name": "category", + "in": "query", + "description": "Filter by category (exact match)", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { - "name": "groupId", - "in": "path", - "required": true, + "name": "status", + "in": "query", + "description": "Filter by current overall_status (exact match)", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageComponentGroupRequest" - } + }, + { + "name": "published", + "in": "query", + "description": "Filter by published status for pSEO pages", + "required": false, + "schema": { + "type": "boolean" } }, - "required": true - }, + { + "name": "slaPublished", + "in": "query", + "description": "Filter by SLA page publication status", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "search", + "in": "query", + "description": "Case-insensitive substring match on service name or slug", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Result ordering: 'recent' (default, newest first) or 'curated' (curated/recognizable first)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor from a previous response", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size (1–100, default 20)", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 20 + } + } + ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" + "$ref": "#/components/schemas/CursorPageServiceCatalogDto" } } } @@ -19658,36 +20181,56 @@ } } } - }, - "delete": { + } + }, + "/api/v1/services/{slugOrId}": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Delete a component group (components become ungrouped)", - "operationId": "deleteGroup", + "summary": "Get a single service by slug or UUID with current status, components, and recent incidents", + "description": "When ``summary=true``, the inline ``components`` list is trimmed to groups + showcase leaves + currently-impacted leaves + ungrouped leaves, and a ``componentsSummary`` block is added with the trimmed counts. Powers SSR for vendors with hundreds of components (Snowflake, Cloudflare, DigitalOcean) without OOM-ing the renderer. Default false for full back-compat.", + "operationId": "getService", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { - "name": "groupId", - "in": "path", - "required": true, + "name": "summary", + "in": "query", + "description": "Return a curated subset of components (groups + showcase + impacted + ungrouped) and a componentsSummary block; default false", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "boolean", + "default": false + } + }, + { + "name": "publishedOnly", + "in": "query", + "description": "Resolve only published services (curated public pSEO set); 404 otherwise. Default false", + "required": false, + "schema": { + "type": "boolean", + "default": false } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseServiceDetailDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -19772,46 +20315,60 @@ } } }, - "/api/v1/status-pages/{id}/incidents": { + "/api/v1/services/{slugOrId}/components": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "List incidents for this status page (paginated)", - "operationId": "listIncidents", + "summary": "List active components for a service with current status and inline uptime", + "description": "When ``groupId`` is supplied, only direct children of that group are returned — used by the pSEO renderer to lazy-load the leaves under a group that summary mode trimmed. Without ``groupId`` the response includes every active component for the service. Supports pagination via ``page``/``size`` and case-insensitive name search via ``search``.", + "operationId": "getComponents", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Restrict result to direct children of this group component id", + "required": false, "schema": { "type": "string", "format": "uuid" } }, { - "name": "status", + "name": "search", "in": "query", + "description": "Case-insensitive substring match on component name", "required": false, "schema": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] - } + "type": "string" } }, { - "name": "pageable", + "name": "page", "in": "query", - "required": true, + "description": "Zero-based page index", + "required": false, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "integer", + "format": "int32" + } + }, + { + "name": "size", + "in": "query", + "description": "Page size (default 25, max 100)", + "required": false, + "schema": { + "type": "integer", + "format": "int32" } } ], @@ -19821,7 +20378,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" + "$ref": "#/components/schemas/TableValueResultServiceComponentDto" } } } @@ -19907,41 +20464,77 @@ } } } - }, - "post": { + } + }, + "/api/v1/services/{slugOrId}/components/{componentId}/uptime": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Create a status page incident (manual)", - "operationId": "createIncident", + "summary": "Get daily uptime data for a component", + "description": "Pass either ``period`` (preset window) or an explicit ``from``/``to`` calendar window (ISO yyyy-MM-dd, max 730 days, ``to`` defaults to today). When both are supplied, the explicit window wins.", + "operationId": "getComponentUptime", "parameters": [ { - "name": "id", + "name": "slugOrId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "componentId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageIncidentRequest" - } + }, + { + "name": "period", + "in": "query", + "description": "Preset time window (used when ``from`` is omitted)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "7d", + "30d", + "90d", + "1y" + ] } }, - "required": true - }, + { + "name": "from", + "in": "query", + "description": "Explicit window start (ISO date); overrides ``period``", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "to", + "in": "query", + "description": "Explicit window end (ISO date); defaults to today", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" } } } @@ -20029,30 +20622,56 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}": { + "/api/v1/services/{slugOrId}/components/uptime": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Get incident details with timeline", - "operationId": "getIncident", + "summary": "Batch daily uptime data for all leaf components", + "description": "Returns daily uptime for every active non-group component with uptime data, keyed by component ID. Replaces N individual per-component uptime calls with a single request. Supports either a preset ``period`` or an explicit ``from``/``to`` window (ISO yyyy-MM-dd, max 730 days). The explicit window wins when both are supplied — this is what powers the sliding 90-day navigator on the public uptime history page.", + "operationId": "getBatchComponentUptime", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "period", + "in": "query", + "description": "Preset time window (used when ``from`` is omitted)", + "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "7d", + "30d", + "90d", + "1y" + ] } }, { - "name": "incidentId", - "in": "path", - "required": true, + "name": "from", + "in": "query", + "description": "Explicit window start (ISO date); overrides ``period``", + "required": false, "schema": { "type": "string", - "format": "uuid" + "format": "date" + } + }, + { + "name": "to", + "in": "query", + "description": "Explicit window end (ISO date); defaults to today", + "required": false, + "schema": { + "type": "string", + "format": "date" } } ], @@ -20062,7 +20681,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseBatchComponentUptimeDto" } } } @@ -20148,50 +20767,43 @@ } } } - }, - "put": { + } + }, + "/api/v1/services/{slugOrId}/days/{date}": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Update an incident", - "operationId": "updateIncident", + "summary": "One-day rollup for a service: aggregated uptime, per-component impacts, and overlapping incidents", + "description": "Powers the click/hover-to-expand panel under each uptime bar on the public status page. Single round-trip — components, sums, and overlapping incidents (with affected component names) are returned in one response.", + "operationId": "getServiceDayDetail", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { - "name": "incidentId", + "name": "date", "in": "path", + "description": "UTC calendar day in ISO format (YYYY-MM-DD)", "required": true, "schema": { "type": "string", - "format": "uuid" + "format": "date" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageIncidentRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseServiceDayDetailDto" } } } @@ -20277,36 +20889,66 @@ } } } - }, - "delete": { + } + }, + "/api/v1/services/{slugOrId}/incidents": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Delete an incident", - "operationId": "deleteIncident", + "summary": "List incident history for a service (paginated)", + "operationId": "listIncidents_1", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "from", + "in": "query", + "description": "Earliest start date (ISO 8601 date)", + "required": false, "schema": { "type": "string", - "format": "uuid" + "format": "date" } }, { - "name": "incidentId", - "in": "path", - "required": true, + "name": "status", + "in": "query", + "description": "Filter: active (unresolved), resolved, or omit for all", + "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "active", + "resolved" + ] + } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -20391,21 +21033,20 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/dismiss": { - "post": { + "/api/v1/services/{slugOrId}/incidents/{incidentId}": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Dismiss a draft incident (soft-deletes: resolves without publishing)", - "operationId": "dismissIncident", + "summary": "Get incident detail with full update timeline", + "operationId": "getIncident_1", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { @@ -20419,8 +21060,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseServiceIncidentDetailDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -20505,49 +21153,31 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/publish": { - "post": { + "/api/v1/services/{slugOrId}/live-status": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Publish a draft incident (sets publishedAt, applies component statuses, notifies subscribers)", - "operationId": "publishIncident", + "summary": "Lightweight live-status snapshot for polling", + "description": "Returns only the current overall status, component statuses, and active incident count. Designed for frequent polling with minimal payload.", + "operationId": "getServiceLiveStatus", "parameters": [ { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "incidentId", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PublishStatusPageIncidentRequest" - } - } - } - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseServiceLiveStatusDto" } } } @@ -20635,50 +21265,42 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/updates": { - "post": { + "/api/v1/services/{slugOrId}/maintenances": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Post an incident timeline update", - "operationId": "postIncidentUpdate", + "summary": "List scheduled maintenances for a service", + "operationId": "getScheduledMaintenances", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { - "name": "incidentId", - "in": "path", - "required": true, + "name": "status", + "in": "query", + "description": "Filter by status (e.g. scheduled, in_progress, verifying, completed)", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "array", + "items": { + "type": "string" + } } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageIncidentUpdateRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/TableValueResultScheduledMaintenanceDto" } } } @@ -20766,59 +21388,50 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/updates/{updateId}": { - "patch": { + "/api/v1/services/{slugOrId}/poll-results": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Edit an existing incident timeline update body", - "operationId": "patchIncidentUpdate", + "summary": "List poll results for a service (cursor-paginated)", + "operationId": "listPollResults", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { - "name": "incidentId", - "in": "path", - "required": true, + "name": "cursor", + "in": "query", + "description": "ISO 8601 timestamp cursor from a previous response", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } }, { - "name": "updateId", - "in": "path", - "required": true, + "name": "limit", + "in": "query", + "description": "Page size (1–100, default 50)", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "integer", + "format": "int32", + "default": 50 } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageIncidentUpdateRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentUpdateDto" + "$ref": "#/components/schemas/CursorPageServicePollResultDto" } } } @@ -20906,38 +21519,48 @@ } } }, - "/api/v1/status-pages/{id}/layout/reorder": { - "put": { + "/api/v1/services/{slugOrId}/poll-summary": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Reorder page-level layout: groups and ungrouped components share one ordering", - "operationId": "reorderLayout", + "summary": "Get aggregated poll metrics and chart data for a service", + "operationId": "getPollSummary", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "window", + "in": "query", + "description": "Time window", + "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "24h", + "7d", + "30d" + ] } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ReorderPageLayoutRequest" + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseServicePollSummaryDto" + } } } }, - "required": true - }, - "responses": { - "204": { - "description": "No Content" - }, "400": { "description": "Bad request — the payload failed validation", "content": { @@ -21021,46 +21644,84 @@ } } }, - "/api/v1/status-pages/{id}/maintenance": { + "/api/v1/services/{slugOrId}/status-events": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "List maintenance windows for this status page (paginated)", - "operationId": "listMaintenance", + "summary": "List curated vendor status events for a service", + "description": "Reverse-chronological merge of vendor incidents, maintenances, and rolled-up component transitions for the Dependencies Detail rail. Optional JWT + x-phelm-org-id annotates incident.opened rows with the caller's linked internal incident.", + "operationId": "listStatusEvents", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "types", + "in": "query", + "description": "Comma-separated type buckets: incident, maintenance, component (default: all)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "period", + "in": "query", + "description": "Preset window", + "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "7d", + "30d", + "90d" + ] } }, { - "name": "status", + "name": "from", "in": "query", + "description": "Explicit lower bound (ISO 8601); overrides period", "required": false, "schema": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] - } + "type": "string", + "format": "date-time" } }, { - "name": "pageable", + "name": "to", "in": "query", - "required": true, + "description": "Explicit upper bound (ISO 8601); default now", + "required": false, "schema": { - "$ref": "#/components/schemas/Pageable" + "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 } } ], @@ -21070,7 +21731,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" + "$ref": "#/components/schemas/CursorPageStatusEventDto" } } } @@ -21156,41 +21817,65 @@ } } } - }, - "post": { + } + }, + "/api/v1/services/{slugOrId}/uptime": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Schedule a maintenance window", - "operationId": "createMaintenance", + "summary": "Get uptime statistics for a service", + "description": "Uptime data aggregated across active non-group components.", + "operationId": "getServiceUptime", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "period", + "in": "query", + "description": "Time window", + "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "24h", + "7d", + "30d", + "90d", + "1y", + "2y", + "all" + ] + } + }, + { + "name": "granularity", + "in": "query", + "description": "Bucket granularity", + "required": false, + "schema": { + "type": "string", + "enum": [ + "hourly", + "daily", + "monthly" + ] } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageMaintenanceRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseServiceUptimeResponse" } } } @@ -21275,33 +21960,61 @@ } } } - } + }, + "security": [ + { + "BearerAuth": [] + } + ] } }, - "/api/v1/status-pages/{id}/maintenance/{windowId}": { + "/api/v1/services/incidents": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Get a maintenance window with timeline", - "operationId": "getMaintenance", + "summary": "List vendor incidents across all services (paginated)", + "description": "Cross-service vendor incident feed ordered by start date descending.", + "operationId": "listCrossServiceIncidents", "parameters": [ { - "name": "id", - "in": "path", - "required": true, + "name": "from", + "in": "query", + "description": "Earliest start date (ISO 8601 date)", + "required": false, "schema": { "type": "string", - "format": "uuid" + "format": "date" } }, { - "name": "windowId", - "in": "path", - "required": true, + "name": "status", + "in": "query", + "description": "Filter: active (unresolved), resolved, or omit for all", + "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "active", + "resolved" + ] + } + }, + { + "name": "category", + "in": "query", + "description": "Filter by service category", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" } } ], @@ -21311,7 +22024,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" } } } @@ -21397,50 +22110,35 @@ } } } - }, - "put": { + } + }, + "/api/v1/services/summary": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Update a maintenance window", - "operationId": "updateMaintenance", + "summary": "Global status summary across all services", + "description": "Returns aggregate counts of services by status and a list of services currently experiencing issues.", + "operationId": "getGlobalStatusSummary", "parameters": [ { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "windowId", - "in": "path", - "required": true, + "name": "publishedOnly", + "in": "query", + "description": "Aggregate only published services (curated public pSEO set); default false", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "boolean", + "default": false } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageIncidentRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseGlobalStatusSummaryDto" } } } @@ -21526,36 +22224,25 @@ } } } - }, - "delete": { + } + }, + "/api/v1/status-pages": { + "get": { "tags": [ "Status Pages" ], - "summary": "Cancel a maintenance window", - "operationId": "deleteMaintenance", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "windowId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], + "summary": "List status pages for the workspace", + "operationId": "list_4", "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -21638,38 +22325,33 @@ } } } - } - }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/dismiss": { + }, "post": { "tags": [ "Status Pages" ], - "summary": "Dismiss a draft maintenance window", - "operationId": "dismissMaintenance", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" + "summary": "Create a status page", + "operationId": "create_5", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageRequest" + } } }, - { - "name": "windowId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], + "required": true + }, "responses": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -21754,13 +22436,13 @@ } } }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/publish": { - "post": { + "/api/v1/status-pages/{id}": { + "get": { "tags": [ "Status Pages" ], - "summary": "Publish a draft maintenance window", - "operationId": "publishMaintenance", + "summary": "Get a status page", + "operationId": "get_2", "parameters": [ { "name": "id", @@ -21770,33 +22452,15 @@ "type": "string", "format": "uuid" } - }, - { - "name": "windowId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PublishStatusPageIncidentRequest" - } - } - } - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" } } } @@ -21882,15 +22546,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/updates": { - "post": { + }, + "put": { "tags": [ "Status Pages" ], - "summary": "Post a maintenance window timeline update", - "operationId": "postMaintenanceUpdate", + "summary": "Update a status page", + "operationId": "update_3", "parameters": [ { "name": "id", @@ -21900,34 +22562,25 @@ "type": "string", "format": "uuid" } - }, - { - "name": "windowId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateStatusPageIncidentUpdateRequest" + "$ref": "#/components/schemas/UpdateStatusPageRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" } } } @@ -22013,15 +22666,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/updates/{updateId}": { - "patch": { + }, + "delete": { "tags": [ "Status Pages" ], - "summary": "Edit an existing maintenance timeline update body", - "operationId": "patchMaintenanceUpdate", + "summary": "Delete a status page", + "operationId": "delete_3", "parameters": [ { "name": "id", @@ -22031,46 +22682,11 @@ "type": "string", "format": "uuid" } - }, - { - "name": "windowId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "updateId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageIncidentUpdateRequest" - } - } - }, - "required": true - }, "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentUpdateDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -22155,14 +22771,13 @@ } } }, - "/api/v1/status-pages/{id}/notification-deliveries": { + "/api/v1/status-pages/{id}/components": { "get": { "tags": [ "Status Pages" ], - "summary": "List notification delivery receipts", - "description": "Returns delivery rows for this status page (newest first). Optional filters: incidentId, eventType.", - "operationId": "listNotificationDeliveries", + "summary": "List all components", + "operationId": "listComponents", "parameters": [ { "name": "id", @@ -22172,29 +22787,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "incidentId", - "in": "query", - "required": false, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "eventType", - "in": "query", - "required": false, - "schema": { - "type": "string", - "enum": [ - "SUBSCRIPTION_CONFIRMATION", - "INCIDENT_CREATED", - "INCIDENT_UPDATED", - "INCIDENT_RESOLVED" - ] - } } ], "responses": { @@ -22203,7 +22795,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageNotificationDeliveryDto" + "$ref": "#/components/schemas/TableValueResultStatusPageComponentDto" } } } @@ -22289,15 +22881,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/notification-deliveries/{deliveryId}": { - "get": { + }, + "post": { "tags": [ "Status Pages" ], - "summary": "Get a notification delivery receipt", - "operationId": "getNotificationDelivery", + "summary": "Add a component to the status page", + "operationId": "createComponent", "parameters": [ { "name": "id", @@ -22307,24 +22897,25 @@ "type": "string", "format": "uuid" } - }, - { - "name": "deliveryId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageComponentRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageNotificationDeliveryDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" } } } @@ -22412,14 +23003,13 @@ } } }, - "/api/v1/status-pages/{id}/notification-deliveries/{deliveryId}/retry": { - "post": { + "/api/v1/status-pages/{id}/components/{componentId}": { + "put": { "tags": [ "Status Pages" ], - "summary": "Retry a failed notification delivery", - "description": "Queues a FAILED delivery for another attempt. Refuses terminal attempt_count (~5). Idempotent when already RETRY_PENDING.", - "operationId": "retryNotificationDelivery", + "summary": "Update a component", + "operationId": "updateComponent", "parameters": [ { "name": "id", @@ -22431,7 +23021,7 @@ } }, { - "name": "deliveryId", + "name": "componentId", "in": "path", "required": true, "schema": { @@ -22440,13 +23030,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageComponentRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageNotificationDeliveryDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" } } } @@ -22532,15 +23132,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/subscribers": { - "get": { + }, + "delete": { "tags": [ "Status Pages" ], - "summary": "List subscribers including awaiting confirmation (paginated)", - "operationId": "listSubscribers", + "summary": "Remove a component from the status page", + "operationId": "deleteComponent", "parameters": [ { "name": "id", @@ -22552,24 +23150,18 @@ } }, { - "name": "pageable", - "in": "query", + "name": "componentId", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageSubscriberDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -22652,13 +23244,16 @@ } } } - }, - "post": { + } + }, + "/api/v1/status-pages/{id}/components/{componentId}/measured-uptime": { + "get": { "tags": [ "Status Pages" ], - "summary": "Add a subscriber; requireConfirmation=true for EMAIL double opt-in, omit/false confirms immediately", - "operationId": "addSubscriber", + "summary": "Get measured (check-based) component uptime history", + "description": "Additive measured daily uptime for MONITOR components (ASK-SP-2 / CHG-2). Reads time-bounded check_results_daily rollups for the linked monitor. Response source is always measured. Does not change legacy GET …/uptime incident-window semantics. days default 90, max 365.", + "operationId": "componentMeasuredUptime", "parameters": [ { "name": "id", @@ -22668,25 +23263,34 @@ "type": "string", "format": "uuid" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AdminAddSubscriberRequest" - } + }, + { + "name": "componentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "required": true - }, + { + "name": "days", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 90 + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageSubscriberDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageMeasuredComponentUptimeDto" } } } @@ -22774,13 +23378,14 @@ } } }, - "/api/v1/status-pages/{id}/subscribers/{subscriberId}": { - "delete": { + "/api/v1/status-pages/{id}/components/{componentId}/override": { + "put": { "tags": [ "Status Pages" ], - "summary": "Remove a subscriber", - "operationId": "removeSubscriber", + "summary": "Set a timed human status override on a component", + "description": "ASK-SP-1 / CHG-1. Effective currentStatus reflects the override until expiry or clear, unless an active incident takes precedence (incident > override > binding). Max expiry horizon is 24 hours.", + "operationId": "setComponentOverride", "parameters": [ { "name": "id", @@ -22792,7 +23397,7 @@ } }, { - "name": "subscriberId", + "name": "componentId", "in": "path", "required": true, "schema": { @@ -22801,117 +23406,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/SetStatusPageComponentOverrideRequest" } } }, - "503": { - "description": "Service unavailable — try again shortly", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v1/tags": { - "get": { - "tags": [ - "Tags" - ], - "summary": "List tags for the authenticated organization", - "operationId": "list_3", - "parameters": [ - { - "name": "pageable", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/Pageable" - } - } - ], + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" } } } @@ -22998,29 +23509,39 @@ } } }, - "post": { + "delete": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "Create a new tag", - "operationId": "create_4", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateTagRequest" - } + "summary": "Clear a timed human status override on a component", + "operationId": "clearComponentOverride", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "required": true - }, + { + "name": "componentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseTagDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" } } } @@ -23108,13 +23629,14 @@ } } }, - "/api/v1/tags/{id}": { + "/api/v1/status-pages/{id}/components/{componentId}/uptime": { "get": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "Get a tag by ID", - "operationId": "getById", + "summary": "Get component uptime history from published incident windows", + "description": "Legacy incident-window rollup (source semantics: incident_window). Daily % is derived from published status-page incident windows, not probe checks. For measured check-based uptime use GET …/measured-uptime (ASK-SP-2 / CHG-2).", + "operationId": "componentUptime_1", "parameters": [ { "name": "id", @@ -23124,6 +23646,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": { @@ -23132,7 +23673,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseTagDto" + "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" } } } @@ -23218,13 +23759,15 @@ } } } - }, + } + }, + "/api/v1/status-pages/{id}/components/reorder": { "put": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "Update a tag's name and/or color", - "operationId": "update_2", + "summary": "Batch reorder components (and optionally move between groups)", + "operationId": "reorderComponents", "parameters": [ { "name": "id", @@ -23240,22 +23783,15 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateTagRequest" + "$ref": "#/components/schemas/ReorderComponentsRequest" } } }, "required": true }, "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseTagDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -23338,13 +23874,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/status-pages/{id}/domains": { + "get": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "Delete a tag (cascades to all monitor associations)", - "operationId": "delete_2", + "summary": "List custom domains", + "operationId": "listDomains", "parameters": [ { "name": "id", @@ -23356,108 +23894,13 @@ } } ], - "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/vaults/rotate": { - "post": { - "tags": [ - "Vault" - ], - "summary": "Rotate DEK", - "description": "Generates a new Data Encryption Key, re-encrypts all secrets and alert-channel configs, and bumps the vault version. Admin-only. Pipeline DEK caches expire within ~10 minutes.", - "operationId": "rotateDek", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseDekRotationResultDto" + "$ref": "#/components/schemas/TableValueResultStatusPageCustomDomainDto" } } } @@ -23543,32 +23986,41 @@ } } } - } - }, - "/api/v1/webhooks": { - "get": { + }, + "post": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "List webhook endpoints for the authenticated org", - "operationId": "list_2", + "summary": "Add a custom domain", + "operationId": "addDomain", "parameters": [ { - "name": "pageable", - "in": "query", + "name": "id", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddCustomDomainRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultWebhookEndpointDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" } } } @@ -23654,33 +24106,38 @@ } } } - }, - "post": { + } + }, + "/api/v1/status-pages/{id}/domains/{domainId}": { + "delete": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Register a new webhook endpoint", - "operationId": "create_3", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateWebhookEndpointRequest" - } + "summary": "Remove a custom domain", + "operationId": "removeDomain", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "required": true - }, - "responses": { - "201": { - "description": "Created", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" - } - } + { + "name": "domainId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } + } + ], + "responses": { + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -23765,13 +24222,13 @@ } } }, - "/api/v1/webhooks/{id}": { - "get": { + "/api/v1/status-pages/{id}/domains/{domainId}/primary": { + "post": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Get a single webhook endpoint", - "operationId": "get_1", + "summary": "Mark a verified custom domain as the page's primary host", + "operationId": "setPrimaryDomain", "parameters": [ { "name": "id", @@ -23781,6 +24238,15 @@ "type": "string", "format": "uuid" } + }, + { + "name": "domainId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], "responses": { @@ -23789,7 +24255,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" } } } @@ -23875,13 +24341,15 @@ } } } - }, - "put": { + } + }, + "/api/v1/status-pages/{id}/domains/{domainId}/verify": { + "post": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Update a webhook endpoint", - "operationId": "update_1", + "summary": "Trigger domain verification check", + "operationId": "verifyDomain", "parameters": [ { "name": "id", @@ -23891,25 +24359,24 @@ "type": "string", "format": "uuid" } + }, + { + "name": "domainId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateWebhookEndpointRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" } } } @@ -23995,13 +24462,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/status-pages/{id}/groups": { + "get": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Delete a webhook endpoint", - "operationId": "delete_1", + "summary": "List component groups with nested components", + "operationId": "listGroups", "parameters": [ { "name": "id", @@ -24014,8 +24483,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageComponentGroupDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -24098,15 +24574,13 @@ } } } - } - }, - "/api/v1/webhooks/{id}/deliveries": { - "get": { + }, + "post": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "List recent deliveries for a webhook endpoint", - "operationId": "listDeliveries", + "summary": "Create a component group", + "operationId": "createGroup", "parameters": [ { "name": "id", @@ -24116,25 +24590,25 @@ "type": "string", "format": "uuid" } - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 20 - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageComponentGroupRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultWebhookDeliveryDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" } } } @@ -24222,13 +24696,13 @@ } } }, - "/api/v1/webhooks/{id}/test": { - "post": { + "/api/v1/status-pages/{id}/groups/{groupId}": { + "put": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Send a test delivery to a webhook endpoint", - "operationId": "test", + "summary": "Update a component group", + "operationId": "updateGroup", "parameters": [ { "name": "id", @@ -24238,16 +24712,26 @@ "type": "string", "format": "uuid" } + }, + { + "name": "groupId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TestWebhookEndpointRequest" + "$ref": "#/components/schemas/UpdateStatusPageComponentGroupRequest" } } - } + }, + "required": true }, "responses": { "200": { @@ -24255,7 +24739,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookTestResult" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" } } } @@ -24341,26 +24825,36 @@ } } } - } - }, - "/api/v1/webhooks/events": { - "get": { + }, + "delete": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "List all available webhook event types", - "description": "Returns the full catalog of supported outbound webhook event types with their surface grouping and human-readable descriptions. Use this to populate subscription checkboxes when creating or updating a webhook endpoint.", - "operationId": "listEvents", - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/WebhookEventCatalogResponse" - } - } + "summary": "Delete a component group (components become ungrouped)", + "operationId": "deleteGroup", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "groupId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } + } + ], + "responses": { + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -24445,121 +24939,56 @@ } } }, - "/api/v1/webhooks/signing-secret": { + "/api/v1/status-pages/{id}/incidents": { "get": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Get signing secret metadata for the authenticated org", - "operationId": "getSigningSecretInfo", - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookSigningSecretDto" - } - } - } - }, - "400": { - "description": "Bad request — the payload failed validation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "401": { - "description": "Unauthorized — missing or invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "403": { - "description": "Forbidden — the actor lacks permission for this resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "404": { - "description": "Not found — the requested resource does not exist", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "409": { - "description": "Conflict — the request collides with current resource state", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + "summary": "List incidents for this status page (paginated)", + "operationId": "listIncidents", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "502": { - "description": "Bad gateway — an upstream provider returned an error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" + ] } } }, - "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/webhooks/signing-secret/rotate": { - "post": { - "tags": [ - "Webhooks" ], - "summary": "Generate or rotate the organization webhook signing secret", - "operationId": "rotateSigningSecret", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseString" + "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" } } } @@ -24645,32 +25074,41 @@ } } } - } - }, - "/api/v1/workspaces": { - "get": { + }, + "post": { "tags": [ - "Workspaces" + "Status Pages" ], - "summary": "List workspaces", - "operationId": "list_1", + "summary": "Create a status page incident (manual)", + "operationId": "createIncident", "parameters": [ { - "name": "pageable", - "in": "query", + "name": "id", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageIncidentRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultWorkspaceDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -24756,30 +25194,42 @@ } } } - }, - "post": { + } + }, + "/api/v1/status-pages/{id}/incidents/{incidentId}": { + "get": { "tags": [ - "Workspaces" + "Status Pages" ], - "summary": "Create workspace", - "operationId": "create_2", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateWorkspaceRequest" - } + "summary": "Get incident details with timeline", + "operationId": "getIncident", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "required": true - }, + { + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -24865,33 +25315,50 @@ } } } - } - }, - "/api/v1/workspaces/{workspaceId}": { - "get": { + }, + "put": { "tags": [ - "Workspaces" + "Status Pages" ], - "summary": "Get workspace by ID", - "operationId": "get", + "summary": "Update an incident", + "operationId": "updateIncident", "parameters": [ { - "name": "workspaceId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "integer", - "format": "int32" + "type": "string", + "format": "uuid" + } + }, + { + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageIncidentRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -24978,43 +25445,35 @@ } } }, - "put": { + "delete": { "tags": [ - "Workspaces" + "Status Pages" ], - "summary": "Update workspace", - "operationId": "update", + "summary": "Delete an incident", + "operationId": "deleteIncident", "parameters": [ { - "name": "workspaceId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "integer", - "format": "int32" + "type": "string", + "format": "uuid" + } + }, + { + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateWorkspaceRequest" - } - } - }, - "required": true - }, "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -25097,21 +25556,32 @@ } } } - }, - "delete": { + } + }, + "/api/v1/status-pages/{id}/incidents/{incidentId}/dismiss": { + "post": { "tags": [ - "Workspaces" + "Status Pages" ], - "summary": "Delete workspace", - "operationId": "delete", + "summary": "Dismiss a draft incident (soft-deletes: resolves without publishing)", + "operationId": "dismissIncident", "parameters": [ { - "name": "workspaceId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "integer", - "format": "int32" + "type": "string", + "format": "uuid" + } + }, + { + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } ], @@ -25201,4637 +25671,11690 @@ } } } - } - }, - "components": { - "schemas": { - "AcknowledgeAllIncidentsResponse": { - "required": [ - "acknowledged", - "skipped" + }, + "/api/v1/status-pages/{id}/incidents/{incidentId}/publish": { + "post": { + "tags": [ + "Status Pages" ], - "type": "object", - "properties": { - "acknowledged": { - "type": "array", - "description": "Dispatches successfully acknowledged in this request", - "items": { - "$ref": "#/components/schemas/NotificationDispatchDto" + "summary": "Publish a draft incident (sets publishedAt, applies component statuses, notifies subscribers)", + "operationId": "publishIncident", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } }, - "skipped": { - "type": "array", - "description": "Dispatches skipped (already acked or not in an acknowledgeable state)", - "items": { - "$ref": "#/components/schemas/SkippedDispatch" + { + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } - }, - "description": "Result of acknowledging all acknowledgeable dispatches for an incident" - }, - "AcquireDeployLockRequest": { - "required": [ - "lockedBy" ], - "type": "object", - "properties": { - "lockedBy": { - "minLength": 1, - "type": "string", - "description": "Identity of the lock requester (e.g. hostname, CI job ID)" - }, - "ttlMinutes": { - "type": "integer", - "description": "Lock TTL in minutes (default: 30, max: 60)", - "format": "int32", - "nullable": true, - "example": 30 + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublishStatusPageIncidentRequest" + } + } } }, - "description": "Request to acquire a deploy lock for the current workspace" - }, - "AddCustomDomainRequest": { - "required": [ - "hostname" - ], - "type": "object", - "properties": { - "hostname": { - "maxLength": 255, - "minLength": 0, - "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$", - "type": "string", - "description": "Custom hostname, e.g. status.acme.com" - } - } - }, - "AddIncidentUpdateRequest": { - "type": "object", - "properties": { - "body": { - "type": "string", - "description": "Update message or post-mortem notes", - "nullable": true + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + } + } + } }, - "newStatus": { - "type": "string", - "description": "Updated incident status; null to keep current status", - "nullable": true, - "enum": [ - "WATCHING", - "TRIGGERED", - "CONFIRMED", - "RESOLVED" - ] + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } }, - "notifySubscribers": { - "type": "boolean", - "description": "Whether to notify subscribers of this update" - } - }, - "required": [ - "notifySubscribers" - ] - }, - "AddMonitorTagsRequest": { - "type": "object", - "properties": { - "tagIds": { - "type": "array", - "description": "IDs of existing org tags to attach", - "nullable": true, - "items": { - "type": "string", - "description": "IDs of existing org tags to attach", - "format": "uuid" + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } }, - "newTags": { - "type": "array", - "description": "New tags to create (if not already present) and attach", - "nullable": true, - "items": { - "$ref": "#/components/schemas/NewTagRequest" + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } - } - }, - "description": "Request body for adding tags to a monitor. Provide existing tag IDs, inline new tags, or both." - }, - "AddResourceGroupMemberRequest": { - "required": [ - "memberId", - "memberType" - ], - "type": "object", - "properties": { - "memberType": { - "minLength": 1, - "pattern": "monitor|service", - "type": "string", - "description": "Type of member: 'monitor' or 'service'" }, - "memberId": { - "type": "string", - "description": "ID of the monitor or service to add", - "format": "uuid" - } - }, - "description": "Request body for adding a member to a resource group" - }, - "AdminAddSubscriberRequest": { - "type": "object", - "properties": { - "email": { - "maxLength": 320, - "minLength": 0, - "type": "string", - "description": "Email for EMAIL channel; legacy clients may send only this", - "format": "email", - "nullable": true + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } }, - "channel": { - "type": "string", - "description": "Delivery channel (default: EMAIL)", - "nullable": true, - "enum": [ - "EMAIL", - "SMS", - "WEBHOOK" - ] + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } }, - "destination": { - "maxLength": 2048, - "minLength": 0, - "type": "string", - "description": "Channel destination (email, phone, or webhook URL)", - "nullable": true + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } }, - "componentIds": { - "type": "array", - "description": "Component IDs to scope; omit to leave existing scope; empty list widens to the whole page", - "nullable": true, - "items": { - "type": "string", - "description": "Component IDs to scope; omit to leave existing scope; empty list widens to the whole page", - "format": "uuid" + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } } }, - "requireConfirmation": { - "type": "boolean", - "description": "When true (EMAIL only), create unconfirmed and send opt-in; null/false confirms immediately", - "nullable": true + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } } } - }, - "AffectedComponent": { - "required": [ - "componentId", - "status" + } + }, + "/api/v1/status-pages/{id}/incidents/{incidentId}/updates": { + "post": { + "tags": [ + "Status Pages" ], - "type": "object", - "properties": { - "componentId": { - "type": "string", - "description": "Status page component ID", - "format": "uuid" + "summary": "Post an incident timeline update", + "operationId": "postIncidentUpdate", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } }, - "status": { - "type": "string", - "description": "Component status during this incident", - "enum": [ - "OPERATIONAL", - "DEGRADED_PERFORMANCE", - "PARTIAL_OUTAGE", - "MAJOR_OUTAGE", - "UNDER_MAINTENANCE" - ] + { + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageIncidentUpdateRequest" + } + } + }, + "required": true }, - "description": "Updated affected components; null preserves current" - }, - "AlertChannelDisplayConfig": { - "type": "object", - "properties": { - "recipients": { - "type": "array", - "description": "Email recipients list (email channels)", - "nullable": true, - "items": { - "type": "string", - "description": "Email recipients list (email channels)" + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + } + } } }, - "region": { - "type": "string", - "description": "OpsGenie API region: us or eu", - "nullable": true + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/incidents/{incidentId}/updates/{updateId}": { + "patch": { + "tags": [ + "Status Pages" + ], + "summary": "Edit an existing incident timeline update body", + "operationId": "patchIncidentUpdate", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "updateId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageIncidentUpdateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentUpdateDto" + } + } + } + }, + "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}/layout/reorder": { + "put": { + "tags": [ + "Status Pages" + ], + "summary": "Reorder page-level layout: groups and ungrouped components share one ordering", + "operationId": "reorderLayout", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReorderPageLayoutRequest" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/maintenance": { + "get": { + "tags": [ + "Status Pages" + ], + "summary": "List maintenance windows for this status page (paginated)", + "operationId": "listMaintenance", + "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", + "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": "Schedule a maintenance window", + "operationId": "createMaintenance", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageMaintenanceRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/maintenance/{windowId}": { + "get": { + "tags": [ + "Status Pages" + ], + "summary": "Get a maintenance window with timeline", + "operationId": "getMaintenance", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "put": { + "tags": [ + "Status Pages" + ], + "summary": "Update a maintenance window", + "operationId": "updateMaintenance", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageIncidentRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + } + } + } + }, + "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": [ + "Status Pages" + ], + "summary": "Cancel a maintenance window", + "operationId": "deleteMaintenance", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/maintenance/{windowId}/dismiss": { + "post": { + "tags": [ + "Status Pages" + ], + "summary": "Dismiss a draft maintenance window", + "operationId": "dismissMaintenance", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/maintenance/{windowId}/publish": { + "post": { + "tags": [ + "Status Pages" + ], + "summary": "Publish a draft maintenance window", + "operationId": "publishMaintenance", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublishStatusPageIncidentRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/maintenance/{windowId}/updates": { + "post": { + "tags": [ + "Status Pages" + ], + "summary": "Post a maintenance window timeline update", + "operationId": "postMaintenanceUpdate", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageIncidentUpdateRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/maintenance/{windowId}/updates/{updateId}": { + "patch": { + "tags": [ + "Status Pages" + ], + "summary": "Edit an existing maintenance timeline update body", + "operationId": "patchMaintenanceUpdate", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "updateId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageIncidentUpdateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentUpdateDto" + } + } + } + }, + "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}/notification-deliveries": { + "get": { + "tags": [ + "Status Pages" + ], + "summary": "List notification delivery receipts", + "description": "Returns delivery rows for this status page (newest first). Optional filters: incidentId, eventType.", + "operationId": "listNotificationDeliveries", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "incidentId", + "in": "query", + "required": false, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "eventType", + "in": "query", + "required": false, + "schema": { + "type": "string", + "enum": [ + "SUBSCRIPTION_CONFIRMATION", + "INCIDENT_CREATED", + "INCIDENT_UPDATED", + "INCIDENT_RESOLVED" + ] + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageNotificationDeliveryDto" + } + } + } + }, + "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}/notification-deliveries/{deliveryId}": { + "get": { + "tags": [ + "Status Pages" + ], + "summary": "Get a notification delivery receipt", + "operationId": "getNotificationDelivery", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "deliveryId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageNotificationDeliveryDto" + } + } + } + }, + "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}/notification-deliveries/{deliveryId}/retry": { + "post": { + "tags": [ + "Status Pages" + ], + "summary": "Retry a failed notification delivery", + "description": "Queues a FAILED delivery for another attempt. Refuses terminal attempt_count (~5). Idempotent when already RETRY_PENDING.", + "operationId": "retryNotificationDelivery", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "deliveryId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageNotificationDeliveryDto" + } + } + } + }, + "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}/subscribers": { + "get": { + "tags": [ + "Status Pages" + ], + "summary": "List subscribers including awaiting confirmation (paginated)", + "operationId": "listSubscribers", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultStatusPageSubscriberDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "post": { + "tags": [ + "Status Pages" + ], + "summary": "Add a subscriber; requireConfirmation=true for EMAIL double opt-in, omit/false confirms immediately", + "operationId": "addSubscriber", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminAddSubscriberRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageSubscriberDto" + } + } + } + }, + "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}/subscribers/{subscriberId}": { + "delete": { + "tags": [ + "Status Pages" + ], + "summary": "Remove a subscriber", + "operationId": "removeSubscriber", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "subscriberId", + "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/tags": { + "get": { + "tags": [ + "Tags" + ], + "summary": "List tags for the authenticated organization", + "operationId": "list_3", + "parameters": [ + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultTagDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "post": { + "tags": [ + "Tags" + ], + "summary": "Create a new tag", + "operationId": "create_4", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTagRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseTagDto" + } + } + } + }, + "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/tags/{id}": { + "get": { + "tags": [ + "Tags" + ], + "summary": "Get a tag by ID", + "operationId": "getById", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseTagDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "put": { + "tags": [ + "Tags" + ], + "summary": "Update a tag's name and/or color", + "operationId": "update_2", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateTagRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseTagDto" + } + } + } + }, + "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": [ + "Tags" + ], + "summary": "Delete a tag (cascades to all monitor associations)", + "operationId": "delete_2", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/vaults/rotate": { + "post": { + "tags": [ + "Vault" + ], + "summary": "Rotate DEK", + "description": "Generates a new Data Encryption Key, re-encrypts all secrets and alert-channel configs, and bumps the vault version. Admin-only. Pipeline DEK caches expire within ~10 minutes.", + "operationId": "rotateDek", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseDekRotationResultDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks": { + "get": { + "tags": [ + "Webhooks" + ], + "summary": "List webhook endpoints for the authenticated org", + "operationId": "list_2", + "parameters": [ + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultWebhookEndpointDto" + } + } + } + }, + "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": [ + "Webhooks" + ], + "summary": "Register a new webhook endpoint", + "operationId": "create_3", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateWebhookEndpointRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/{id}": { + "get": { + "tags": [ + "Webhooks" + ], + "summary": "Get a single webhook endpoint", + "operationId": "get_1", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "put": { + "tags": [ + "Webhooks" + ], + "summary": "Update a webhook endpoint", + "operationId": "update_1", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateWebhookEndpointRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Webhooks" + ], + "summary": "Delete a webhook endpoint", + "operationId": "delete_1", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/{id}/deliveries": { + "get": { + "tags": [ + "Webhooks" + ], + "summary": "List recent deliveries for a webhook endpoint", + "operationId": "listDeliveries", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 20 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultWebhookDeliveryDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/{id}/test": { + "post": { + "tags": [ + "Webhooks" + ], + "summary": "Send a test delivery to a webhook endpoint", + "operationId": "test", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestWebhookEndpointRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWebhookTestResult" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/events": { + "get": { + "tags": [ + "Webhooks" + ], + "summary": "List all available webhook event types", + "description": "Returns the full catalog of supported outbound webhook event types with their surface grouping and human-readable descriptions. Use this to populate subscription checkboxes when creating or updating a webhook endpoint.", + "operationId": "listEvents", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/WebhookEventCatalogResponse" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/signing-secret": { + "get": { + "tags": [ + "Webhooks" + ], + "summary": "Get signing secret metadata for the authenticated org", + "operationId": "getSigningSecretInfo", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWebhookSigningSecretDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/webhooks/signing-secret/rotate": { + "post": { + "tags": [ + "Webhooks" + ], + "summary": "Generate or rotate the organization webhook signing secret", + "operationId": "rotateSigningSecret", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseString" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/workspaces": { + "get": { + "tags": [ + "Workspaces" + ], + "summary": "List workspaces", + "operationId": "list_1", + "parameters": [ + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultWorkspaceDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "post": { + "tags": [ + "Workspaces" + ], + "summary": "Create workspace", + "operationId": "create_2", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateWorkspaceRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/workspaces/{workspaceId}": { + "get": { + "tags": [ + "Workspaces" + ], + "summary": "Get workspace by ID", + "operationId": "get", + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + } + } + } + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "put": { + "tags": [ + "Workspaces" + ], + "summary": "Update workspace", + "operationId": "update", + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateWorkspaceRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + } + } + } + }, + "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": [ + "Workspaces" + ], + "summary": "Delete workspace", + "operationId": "delete", + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "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" + } + } + } + } + } + } + } + }, + "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" + ], + "type": "object", + "properties": { + "lockedBy": { + "minLength": 1, + "type": "string", + "description": "Identity of the lock requester (e.g. hostname, CI job ID)" + }, + "ttlMinutes": { + "type": "integer", + "description": "Lock TTL in minutes (default: 30, max: 60)", + "format": "int32", + "nullable": true, + "example": 30 + } + }, + "description": "Request to acquire a deploy lock for the current workspace" + }, + "AddCustomDomainRequest": { + "required": [ + "hostname" + ], + "type": "object", + "properties": { + "hostname": { + "maxLength": 255, + "minLength": 0, + "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$", + "type": "string", + "description": "Custom hostname, e.g. status.acme.com" + } + } + }, + "AddIncidentUpdateRequest": { + "type": "object", + "properties": { + "body": { + "type": "string", + "description": "Update message or post-mortem notes", + "nullable": true + }, + "newStatus": { + "type": "string", + "description": "Updated incident status; null to keep current status", + "nullable": true, + "enum": [ + "WATCHING", + "TRIGGERED", + "CONFIRMED", + "RESOLVED" + ] + }, + "notifySubscribers": { + "type": "boolean", + "description": "Whether to notify subscribers of this update" + } + }, + "required": [ + "notifySubscribers" + ] + }, + "AddMonitorTagsRequest": { + "type": "object", + "properties": { + "tagIds": { + "type": "array", + "description": "IDs of existing org tags to attach", + "nullable": true, + "items": { + "type": "string", + "description": "IDs of existing org tags to attach", + "format": "uuid" + } + }, + "newTags": { + "type": "array", + "description": "New tags to create (if not already present) and attach", + "nullable": true, + "items": { + "$ref": "#/components/schemas/NewTagRequest" + } + } + }, + "description": "Request body for adding tags to a monitor. Provide existing tag IDs, inline new tags, or both." + }, + "AddResourceGroupMemberRequest": { + "required": [ + "memberId", + "memberType" + ], + "type": "object", + "properties": { + "memberType": { + "minLength": 1, + "pattern": "monitor|service", + "type": "string", + "description": "Type of member: 'monitor' or 'service'" + }, + "memberId": { + "type": "string", + "description": "ID of the monitor or service to add", + "format": "uuid" + } + }, + "description": "Request body for adding a member to a resource group" + }, + "AdminAddSubscriberRequest": { + "type": "object", + "properties": { + "email": { + "maxLength": 320, + "minLength": 0, + "type": "string", + "description": "Email for EMAIL channel; legacy clients may send only this", + "format": "email", + "nullable": true + }, + "channel": { + "type": "string", + "description": "Delivery channel (default: EMAIL)", + "nullable": true, + "enum": [ + "EMAIL", + "SMS", + "WEBHOOK" + ] + }, + "destination": { + "maxLength": 2048, + "minLength": 0, + "type": "string", + "description": "Channel destination (email, phone, or webhook URL)", + "nullable": true + }, + "componentIds": { + "type": "array", + "description": "Component IDs to scope; omit to leave existing scope; empty list widens to the whole page", + "nullable": true, + "items": { + "type": "string", + "description": "Component IDs to scope; omit to leave existing scope; empty list widens to the whole page", + "format": "uuid" + } + }, + "requireConfirmation": { + "type": "boolean", + "description": "When true (EMAIL only), create unconfirmed and send opt-in; null/false confirms immediately", + "nullable": true + } + } + }, + "AffectedComponent": { + "required": [ + "componentId", + "status" + ], + "type": "object", + "properties": { + "componentId": { + "type": "string", + "description": "Status page component ID", + "format": "uuid" + }, + "status": { + "type": "string", + "description": "Component status during this incident", + "enum": [ + "OPERATIONAL", + "DEGRADED_PERFORMANCE", + "PARTIAL_OUTAGE", + "MAJOR_OUTAGE", + "UNDER_MAINTENANCE" + ] + } + }, + "description": "Updated affected components; null preserves current" + }, + "AlertChannelDisplayConfig": { + "type": "object", + "properties": { + "recipients": { + "type": "array", + "description": "Email recipients list (email channels)", + "nullable": true, + "items": { + "type": "string", + "description": "Email recipients list (email channels)" + } + }, + "region": { + "type": "string", + "description": "OpsGenie API region: us or eu", + "nullable": true }, "severityOverride": { "type": "string", - "description": "PagerDuty severity override (critical, error, warning, info)", + "description": "PagerDuty severity override (critical, error, warning, info)", + "nullable": true + }, + "mentionRoleId": { + "type": "string", + "description": "Discord role ID to mention in notifications", + "nullable": true + }, + "customHeaders": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Custom HTTP headers for webhook requests", + "nullable": true + }, + "description": "Custom HTTP headers for webhook requests", + "nullable": true + }, + "chatId": { + "type": "string", + "description": "Telegram chat ID", + "nullable": true + }, + "priority": { + "type": "string", + "description": "Pushover notification priority override", + "nullable": true + }, + "channel": { + "type": "string", + "description": "Mattermost channel override", + "nullable": true + }, + "routingKey": { + "type": "string", + "description": "Splunk On-Call routing key", + "nullable": true + }, + "deviceIden": { + "type": "string", + "description": "Pushbullet target device identifier", + "nullable": true + }, + "teamId": { + "type": "string", + "description": "Linear team ID for issue creation", + "nullable": true + }, + "visibility": { + "type": "string", + "description": "incident.io incident visibility", + "nullable": true + }, + "severity": { + "type": "string", + "description": "Rootly incident severity slug", + "nullable": true + }, + "site": { + "type": "string", + "description": "Datadog site region", + "nullable": true + }, + "projectKey": { + "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" + }, + "AlertChannelDto": { + "required": [ + "channelType", + "createdAt", + "enabled", + "id", + "name", + "updatedAt" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique alert channel identifier", + "format": "uuid" + }, + "name": { + "type": "string", + "description": "Human-readable channel name" + }, + "channelType": { + "type": "string", + "description": "Channel integration type (e.g. SLACK, PAGERDUTY, EMAIL)", + "enum": [ + "email", + "webhook", + "slack", + "pagerduty", + "opsgenie", + "teams", + "discord", + "telegram", + "google_chat", + "pushover", + "mattermost", + "splunk_oncall", + "pushbullet", + "linear", + "incident_io", + "rootly", + "zapier", + "datadog", + "jira", + "gitlab", + "sms", + "phone_call" + ] + }, + "displayConfig": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/AlertChannelDisplayConfig" + } + ] + }, + "enabled": { + "type": "boolean", + "description": "Whether this channel is enabled and will receive alerts" + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the channel was created", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "description": "Timestamp when the channel was last updated", + "format": "date-time" + }, + "configHash": { + "type": "string", + "description": "SHA-256 hash of the channel config; use for change detection", + "nullable": true + }, + "managedBy": { + "type": "string", + "description": "Source that created/owns this channel: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on channels created before this attribution column existed.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] + }, + "lastDeliveryAt": { + "type": "string", + "description": "Timestamp of the most recent delivery attempt", + "format": "date-time", + "nullable": true + }, + "lastDeliveryStatus": { + "type": "string", + "description": "Outcome of the most recent delivery (SUCCESS, FAILED, etc.)", + "nullable": true + } + }, + "description": "Alert channel with non-sensitive configuration metadata" + }, + "AlertDeliveryDto": { + "required": [ + "channel", + "channelId", + "channelType", + "createdAt", + "eventType", + "id", + "incidentId", + "status", + "stepNumber", + "fireCount", + "attemptCount" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "incidentId": { + "type": "string", + "description": "Incident that triggered this delivery", + "format": "uuid" + }, + "dispatchId": { + "type": "string", + "description": "Notification dispatch that created this delivery", + "format": "uuid", + "nullable": true + }, + "channelId": { + "type": "string", + "description": "Alert channel ID", + "format": "uuid" + }, + "channel": { + "type": "string", + "description": "Human-readable channel name" + }, + "channelType": { + "type": "string", + "description": "Alert channel type (e.g. slack, email, webhook)" + }, + "status": { + "type": "string", + "description": "Current delivery status", + "enum": [ + "PENDING", + "DELIVERED", + "RETRY_PENDING", + "FAILED", + "CANCELLED", + "SKIPPED_NO_CREDIT", + "SKIPPED_UNVERIFIED", + "SKIPPED_OPTED_OUT", + "SKIPPED_RATE_LIMITED" + ] + }, + "eventType": { + "type": "string", + "description": "Incident lifecycle event that triggered this delivery", + "enum": [ + "INCIDENT_CREATED", + "INCIDENT_RESOLVED", + "INCIDENT_REOPENED" + ] + }, + "stepNumber": { + "type": "integer", + "description": "1-based escalation step this delivery belongs to", + "format": "int32" + }, + "fireCount": { + "type": "integer", + "description": "Fire sequence within the step: 1 = initial, 2+ = repeat re-fires", + "format": "int32" + }, + "attemptCount": { + "type": "integer", + "description": "Number of delivery attempts made", + "format": "int32" + }, + "lastAttemptAt": { + "type": "string", + "description": "When the last attempt was made", + "format": "date-time", + "nullable": true + }, + "nextRetryAt": { + "type": "string", + "description": "When the next retry is scheduled (null if not retrying)", + "format": "date-time", + "nullable": true + }, + "deliveredAt": { + "type": "string", + "description": "Timestamp when the delivery was confirmed (null if not yet delivered)", + "format": "date-time", + "nullable": true + }, + "errorMessage": { + "type": "string", + "description": "Error message from the last failed attempt", + "nullable": true + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + }, + "description": "Delivery record for a single channel within a notification dispatch" + }, + "ApiKeyAuthConfig": { + "required": [ + "type", + "headerName" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "api_key" + ] + }, + "headerName": { + "minLength": 1, + "pattern": "^[A-Za-z0-9\\-_]+$", + "type": "string", + "description": "HTTP header name that carries the API key" + }, + "vaultSecretId": { + "type": "string", + "description": "Vault secret ID for the API key value", + "format": "uuid", + "nullable": true + } + } + }, + "ApiKeyCreateResponse": { + "required": [ + "createdAt", + "key", + "name", + "id" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Unique API key identifier", + "format": "int32" + }, + "name": { + "minLength": 1, + "type": "string", + "description": "Human-readable name for this API key" + }, + "key": { + "minLength": 1, + "type": "string", + "description": "Full API key value in dh_live_* format; store this now" + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the key was created", + "format": "date-time" + }, + "expiresAt": { + "type": "string", + "description": "Timestamp when the key expires; null if no expiration", + "format": "date-time", + "nullable": true + } + }, + "description": "Created API key with the full key value — store it now, it won't be shown again" + }, + "ApiKeyDto": { + "required": [ + "createdAt", + "key", + "name", + "updatedAt", + "id" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Unique API key identifier", + "format": "int32" + }, + "name": { + "minLength": 1, + "type": "string", + "description": "Human-readable name for this API key" + }, + "key": { + "minLength": 1, + "type": "string", + "description": "Full API key value in dh_live_* format" + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the key was created", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "description": "Timestamp when the key was last updated", + "format": "date-time" + }, + "lastUsedAt": { + "type": "string", + "description": "Timestamp of the most recent API call; null if never used", + "format": "date-time", + "nullable": true + }, + "revokedAt": { + "type": "string", + "description": "Timestamp when the key was revoked; null if active", + "format": "date-time", + "nullable": true + }, + "expiresAt": { + "type": "string", + "description": "Timestamp when the key expires; null if no expiration", + "format": "date-time", + "nullable": true + } + }, + "description": "API key for programmatic access to the DevHelm API" + }, + "ArtifactTraceMeta": { + "type": "object", + "properties": { + "actionCount": { + "type": "integer", + "description": "Action count in the trace", + "format": "int32", + "nullable": true + }, + "snapshotCount": { + "type": "integer", + "description": "Snapshot count in the trace", + "format": "int32", + "nullable": true + }, + "nearbyActions": { + "type": "array", + "description": "Actions around the failure, teardown labelled", + "nullable": true, + "items": { + "$ref": "#/components/schemas/TraceNearbyAction" + } + }, + "entryPoints": { + "type": "array", + "description": "Four doorways into the downloaded file", + "nullable": true, + "items": { + "$ref": "#/components/schemas/TraceEntryPoint" + } + } + }, + "description": "Packed trace doorway; do not unpack the zip" + }, + "ArtifactViewport": { + "required": [ + "dpr", + "height", + "width" + ], + "type": "object", + "properties": { + "width": { + "type": "integer", + "description": "Viewport width in CSS pixels", + "format": "int32" + }, + "height": { + "type": "integer", + "description": "Viewport height in CSS pixels", + "format": "int32" + }, + "dpr": { + "type": "integer", + "description": "Device pixel ratio at capture", + "format": "int32" + } + }, + "description": "Screenshot viewport" + }, + "AssertionResultDto": { + "required": [ + "severity", + "type", + "passed" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Assertion type", + "example": "status_code" + }, + "passed": { + "type": "boolean", + "description": "Whether the assertion passed" + }, + "severity": { + "type": "string", + "description": "Assertion severity", + "enum": [ + "fail", + "warn" + ] + }, + "message": { + "type": "string", + "description": "Human-readable result message", + "nullable": true + }, + "expected": { + "type": "string", + "description": "Expected value", + "nullable": true, + "example": "200" + }, + "actual": { + "type": "string", + "description": "Actual value observed", + "nullable": true, + "example": "503" + } + }, + "description": "Result of evaluating a single assertion against a check result" + }, + "AssertionTestResultDto": { + "required": [ + "assertionType", + "message", + "severity", + "passed" + ], + "type": "object", + "properties": { + "assertionType": { + "type": "string", + "description": "Assertion type evaluated", + "enum": [ + "status_code", + "response_time", + "body_contains", + "json_path", + "header_value", + "regex_body", + "dns_resolves", + "dns_response_time", + "dns_expected_ips", + "dns_expected_cname", + "dns_record_contains", + "dns_record_equals", + "dns_txt_contains", + "dns_min_answers", + "dns_max_answers", + "dns_response_time_warn", + "dns_ttl_low", + "dns_ttl_high", + "mcp_connects", + "mcp_response_time", + "mcp_has_capability", + "mcp_tool_available", + "mcp_min_tools", + "mcp_protocol_version", + "mcp_response_time_warn", + "mcp_tool_count_changed", + "ssl_expiry", + "response_size", + "redirect_count", + "redirect_target", + "response_time_warn", + "tcp_connects", + "tcp_response_time", + "tcp_response_time_warn", + "icmp_reachable", + "icmp_response_time", + "icmp_response_time_warn", + "icmp_packet_loss", + "heartbeat_received", + "heartbeat_max_interval", + "heartbeat_interval_drift", + "heartbeat_payload_contains" + ] + }, + "passed": { + "type": "boolean", + "description": "Whether the assertion passed" + }, + "severity": { + "type": "string", + "description": "Assertion severity: FAIL or WARN", + "enum": [ + "fail", + "warn" + ] + }, + "message": { + "type": "string", + "description": "Human-readable result description" + }, + "expected": { + "type": "string", + "description": "Expected value", + "nullable": true + }, + "actual": { + "type": "string", + "description": "Actual value observed during the test", + "nullable": true + } + } + }, + "AuditEventDto": { + "required": [ + "action", + "createdAt", + "id" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Unique audit event identifier", + "format": "int64" + }, + "actorId": { + "type": "integer", + "description": "User ID who performed the action; null for system actions", + "format": "int32", + "nullable": true + }, + "actorEmail": { + "type": "string", + "description": "Email of the actor; null for system actions", + "nullable": true + }, + "action": { + "type": "string", + "description": "Audit action type (e.g. monitor.created, api_key.revoked)" + }, + "resourceType": { + "type": "string", + "description": "Type of resource affected (e.g. monitor, api_key)", + "nullable": true + }, + "resourceId": { + "type": "string", + "description": "ID of the affected resource", + "nullable": true + }, + "resourceName": { + "type": "string", + "description": "Human-readable name of the affected resource", + "nullable": true + }, + "metadata": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/AuditMetadata" + } + ] + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the action was performed", + "format": "date-time" + } + } + }, + "AuditMetadata": { + "description": "Typed metadata payload attached to an audit event; null for actions that carry no extra context.", + "nullable": true, + "discriminator": { + "propertyName": "kind", + "mapping": { + "member_role_changed": "#/components/schemas/MemberRoleChangedMetadata" + } + }, + "oneOf": [ + { + "$ref": "#/components/schemas/MemberRoleChangedMetadata" + } + ] + }, + "AuthMeResponse": { + "required": [ + "key", + "organization", + "plan", + "rateLimits" + ], + "type": "object", + "properties": { + "key": { + "$ref": "#/components/schemas/KeyInfo" + }, + "organization": { + "$ref": "#/components/schemas/OrgInfo" + }, + "plan": { + "$ref": "#/components/schemas/PlanInfo" + }, + "rateLimits": { + "$ref": "#/components/schemas/RateLimitInfo" + } + }, + "description": "Identity, organization, plan, and rate-limit info for the authenticated API key" + }, + "BasicAuthConfig": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "basic" + ] + }, + "vaultSecretId": { + "type": "string", + "description": "Vault secret ID holding Basic auth username and password", + "format": "uuid", + "nullable": true + } + }, + "required": [ + "type" + ] + }, + "BatchComponentUptimeDto": { + "required": [ + "components" + ], + "type": "object", + "properties": { + "components": { + "type": "object", + "additionalProperties": { + "type": "array", + "description": "Map of component ID → list of per-day uptime entries (oldest → newest)", + "items": { + "$ref": "#/components/schemas/ComponentUptimeDayDto" + } + }, + "description": "Map of component ID → list of per-day uptime entries (oldest → newest)" + } + }, + "description": "Batch daily uptime per component, keyed by component ID" + }, + "BearerAuthConfig": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "bearer" + ] + }, + "vaultSecretId": { + "type": "string", + "description": "Vault secret ID holding the bearer token value", + "format": "uuid", + "nullable": true + } + }, + "required": [ + "type" + ] + }, + "BodyContainsAssertion": { + "required": [ + "type", + "substring" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "body_contains" + ] + }, + "substring": { + "minLength": 1, + "type": "string", + "description": "Substring that must appear in the response body" + } + } + }, + "BulkMonitorActionRequest": { + "required": [ + "action", + "monitorIds" + ], + "type": "object", + "properties": { + "monitorIds": { + "maxItems": 200, + "minItems": 0, + "type": "array", + "description": "IDs of monitors to act on (max 200)", + "items": { + "type": "string", + "description": "IDs of monitors to act on (max 200)", + "format": "uuid" + } + }, + "action": { + "type": "string", + "description": "Action to apply to every monitor in the bulk request", + "enum": [ + "PAUSE", + "RESUME", + "DELETE", + "ADD_TAG", + "REMOVE_TAG" + ] + }, + "tagIds": { + "type": "array", + "description": "Tag IDs to attach or detach (required for ADD_TAG and REMOVE_TAG)", + "nullable": true, + "items": { + "type": "string", + "description": "Tag IDs to attach or detach (required for ADD_TAG and REMOVE_TAG)", + "format": "uuid" + } + }, + "newTags": { + "type": "array", + "description": "New tags to create and attach (only for ADD_TAG)", + "nullable": true, + "items": { + "$ref": "#/components/schemas/NewTagRequest" + } + } + }, + "description": "Request body for performing a bulk action on multiple monitors" + }, + "BulkMonitorActionResult": { + "required": [ + "failed", + "succeeded" + ], + "type": "object", + "properties": { + "succeeded": { + "type": "array", + "description": "IDs of monitors on which the action succeeded", + "items": { + "type": "string", + "description": "IDs of monitors on which the action succeeded", + "format": "uuid" + } + }, + "failed": { + "type": "array", + "description": "Monitors on which the action failed, with the reason for each failure", + "items": { + "$ref": "#/components/schemas/FailureDetail" + } + } + }, + "description": "Result of a bulk monitor action, including partial-success details" + }, + "CaptureCompareDto": { + "required": [ + "baselineKind", + "thisArtifactId" + ], + "type": "object", + "properties": { + "thisArtifactId": { + "type": "string", + "description": "Screenshot on this run", + "format": "uuid" + }, + "baselineArtifactId": { + "type": "string", + "description": "Matching screenshot on the prior pass; null when none", + "format": "uuid", + "nullable": true + }, + "baselineRunId": { + "type": "string", + "description": "Run that owns the baseline screenshot", + "format": "uuid", + "nullable": true + }, + "baselineKind": { + "type": "string", + "description": "Always last_pass_this_step_this_region", + "enum": [ + "last_pass_this_step_this_region" + ] + }, + "emptyReason": { + "type": "string", + "description": "Why the baseline is empty; null when a baseline exists", + "nullable": true + }, + "nearestOtherRegion": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/NearestOtherRegion" + } + ] + } + }, + "description": "Screenshot compare against the last pass of this step" + }, + "CapturePolicy": { + "type": "object", + "properties": { + "screenshots": { + "type": "string", + "description": "When to capture screenshots", + "nullable": true, + "enum": [ + "always", + "on_failure", + "off" + ] + }, + "trace": { + "type": "string", + "description": "When to capture a Playwright trace", + "nullable": true, + "enum": [ + "always", + "on_failure", + "off" + ] + }, + "video": { + "type": "string", + "description": "When to capture video", + "nullable": true, + "enum": [ + "always", + "on_failure", + "off" + ] + } + }, + "description": "When to capture screenshots, traces, and video during a code run" + }, + "CategoryDto": { + "required": [ + "category", + "serviceCount" + ], + "type": "object", + "properties": { + "category": { + "type": "string", + "description": "Category name (e.g. CI/CD, Cloud, Payments)" + }, + "serviceCount": { + "type": "integer", + "description": "Number of services in this category", + "format": "int64" + } + }, + "description": "Service category with its count of catalog entries" + }, + "ChangeRoleRequest": { + "required": [ + "orgRole" + ], + "type": "object", + "properties": { + "orgRole": { + "type": "string", + "description": "New role to assign", + "enum": [ + "OWNER", + "ADMIN", + "MEMBER" + ] + } + }, + "description": "Update an organization member's role" + }, + "ChangeStatusRequest": { + "required": [ + "status" + ], + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "New membership status (ACTIVE or SUSPENDED)", + "enum": [ + "INVITED", + "ACTIVE", + "SUSPENDED", + "LEFT", + "REMOVED", + "DECLINED" + ] + } + }, + "description": "Update an organization member's status" + }, + "ChartBucketDto": { + "required": [ + "bucket" + ], + "type": "object", + "properties": { + "bucket": { + "type": "string", + "description": "Start of the time bucket (ISO 8601)", + "format": "date-time", + "example": "2026-03-12T10:00:00Z" + }, + "uptimePercent": { + "type": "number", + "description": "Uptime percentage for this bucket; null when no data", + "format": "double", + "nullable": true, + "example": 100 + }, + "avgLatencyMs": { + "type": "number", + "description": "Weighted average latency in milliseconds for this bucket", + "format": "double", + "nullable": true, + "example": 120.3 + }, + "p95LatencyMs": { + "type": "number", + "description": "95th percentile latency in milliseconds (max across regions)", + "format": "double", + "nullable": true, + "example": 250 + }, + "p99LatencyMs": { + "type": "number", + "description": "99th percentile latency in milliseconds (max across regions)", + "format": "double", + "nullable": true, + "example": 480 + } + }, + "description": "Aggregated metrics for a time bucket" + }, + "CheckResultDetailsDto": { + "type": "object", + "properties": { + "statusCode": { + "type": "integer", + "description": "HTTP status code of the response", + "format": "int32", + "nullable": true, + "example": 200 + }, + "responseHeaders": { + "type": "object", + "additionalProperties": { + "type": "array", + "description": "HTTP response headers", + "nullable": true, + "items": { + "type": "string", + "description": "HTTP response headers", + "nullable": true + } + }, + "description": "HTTP response headers", + "nullable": true + }, + "responseBodySnapshot": { + "type": "string", + "description": "Raw response body snapshot (may be HTML, XML, JSON, or plain text)", + "nullable": true + }, + "assertionResults": { + "type": "array", + "description": "Individual assertion evaluation results", + "nullable": true, + "items": { + "$ref": "#/components/schemas/AssertionResultDto" + } + }, + "tlsInfo": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/TlsInfoDto" + } + ] + }, + "redirectCount": { + "type": "integer", + "description": "Number of HTTP redirects followed", + "format": "int32", + "nullable": true, + "example": 2 + }, + "redirectTarget": { + "type": "string", + "description": "Final URL after redirects", + "nullable": true + }, + "responseSizeBytes": { + "type": "integer", + "description": "Response body size in bytes", + "format": "int32", + "nullable": true, + "example": 4096 + }, + "checkDetails": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CheckTypeDetailsDto" + } + ] + } + }, + "description": "Type-specific details captured during a check execution" + }, + "CheckResultDto": { + "required": [ + "id", + "region", + "timestamp", + "passed" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique identifier of the check result", + "format": "uuid" + }, + "timestamp": { + "type": "string", + "description": "Timestamp when the check was executed (ISO 8601)", + "format": "date-time" + }, + "region": { + "type": "string", + "description": "Region where the check was executed", + "example": "us-east" + }, + "responseTimeMs": { + "type": "integer", + "description": "Response time in milliseconds", + "format": "int32", + "nullable": true, + "example": 123 + }, + "passed": { + "type": "boolean", + "description": "Whether the check passed", + "example": true + }, + "failureReason": { + "type": "string", + "description": "Reason for failure when passed=false", + "nullable": true + }, + "severityHint": { + "type": "string", + "description": "Severity hint: 'down' for hard failures, 'degraded' for warn-only failures, null when passing", + "nullable": true + }, + "details": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CheckResultDetailsDto" + } + ] + }, + "checkId": { + "type": "string", + "description": "Unique execution trace ID for cross-service correlation", + "format": "uuid", + "nullable": true + } + }, + "description": "A single check result from a monitor run" + }, + "CheckTraceDto": { + "required": [ + "checkId", + "evaluations", + "transitions" + ], + "type": "object", + "properties": { + "checkId": { + "type": "string", + "description": "The check execution ID this trace is keyed by", + "format": "uuid" + }, + "evaluations": { + "type": "array", + "description": "All rule evaluations that ran for this check", + "items": { + "$ref": "#/components/schemas/RuleEvaluationDto" + } + }, + "transitions": { + "type": "array", + "description": "State-machine transitions this check caused (may be empty if nothing fired)", + "items": { + "$ref": "#/components/schemas/IncidentStateTransitionDto" + } + }, + "policySnapshot": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/PolicySnapshotDto" + } + ] + } + } + }, + "CheckTypeDetailsDto": { + "description": "Check-type-specific details — polymorphic by check_type discriminator", + "discriminator": { + "propertyName": "check_type", + "mapping": { + "http": "#/components/schemas/Http", + "tcp": "#/components/schemas/Tcp", + "icmp": "#/components/schemas/Icmp", + "dns": "#/components/schemas/Dns", + "mcp_server": "#/components/schemas/McpServer", + "code": "#/components/schemas/Code" + } + }, + "oneOf": [ + { + "$ref": "#/components/schemas/Http" + }, + { + "$ref": "#/components/schemas/Tcp" + }, + { + "$ref": "#/components/schemas/Icmp" + }, + { + "$ref": "#/components/schemas/Dns" + }, + { + "$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", + "componentName", + "uptimePercentage", + "partialOutageSeconds", + "majorOutageSeconds" + ], + "type": "object", + "properties": { + "componentId": { + "type": "string", + "description": "Status page component UUID", + "format": "uuid" + }, + "componentName": { + "type": "string", + "description": "Component display name" + }, + "groupName": { + "type": "string", + "description": "Parent group display name when the component belongs to a group", + "nullable": true + }, + "uptimePercentage": { + "type": "number", + "description": "Computed uptime % for this component on this day", + "format": "double" + }, + "partialOutageSeconds": { + "type": "integer", + "description": "Seconds of partial outage observed on this day", + "format": "int32" + }, + "majorOutageSeconds": { + "type": "integer", + "description": "Seconds of major outage observed on this day", + "format": "int32" + } + }, + "description": "One component's uptime contribution for the day" + }, + "ComponentPosition": { + "required": [ + "componentId", + "displayOrder" + ], + "type": "object", + "properties": { + "componentId": { + "type": "string", + "description": "Component ID", + "format": "uuid" + }, + "displayOrder": { + "type": "integer", + "description": "New display order (0-based)", + "format": "int32" + }, + "groupId": { + "type": "string", + "description": "Target group ID, null for ungrouped", + "format": "uuid", + "nullable": true + } + }, + "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", + "includedCount", + "totalCount" + ], + "type": "object", + "properties": { + "totalCount": { + "type": "integer", + "description": "Total active components for this service across all groups", + "format": "int32" + }, + "includedCount": { + "type": "integer", + "description": "Number of components actually returned in the inline ``components`` list", + "format": "int32" + }, + "groupComponentCounts": { + "type": "object", + "additionalProperties": { + "type": "integer", + "description": "Per-group active leaf count, keyed by group component id (UUID stringified). Empty when the service has no groups; lets the UI render \"show all N\" affordances without a second round trip", + "format": "int32" + }, + "description": "Per-group active leaf count, keyed by group component id (UUID stringified). Empty when the service has no groups; lets the UI render \"show all N\" affordances without a second round trip" + } + } + }, + "ComponentStatusDto": { + "required": [ + "id", + "name", + "status" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Component UUID" + }, + "name": { + "type": "string", + "description": "Human-readable component name" + }, + "status": { + "type": "string", + "description": "Current component status, e.g. operational, degraded_performance" + } + }, + "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", + "partialOutageSeconds", + "majorOutageSeconds", + "degradedSeconds", + "uptimePercentage" + ], + "type": "object", + "properties": { + "date": { + "type": "string", + "description": "Start-of-day timestamp for this bucket (UTC midnight, ISO 8601)", + "format": "date-time" + }, + "partialOutageSeconds": { + "type": "integer", + "description": "Seconds of partial outage observed on this day", + "format": "int32" + }, + "majorOutageSeconds": { + "type": "integer", + "description": "Seconds of major outage observed on this day", + "format": "int32" + }, + "degradedSeconds": { + "type": "integer", + "description": "Seconds the component spent in degraded performance on this day", + "format": "int32" + }, + "uptimePercentage": { + "type": "number", + "description": "Computed uptime percentage using the weighted formula (degraded does not lower it)", + "format": "double" + }, + "incidents": { + "type": "array", + "description": "Incidents that overlapped this day, in display order", + "nullable": true, + "items": { + "$ref": "#/components/schemas/IncidentRef" + } + } + }, + "description": "Daily uptime data for a component" + }, + "ComponentUptimeSummaryDto": { + "required": [ + "source" + ], + "type": "object", + "properties": { + "day": { + "type": "number", + "description": "Uptime percentage over the last 24 hours", + "format": "double", + "nullable": true, + "example": 99.95 + }, + "week": { + "type": "number", + "description": "Uptime percentage over the last 7 days", + "format": "double", + "nullable": true, + "example": 99.98 + }, + "month": { + "type": "number", + "description": "Uptime percentage over the last 30 days", + "format": "double", + "nullable": true, + "example": 99.92 + }, + "source": { + "type": "string", + "description": "Data source: vendor_reported or incident_derived", + "example": "vendor_reported" + } + }, + "description": "Inline uptime percentages for 24h, 7d, 30d" + }, + "ConfirmationPolicy": { + "required": [ + "type", + "minRegionsFailing", + "maxWaitSeconds" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "How incident confirmation is coordinated across regions", + "enum": [ + "multi_region" + ] + }, + "minRegionsFailing": { + "type": "integer", + "description": "Minimum failing regions required to confirm an incident", + "format": "int32" + }, + "maxWaitSeconds": { + "type": "integer", + "description": "Maximum seconds to wait for enough regions to fail after first trigger", + "format": "int32" + } + }, + "description": "Multi-region confirmation settings" + }, + "ConsoleGroupDto": { + "required": [ + "level", + "sourceUrl", + "text", + "count" + ], + "type": "object", + "properties": { + "level": { + "minLength": 1, + "type": "string", + "description": "UI bucket: error, warning, or info" + }, + "text": { + "minLength": 1, + "type": "string", + "description": "Repeated message text" + }, + "count": { + "type": "integer", + "description": "How many times this message occurred", + "format": "int32" + }, + "sourceUrl": { + "minLength": 1, + "type": "string", + "description": "Source URL of the first occurrence" + }, + "stepIdFirst": { + "type": "string", + "description": "First step that logged this message", + "nullable": true + }, + "stepIdLast": { + "type": "string", + "description": "Last step that logged this message", + "nullable": true + } + }, + "description": "Grouped console messages" + }, + "ConsoleLineDto": { + "required": [ + "id", + "level", + "sourceUrl", + "text", + "ts", + "lineNumber", + "columnNumber" + ], + "type": "object", + "properties": { + "id": { + "minLength": 1, + "type": "string", + "description": "Stable line id from capture" + }, + "stepId": { + "type": "string", + "description": "Step this line belonged to", + "nullable": true + }, + "level": { + "minLength": 1, + "type": "string", + "description": "UI bucket: error, warning, or info" + }, + "text": { + "minLength": 1, + "type": "string", + "description": "Console message text" + }, + "sourceUrl": { + "minLength": 1, + "type": "string", + "description": "Script URL that logged this line" + }, + "lineNumber": { + "type": "integer", + "description": "Source line number", + "format": "int32" + }, + "columnNumber": { + "type": "integer", + "description": "Source column number", + "format": "int32" + }, + "ts": { + "minLength": 1, + "type": "string", + "description": "When the line was captured" + } + }, + "description": "One console line" + }, + "CreateAlertChannelRequest": { + "required": [ + "config", + "name" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Human-readable name for this alert channel" + }, + "config": { + "oneOf": [ + { + "$ref": "#/components/schemas/DatadogChannelConfig" + }, + { + "$ref": "#/components/schemas/DiscordChannelConfig" + }, + { + "$ref": "#/components/schemas/EmailChannelConfig" + }, + { + "$ref": "#/components/schemas/GitLabChannelConfig" + }, + { + "$ref": "#/components/schemas/GoogleChatChannelConfig" + }, + { + "$ref": "#/components/schemas/IncidentIoChannelConfig" + }, + { + "$ref": "#/components/schemas/JiraChannelConfig" + }, + { + "$ref": "#/components/schemas/LinearChannelConfig" + }, + { + "$ref": "#/components/schemas/MattermostChannelConfig" + }, + { + "$ref": "#/components/schemas/OpsGenieChannelConfig" + }, + { + "$ref": "#/components/schemas/PagerDutyChannelConfig" + }, + { + "$ref": "#/components/schemas/PhoneCallChannelConfig" + }, + { + "$ref": "#/components/schemas/PushbulletChannelConfig" + }, + { + "$ref": "#/components/schemas/PushoverChannelConfig" + }, + { + "$ref": "#/components/schemas/RootlyChannelConfig" + }, + { + "$ref": "#/components/schemas/SlackChannelConfig" + }, + { + "$ref": "#/components/schemas/SmsChannelConfig" + }, + { + "$ref": "#/components/schemas/SplunkOnCallChannelConfig" + }, + { + "$ref": "#/components/schemas/TeamsChannelConfig" + }, + { + "$ref": "#/components/schemas/TelegramChannelConfig" + }, + { + "$ref": "#/components/schemas/WebhookChannelConfig" + }, + { + "$ref": "#/components/schemas/ZapierChannelConfig" + } + ] + }, + "managedBy": { + "type": "string", + "description": "Source creating this channel: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] + } + } + }, + "CreateApiKeyRequest": { + "required": [ + "name" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 200, + "minLength": 0, + "type": "string", + "description": "Human-readable name to identify this API key" + }, + "expiresAt": { + "type": "string", + "description": "Optional expiration timestamp in ISO 8601 format", + "format": "date-time", + "nullable": true + } + } + }, + "CreateAssertionRequest": { + "required": [ + "config" + ], + "type": "object", + "properties": { + "config": { + "oneOf": [ + { + "$ref": "#/components/schemas/BodyContainsAssertion" + }, + { + "$ref": "#/components/schemas/DnsExpectedCnameAssertion" + }, + { + "$ref": "#/components/schemas/DnsExpectedIpsAssertion" + }, + { + "$ref": "#/components/schemas/DnsMaxAnswersAssertion" + }, + { + "$ref": "#/components/schemas/DnsMinAnswersAssertion" + }, + { + "$ref": "#/components/schemas/DnsRecordContainsAssertion" + }, + { + "$ref": "#/components/schemas/DnsRecordEqualsAssertion" + }, + { + "$ref": "#/components/schemas/DnsResolvesAssertion" + }, + { + "$ref": "#/components/schemas/DnsResponseTimeAssertion" + }, + { + "$ref": "#/components/schemas/DnsResponseTimeWarnAssertion" + }, + { + "$ref": "#/components/schemas/DnsTtlHighAssertion" + }, + { + "$ref": "#/components/schemas/DnsTtlLowAssertion" + }, + { + "$ref": "#/components/schemas/DnsTxtContainsAssertion" + }, + { + "$ref": "#/components/schemas/HeaderValueAssertion" + }, + { + "$ref": "#/components/schemas/HeartbeatIntervalDriftAssertion" + }, + { + "$ref": "#/components/schemas/HeartbeatMaxIntervalAssertion" + }, + { + "$ref": "#/components/schemas/HeartbeatPayloadContainsAssertion" + }, + { + "$ref": "#/components/schemas/HeartbeatReceivedAssertion" + }, + { + "$ref": "#/components/schemas/IcmpPacketLossAssertion" + }, + { + "$ref": "#/components/schemas/IcmpReachableAssertion" + }, + { + "$ref": "#/components/schemas/IcmpResponseTimeAssertion" + }, + { + "$ref": "#/components/schemas/IcmpResponseTimeWarnAssertion" + }, + { + "$ref": "#/components/schemas/JsonPathAssertion" + }, + { + "$ref": "#/components/schemas/McpConnectsAssertion" + }, + { + "$ref": "#/components/schemas/McpHasCapabilityAssertion" + }, + { + "$ref": "#/components/schemas/McpMinToolsAssertion" + }, + { + "$ref": "#/components/schemas/McpProtocolVersionAssertion" + }, + { + "$ref": "#/components/schemas/McpResponseTimeAssertion" + }, + { + "$ref": "#/components/schemas/McpResponseTimeWarnAssertion" + }, + { + "$ref": "#/components/schemas/McpToolAvailableAssertion" + }, + { + "$ref": "#/components/schemas/McpToolCountChangedAssertion" + }, + { + "$ref": "#/components/schemas/RedirectCountAssertion" + }, + { + "$ref": "#/components/schemas/RedirectTargetAssertion" + }, + { + "$ref": "#/components/schemas/RegexBodyAssertion" + }, + { + "$ref": "#/components/schemas/ResponseSizeAssertion" + }, + { + "$ref": "#/components/schemas/ResponseTimeAssertion" + }, + { + "$ref": "#/components/schemas/ResponseTimeWarnAssertion" + }, + { + "$ref": "#/components/schemas/SslExpiryAssertion" + }, + { + "$ref": "#/components/schemas/StatusCodeAssertion" + }, + { + "$ref": "#/components/schemas/TcpConnectsAssertion" + }, + { + "$ref": "#/components/schemas/TcpResponseTimeAssertion" + }, + { + "$ref": "#/components/schemas/TcpResponseTimeWarnAssertion" + } + ] + }, + "severity": { + "type": "string", + "description": "Outcome severity: FAIL (fails the check) or WARN (warns without failing, default: FAIL)", + "nullable": true, + "enum": [ + "fail", + "warn" + ] + } + }, + "description": "Replace all assertions. Null preserves current" + }, + "CreateEnvironmentRequest": { + "required": [ + "name", + "slug" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "minLength": 0, + "type": "string", + "description": "Human-readable environment name" + }, + "slug": { + "maxLength": 100, + "minLength": 0, + "pattern": "^[a-z0-9][a-z0-9_-]*$", + "type": "string", + "description": "URL-safe identifier (lowercase alphanumeric, hyphens, underscores)" + }, + "variables": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Initial key-value variable pairs for this environment", + "nullable": true + }, + "description": "Initial key-value variable pairs for this environment", + "nullable": true + }, + "isDefault": { + "type": "boolean", + "description": "Whether this is the default environment for new monitors (default: false)", + "nullable": true + } + } + }, + "CreateInviteRequest": { + "required": [ + "email", + "roleOffered" + ], + "type": "object", + "properties": { + "email": { + "minLength": 1, + "type": "string", + "description": "Email address to invite", + "format": "email" + }, + "roleOffered": { + "type": "string", + "description": "Role to assign on acceptance", + "enum": [ + "OWNER", + "ADMIN", + "MEMBER" + ] + } + }, + "description": "Invite a new member to the organization by email" + }, + "CreateMaintenanceWindowRequest": { + "required": [ + "endsAt", + "startsAt" + ], + "type": "object", + "properties": { + "monitorId": { + "type": "string", + "description": "Monitor to attach this maintenance window to; null for org-wide", + "format": "uuid", + "nullable": true + }, + "startsAt": { + "type": "string", + "description": "Scheduled start of the maintenance window (ISO 8601)", + "format": "date-time" + }, + "endsAt": { + "type": "string", + "description": "Scheduled end of the maintenance window (ISO 8601)", + "format": "date-time" + }, + "repeatRule": { + "maxLength": 100, + "minLength": 0, + "type": "string", + "description": "Reserved: iCal RRULE for recurring windows (stored but not yet honored)", + "nullable": true + }, + "reason": { + "maxLength": 500, + "minLength": 0, + "type": "string", + "description": "Human-readable reason for the maintenance (max 500 chars)", + "nullable": true + }, + "suppressAlerts": { + "type": "boolean", + "description": "Whether to suppress alerts during this window (default: true)", + "nullable": true + } + } + }, + "CreateManualIncidentRequest": { + "required": [ + "severity", + "title" + ], + "type": "object", + "properties": { + "title": { + "minLength": 1, + "type": "string", + "description": "Short summary of the incident" + }, + "severity": { + "type": "string", + "description": "Incident severity: DOWN, DEGRADED, or MAINTENANCE", + "enum": [ + "DOWN", + "DEGRADED", + "MAINTENANCE" + ] + }, + "monitorId": { + "type": "string", + "description": "Monitor to associate with this incident", + "format": "uuid", + "nullable": true + }, + "body": { + "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 + } + } + }, + "CreateMonitorRequest": { + "required": [ + "name", + "type" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Human-readable name for this monitor" + }, + "type": { + "type": "string", + "description": "Monitor protocol type", + "enum": [ + "HTTP", + "DNS", + "MCP_SERVER", + "TCP", + "ICMP", + "HEARTBEAT", + "BROWSER", + "MULTI_STEP_API" + ] + }, + "config": { + "nullable": true, + "oneOf": [ + { + "$ref": "#/components/schemas/DnsMonitorConfig" + }, + { + "$ref": "#/components/schemas/HeartbeatMonitorConfig" + }, + { + "$ref": "#/components/schemas/HttpMonitorConfig" + }, + { + "$ref": "#/components/schemas/IcmpMonitorConfig" + }, + { + "$ref": "#/components/schemas/McpServerMonitorConfig" + }, + { + "$ref": "#/components/schemas/ScriptMonitorConfig" + }, + { + "$ref": "#/components/schemas/TcpMonitorConfig" + } + ] + }, + "frequencySeconds": { + "maximum": 86400, + "minimum": 10, + "type": "integer", + "description": "Check frequency in seconds (10–86400). Null defaults to the plan minimum", + "format": "int32", + "nullable": true + }, + "enabled": { + "type": "boolean", + "description": "Whether the monitor is active (default: true)", + "nullable": true + }, + "regions": { + "type": "array", + "description": "Probe regions to run checks from. Allowed values are deployment-dependent. Production: us-east, us-west, eu-west, ap-south", + "nullable": true, + "items": { + "type": "string", + "description": "Probe regions to run checks from. Allowed values are deployment-dependent. Production: us-east, us-west, eu-west, ap-south" + } + }, + "managedBy": { + "type": "string", + "description": "Source that created this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] + }, + "environmentId": { + "type": "string", + "description": "Environment to associate with this monitor. Required for browser and multi-step monitors", + "format": "uuid", + "nullable": true + }, + "assertions": { + "type": "array", + "description": "Assertions to evaluate against each check result", + "nullable": true, + "items": { + "$ref": "#/components/schemas/CreateAssertionRequest" + } + }, + "auth": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/MonitorAuthConfig" + } + ] + }, + "incidentPolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/UpdateIncidentPolicyRequest" + } + ] + }, + "alertChannelIds": { + "type": "array", + "description": "Alert channels to notify when this monitor triggers", + "nullable": true, + "items": { + "type": "string", + "description": "Alert channels to notify when this monitor triggers", + "format": "uuid" + } + }, + "tags": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/AddMonitorTagsRequest" + } + ] + }, + "capturePolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CapturePolicy" + } + ] + }, + "fastRetryMaxAttempts": { + "maximum": 10, + "minimum": 0, + "type": "integer", + "description": "Fast-retry attempts after failure. Null or 0 disables", + "format": "int32", + "nullable": true + }, + "definitionId": { + "type": "string", + "description": "Existing definition to reuse for a sibling monitor", + "format": "uuid", + "nullable": true + }, + "package": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/MonitorPackageSpec" + } + ] + } + } + }, + "CreateNotificationPolicyRequest": { + "required": [ + "escalation", + "name" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Human-readable name for this policy" + }, + "description": { + "maxLength": 500, + "minLength": 0, + "type": "string", + "description": "Optional note; omit or null when unused", + "nullable": true + }, + "matchRules": { + "type": "array", + "description": "Match rules to evaluate (all must pass; omit or empty for catch-all)", + "nullable": true, + "items": { + "$ref": "#/components/schemas/MatchRule" + } + }, + "escalation": { + "$ref": "#/components/schemas/EscalationChain" + }, + "enabled": { + "type": "boolean", + "description": "Whether this policy is enabled (default true)", + "nullable": true, + "default": true + }, + "priority": { + "type": "integer", + "description": "Evaluation priority; higher value = evaluated first (default 0)", + "format": "int32", + "nullable": true, + "default": 0 + } + }, + "description": "Request body for creating a notification policy" + }, + "CreatePackageUploadRequest": { + "required": [ + "digest" + ], + "type": "object", + "properties": { + "digest": { + "maxLength": 64, + "minLength": 64, + "type": "string", + "description": "SHA-256 hex digest of the package zip to upload (64 chars)" + } + } + }, + "CreateResourceGroupRequest": { + "required": [ + "name" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Human-readable name for this group" + }, + "description": { + "maxLength": 500, + "minLength": 0, + "type": "string", + "description": "Optional description (max 500)", "nullable": true }, - "mentionRoleId": { + "alertPolicyId": { "type": "string", - "description": "Discord role ID to mention in notifications", + "description": "Optional notification policy to apply for this group", + "format": "uuid", "nullable": true }, - "customHeaders": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Custom HTTP headers for webhook requests", - "nullable": true - }, - "description": "Custom HTTP headers for webhook requests", + "defaultFrequency": { + "maximum": 86400, + "minimum": 30, + "type": "integer", + "description": "Default check frequency in seconds applied to members (30–86400)", + "format": "int32", "nullable": true }, - "chatId": { + "defaultRegions": { + "type": "array", + "description": "Default regions applied to member monitors", + "nullable": true, + "items": { + "type": "string", + "description": "Default regions applied to member monitors" + } + }, + "defaultRetryStrategy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/RetryStrategy" + } + ] + }, + "defaultAlertChannels": { + "type": "array", + "description": "Default alert channel IDs applied to member monitors", + "nullable": true, + "items": { + "type": "string", + "description": "Default alert channel IDs applied to member monitors", + "format": "uuid" + } + }, + "defaultEnvironmentId": { "type": "string", - "description": "Telegram chat ID", + "description": "Default environment ID applied to member monitors", + "format": "uuid", "nullable": true }, - "priority": { + "healthThresholdType": { "type": "string", - "description": "Pushover notification priority override", + "description": "Health threshold type: COUNT or PERCENTAGE", + "nullable": true, + "enum": [ + "COUNT", + "PERCENTAGE" + ] + }, + "healthThresholdValue": { + "maximum": 100, + "exclusiveMaximum": false, + "minimum": 0, + "exclusiveMinimum": false, + "type": "number", + "description": "Health threshold value: count (0+) or percentage (0–100)", "nullable": true }, - "channel": { - "type": "string", - "description": "Mattermost channel override", + "suppressMemberAlerts": { + "type": "boolean", + "description": "Suppress member-level alert notifications when group manages alerting", "nullable": true }, - "routingKey": { - "type": "string", - "description": "Splunk On-Call routing key", + "confirmationDelaySeconds": { + "maximum": 600, + "minimum": 0, + "type": "integer", + "description": "Confirmation delay in seconds before group incident creation (0–600)", + "format": "int32", "nullable": true }, - "deviceIden": { - "type": "string", - "description": "Pushbullet target device identifier", + "recoveryCooldownMinutes": { + "maximum": 60, + "minimum": 0, + "type": "integer", + "description": "Recovery cooldown in minutes after group incident resolves (0–60)", + "format": "int32", "nullable": true }, - "teamId": { + "managedBy": { "type": "string", - "description": "Linear team ID for issue creation", + "description": "Source creating this group: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] + } + }, + "description": "Request body for creating a resource group" + }, + "CreateSecretRequest": { + "required": [ + "key", + "value" + ], + "type": "object", + "properties": { + "key": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Unique secret key within the workspace (max 255 chars)" + }, + "value": { + "maxLength": 32768, + "minLength": 0, + "type": "string", + "description": "Secret value, stored encrypted (max 32KB)" + } + } + }, + "CreateStatusPageComponentGroupRequest": { + "required": [ + "name" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Group display name" + }, + "description": { + "maxLength": 500, + "minLength": 0, + "type": "string", + "description": "Optional group description", "nullable": true }, - "visibility": { + "displayOrder": { + "type": "integer", + "description": "Position in the group list", + "format": "int32", + "nullable": true + }, + "defaultOpen": { + "type": "boolean", + "description": "Initial expand/collapse state when a visitor first loads the page; renderer may auto-expand on active incidents (default: true)", + "nullable": true + } + } + }, + "CreateStatusPageComponentRequest": { + "required": [ + "name", + "type" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 255, + "minLength": 0, "type": "string", - "description": "incident.io incident visibility", + "description": "Component display name" + }, + "description": { + "maxLength": 500, + "minLength": 0, + "type": "string", + "description": "Optional description shown on expand", "nullable": true }, - "severity": { + "type": { "type": "string", - "description": "Rootly incident severity slug", + "description": "Component type: MONITOR, GROUP, STATIC, or DEPENDENCY", + "enum": [ + "MONITOR", + "GROUP", + "STATIC", + "DEPENDENCY" + ] + }, + "monitorId": { + "type": "string", + "description": "Monitor ID (required when type=MONITOR)", + "format": "uuid", "nullable": true }, - "site": { + "resourceGroupId": { "type": "string", - "description": "Datadog site region", + "description": "Resource group ID (required when type=GROUP)", + "format": "uuid", "nullable": true }, - "projectKey": { + "serviceSubscriptionId": { "type": "string", - "description": "Jira project key", + "description": "Service subscription (Dependency) ID — required when type=DEPENDENCY. Bind an existing org subscription; catalog picks must create the subscription first, then pass its id", + "format": "uuid", "nullable": true }, - "phoneNumber": { + "groupId": { "type": "string", - "description": "Recipient phone number in E.164 format (SMS / phone-call channels)", + "description": "Component group ID for visual grouping", + "format": "uuid", "nullable": true }, - "verifiedPhoneNumberId": { - "type": "integer", - "description": "Id of the org verified_phone_number row bound to this channel", - "format": "int64", + "showUptime": { + "type": "boolean", + "description": "Whether to show the uptime bar (default: true; false for DEPENDENCY)", "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" - } + "displayOrder": { + "type": "integer", + "description": "Position in the component list", + "format": "int32", + "nullable": true }, - "voiceLanguage": { - "type": "string", - "description": "BCP-47 voice language for phone-call TTS (e.g. en-US, de-DE)", + "excludeFromOverall": { + "type": "boolean", + "description": "Exclude from overall status calculation (default: false; true for DEPENDENCY)", "nullable": true }, - "preferredLanguage": { + "startDate": { "type": "string", - "description": "Preferred language for SMS/voice (BCP-47, e.g. en-US, de-DE)", + "description": "Date from which to start showing uptime; defaults to component creation. Set earlier to backdate (e.g. launch day); clamped at the monitor's createdAt for MONITOR-type components", + "format": "date", "nullable": true } - }, - "description": "Non-sensitive alert channel configuration metadata" + } }, - "AlertChannelDto": { + "CreateStatusPageIncidentRequest": { "required": [ - "channelType", - "createdAt", - "enabled", - "id", - "name", - "updatedAt" + "body", + "impact", + "title" ], "type": "object", "properties": { - "id": { + "title": { + "maxLength": 500, + "minLength": 0, "type": "string", - "description": "Unique alert channel identifier", - "format": "uuid" + "description": "Customer-facing incident title" }, - "name": { + "status": { "type": "string", - "description": "Human-readable channel name" + "description": "Initial status (default: INVESTIGATING)", + "nullable": true, + "enum": [ + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" + ] }, - "channelType": { + "impact": { "type": "string", - "description": "Channel integration type (e.g. SLACK, PAGERDUTY, EMAIL)", + "description": "Impact level: NONE, MINOR, MAJOR, or CRITICAL", "enum": [ - "email", - "webhook", - "slack", - "pagerduty", - "opsgenie", - "teams", - "discord", - "telegram", - "google_chat", - "pushover", - "mattermost", - "splunk_oncall", - "pushbullet", - "linear", - "incident_io", - "rootly", - "zapier", - "datadog", - "jira", - "gitlab", - "sms", - "phone_call" + "NONE", + "MINOR", + "MAJOR", + "CRITICAL" ] }, - "displayConfig": { + "body": { + "minLength": 1, + "type": "string", + "description": "Initial update body in markdown" + }, + "affectedComponents": { + "type": "array", + "description": "Component IDs affected by this incident", "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/AlertChannelDisplayConfig" - } - ] + "items": { + "$ref": "#/components/schemas/AffectedComponent" + } }, - "enabled": { + "notifySubscribers": { "type": "boolean", - "description": "Whether this channel is enabled and will receive alerts" + "description": "Whether to email confirmed subscribers about this incident (default: true)", + "nullable": true }, - "createdAt": { + "monitoringIncidentId": { "type": "string", - "description": "Timestamp when the channel was created", - "format": "date-time" - }, - "updatedAt": { + "description": "Monitoring incident ID to link this status page incident to; null for standalone", + "format": "uuid", + "nullable": true + } + } + }, + "CreateStatusPageIncidentUpdateRequest": { + "required": [ + "body", + "status" + ], + "type": "object", + "properties": { + "status": { "type": "string", - "description": "Timestamp when the channel was last updated", - "format": "date-time" + "description": "Incident status at this point in the timeline", + "enum": [ + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" + ] }, - "configHash": { + "body": { + "minLength": 1, "type": "string", - "description": "SHA-256 hash of the channel config; use for change detection", + "description": "Update body in markdown" + }, + "notifySubscribers": { + "type": "boolean", + "description": "Whether to email confirmed subscribers about this update (default: true)", "nullable": true }, - "managedBy": { + "affectedComponents": { + "type": "array", + "description": "Updated affected components; null preserves current", + "nullable": true, + "items": { + "$ref": "#/components/schemas/AffectedComponent" + } + } + } + }, + "CreateStatusPageMaintenanceRequest": { + "required": [ + "body", + "impact", + "scheduledFor", + "title" + ], + "type": "object", + "properties": { + "title": { + "maxLength": 500, + "minLength": 0, "type": "string", - "description": "Source that created/owns this channel: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on channels created before this attribution column existed.", + "description": "Customer-facing maintenance title" + }, + "status": { + "type": "string", + "description": "Initial status (default: INVESTIGATING)", "nullable": true, "enum": [ - "DASHBOARD", - "CLI", - "TERRAFORM", - "MCP", - "API" + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" ] }, - "lastDeliveryAt": { + "impact": { "type": "string", - "description": "Timestamp of the most recent delivery attempt", + "description": "Impact level: NONE, MINOR, MAJOR, or CRITICAL", + "enum": [ + "NONE", + "MINOR", + "MAJOR", + "CRITICAL" + ] + }, + "body": { + "minLength": 1, + "type": "string", + "description": "Initial update body in markdown" + }, + "affectedComponents": { + "type": "array", + "description": "Component IDs affected by this window", + "nullable": true, + "items": { + "$ref": "#/components/schemas/AffectedComponent" + } + }, + "scheduledFor": { + "type": "string", + "description": "Maintenance start time", + "format": "date-time" + }, + "scheduledUntil": { + "type": "string", + "description": "Maintenance end time", "format": "date-time", "nullable": true }, - "lastDeliveryStatus": { - "type": "string", - "description": "Outcome of the most recent delivery (SUCCESS, FAILED, etc.)", + "autoResolve": { + "type": "boolean", + "description": "Auto-resolve at scheduledUntil (default: false)", + "nullable": true + }, + "notifySubscribers": { + "type": "boolean", + "description": "Whether to email confirmed subscribers about this window (default: true)", "nullable": true } - }, - "description": "Alert channel with non-sensitive configuration metadata" + } }, - "AlertDeliveryDto": { + "CreateStatusPageRequest": { "required": [ - "channel", - "channelId", - "channelType", - "createdAt", - "eventType", - "id", - "incidentId", - "status", - "stepNumber", - "fireCount", - "attemptCount" + "name", + "slug" ], "type": "object", "properties": { - "id": { + "name": { + "maxLength": 255, + "minLength": 0, "type": "string", - "format": "uuid" + "description": "Human-readable name for this status page" }, - "incidentId": { + "slug": { + "maxLength": 63, + "minLength": 3, + "pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$", "type": "string", - "description": "Incident that triggered this delivery", - "format": "uuid" + "description": "URL slug (lowercase, hyphens, globally unique)" }, - "dispatchId": { + "description": { + "maxLength": 500, + "minLength": 0, "type": "string", - "description": "Notification dispatch that created this delivery", - "format": "uuid", + "description": "Optional description shown below the page header", "nullable": true }, - "channelId": { - "type": "string", - "description": "Alert channel ID", - "format": "uuid" - }, - "channel": { - "type": "string", - "description": "Human-readable channel name" - }, - "channelType": { - "type": "string", - "description": "Alert channel type (e.g. slack, email, webhook)" - }, - "status": { - "type": "string", - "description": "Current delivery status", - "enum": [ - "PENDING", - "DELIVERED", - "RETRY_PENDING", - "FAILED", - "CANCELLED", - "SKIPPED_NO_CREDIT", - "SKIPPED_UNVERIFIED", - "SKIPPED_OPTED_OUT", - "SKIPPED_RATE_LIMITED" + "branding": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/StatusPageBranding" + } ] }, - "eventType": { + "visibility": { "type": "string", - "description": "Incident lifecycle event that triggered this delivery", + "description": "Page visibility: PUBLIC, PASSWORD, or IP_RESTRICTED (default: PUBLIC)", + "nullable": true, "enum": [ - "INCIDENT_CREATED", - "INCIDENT_RESOLVED", - "INCIDENT_REOPENED" + "PUBLIC", + "PASSWORD", + "IP_RESTRICTED" ] }, - "stepNumber": { - "type": "integer", - "description": "1-based escalation step this delivery belongs to", - "format": "int32" - }, - "fireCount": { - "type": "integer", - "description": "Fire sequence within the step: 1 = initial, 2+ = repeat re-fires", - "format": "int32" - }, - "attemptCount": { - "type": "integer", - "description": "Number of delivery attempts made", - "format": "int32" - }, - "lastAttemptAt": { - "type": "string", - "description": "When the last attempt was made", - "format": "date-time", + "enabled": { + "type": "boolean", + "description": "Whether the page is enabled (default: true)", "nullable": true }, - "nextRetryAt": { + "incidentMode": { "type": "string", - "description": "When the next retry is scheduled (null if not retrying)", - "format": "date-time", - "nullable": true + "description": "Incident mode: MANUAL, REVIEW, or AUTOMATIC (default: AUTOMATIC)", + "nullable": true, + "enum": [ + "MANUAL", + "REVIEW", + "AUTOMATIC" + ] }, - "deliveredAt": { + "managedBy": { "type": "string", - "description": "Timestamp when the delivery was confirmed (null if not yet delivered)", - "format": "date-time", - "nullable": true - }, - "errorMessage": { + "description": "Source creating this page: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted.", + "nullable": true, + "enum": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] + } + } + }, + "CreateTagRequest": { + "required": [ + "name" + ], + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "minLength": 0, "type": "string", - "description": "Error message from the last failed attempt", - "nullable": true + "description": "Tag name, unique within the org" }, - "createdAt": { + "color": { + "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$", "type": "string", - "format": "date-time" + "description": "Hex color code (defaults to #6B7280 if omitted)", + "nullable": true } }, - "description": "Delivery record for a single channel within a notification dispatch" + "description": "Request body for creating a tag" }, - "ApiKeyAuthConfig": { + "CreateWebhookEndpointRequest": { "required": [ - "type", - "headerName" + "subscribedEvents", + "url" ], "type": "object", "properties": { - "type": { - "type": "string", - "enum": [ - "api_key" - ] - }, - "headerName": { - "minLength": 1, - "pattern": "^[A-Za-z0-9\\-_]+$", + "url": { + "maxLength": 2048, + "minLength": 0, "type": "string", - "description": "HTTP header name that carries the API key" + "description": "HTTPS endpoint that receives webhook event payloads" }, - "vaultSecretId": { + "description": { + "maxLength": 255, + "minLength": 0, "type": "string", - "description": "Vault secret ID for the API key value", - "format": "uuid", + "description": "Optional human-readable description", "nullable": true + }, + "subscribedEvents": { + "minItems": 1, + "type": "array", + "description": "Event types to deliver", + "items": { + "minLength": 1, + "type": "string", + "enum": [ + "monitor.created", + "monitor.updated", + "monitor.deleted", + "incident.created", + "incident.resolved", + "incident.reopened", + "service.status_changed", + "service.component_changed", + "service.incident_created", + "service.incident_updated", + "service.incident_resolved" + ] + } } } }, - "ApiKeyCreateResponse": { + "CreateWorkspaceRequest": { "required": [ - "createdAt", - "key", - "name", - "id" + "name" ], "type": "object", "properties": { - "id": { - "type": "integer", - "description": "Unique API key identifier", - "format": "int32" - }, "name": { "minLength": 1, "type": "string", - "description": "Human-readable name for this API key" - }, - "key": { - "minLength": 1, + "description": "Workspace name" + } + }, + "description": "Create a new workspace within the organization" + }, + "CreditPolicy": { + "type": "object", + "properties": { + "summary": { "type": "string", - "description": "Full API key value in dh_live_* format; store this now" + "description": "Brief summary of credit policy", + "nullable": true }, - "createdAt": { - "type": "string", - "description": "Timestamp when the key was created", - "format": "date-time" + "maxCreditPercent": { + "type": "integer", + "description": "Max credit as percent of monthly fee", + "format": "int32", + "nullable": true }, - "expiresAt": { - "type": "string", - "description": "Timestamp when the key expires; null if no expiration", - "format": "date-time", + "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": "Created API key with the full key value — store it now, it won't be shown again" + "description": "Service credit policy for SLA violations" }, - "ApiKeyDto": { + "CreditTier": { "required": [ - "createdAt", - "key", - "name", - "updatedAt", - "id" + "uptimeRange" ], "type": "object", "properties": { - "id": { - "type": "integer", - "description": "Unique API key identifier", - "format": "int32" - }, - "name": { - "minLength": 1, - "type": "string", - "description": "Human-readable name for this API key" - }, - "key": { - "minLength": 1, - "type": "string", - "description": "Full API key value in dh_live_* format" - }, - "createdAt": { - "type": "string", - "description": "Timestamp when the key was created", - "format": "date-time" - }, - "updatedAt": { + "uptimeRange": { "type": "string", - "description": "Timestamp when the key was last updated", - "format": "date-time" + "description": "Uptime range, e.g. '99.1% – 99.98%'" }, - "lastUsedAt": { - "type": "string", - "description": "Timestamp of the most recent API call; null if never used", - "format": "date-time", + "creditPercent": { + "type": "integer", + "description": "Credit percent of monthly fee", + "format": "int32", "nullable": true }, - "revokedAt": { + "formula": { "type": "string", - "description": "Timestamp when the key was revoked; null if active", - "format": "date-time", + "description": "Credit formula when percent is not a fixed number", "nullable": true }, - "expiresAt": { + "notes": { "type": "string", - "description": "Timestamp when the key expires; null if no expiration", - "format": "date-time", + "description": "Additional notes on this credit tier", "nullable": true } }, - "description": "API key for programmatic access to the DevHelm API" + "description": "Credit tiers by uptime threshold" }, - "AssertionResultDto": { + "CursorPageCheckResultDto": { "required": [ - "severity", - "type", - "passed" + "data", + "hasMore" ], "type": "object", "properties": { - "type": { - "type": "string", - "description": "Assertion type", - "example": "status_code" - }, - "passed": { - "type": "boolean", - "description": "Whether the assertion passed" - }, - "severity": { - "type": "string", - "description": "Assertion severity", - "enum": [ - "fail", - "warn" - ] + "data": { + "type": "array", + "description": "Items on this page", + "items": { + "$ref": "#/components/schemas/CheckResultDto" + } }, - "message": { + "nextCursor": { "type": "string", - "description": "Human-readable result message", + "description": "Opaque cursor for the next page; null when there are no more results", "nullable": true }, - "expected": { - "type": "string", - "description": "Expected value", - "nullable": true, - "example": "200" + "hasMore": { + "type": "boolean", + "description": "Whether more results exist beyond this page" }, - "actual": { - "type": "string", - "description": "Actual value observed", - "nullable": true, - "example": "503" + "total": { + "type": "integer", + "description": "Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total", + "format": "int64", + "nullable": true } }, - "description": "Result of evaluating a single assertion against a check result" + "description": "Cursor-paginated response for time-series and append-only data" }, - "AssertionTestResultDto": { + "CursorPageIncidentActivityEventDto": { "required": [ - "assertionType", - "message", - "severity", - "passed" + "data", + "hasMore" ], "type": "object", "properties": { - "assertionType": { + "data": { + "type": "array", + "description": "Items on this page", + "items": { + "$ref": "#/components/schemas/IncidentActivityEventDto" + } + }, + "nextCursor": { "type": "string", - "description": "Assertion type evaluated", - "enum": [ - "status_code", - "response_time", - "body_contains", - "json_path", - "header_value", - "regex_body", - "dns_resolves", - "dns_response_time", - "dns_expected_ips", - "dns_expected_cname", - "dns_record_contains", - "dns_record_equals", - "dns_txt_contains", - "dns_min_answers", - "dns_max_answers", - "dns_response_time_warn", - "dns_ttl_low", - "dns_ttl_high", - "mcp_connects", - "mcp_response_time", - "mcp_has_capability", - "mcp_tool_available", - "mcp_min_tools", - "mcp_protocol_version", - "mcp_response_time_warn", - "mcp_tool_count_changed", - "ssl_expiry", - "response_size", - "redirect_count", - "redirect_target", - "response_time_warn", - "tcp_connects", - "tcp_response_time", - "tcp_response_time_warn", - "icmp_reachable", - "icmp_response_time", - "icmp_response_time_warn", - "icmp_packet_loss", - "heartbeat_received", - "heartbeat_max_interval", - "heartbeat_interval_drift", - "heartbeat_payload_contains" - ] + "description": "Opaque cursor for the next page; null when there are no more results", + "nullable": true }, - "passed": { + "hasMore": { "type": "boolean", - "description": "Whether the assertion passed" - }, - "severity": { - "type": "string", - "description": "Assertion severity: FAIL or WARN", - "enum": [ - "fail", - "warn" - ] + "description": "Whether more results exist beyond this page" }, - "message": { - "type": "string", - "description": "Human-readable result description" + "total": { + "type": "integer", + "description": "Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total", + "format": "int64", + "nullable": true + } + }, + "description": "Cursor-paginated response for time-series and append-only data" + }, + "CursorPageNotificationDispatchDto": { + "required": [ + "data", + "hasMore" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "description": "Items on this page", + "items": { + "$ref": "#/components/schemas/NotificationDispatchDto" + } }, - "expected": { + "nextCursor": { "type": "string", - "description": "Expected value", + "description": "Opaque cursor for the next page; null when there are no more results", "nullable": true }, - "actual": { - "type": "string", - "description": "Actual value observed during the test", + "hasMore": { + "type": "boolean", + "description": "Whether more results exist beyond this page" + }, + "total": { + "type": "integer", + "description": "Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total", + "format": "int64", "nullable": true } - } + }, + "description": "Cursor-paginated response for time-series and append-only data" }, - "AuditEventDto": { + "CursorPageRunDto": { "required": [ - "action", - "createdAt", - "id" + "data", + "hasMore" ], "type": "object", "properties": { - "id": { - "type": "integer", - "description": "Unique audit event identifier", - "format": "int64" - }, - "actorId": { - "type": "integer", - "description": "User ID who performed the action; null for system actions", - "format": "int32", - "nullable": true + "data": { + "type": "array", + "description": "Items on this page", + "items": { + "$ref": "#/components/schemas/RunDto" + } }, - "actorEmail": { + "nextCursor": { "type": "string", - "description": "Email of the actor; null for system actions", + "description": "Opaque cursor for the next page; null when there are no more results", "nullable": true }, - "action": { - "type": "string", - "description": "Audit action type (e.g. monitor.created, api_key.revoked)" - }, - "resourceType": { - "type": "string", - "description": "Type of resource affected (e.g. monitor, api_key)", - "nullable": true + "hasMore": { + "type": "boolean", + "description": "Whether more results exist beyond this page" }, - "resourceId": { - "type": "string", - "description": "ID of the affected resource", + "total": { + "type": "integer", + "description": "Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total", + "format": "int64", "nullable": true + } + }, + "description": "Cursor-paginated response for time-series and append-only data" + }, + "CursorPageServiceCatalogDto": { + "required": [ + "data", + "hasMore" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "description": "Items on this page", + "items": { + "$ref": "#/components/schemas/ServiceCatalogDto" + } }, - "resourceName": { + "nextCursor": { "type": "string", - "description": "Human-readable name of the affected resource", + "description": "Opaque cursor for the next page; null when there are no more results", "nullable": true }, - "metadata": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/AuditMetadata" - } - ] + "hasMore": { + "type": "boolean", + "description": "Whether more results exist beyond this page" }, - "createdAt": { - "type": "string", - "description": "Timestamp when the action was performed", - "format": "date-time" - } - } - }, - "AuditMetadata": { - "description": "Typed metadata payload attached to an audit event; null for actions that carry no extra context.", - "nullable": true, - "discriminator": { - "propertyName": "kind", - "mapping": { - "member_role_changed": "#/components/schemas/MemberRoleChangedMetadata" - } - }, - "oneOf": [ - { - "$ref": "#/components/schemas/MemberRoleChangedMetadata" + "total": { + "type": "integer", + "description": "Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total", + "format": "int64", + "nullable": true } - ] + }, + "description": "Cursor-paginated response for time-series and append-only data" }, - "AuthMeResponse": { + "CursorPageServicePollResultDto": { "required": [ - "key", - "organization", - "plan", - "rateLimits" + "data", + "hasMore" ], "type": "object", "properties": { - "key": { - "$ref": "#/components/schemas/KeyInfo" + "data": { + "type": "array", + "description": "Items on this page", + "items": { + "$ref": "#/components/schemas/ServicePollResultDto" + } }, - "organization": { - "$ref": "#/components/schemas/OrgInfo" + "nextCursor": { + "type": "string", + "description": "Opaque cursor for the next page; null when there are no more results", + "nullable": true }, - "plan": { - "$ref": "#/components/schemas/PlanInfo" + "hasMore": { + "type": "boolean", + "description": "Whether more results exist beyond this page" }, - "rateLimits": { - "$ref": "#/components/schemas/RateLimitInfo" + "total": { + "type": "integer", + "description": "Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total", + "format": "int64", + "nullable": true } }, - "description": "Identity, organization, plan, and rate-limit info for the authenticated API key" + "description": "Cursor-paginated response for time-series and append-only data" }, - "BasicAuthConfig": { + "CursorPageStatusEventDto": { + "required": [ + "data", + "hasMore" + ], "type": "object", "properties": { - "type": { - "type": "string", - "enum": [ - "basic" - ] + "data": { + "type": "array", + "description": "Items on this page", + "items": { + "$ref": "#/components/schemas/StatusEventDto" + } }, - "vaultSecretId": { + "nextCursor": { "type": "string", - "description": "Vault secret ID holding Basic auth username and password", - "format": "uuid", + "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" + }, + "total": { + "type": "integer", + "description": "Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total", + "format": "int64", "nullable": true } }, - "required": [ - "type" - ] + "description": "Cursor-paginated response for time-series and append-only data" }, - "BatchComponentUptimeDto": { + "DashboardOverviewDto": { "required": [ - "components" + "incidents", + "monitors" ], "type": "object", "properties": { - "components": { - "type": "object", - "additionalProperties": { - "type": "array", - "description": "Map of component ID → list of per-day uptime entries (oldest → newest)", - "items": { - "$ref": "#/components/schemas/ComponentUptimeDayDto" - } - }, - "description": "Map of component ID → list of per-day uptime entries (oldest → newest)" - } - }, - "description": "Batch daily uptime per component, keyed by component ID" - }, - "BearerAuthConfig": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "bearer" - ] + "monitors": { + "$ref": "#/components/schemas/MonitorsSummaryDto" }, - "vaultSecretId": { - "type": "string", - "description": "Vault secret ID holding the bearer token value", - "format": "uuid", - "nullable": true + "incidents": { + "$ref": "#/components/schemas/IncidentsSummaryDto" } }, - "required": [ - "type" - ] + "description": "Combined dashboard overview for monitors and incidents" }, - "BodyContainsAssertion": { + "DatadogChannelConfig": { "required": [ - "type", - "substring" + "channelType", + "apiKey" ], "type": "object", "properties": { - "type": { + "channelType": { "type": "string", "enum": [ - "body_contains" + "datadog" ] }, - "substring": { + "apiKey": { "minLength": 1, "type": "string", - "description": "Substring that must appear in the response body" + "description": "Datadog API key" + }, + "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 } } }, - "BulkMonitorActionRequest": { + "DayIncident": { "required": [ - "action", - "monitorIds" + "affectedComponentIds", + "affectedComponentNames", + "id", + "impact", + "status", + "title", + "scheduled" ], "type": "object", "properties": { - "monitorIds": { - "maxItems": 200, - "minItems": 0, - "type": "array", - "description": "IDs of monitors to act on (max 200)", - "items": { - "type": "string", - "description": "IDs of monitors to act on (max 200)", - "format": "uuid" - } + "id": { + "type": "string", + "description": "Status page incident UUID", + "format": "uuid" }, - "action": { + "title": { "type": "string", - "description": "Action to apply to every monitor in the bulk request", + "description": "Incident title" + }, + "status": { + "type": "string", + "description": "Lifecycle status (investigating, identified, monitoring, resolved, …)", "enum": [ - "PAUSE", - "RESUME", - "DELETE", - "ADD_TAG", - "REMOVE_TAG" + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" ] }, - "tagIds": { + "impact": { + "type": "string", + "description": "Severity bucket (none, minor, major, critical)", + "enum": [ + "NONE", + "MINOR", + "MAJOR", + "CRITICAL" + ] + }, + "scheduled": { + "type": "boolean", + "description": "True for a maintenance window; false for an incident" + }, + "startedAt": { + "type": "string", + "description": "Incident start timestamp", + "format": "date-time", + "nullable": true + }, + "resolvedAt": { + "type": "string", + "description": "Incident resolved timestamp; null while still active", + "format": "date-time", + "nullable": true + }, + "affectedComponentNames": { "type": "array", - "description": "Tag IDs to attach or detach (required for ADD_TAG and REMOVE_TAG)", - "nullable": true, + "description": "Display names of components affected by this incident (deduplicated)", "items": { "type": "string", - "description": "Tag IDs to attach or detach (required for ADD_TAG and REMOVE_TAG)", - "format": "uuid" + "description": "Display names of components affected by this incident (deduplicated)" } }, - "newTags": { + "affectedComponentIds": { "type": "array", - "description": "New tags to create and attach (only for ADD_TAG)", - "nullable": true, + "description": "UUIDs of components this incident affected", "items": { - "$ref": "#/components/schemas/NewTagRequest" + "type": "string", + "description": "UUIDs of components this incident affected", + "format": "uuid" } } }, - "description": "Request body for performing a bulk action on multiple monitors" + "description": "Incident that overlapped the day" }, - "BulkMonitorActionResult": { + "DefinitionDetailDto": { "required": [ - "failed", - "succeeded" + "definition", + "heads" ], "type": "object", "properties": { - "succeeded": { - "type": "array", - "description": "IDs of monitors on which the action succeeded", - "items": { - "type": "string", - "description": "IDs of monitors on which the action succeeded", - "format": "uuid" - } + "definition": { + "$ref": "#/components/schemas/DefinitionDto" }, - "failed": { + "heads": { "type": "array", - "description": "Monitors on which the action failed, with the reason for each failure", + "description": "Active Heads per environment", "items": { - "$ref": "#/components/schemas/FailureDetail" + "$ref": "#/components/schemas/DefinitionHeadDto" } } }, - "description": "Result of a bulk monitor action, including partial-success details" + "description": "Definition with Heads for each environment" }, - "CategoryDto": { + "DefinitionDto": { "required": [ - "category", - "serviceCount" + "createdAt", + "id", + "name", + "slug", + "updatedAt", + "organizationId" ], "type": "object", "properties": { - "category": { + "id": { "type": "string", - "description": "Category name (e.g. CI/CD, Cloud, Payments)" + "description": "Definition identifier", + "format": "uuid" }, - "serviceCount": { + "organizationId": { "type": "integer", - "description": "Number of services in this category", - "format": "int64" + "description": "Organization this definition belongs to", + "format": "int32" + }, + "name": { + "minLength": 1, + "type": "string", + "description": "Human-readable name" + }, + "slug": { + "minLength": 1, + "type": "string", + "description": "URL-safe slug unique within the organization" + }, + "createdAt": { + "type": "string", + "description": "When the definition was created", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "description": "When the definition was last updated", + "format": "date-time" } }, - "description": "Service category with its count of catalog entries" + "description": "Code-monitor definition" }, - "ChangeRoleRequest": { + "DefinitionHeadDto": { "required": [ - "orgRole" + "activatedAt", + "definitionId", + "environment", + "revision" ], "type": "object", "properties": { - "orgRole": { + "definitionId": { "type": "string", - "description": "New role to assign", - "enum": [ - "OWNER", - "ADMIN", - "MEMBER" - ] + "description": "Definition this Head belongs to", + "format": "uuid" + }, + "environment": { + "$ref": "#/components/schemas/EnvironmentDto" + }, + "revision": { + "$ref": "#/components/schemas/RevisionDto" + }, + "activatedAt": { + "type": "string", + "description": "When this Head last activated", + "format": "date-time" + }, + "activatedBy": { + "type": "string", + "description": "Who last activated this Head", + "nullable": true + }, + "reason": { + "type": "string", + "description": "Rollback reason when this Head was restored", + "nullable": true } }, - "description": "Update an organization member's role" + "description": "Active Head for a definition in one environment" }, - "ChangeStatusRequest": { + "DekRotationResultDto": { "required": [ - "status" + "rotatedAt", + "previousDekVersion", + "newDekVersion", + "secretsReEncrypted", + "channelsReEncrypted" + ], + "type": "object", + "properties": { + "previousDekVersion": { + "type": "integer", + "description": "DEK version before rotation", + "format": "int32" + }, + "newDekVersion": { + "type": "integer", + "description": "DEK version after rotation", + "format": "int32" + }, + "secretsReEncrypted": { + "type": "integer", + "description": "Number of secrets re-encrypted with the new DEK", + "format": "int32" + }, + "channelsReEncrypted": { + "type": "integer", + "description": "Number of alert channels re-encrypted with the new DEK", + "format": "int32" + }, + "rotatedAt": { + "type": "string", + "description": "Timestamp when the rotation was performed", + "format": "date-time" + } + }, + "description": "Result of a data encryption key rotation operation" + }, + "DeleteChannelResult": { + "type": "object", + "properties": { + "affectedPolicies": { + "type": "integer", + "description": "Number of notification policies whose escalation steps were modified", + "format": "int32" + }, + "disabledPolicies": { + "type": "integer", + "description": "Number of notification policies disabled because they had no remaining channels", + "format": "int32" + } + }, + "description": "Summary of policies affected by channel deletion", + "required": [ + "affectedPolicies", + "disabledPolicies" + ] + }, + "DeliveryAttemptDto": { + "required": [ + "attemptedAt", + "deliveryId", + "id", + "status", + "attemptNumber" ], "type": "object", "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "deliveryId": { + "type": "string", + "format": "uuid" + }, + "attemptNumber": { + "type": "integer", + "description": "1-based attempt number", + "format": "int32" + }, "status": { "type": "string", - "description": "New membership status (ACTIVE or SUSPENDED)", - "enum": [ - "INVITED", - "ACTIVE", - "SUSPENDED", - "LEFT", - "REMOVED", - "DECLINED" - ] + "description": "Outcome: SUCCESS, FAILED, TIMEOUT, ERROR" + }, + "responseStatusCode": { + "type": "integer", + "description": "HTTP response status code from the external service", + "format": "int32", + "nullable": true + }, + "requestPayload": { + "type": "string", + "description": "JSON payload sent to the external service", + "nullable": true + }, + "responseBody": { + "type": "string", + "description": "Response body from the external service (truncated)", + "nullable": true + }, + "errorMessage": { + "type": "string", + "description": "Error message if the attempt failed", + "nullable": true + }, + "responseTimeMs": { + "type": "integer", + "description": "Round-trip time in milliseconds", + "format": "int32", + "nullable": true + }, + "externalId": { + "type": "string", + "description": "External identifier (e.g. PagerDuty dedup_key, SES MessageId, webhook delivery UUID)", + "nullable": true + }, + "requestHeaders": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "HTTP request headers sent to the external service", + "nullable": true + }, + "description": "HTTP request headers sent to the external service", + "nullable": true + }, + "attemptedAt": { + "type": "string", + "format": "date-time" } }, - "description": "Update an organization member's status" + "description": "Single delivery attempt with request/response audit data" }, - "ChartBucketDto": { + "DeployLockDto": { "required": [ - "bucket" + "expiresAt", + "id", + "lockedAt", + "lockedBy" ], "type": "object", "properties": { - "bucket": { + "id": { "type": "string", - "description": "Start of the time bucket (ISO 8601)", - "format": "date-time", - "example": "2026-03-12T10:00:00Z" + "description": "Unique lock identifier", + "format": "uuid" }, - "uptimePercent": { - "type": "number", - "description": "Uptime percentage for this bucket; null when no data", - "format": "double", - "nullable": true, - "example": 100 + "lockedBy": { + "minLength": 1, + "type": "string", + "description": "Identity of the lock holder (e.g. CLI session ID, username)" }, - "avgLatencyMs": { - "type": "number", - "description": "Weighted average latency in milliseconds for this bucket", - "format": "double", - "nullable": true, - "example": 120.3 + "lockedAt": { + "type": "string", + "description": "Timestamp when the lock was acquired", + "format": "date-time" }, - "p95LatencyMs": { - "type": "number", - "description": "95th percentile latency in milliseconds (max across regions)", - "format": "double", - "nullable": true, - "example": 250 + "expiresAt": { + "type": "string", + "description": "Timestamp when the lock automatically expires", + "format": "date-time" + } + }, + "description": "Represents an active deploy lock for a workspace" + }, + "DiscordChannelConfig": { + "required": [ + "channelType", + "webhookUrl" + ], + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "discord" + ] }, - "p99LatencyMs": { - "type": "number", - "description": "99th percentile latency in milliseconds (max across regions)", - "format": "double", - "nullable": true, - "example": 480 + "webhookUrl": { + "minLength": 1, + "type": "string", + "description": "Discord webhook URL" + }, + "mentionRoleId": { + "type": "string", + "description": "Optional Discord role ID to mention in notifications", + "nullable": true } - }, - "description": "Aggregated metrics for a time bucket" + } }, - "CheckResultDetailsDto": { + "Dns": { "type": "object", + "description": "DNS check-type-specific details", "properties": { - "statusCode": { - "type": "integer", - "description": "HTTP status code of the response", - "format": "int32", + "check_type": { + "type": "string", + "enum": [ + "dns" + ] + }, + "hostname": { + "type": "string", + "description": "Target hostname", + "nullable": true + }, + "requestedTypes": { + "type": "array", + "description": "Requested DNS record types", "nullable": true, - "example": 200 + "items": { + "type": "string", + "description": "Requested DNS record types", + "nullable": true + } }, - "responseHeaders": { + "usedResolver": { + "type": "string", + "description": "Resolver used for lookup", + "nullable": true + }, + "records": { "type": "object", "additionalProperties": { "type": "array", - "description": "HTTP response headers", + "description": "Resolved DNS records keyed by record type", "nullable": true, "items": { - "type": "string", - "description": "HTTP response headers", + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Resolved DNS records keyed by record type", + "nullable": true + }, + "description": "Resolved DNS records keyed by record type", "nullable": true } }, - "description": "HTTP response headers", - "nullable": true - }, - "responseBodySnapshot": { - "type": "string", - "description": "Raw response body snapshot (may be HTML, XML, JSON, or plain text)", + "description": "Resolved DNS records keyed by record type", "nullable": true }, - "assertionResults": { + "attempts": { "type": "array", - "description": "Individual assertion evaluation results", + "description": "DNS resolution attempts", "nullable": true, "items": { - "$ref": "#/components/schemas/AssertionResultDto" + "type": "object", + "additionalProperties": { + "type": "object", + "description": "DNS resolution attempts", + "nullable": true + }, + "description": "DNS resolution attempts", + "nullable": true } }, - "tlsInfo": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/TlsInfoDto" - } - ] - }, - "redirectCount": { - "type": "integer", - "description": "Number of HTTP redirects followed", - "format": "int32", - "nullable": true, - "example": 2 - }, - "redirectTarget": { + "failureKind": { "type": "string", - "description": "Final URL after redirects", + "description": "Kind of DNS failure, if any", "nullable": true - }, - "responseSizeBytes": { - "type": "integer", - "description": "Response body size in bytes", - "format": "int32", - "nullable": true, - "example": 4096 - }, - "checkDetails": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/CheckTypeDetailsDto" - } - ] } }, - "description": "Type-specific details captured during a check execution" + "required": [ + "check_type" + ] }, - "CheckResultDto": { + "DnsExpectedCnameAssertion": { "required": [ - "id", - "region", - "timestamp", - "passed" + "type", + "value" ], "type": "object", "properties": { - "id": { - "type": "string", - "description": "Unique identifier of the check result", - "format": "uuid" - }, - "timestamp": { - "type": "string", - "description": "Timestamp when the check was executed (ISO 8601)", - "format": "date-time" - }, - "region": { - "type": "string", - "description": "Region where the check was executed", - "example": "us-east" - }, - "responseTimeMs": { - "type": "integer", - "description": "Response time in milliseconds", - "format": "int32", - "nullable": true, - "example": 123 - }, - "passed": { - "type": "boolean", - "description": "Whether the check passed", - "example": true - }, - "failureReason": { - "type": "string", - "description": "Reason for failure when passed=false", - "nullable": true - }, - "severityHint": { + "type": { "type": "string", - "description": "Severity hint: 'down' for hard failures, 'degraded' for warn-only failures, null when passing", - "nullable": true - }, - "details": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/CheckResultDetailsDto" - } + "enum": [ + "dns_expected_cname" ] }, - "checkId": { + "value": { + "minLength": 1, "type": "string", - "description": "Unique execution trace ID for cross-service correlation", - "format": "uuid", - "nullable": true + "description": "Expected CNAME target the resolution must include" } - }, - "description": "A single check result from a monitor run" + } }, - "CheckTraceDto": { + "DnsExpectedIpsAssertion": { "required": [ - "checkId", - "evaluations", - "transitions" + "type", + "ips" ], "type": "object", "properties": { - "checkId": { + "type": { "type": "string", - "description": "The check execution ID this trace is keyed by", - "format": "uuid" - }, - "evaluations": { - "type": "array", - "description": "All rule evaluations that ran for this check", - "items": { - "$ref": "#/components/schemas/RuleEvaluationDto" - } + "enum": [ + "dns_expected_ips" + ] }, - "transitions": { + "ips": { + "minItems": 1, "type": "array", - "description": "State-machine transitions this check caused (may be empty if nothing fired)", + "description": "Allowed IP addresses; at least one resolved address must match", "items": { - "$ref": "#/components/schemas/IncidentStateTransitionDto" + "type": "string", + "description": "Allowed IP addresses; at least one resolved address must match" } - }, - "policySnapshot": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/PolicySnapshotDto" - } - ] } } }, - "CheckTypeDetailsDto": { - "description": "Check-type-specific details — polymorphic by check_type discriminator", - "discriminator": { - "propertyName": "check_type", - "mapping": { - "http": "#/components/schemas/Http", - "tcp": "#/components/schemas/Tcp", - "icmp": "#/components/schemas/Icmp", - "dns": "#/components/schemas/Dns", - "mcp_server": "#/components/schemas/McpServer", - "code": "#/components/schemas/Code" - } - }, - "oneOf": [ - { - "$ref": "#/components/schemas/Http" - }, - { - "$ref": "#/components/schemas/Tcp" - }, - { - "$ref": "#/components/schemas/Icmp" - }, - { - "$ref": "#/components/schemas/Dns" + "DnsMaxAnswersAssertion": { + "required": [ + "type", + "recordType", + "max" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "dns_max_answers" + ] }, - { - "$ref": "#/components/schemas/McpServer" + "recordType": { + "minLength": 1, + "type": "string", + "description": "DNS record type whose answer count is checked" }, - { - "$ref": "#/components/schemas/Code" + "max": { + "type": "integer", + "description": "Maximum number of answers allowed for that record type", + "format": "int32" } - ] + } }, - "Code": { + "DnsMinAnswersAssertion": { + "required": [ + "type", + "recordType", + "min" + ], "type": "object", - "description": "Code check (browser / multi-step API) specific details", "properties": { - "check_type": { + "type": { "type": "string", "enum": [ - "code" + "dns_min_answers" ] }, - "exitCode": { - "type": "integer", - "description": "Container exit code (0 = pass)", - "format": "int32" - }, - "stdoutSnippet": { + "recordType": { + "minLength": 1, "type": "string", - "description": "Truncated stdout from the container", - "nullable": true + "description": "DNS record type whose answer count is checked" }, - "stderrSnippet": { + "min": { + "type": "integer", + "description": "Minimum number of answers required for that record type", + "format": "int32" + } + } + }, + "DnsMonitorConfig": { + "required": [ + "hostname" + ], + "type": "object", + "properties": { + "hostname": { + "minLength": 1, "type": "string", - "description": "Truncated stderr from the container", - "nullable": true + "description": "Domain name to resolve" }, - "steps": { + "recordTypes": { "type": "array", - "description": "Named steps extracted from Playwright test output", + "description": "DNS record types to query: A, AAAA, CNAME, MX, NS, TXT, SRV, SOA, CAA, PTR", "nullable": true, "items": { + "type": "string", + "description": "DNS record types to query: A, AAAA, CNAME, MX, NS, TXT, SRV, SOA, CAA, PTR", "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/CodeCheckStep" - } + "enum": [ + "A", + "AAAA", + "CNAME", + "MX", + "NS", + "TXT", + "SRV", + "SOA", + "CAA", + "PTR" ] } }, - "failureKind": { - "type": "string", - "description": "Failure classification: timeout, assertion, or error", + "nameservers": { + "type": "array", + "description": "Custom nameservers to query (uses system defaults if omitted)", + "nullable": true, + "items": { + "type": "string", + "description": "Custom nameservers to query (uses system defaults if omitted)", + "nullable": true + } + }, + "timeoutMs": { + "type": "integer", + "description": "Per-query timeout in milliseconds", + "format": "int32", "nullable": true }, - "timedOut": { - "type": "boolean", - "description": "Whether the run hit a step/total/run-budget timeout", + "totalTimeoutMs": { + "type": "integer", + "description": "Total timeout for all queries in milliseconds", + "format": "int32", "nullable": true } - }, - "required": [ - "check_type", - "exitCode" - ] + } }, - "CodeCheckStep": { + "DnsRecordContainsAssertion": { "required": [ - "name", - "status" + "type", + "recordType", + "substring" ], "type": "object", "properties": { - "name": { + "type": { "type": "string", - "description": "Step name from test.step() or test() call" + "enum": [ + "dns_record_contains" + ] }, - "status": { + "recordType": { + "minLength": 1, "type": "string", - "description": "Step outcome: passed, failed, skipped, or timedOut" - }, - "durationMs": { - "type": "integer", - "description": "Step duration in milliseconds", - "format": "int32", - "nullable": true + "description": "DNS record type to assert on (A, AAAA, CNAME, MX, TXT)" }, - "error": { + "substring": { + "minLength": 1, "type": "string", - "description": "Error message if the step failed", - "nullable": true + "description": "Substring that must appear in a matching record value" } - }, - "description": "A single named step within a code check execution" + } }, - "ComponentImpact": { + "DnsRecordEqualsAssertion": { "required": [ - "componentId", - "componentName", - "uptimePercentage", - "partialOutageSeconds", - "majorOutageSeconds" + "type", + "recordType", + "value" ], "type": "object", "properties": { - "componentId": { + "type": { "type": "string", - "description": "Status page component UUID", - "format": "uuid" + "enum": [ + "dns_record_equals" + ] }, - "componentName": { + "recordType": { + "minLength": 1, "type": "string", - "description": "Component display name" + "description": "DNS record type to assert on (A, AAAA, CNAME, MX, TXT)" }, - "groupName": { + "value": { + "minLength": 1, "type": "string", - "description": "Parent group display name when the component belongs to a group", - "nullable": true - }, - "uptimePercentage": { - "type": "number", - "description": "Computed uptime % for this component on this day", - "format": "double" - }, - "partialOutageSeconds": { - "type": "integer", - "description": "Seconds of partial outage observed on this day", - "format": "int32" + "description": "Expected DNS record value for an exact match" + } + } + }, + "DnsResolvesAssertion": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "dns_resolves" + ] + } + }, + "required": [ + "type" + ] + }, + "DnsResponseTimeAssertion": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "dns_response_time" + ] }, - "majorOutageSeconds": { + "maxMs": { "type": "integer", - "description": "Seconds of major outage observed on this day", + "description": "Maximum allowed DNS resolution time in milliseconds", "format": "int32" } }, - "description": "One component's uptime contribution for the day" - }, - "ComponentPosition": { "required": [ - "componentId", - "displayOrder" - ], + "type", + "maxMs" + ] + }, + "DnsResponseTimeWarnAssertion": { "type": "object", "properties": { - "componentId": { + "type": { "type": "string", - "description": "Component ID", - "format": "uuid" + "enum": [ + "dns_response_time_warn" + ] }, - "displayOrder": { + "warnMs": { "type": "integer", - "description": "New display order (0-based)", + "description": "DNS resolution time in milliseconds that triggers a warning only", "format": "int32" - }, - "groupId": { - "type": "string", - "description": "Target group ID, null for ungrouped", - "format": "uuid", - "nullable": true } }, - "description": "A single component position" - }, - "ComponentSample": { "required": [ - "componentId", - "newStatus" - ], + "type", + "warnMs" + ] + }, + "DnsTtlHighAssertion": { "type": "object", "properties": { - "componentId": { - "type": "string", - "description": "Component ID", - "format": "uuid" - }, - "componentName": { - "type": "string", - "description": "Component display name", - "nullable": true - }, - "oldStatus": { + "type": { "type": "string", - "description": "Previous status before the flip", - "nullable": true + "enum": [ + "dns_ttl_high" + ] }, - "newStatus": { - "type": "string", - "description": "New status after the flip" + "maxTtl": { + "type": "integer", + "description": "Maximum TTL in seconds before a high-TTL warning is raised", + "format": "int32" } }, - "description": "One component sample inside a transition rollup" + "required": [ + "type", + "maxTtl" + ] }, - "ComponentsSummaryDto": { + "DnsTtlLowAssertion": { "required": [ - "groupComponentCounts", - "includedCount", - "totalCount" + "type", + "minTtl" ], "type": "object", "properties": { - "totalCount": { - "type": "integer", - "description": "Total active components for this service across all groups", - "format": "int32" + "type": { + "type": "string", + "enum": [ + "dns_ttl_low" + ] }, - "includedCount": { + "minTtl": { "type": "integer", - "description": "Number of components actually returned in the inline ``components`` list", + "description": "Minimum acceptable TTL in seconds before a warning is raised", "format": "int32" - }, - "groupComponentCounts": { - "type": "object", - "additionalProperties": { - "type": "integer", - "description": "Per-group active leaf count, keyed by group component id (UUID stringified). Empty when the service has no groups; lets the UI render \"show all N\" affordances without a second round trip", - "format": "int32" - }, - "description": "Per-group active leaf count, keyed by group component id (UUID stringified). Empty when the service has no groups; lets the UI render \"show all N\" affordances without a second round trip" } } }, - "ComponentStatusDto": { + "DnsTxtContainsAssertion": { "required": [ - "id", - "name", - "status" + "type", + "substring" ], "type": "object", "properties": { - "id": { - "type": "string", - "description": "Component UUID" - }, - "name": { + "type": { "type": "string", - "description": "Human-readable component name" + "enum": [ + "dns_txt_contains" + ] }, - "status": { + "substring": { + "minLength": 1, "type": "string", - "description": "Current component status, e.g. operational, degraded_performance" + "description": "Substring that must appear in at least one TXT record" } - }, - "description": "Current status of each active component" + } }, - "ComponentTransitionEventDto": { + "EmailChannelConfig": { "required": [ - "componentSample", - "newStatus", - "componentCount" + "channelType", + "recipients" ], "type": "object", "properties": { - "newStatus": { + "channelType": { "type": "string", - "description": "New status that defines this rollup bucket" - }, - "componentCount": { - "type": "integer", - "description": "Total components in the 5-minute rollup bucket", - "format": "int32" + "enum": [ + "email" + ] }, - "componentSample": { + "recipients": { + "minItems": 1, "type": "array", - "description": "Up to 5 sample components from the bucket", + "description": "Email addresses to send notifications to", "items": { - "$ref": "#/components/schemas/ComponentSample" + "type": "string", + "description": "Email addresses to send notifications to", + "format": "email" } } - }, - "description": "Rolled-up component status transitions for a status-events rail row" + } }, - "ComponentUptimeDayDto": { + "EntitlementDto": { "required": [ - "date", - "partialOutageSeconds", - "majorOutageSeconds", - "degradedSeconds", - "uptimePercentage" + "key", + "value", + "defaultValue", + "overridden" ], "type": "object", "properties": { - "date": { + "key": { "type": "string", - "description": "Start-of-day timestamp for this bucket (UTC midnight, ISO 8601)", - "format": "date-time" - }, - "partialOutageSeconds": { - "type": "integer", - "description": "Seconds of partial outage observed on this day", - "format": "int32" + "description": "Entitlement key" }, - "majorOutageSeconds": { + "value": { "type": "integer", - "description": "Seconds of major outage observed on this day", - "format": "int32" + "description": "Effective limit value (overrides applied)", + "format": "int64" }, - "degradedSeconds": { + "defaultValue": { "type": "integer", - "description": "Seconds the component spent in degraded performance on this day", - "format": "int32" - }, - "uptimePercentage": { - "type": "number", - "description": "Computed uptime percentage using the weighted formula (degraded does not lower it)", - "format": "double" + "description": "Plan-tier default value before overrides", + "format": "int64" }, - "incidents": { - "type": "array", - "description": "Incidents that overlapped this day, in display order", - "nullable": true, - "items": { - "$ref": "#/components/schemas/IncidentRef" - } + "overridden": { + "type": "boolean", + "description": "Whether this entitlement has an org-level override" } }, - "description": "Daily uptime data for a component" + "description": "A single resolved entitlement for the organization" }, - "ComponentUptimeSummaryDto": { + "EnvironmentDto": { "required": [ - "source" + "createdAt", + "id", + "name", + "slug", + "updatedAt", + "variables", + "orgId", + "monitorCount", + "isDefault" ], "type": "object", "properties": { - "day": { - "type": "number", - "description": "Uptime percentage over the last 24 hours", - "format": "double", - "nullable": true, - "example": 99.95 + "id": { + "type": "string", + "description": "Unique environment identifier", + "format": "uuid" }, - "week": { - "type": "number", - "description": "Uptime percentage over the last 7 days", - "format": "double", - "nullable": true, - "example": 99.98 + "orgId": { + "type": "integer", + "description": "Organization this environment belongs to", + "format": "int32" }, - "month": { - "type": "number", - "description": "Uptime percentage over the last 30 days", - "format": "double", - "nullable": true, - "example": 99.92 + "name": { + "minLength": 1, + "type": "string", + "description": "Human-readable environment name" }, - "source": { + "slug": { + "minLength": 1, "type": "string", - "description": "Data source: vendor_reported or incident_derived", - "example": "vendor_reported" - } - }, - "description": "Inline uptime percentages for 24h, 7d, 30d" - }, - "ConfirmationPolicy": { - "required": [ - "type", - "minRegionsFailing", - "maxWaitSeconds" - ], - "type": "object", - "properties": { - "type": { + "description": "URL-safe identifier" + }, + "variables": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Key-value variable pairs available for interpolation" + }, + "description": "Key-value variable pairs available for interpolation" + }, + "createdAt": { "type": "string", - "description": "How incident confirmation is coordinated across regions", - "enum": [ - "multi_region" - ] + "description": "Timestamp when the environment was created", + "format": "date-time" }, - "minRegionsFailing": { - "type": "integer", - "description": "Minimum failing regions required to confirm an incident", - "format": "int32" + "updatedAt": { + "type": "string", + "description": "Timestamp when the environment was last updated", + "format": "date-time" }, - "maxWaitSeconds": { + "monitorCount": { "type": "integer", - "description": "Maximum seconds to wait for enough regions to fail after first trigger", + "description": "Number of monitors using this environment", "format": "int32" + }, + "isDefault": { + "type": "boolean", + "description": "Whether this is the default environment for new monitors" } }, - "description": "Multi-region confirmation settings" + "description": "Environment with variable substitutions for monitor configs" }, - "CreateAlertChannelRequest": { + "ErrorEntry": { "required": [ - "config", - "name" + "code", + "message" ], "type": "object", "properties": { - "name": { - "maxLength": 255, - "minLength": 0, + "code": { + "minLength": 1, "type": "string", - "description": "Human-readable name for this alert channel" - }, - "config": { - "oneOf": [ - { - "$ref": "#/components/schemas/DatadogChannelConfig" - }, - { - "$ref": "#/components/schemas/DiscordChannelConfig" - }, - { - "$ref": "#/components/schemas/EmailChannelConfig" - }, - { - "$ref": "#/components/schemas/GitLabChannelConfig" - }, - { - "$ref": "#/components/schemas/GoogleChatChannelConfig" - }, - { - "$ref": "#/components/schemas/IncidentIoChannelConfig" - }, - { - "$ref": "#/components/schemas/JiraChannelConfig" - }, - { - "$ref": "#/components/schemas/LinearChannelConfig" - }, - { - "$ref": "#/components/schemas/MattermostChannelConfig" - }, - { - "$ref": "#/components/schemas/OpsGenieChannelConfig" - }, - { - "$ref": "#/components/schemas/PagerDutyChannelConfig" - }, - { - "$ref": "#/components/schemas/PhoneCallChannelConfig" - }, - { - "$ref": "#/components/schemas/PushbulletChannelConfig" - }, - { - "$ref": "#/components/schemas/PushoverChannelConfig" - }, - { - "$ref": "#/components/schemas/RootlyChannelConfig" - }, - { - "$ref": "#/components/schemas/SlackChannelConfig" - }, - { - "$ref": "#/components/schemas/SmsChannelConfig" - }, - { - "$ref": "#/components/schemas/SplunkOnCallChannelConfig" - }, - { - "$ref": "#/components/schemas/TeamsChannelConfig" - }, - { - "$ref": "#/components/schemas/TelegramChannelConfig" - }, - { - "$ref": "#/components/schemas/WebhookChannelConfig" - }, - { - "$ref": "#/components/schemas/ZapierChannelConfig" - } - ] + "description": "Stable machine-readable code; see ValidationErrorCode for the registry", + "example": "MONITOR_HEARTBEAT_GRACE_EXCEEDS_INTERVAL" }, - "managedBy": { + "field": { "type": "string", - "description": "Source creating this channel: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted.", + "description": "JSON-pointer-like path to the offending field, or null for request-wide errors", "nullable": true, - "enum": [ - "DASHBOARD", - "CLI", - "TERRAFORM", - "MCP", - "API" - ] + "example": "config.gracePeriod" + }, + "message": { + "minLength": 1, + "type": "string", + "description": "Human-readable message; safe to surface to end users" } - } + }, + "description": "One structured validation rejection" }, - "CreateApiKeyRequest": { + "ErrorResponse": { "required": [ - "name" + "code", + "message", + "status", + "timestamp" ], "type": "object", "properties": { - "name": { - "maxLength": 200, - "minLength": 0, + "status": { + "type": "integer", + "description": "HTTP status code (mirrors the response status line)", + "format": "int32", + "example": 404 + }, + "code": { "type": "string", - "description": "Human-readable name to identify this API key" + "description": "Coarse machine-readable error category (e.g. NOT_FOUND, RATE_LIMITED); stable per status", + "example": "NOT_FOUND" }, - "expiresAt": { + "message": { "type": "string", - "description": "Optional expiration timestamp in ISO 8601 format", - "format": "date-time", - "nullable": true - } - } - }, - "CreateAssertionRequest": { - "required": [ - "config" - ], - "type": "object", - "properties": { - "config": { - "oneOf": [ - { - "$ref": "#/components/schemas/BodyContainsAssertion" - }, - { - "$ref": "#/components/schemas/DnsExpectedCnameAssertion" - }, - { - "$ref": "#/components/schemas/DnsExpectedIpsAssertion" - }, - { - "$ref": "#/components/schemas/DnsMaxAnswersAssertion" - }, - { - "$ref": "#/components/schemas/DnsMinAnswersAssertion" - }, - { - "$ref": "#/components/schemas/DnsRecordContainsAssertion" - }, - { - "$ref": "#/components/schemas/DnsRecordEqualsAssertion" - }, - { - "$ref": "#/components/schemas/DnsResolvesAssertion" - }, - { - "$ref": "#/components/schemas/DnsResponseTimeAssertion" - }, - { - "$ref": "#/components/schemas/DnsResponseTimeWarnAssertion" - }, - { - "$ref": "#/components/schemas/DnsTtlHighAssertion" - }, - { - "$ref": "#/components/schemas/DnsTtlLowAssertion" - }, - { - "$ref": "#/components/schemas/DnsTxtContainsAssertion" - }, - { - "$ref": "#/components/schemas/HeaderValueAssertion" - }, - { - "$ref": "#/components/schemas/HeartbeatIntervalDriftAssertion" - }, - { - "$ref": "#/components/schemas/HeartbeatMaxIntervalAssertion" - }, - { - "$ref": "#/components/schemas/HeartbeatPayloadContainsAssertion" - }, - { - "$ref": "#/components/schemas/HeartbeatReceivedAssertion" - }, - { - "$ref": "#/components/schemas/IcmpPacketLossAssertion" - }, - { - "$ref": "#/components/schemas/IcmpReachableAssertion" - }, - { - "$ref": "#/components/schemas/IcmpResponseTimeAssertion" - }, - { - "$ref": "#/components/schemas/IcmpResponseTimeWarnAssertion" - }, - { - "$ref": "#/components/schemas/JsonPathAssertion" - }, - { - "$ref": "#/components/schemas/McpConnectsAssertion" - }, - { - "$ref": "#/components/schemas/McpHasCapabilityAssertion" - }, - { - "$ref": "#/components/schemas/McpMinToolsAssertion" - }, - { - "$ref": "#/components/schemas/McpProtocolVersionAssertion" - }, - { - "$ref": "#/components/schemas/McpResponseTimeAssertion" - }, - { - "$ref": "#/components/schemas/McpResponseTimeWarnAssertion" - }, - { - "$ref": "#/components/schemas/McpToolAvailableAssertion" - }, - { - "$ref": "#/components/schemas/McpToolCountChangedAssertion" - }, - { - "$ref": "#/components/schemas/RedirectCountAssertion" - }, - { - "$ref": "#/components/schemas/RedirectTargetAssertion" - }, - { - "$ref": "#/components/schemas/RegexBodyAssertion" - }, - { - "$ref": "#/components/schemas/ResponseSizeAssertion" - }, - { - "$ref": "#/components/schemas/ResponseTimeAssertion" - }, - { - "$ref": "#/components/schemas/ResponseTimeWarnAssertion" - }, - { - "$ref": "#/components/schemas/SslExpiryAssertion" - }, - { - "$ref": "#/components/schemas/StatusCodeAssertion" - }, - { - "$ref": "#/components/schemas/TcpConnectsAssertion" - }, - { - "$ref": "#/components/schemas/TcpResponseTimeAssertion" - }, - { - "$ref": "#/components/schemas/TcpResponseTimeWarnAssertion" - } - ] + "description": "Human-readable error message; safe to surface to end users", + "example": "Monitor not found" + }, + "timestamp": { + "type": "integer", + "description": "Server time when the error was produced (epoch milliseconds)", + "format": "int64", + "example": 1737302400000 }, - "severity": { + "requestId": { "type": "string", - "description": "Outcome severity: FAIL (fails the check) or WARN (warns without failing, default: FAIL)", + "description": "Opaque per-request id; same value as the X-Request-Id response header. Use in support tickets.", "nullable": true, - "enum": [ - "fail", - "warn" - ] + "example": "5b6f7a8c-1234-4d5e-9f0a-1b2c3d4e5f6a" + }, + "errors": { + "type": "array", + "description": "Structured per-field rejections; populated for validation errors, null otherwise", + "nullable": true, + "items": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/ErrorEntry" + } + ] + } } }, - "description": "Replace all assertions; null preserves current" + "description": "Uniform error envelope returned for every non-2xx response", + "example": { + "status": 404, + "code": "NOT_FOUND", + "message": "Monitor not found", + "timestamp": 1737302400000, + "requestId": "5b6f7a8c-1234-4d5e-9f0a-1b2c3d4e5f6a" + } }, - "CreateEnvironmentRequest": { + "EscalationChain": { "required": [ - "name", - "slug" + "steps" ], "type": "object", "properties": { - "name": { - "maxLength": 100, - "minLength": 0, + "steps": { + "minItems": 1, + "type": "array", + "description": "Ordered escalation steps, evaluated in sequence", + "items": { + "$ref": "#/components/schemas/EscalationStep" + } + }, + "onResolve": { "type": "string", - "description": "Human-readable environment name" + "description": "Action when the incident resolves", + "nullable": true }, - "slug": { - "maxLength": 100, - "minLength": 0, - "pattern": "^[a-z0-9][a-z0-9_-]*$", + "onReopen": { "type": "string", - "description": "URL-safe identifier (lowercase alphanumeric, hyphens, underscores)" + "description": "Action when a resolved incident reopens", + "nullable": true + } + }, + "description": "Escalation chain defining which channels to notify; null preserves current" + }, + "EscalationStep": { + "required": [ + "channelIds", + "delayMinutes" + ], + "type": "object", + "properties": { + "delayMinutes": { + "minimum": 0, + "type": "integer", + "description": "Minutes to wait before executing this step (0 = immediate)", + "format": "int32" }, - "variables": { - "type": "object", - "additionalProperties": { + "channelIds": { + "minItems": 1, + "type": "array", + "description": "Alert channel IDs to notify in this step", + "items": { "type": "string", - "description": "Initial key-value variable pairs for this environment", - "nullable": true - }, - "description": "Initial key-value variable pairs for this environment", - "nullable": true + "description": "Alert channel IDs to notify in this step", + "format": "uuid" + } }, - "isDefault": { + "requireAck": { "type": "boolean", - "description": "Whether this is the default environment for new monitors (default: false)", + "description": "Whether an acknowledgment is required before escalating", + "nullable": true + }, + "repeatIntervalSeconds": { + "minimum": 1, + "type": "integer", + "description": "Repeat notification interval in seconds until acknowledged", + "format": "int32", "nullable": true } - } + }, + "description": "Ordered escalation steps, evaluated in sequence" }, - "CreateInviteRequest": { + "FailureDetail": { "required": [ - "email", - "roleOffered" + "monitorId", + "reason" ], "type": "object", "properties": { - "email": { - "minLength": 1, + "monitorId": { "type": "string", - "description": "Email address to invite", - "format": "email" + "description": "Monitor ID that failed", + "format": "uuid" }, - "roleOffered": { + "reason": { "type": "string", - "description": "Role to assign on acceptance", - "enum": [ - "OWNER", - "ADMIN", - "MEMBER" - ] + "description": "Human-readable reason for the failure" } }, - "description": "Invite a new member to the organization by email" + "description": "Details about a single monitor that failed the bulk action" }, - "CreateMaintenanceWindowRequest": { + "GitLabChannelConfig": { "required": [ - "endsAt", - "startsAt" + "channelType", + "endpointUrl", + "authorizationKey" ], "type": "object", "properties": { - "monitorId": { + "channelType": { "type": "string", - "description": "Monitor to attach this maintenance window to; null for org-wide", - "format": "uuid", - "nullable": true + "enum": [ + "gitlab" + ] }, - "startsAt": { + "endpointUrl": { + "minLength": 1, "type": "string", - "description": "Scheduled start of the maintenance window (ISO 8601)", - "format": "date-time" + "description": "GitLab alert integration endpoint URL" }, - "endsAt": { + "authorizationKey": { + "minLength": 1, "type": "string", - "description": "Scheduled end of the maintenance window (ISO 8601)", - "format": "date-time" + "description": "Authorization key from GitLab alert integration settings" + } + } + }, + "GlobalStatusSummaryDto": { + "required": [ + "servicesWithIssues", + "totalServices", + "operationalCount", + "degradedCount", + "partialOutageCount", + "majorOutageCount", + "maintenanceCount", + "unknownCount", + "activeIncidentCount" + ], + "type": "object", + "properties": { + "totalServices": { + "type": "integer", + "description": "Total number of services in the catalog", + "format": "int32" }, - "repeatRule": { - "maxLength": 100, - "minLength": 0, - "type": "string", - "description": "Reserved: iCal RRULE for recurring windows (stored but not yet honored)", - "nullable": true + "operationalCount": { + "type": "integer", + "description": "Number of services currently fully operational", + "format": "int32" }, - "reason": { - "maxLength": 500, - "minLength": 0, + "degradedCount": { + "type": "integer", + "description": "Number of services with degraded status", + "format": "int32" + }, + "partialOutageCount": { + "type": "integer", + "description": "Number of services with partial outage", + "format": "int32" + }, + "majorOutageCount": { + "type": "integer", + "description": "Number of services with major outage", + "format": "int32" + }, + "maintenanceCount": { + "type": "integer", + "description": "Number of services currently under maintenance", + "format": "int32" + }, + "unknownCount": { + "type": "integer", + "description": "Number of services with unknown or null status", + "format": "int32" + }, + "activeIncidentCount": { + "type": "integer", + "description": "Total number of active incidents across all services", + "format": "int64" + }, + "servicesWithIssues": { + "type": "array", + "description": "Services that are not fully operational", + "items": { + "$ref": "#/components/schemas/ServiceCatalogDto" + } + } + }, + "description": "Global status summary across all subscribed vendor services" + }, + "GoogleChatChannelConfig": { + "required": [ + "channelType", + "webhookUrl" + ], + "type": "object", + "properties": { + "channelType": { "type": "string", - "description": "Human-readable reason for the maintenance (max 500 chars)", - "nullable": true + "enum": [ + "google_chat" + ] }, - "suppressAlerts": { - "type": "boolean", - "description": "Whether to suppress alerts during this window (default: true)", - "nullable": true + "webhookUrl": { + "minLength": 1, + "type": "string", + "description": "Google Chat space webhook URL" } } }, - "CreateManualIncidentRequest": { + "GroupComponentOrder": { "required": [ - "severity", - "title" + "groupId", + "positions" ], "type": "object", "properties": { - "title": { - "minLength": 1, + "groupId": { "type": "string", - "description": "Short summary of the incident" + "description": "Group these components belong to", + "format": "uuid" }, - "severity": { + "positions": { + "minItems": 1, + "type": "array", + "description": "Ordered component IDs with their within-group display order", + "items": { + "$ref": "#/components/schemas/ComponentPosition" + } + } + }, + "description": "Component ordering within a single group" + }, + "HeaderAuthConfig": { + "required": [ + "type", + "headerName" + ], + "type": "object", + "properties": { + "type": { "type": "string", - "description": "Incident severity: DOWN, DEGRADED, or MAINTENANCE", "enum": [ - "DOWN", - "DEGRADED", - "MAINTENANCE" + "header" ] }, - "monitorId": { + "headerName": { + "minLength": 1, + "pattern": "^[A-Za-z0-9\\-_]+$", "type": "string", - "description": "Monitor to associate with this incident", + "description": "Custom HTTP header name for the secret value" + }, + "vaultSecretId": { + "type": "string", + "description": "Vault secret ID for the header value", "format": "uuid", "nullable": true + } + } + }, + "HeaderValueAssertion": { + "required": [ + "type", + "headerName", + "expected", + "operator" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "header_value" + ] }, - "body": { + "headerName": { + "minLength": 1, "type": "string", - "description": "Detailed description or context for the incident", - "nullable": true + "description": "HTTP header name to assert on" }, - "serviceId": { + "expected": { + "minLength": 1, "type": "string", - "description": "Vendor service to link; optional for Dependencies create CTA", - "format": "uuid", - "nullable": true + "description": "Expected value to compare against" }, - "serviceIncidentId": { + "operator": { "type": "string", - "description": "Vendor incident to link; idempotent if an active org incident already links it", - "format": "uuid", - "nullable": true + "description": "Comparison operator (equals, contains, less_than, greater_than, etc.)", + "enum": [ + "equals", + "contains", + "less_than", + "greater_than", + "matches", + "range" + ] } } }, - "CreateMonitorRequest": { + "HeartbeatIntervalDriftAssertion": { "required": [ - "config", - "name", - "type" + "type", + "maxDeviationPercent" ], "type": "object", "properties": { - "name": { - "maxLength": 255, - "minLength": 0, - "type": "string", - "description": "Human-readable name for this monitor" - }, "type": { "type": "string", - "description": "Monitor protocol type", "enum": [ - "HTTP", - "DNS", - "MCP_SERVER", - "TCP", - "ICMP", - "HEARTBEAT", - "BROWSER", - "MULTI_STEP_API" + "heartbeat_interval_drift" ] }, - "config": { - "oneOf": [ - { - "$ref": "#/components/schemas/DnsMonitorConfig" - }, - { - "$ref": "#/components/schemas/HeartbeatMonitorConfig" - }, - { - "$ref": "#/components/schemas/HttpMonitorConfig" - }, - { - "$ref": "#/components/schemas/IcmpMonitorConfig" - }, - { - "$ref": "#/components/schemas/McpServerMonitorConfig" - }, - { - "$ref": "#/components/schemas/ScriptMonitorConfig" - }, - { - "$ref": "#/components/schemas/TcpMonitorConfig" - } + "maxDeviationPercent": { + "maximum": 100, + "minimum": 1, + "type": "integer", + "description": "Max percent drift from expected ping interval before warning (non-fatal)", + "format": "int32" + } + } + }, + "HeartbeatMaxIntervalAssertion": { + "required": [ + "type", + "maxSeconds" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "heartbeat_max_interval" ] }, - "frequencySeconds": { + "maxSeconds": { + "minimum": 1, + "type": "integer", + "description": "Maximum allowed gap in seconds between consecutive heartbeat pings", + "format": "int32" + } + } + }, + "HeartbeatMonitorConfig": { + "required": [ + "expectedInterval", + "gracePeriod" + ], + "type": "object", + "properties": { + "expectedInterval": { "maximum": 86400, - "minimum": 10, + "minimum": 1, "type": "integer", - "description": "Check frequency in seconds (10–86400); null defaults to plan minimum (60s on most paid plans)", - "format": "int32", - "nullable": true - }, - "enabled": { - "type": "boolean", - "description": "Whether the monitor is active (default: true)", - "nullable": true - }, - "regions": { - "type": "array", - "description": "Probe regions to run checks from. Allowed values are deployment-dependent; production: us-east, us-west, eu-west, ap-south.", - "nullable": true, - "items": { - "type": "string", - "description": "Probe regions to run checks from. Allowed values are deployment-dependent; production: us-east, us-west, eu-west, ap-south." - } + "description": "Expected heartbeat interval in seconds", + "format": "int32" }, - "managedBy": { + "gracePeriod": { + "minimum": 1, + "type": "integer", + "description": "Grace period in seconds before marking as down", + "format": "int32" + } + } + }, + "HeartbeatPayloadContainsAssertion": { + "required": [ + "type", + "path", + "value" + ], + "type": "object", + "properties": { + "type": { "type": "string", - "description": "Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted; set to your surface so audit logs, drift detection, and analytics attribute correctly.", - "nullable": true, "enum": [ - "DASHBOARD", - "CLI", - "TERRAFORM", - "MCP", - "API" + "heartbeat_payload_contains" ] }, - "environmentId": { + "path": { + "minLength": 1, "type": "string", - "description": "Environment to associate with this monitor", - "format": "uuid", - "nullable": true - }, - "assertions": { - "type": "array", - "description": "Assertions to evaluate against each check result", - "nullable": true, - "items": { - "$ref": "#/components/schemas/CreateAssertionRequest" - } + "description": "JSONPath expression into the heartbeat ping JSON payload" }, - "auth": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/MonitorAuthConfig" - } + "value": { + "type": "string", + "description": "Expected value to compare against at that path" + } + } + }, + "HeartbeatPingResponse": { + "required": [ + "ok" + ], + "type": "object", + "properties": { + "ok": { + "type": "boolean", + "description": "Always true on a 2xx response", + "example": true + } + }, + "description": "Acknowledgement that a heartbeat ping was accepted" + }, + "HeartbeatReceivedAssertion": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "heartbeat_received" ] - }, - "incidentPolicy": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/UpdateIncidentPolicyRequest" - } + } + }, + "required": [ + "type" + ] + }, + "Http": { + "type": "object", + "description": "HTTP check-type-specific details", + "properties": { + "check_type": { + "type": "string", + "enum": [ + "http" ] }, - "alertChannelIds": { - "type": "array", - "description": "Alert channels to notify when this monitor triggers", - "nullable": true, - "items": { - "type": "string", - "description": "Alert channels to notify when this monitor triggers", - "format": "uuid" - } - }, - "tags": { + "timing": { "nullable": true, "allOf": [ { - "$ref": "#/components/schemas/AddMonitorTagsRequest" + "$ref": "#/components/schemas/TimingPhasesDto" } ] + }, + "bodyTruncated": { + "type": "boolean", + "description": "Whether the response body was truncated before storage", + "nullable": true } - } + }, + "required": [ + "check_type" + ] }, - "CreateNotificationPolicyRequest": { + "HttpMonitorConfig": { "required": [ - "escalation", - "name" + "method", + "url" ], "type": "object", "properties": { - "name": { - "maxLength": 255, - "minLength": 0, + "url": { + "minLength": 1, "type": "string", - "description": "Human-readable name for this policy" + "description": "Target URL to send requests to" }, - "description": { - "maxLength": 500, - "minLength": 0, + "method": { "type": "string", - "description": "Optional note; omit or null when unused", + "description": "HTTP method: GET, POST, PUT, PATCH, DELETE, or HEAD", + "enum": [ + "GET", + "POST", + "PUT", + "PATCH", + "DELETE", + "HEAD" + ] + }, + "customHeaders": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Additional HTTP headers to include in requests", + "nullable": true + }, + "description": "Additional HTTP headers to include in requests", "nullable": true }, - "matchRules": { - "type": "array", - "description": "Match rules to evaluate (all must pass; omit or empty for catch-all)", - "nullable": true, - "items": { - "$ref": "#/components/schemas/MatchRule" - } + "requestBody": { + "type": "string", + "description": "Request body content for POST/PUT/PATCH methods", + "nullable": true }, - "escalation": { - "$ref": "#/components/schemas/EscalationChain" + "contentType": { + "type": "string", + "description": "Content-Type header value for the request body", + "nullable": true }, - "enabled": { + "verifyTls": { "type": "boolean", - "description": "Whether this policy is enabled (default true)", - "nullable": true, - "default": true - }, - "priority": { - "type": "integer", - "description": "Evaluation priority; higher value = evaluated first (default 0)", - "format": "int32", - "nullable": true, - "default": 0 + "description": "Whether to verify TLS certificates (default: true)", + "nullable": true } - }, - "description": "Request body for creating a notification policy" + } }, - "CreateResourceGroupRequest": { + "Icmp": { "required": [ - "name" + "check_type", + "host" ], "type": "object", + "description": "ICMP (ping) check-type-specific details", "properties": { - "name": { - "maxLength": 255, - "minLength": 0, + "check_type": { "type": "string", - "description": "Human-readable name for this group" + "enum": [ + "icmp" + ] }, - "description": { - "maxLength": 500, - "minLength": 0, + "host": { "type": "string", - "description": "Optional description (max 500)", - "nullable": true + "description": "Target host", + "example": "1.1.1.1" }, - "alertPolicyId": { - "type": "string", - "description": "Optional notification policy to apply for this group", - "format": "uuid", + "packetsSent": { + "type": "integer", + "description": "Number of ICMP packets sent", + "format": "int32", "nullable": true }, - "defaultFrequency": { - "maximum": 86400, - "minimum": 30, + "packetsReceived": { "type": "integer", - "description": "Default check frequency in seconds applied to members (30–86400)", + "description": "Number of ICMP packets received", "format": "int32", "nullable": true }, - "defaultRegions": { - "type": "array", - "description": "Default regions applied to member monitors", - "nullable": true, - "items": { - "type": "string", - "description": "Default regions applied to member monitors" - } - }, - "defaultRetryStrategy": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/RetryStrategy" - } - ] - }, - "defaultAlertChannels": { - "type": "array", - "description": "Default alert channel IDs applied to member monitors", + "packetLoss": { + "type": "number", + "description": "Packet loss percentage", + "format": "double", "nullable": true, - "items": { - "type": "string", - "description": "Default alert channel IDs applied to member monitors", - "format": "uuid" - } + "example": 0 }, - "defaultEnvironmentId": { - "type": "string", - "description": "Default environment ID applied to member monitors", - "format": "uuid", + "avgRttMs": { + "type": "number", + "description": "Average round-trip time in ms", + "format": "double", "nullable": true }, - "healthThresholdType": { - "type": "string", - "description": "Health threshold type: COUNT or PERCENTAGE", - "nullable": true, - "enum": [ - "COUNT", - "PERCENTAGE" - ] + "minRttMs": { + "type": "number", + "description": "Minimum round-trip time in ms", + "format": "double", + "nullable": true }, - "healthThresholdValue": { - "maximum": 100, - "exclusiveMaximum": false, - "minimum": 0, - "exclusiveMinimum": false, + "maxRttMs": { "type": "number", - "description": "Health threshold value: count (0+) or percentage (0–100)", + "description": "Maximum round-trip time in ms", + "format": "double", "nullable": true }, - "suppressMemberAlerts": { - "type": "boolean", - "description": "Suppress member-level alert notifications when group manages alerting", + "jitterMs": { + "type": "number", + "description": "Jitter in ms", + "format": "double", "nullable": true + } + } + }, + "IcmpMonitorConfig": { + "required": [ + "host" + ], + "type": "object", + "properties": { + "host": { + "minLength": 1, + "type": "string", + "description": "Target hostname or IP address to ping" }, - "confirmationDelaySeconds": { - "maximum": 600, - "minimum": 0, + "packetCount": { + "maximum": 20, + "minimum": 1, "type": "integer", - "description": "Confirmation delay in seconds before group incident creation (0–600)", + "description": "Number of ICMP packets to send", "format": "int32", "nullable": true }, - "recoveryCooldownMinutes": { - "maximum": 60, - "minimum": 0, + "timeoutMs": { "type": "integer", - "description": "Recovery cooldown in minutes after group incident resolves (0–60)", + "description": "Ping timeout in milliseconds", "format": "int32", "nullable": true - }, - "managedBy": { - "type": "string", - "description": "Source creating this group: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted.", - "nullable": true, - "enum": [ - "DASHBOARD", - "CLI", - "TERRAFORM", - "MCP", - "API" - ] } - }, - "description": "Request body for creating a resource group" + } }, - "CreateSecretRequest": { + "IcmpPacketLossAssertion": { "required": [ - "key", - "value" + "type", + "maxPercent" ], "type": "object", "properties": { - "key": { - "maxLength": 255, - "minLength": 0, + "type": { "type": "string", - "description": "Unique secret key within the workspace (max 255 chars)" + "enum": [ + "icmp_packet_loss" + ] }, - "value": { - "maxLength": 32768, - "minLength": 0, - "type": "string", - "description": "Secret value, stored encrypted (max 32KB)" + "maxPercent": { + "maximum": 100, + "exclusiveMaximum": false, + "minimum": 0, + "exclusiveMinimum": false, + "type": "number", + "description": "Maximum allowed packet loss percentage before the check fails (0–100)", + "format": "double" } } }, - "CreateStatusPageComponentGroupRequest": { - "required": [ - "name" - ], + "IcmpReachableAssertion": { "type": "object", "properties": { - "name": { - "maxLength": 255, - "minLength": 0, - "type": "string", - "description": "Group display name" - }, - "description": { - "maxLength": 500, - "minLength": 0, + "type": { "type": "string", - "description": "Optional group description", - "nullable": true - }, - "displayOrder": { - "type": "integer", - "description": "Position in the group list", - "format": "int32", - "nullable": true - }, - "defaultOpen": { - "type": "boolean", - "description": "Initial expand/collapse state when a visitor first loads the page; renderer may auto-expand on active incidents (default: true)", - "nullable": true + "enum": [ + "icmp_reachable" + ] } - } - }, - "CreateStatusPageComponentRequest": { + }, "required": [ - "name", "type" - ], + ] + }, + "IcmpResponseTimeAssertion": { "type": "object", "properties": { - "name": { - "maxLength": 255, - "minLength": 0, - "type": "string", - "description": "Component display name" - }, - "description": { - "maxLength": 500, - "minLength": 0, - "type": "string", - "description": "Optional description shown on expand", - "nullable": true - }, "type": { "type": "string", - "description": "Component type: MONITOR, GROUP, STATIC, or DEPENDENCY", "enum": [ - "MONITOR", - "GROUP", - "STATIC", - "DEPENDENCY" + "icmp_response_time" ] }, - "monitorId": { - "type": "string", - "description": "Monitor ID (required when type=MONITOR)", - "format": "uuid", - "nullable": true - }, - "resourceGroupId": { - "type": "string", - "description": "Resource group ID (required when type=GROUP)", - "format": "uuid", - "nullable": true - }, - "serviceSubscriptionId": { - "type": "string", - "description": "Service subscription (Dependency) ID — required when type=DEPENDENCY. Bind an existing org subscription; catalog picks must create the subscription first, then pass its id", - "format": "uuid", - "nullable": true - }, - "groupId": { + "maxMs": { + "type": "integer", + "description": "Maximum average ICMP round-trip time in milliseconds", + "format": "int32" + } + }, + "required": [ + "type", + "maxMs" + ] + }, + "IcmpResponseTimeWarnAssertion": { + "type": "object", + "properties": { + "type": { "type": "string", - "description": "Component group ID for visual grouping", - "format": "uuid", - "nullable": true - }, - "showUptime": { - "type": "boolean", - "description": "Whether to show the uptime bar (default: true; false for DEPENDENCY)", - "nullable": true + "enum": [ + "icmp_response_time_warn" + ] }, - "displayOrder": { + "warnMs": { "type": "integer", - "description": "Position in the component list", - "format": "int32", - "nullable": true - }, - "excludeFromOverall": { - "type": "boolean", - "description": "Exclude from overall status calculation (default: false; true for DEPENDENCY)", - "nullable": true - }, - "startDate": { - "type": "string", - "description": "Date from which to start showing uptime; defaults to component creation. Set earlier to backdate (e.g. launch day); clamped at the monitor's createdAt for MONITOR-type components", - "format": "date", - "nullable": true + "description": "ICMP round-trip time in milliseconds that triggers a warning only", + "format": "int32" } - } + }, + "required": [ + "type", + "warnMs" + ] }, - "CreateStatusPageIncidentRequest": { + "IncidentActivityEventDto": { "required": [ - "body", - "impact", - "title" + "at", + "id", + "kind", + "summary" ], "type": "object", "properties": { - "title": { - "maxLength": 500, - "minLength": 0, + "id": { "type": "string", - "description": "Customer-facing incident title" + "description": "Stable event ID (source row ID)", + "format": "uuid" }, - "status": { + "at": { "type": "string", - "description": "Initial status (default: INVESTIGATING)", - "nullable": true, - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] + "description": "When the event occurred (ISO 8601)", + "format": "date-time" }, - "impact": { + "kind": { "type": "string", - "description": "Impact level: NONE, MINOR, MAJOR, or CRITICAL", + "description": "Activity event kind in the merged incident activity stream", "enum": [ - "NONE", - "MINOR", - "MAJOR", - "CRITICAL" + "update", + "dispatch", + "delivery", + "forensic_transition", + "status_page_update" ] }, - "body": { - "minLength": 1, + "actor": { "type": "string", - "description": "Initial update body in markdown" - }, - "affectedComponents": { - "type": "array", - "description": "Component IDs affected by this incident", - "nullable": true, - "items": { - "$ref": "#/components/schemas/AffectedComponent" - } - }, - "notifySubscribers": { - "type": "boolean", - "description": "Whether to email confirmed subscribers about this incident (default: true)", + "description": "Actor label when known (user email, system, etc.)", "nullable": true }, - "monitoringIncidentId": { + "summary": { "type": "string", - "description": "Monitoring incident ID to link this status page incident to; null for standalone", - "format": "uuid", - "nullable": true + "description": "Human-readable summary of the event" + }, + "payload": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/IncidentActivityPayloadDto" + } + ] } - } + }, + "description": "Merged incident activity event (updates, dispatches, deliveries, forensics, SP updates)" }, - "CreateStatusPageIncidentUpdateRequest": { - "required": [ - "body", - "status" - ], + "IncidentActivityPayloadDto": { "type": "object", "properties": { - "status": { + "oldStatus": { "type": "string", - "description": "Incident status at this point in the timeline", - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] + "description": "Previous incident status on an update", + "nullable": true + }, + "newStatus": { + "type": "string", + "description": "New incident status on an update", + "nullable": true }, "body": { - "minLength": 1, "type": "string", - "description": "Update body in markdown" + "description": "Update or status-page note body", + "nullable": true }, - "notifySubscribers": { - "type": "boolean", - "description": "Whether to email confirmed subscribers about this update (default: true)", + "createdBy": { + "type": "string", + "description": "Who created the update (SYSTEM, USER, …)", "nullable": true }, - "affectedComponents": { - "type": "array", - "description": "Updated affected components; null preserves current", - "nullable": true, - "items": { - "$ref": "#/components/schemas/AffectedComponent" - } - } - } - }, - "CreateStatusPageMaintenanceRequest": { - "required": [ - "body", - "impact", - "scheduledFor", - "title" - ], - "type": "object", - "properties": { - "title": { - "maxLength": 500, - "minLength": 0, + "phase": { "type": "string", - "description": "Customer-facing maintenance title" + "description": "Dispatch lifecycle phase (fired, acked)", + "nullable": true }, "status": { "type": "string", - "description": "Initial status (default: INVESTIGATING)", - "nullable": true, - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] + "description": "Dispatch, delivery, or status-page status", + "nullable": true }, - "impact": { + "policyId": { "type": "string", - "description": "Impact level: NONE, MINOR, MAJOR, or CRITICAL", - "enum": [ - "NONE", - "MINOR", - "MAJOR", - "CRITICAL" - ] + "description": "Notification policy id for a dispatch row", + "nullable": true }, - "body": { - "minLength": 1, + "policyName": { "type": "string", - "description": "Initial update body in markdown" + "description": "Notification policy name when resolved", + "nullable": true }, - "affectedComponents": { - "type": "array", - "description": "Component IDs affected by this window", - "nullable": true, - "items": { - "$ref": "#/components/schemas/AffectedComponent" - } + "currentStep": { + "type": "integer", + "description": "Current escalation step (1-based)", + "format": "int32", + "nullable": true }, - "scheduledFor": { + "dispatchId": { "type": "string", - "description": "Maintenance start time", - "format": "date-time" + "description": "Notification dispatch id", + "nullable": true }, - "scheduledUntil": { + "acknowledgedBy": { "type": "string", - "description": "Maintenance end time", - "format": "date-time", + "description": "Who acknowledged the dispatch", "nullable": true }, - "autoResolve": { - "type": "boolean", - "description": "Auto-resolve at scheduledUntil (default: false)", + "acknowledgedVia": { + "type": "string", + "description": "Ack channel (UI, Slack, …)", "nullable": true }, - "notifySubscribers": { - "type": "boolean", - "description": "Whether to email confirmed subscribers about this window (default: true)", - "nullable": true - } - } - }, - "CreateStatusPageRequest": { - "required": [ - "name", - "slug" - ], - "type": "object", - "properties": { - "name": { - "maxLength": 255, - "minLength": 0, + "eventType": { "type": "string", - "description": "Human-readable name for this status page" + "description": "Alert delivery event type", + "nullable": true }, - "slug": { - "maxLength": 63, - "minLength": 3, - "pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$", + "stepNumber": { + "type": "integer", + "description": "Escalation step that sent this delivery", + "format": "int32", + "nullable": true + }, + "fireCount": { + "type": "integer", + "description": "How many times this delivery has fired", + "format": "int32", + "nullable": true + }, + "channelId": { "type": "string", - "description": "URL slug (lowercase, hyphens, globally unique)" + "description": "Alert channel id", + "nullable": true }, - "description": { - "maxLength": 500, - "minLength": 0, + "channelName": { "type": "string", - "description": "Optional description shown below the page header", + "description": "Alert channel name", "nullable": true }, - "branding": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/StatusPageBranding" - } - ] + "channelType": { + "type": "string", + "description": "Alert channel type", + "nullable": true }, - "visibility": { + "errorMessage": { "type": "string", - "description": "Page visibility: PUBLIC, PASSWORD, or IP_RESTRICTED (default: PUBLIC)", - "nullable": true, - "enum": [ - "PUBLIC", - "PASSWORD", - "IP_RESTRICTED" - ] + "description": "Delivery error message when the send failed", + "nullable": true }, - "enabled": { - "type": "boolean", - "description": "Whether the page is enabled (default: true)", + "fromStatus": { + "type": "string", + "description": "Forensic from-status", "nullable": true }, - "incidentMode": { + "toStatus": { "type": "string", - "description": "Incident mode: MANUAL, REVIEW, or AUTOMATIC (default: AUTOMATIC)", - "nullable": true, - "enum": [ - "MANUAL", - "REVIEW", - "AUTOMATIC" - ] + "description": "Forensic to-status", + "nullable": true }, - "managedBy": { + "reason": { "type": "string", - "description": "Source creating this page: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted.", + "description": "Forensic transition reason", + "nullable": true + }, + "affectedRegions": { + "type": "array", + "description": "Regions named on the forensic transition", "nullable": true, - "enum": [ - "DASHBOARD", - "CLI", - "TERRAFORM", - "MCP", - "API" - ] - } - } - }, - "CreateTagRequest": { - "required": [ - "name" - ], - "type": "object", - "properties": { - "name": { - "maxLength": 100, - "minLength": 0, - "type": "string", - "description": "Tag name, unique within the org" + "items": { + "type": "string", + "description": "Regions named on the forensic transition" + } }, - "color": { - "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$", + "statusPageIncidentId": { "type": "string", - "description": "Hex color code (defaults to #6B7280 if omitted)", + "description": "Linked status-page incident id", "nullable": true } }, - "description": "Request body for creating a tag" + "description": "Kind-specific activity fields; omitted keys are absent, not null" }, - "CreateWebhookEndpointRequest": { + "IncidentDetailDto": { "required": [ - "subscribedEvents", - "url" + "incident", + "updates" ], "type": "object", "properties": { - "url": { - "maxLength": 2048, - "minLength": 0, - "type": "string", - "description": "HTTPS endpoint that receives webhook event payloads" + "incident": { + "$ref": "#/components/schemas/IncidentDto" }, - "description": { - "maxLength": 255, - "minLength": 0, - "type": "string", - "description": "Optional human-readable description", - "nullable": true + "updates": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IncidentUpdateDto" + } }, - "subscribedEvents": { - "minItems": 1, + "statusPageIncidents": { "type": "array", - "description": "Event types to deliver", + "nullable": true, "items": { - "minLength": 1, - "type": "string", - "enum": [ - "monitor.created", - "monitor.updated", - "monitor.deleted", - "incident.created", - "incident.resolved", - "incident.reopened", - "service.status_changed", - "service.component_changed", - "service.incident_created", - "service.incident_updated", - "service.incident_resolved" - ] + "$ref": "#/components/schemas/LinkedStatusPageIncidentDto" } + }, + "trigger": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/IncidentTriggerDto" + } + ] } } }, - "CreateWorkspaceRequest": { + "IncidentDto": { "required": [ - "name" + "affectedRegions", + "createdAt", + "id", + "severity", + "source", + "status", + "updatedAt", + "organizationId", + "reopenCount", + "statusPageVisible", + "suppressDispatch" ], "type": "object", "properties": { - "name": { - "minLength": 1, + "id": { "type": "string", - "description": "Workspace name" - } - }, - "description": "Create a new workspace within the organization" - }, - "CreditPolicy": { - "type": "object", - "properties": { - "summary": { + "description": "Unique incident identifier", + "format": "uuid" + }, + "monitorId": { "type": "string", - "description": "Brief summary of credit policy", + "description": "Monitor that triggered the incident; null for service or manual incidents", + "format": "uuid", "nullable": true }, - "maxCreditPercent": { + "organizationId": { "type": "integer", - "description": "Max credit as percent of monthly fee", - "format": "int32", - "nullable": true + "description": "Organization this incident belongs to", + "format": "int32" }, - "claimWindowDays": { - "type": "integer", - "description": "Days to submit a credit claim after eligibility", - "format": "int32", + "source": { + "type": "string", + "description": "Incident origin: MONITOR, SERVICE, or MANUAL", + "enum": [ + "AUTOMATIC", + "MANUAL", + "MONITORS", + "STATUS_DATA", + "RESOURCE_GROUP" + ] + }, + "status": { + "type": "string", + "description": "Current lifecycle status (OPEN, RESOLVED, etc.)", + "enum": [ + "WATCHING", + "TRIGGERED", + "CONFIRMED", + "RESOLVED" + ] + }, + "severity": { + "type": "string", + "description": "Severity level: DOWN, DEGRADED, or MAINTENANCE", + "enum": [ + "DOWN", + "DEGRADED", + "MAINTENANCE" + ] + }, + "title": { + "type": "string", + "description": "Short summary of the incident; null for auto-generated incidents", "nullable": true }, - "creditApplicationDays": { - "type": "integer", - "description": "Days for credit to be applied after approval", - "format": "int32", + "triggeredByRule": { + "type": "string", + "description": "Human-readable description of the trigger rule that fired", "nullable": true }, - "tiers": { + "affectedRegions": { "type": "array", - "description": "Credit tiers by uptime threshold", - "nullable": true, + "description": "Probe regions that observed the failure", "items": { - "$ref": "#/components/schemas/CreditTier" + "type": "string", + "description": "Probe regions that observed the failure" } - } - }, - "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": { + "reopenCount": { "type": "integer", - "description": "Credit percent of monthly fee", + "description": "Number of times this incident has been reopened", + "format": "int32" + }, + "createdByUserId": { + "type": "integer", + "description": "User who created the incident (manual incidents only)", "format": "int32", "nullable": true }, - "formula": { + "statusPageVisible": { + "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": "Credit formula when percent is not a fixed number", + "description": "Linked vendor service incident ID; null for monitor incidents", + "format": "uuid", "nullable": true }, - "notes": { + "serviceId": { "type": "string", - "description": "Additional notes on this credit tier", + "description": "Linked service catalog ID; null for monitor incidents", + "format": "uuid", "nullable": true - } - }, - "description": "Credit tiers by uptime threshold" - }, - "CursorPageCheckResultDto": { - "required": [ - "data", - "hasMore" - ], - "type": "object", - "properties": { - "data": { - "type": "array", - "description": "Items on this page", - "items": { - "$ref": "#/components/schemas/CheckResultDto" - } }, - "nextCursor": { + "externalRef": { "type": "string", - "description": "Opaque cursor for the next page; null when there are no more results", + "description": "External reference ID (e.g. PagerDuty incident ID)", "nullable": true }, - "hasMore": { - "type": "boolean", - "description": "Whether more results exist beyond this page" - } - }, - "description": "Cursor-paginated response for time-series and append-only data" - }, - "CursorPageIncidentActivityEventDto": { - "required": [ - "data", - "hasMore" - ], - "type": "object", - "properties": { - "data": { + "affectedComponents": { "type": "array", - "description": "Items on this page", + "description": "Service components affected by this incident", + "nullable": true, "items": { - "$ref": "#/components/schemas/IncidentActivityEventDto" + "type": "string", + "description": "Service components affected by this incident" } }, - "nextCursor": { + "shortlink": { "type": "string", - "description": "Opaque cursor for the next page; null when there are no more results", + "description": "Short URL linking to the incident details", "nullable": true }, - "hasMore": { - "type": "boolean", - "description": "Whether more results exist beyond this page" - } - }, - "description": "Cursor-paginated response for time-series and append-only data" - }, - "CursorPageServiceCatalogDto": { - "required": [ - "data", - "hasMore" - ], - "type": "object", - "properties": { - "data": { - "type": "array", - "description": "Items on this page", - "items": { - "$ref": "#/components/schemas/ServiceCatalogDto" - } + "resolutionReason": { + "type": "string", + "description": "How the incident was resolved (AUTO_RECOVERED, MANUAL, etc.)", + "nullable": true, + "enum": [ + "MANUAL", + "AUTO_RECOVERED", + "AUTO_RESOLVED" + ] }, - "nextCursor": { + "resolutionNote": { "type": "string", - "description": "Opaque cursor for the next page; null when there are no more results", + "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 }, - "hasMore": { - "type": "boolean", - "description": "Whether more results exist beyond this page" - } - }, - "description": "Cursor-paginated response for time-series and append-only data" - }, - "CursorPageServicePollResultDto": { - "required": [ - "data", - "hasMore" - ], - "type": "object", - "properties": { - "data": { - "type": "array", - "description": "Items on this page", - "items": { - "$ref": "#/components/schemas/ServicePollResultDto" - } + "startedAt": { + "type": "string", + "description": "Timestamp when the incident was detected or created", + "format": "date-time", + "nullable": true }, - "nextCursor": { + "confirmedAt": { "type": "string", - "description": "Opaque cursor for the next page; null when there are no more results", + "description": "Timestamp when the incident was confirmed (multi-region confirmation)", + "format": "date-time", "nullable": true }, - "hasMore": { - "type": "boolean", - "description": "Whether more results exist beyond this page" - } - }, - "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" - } + "resolvedAt": { + "type": "string", + "description": "Timestamp when the incident was resolved", + "format": "date-time", + "nullable": true }, - "nextCursor": { + "cooldownUntil": { "type": "string", - "description": "Opaque cursor for the next page; null when there are no more results", + "description": "Cooldown window end; new incidents suppressed until this time", + "format": "date-time", "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", - "monitors" - ], - "type": "object", - "properties": { - "monitors": { - "$ref": "#/components/schemas/MonitorsSummaryDto" + "createdAt": { + "type": "string", + "description": "Timestamp when the incident record was created", + "format": "date-time" }, - "incidents": { - "$ref": "#/components/schemas/IncidentsSummaryDto" - } - }, - "description": "Combined dashboard overview for monitors and incidents" - }, - "DatadogChannelConfig": { - "required": [ - "channelType", - "apiKey" - ], - "type": "object", - "properties": { - "channelType": { + "updatedAt": { "type": "string", - "enum": [ - "datadog" - ] + "description": "Timestamp when the incident was last updated", + "format": "date-time" }, - "apiKey": { - "minLength": 1, + "monitorName": { "type": "string", - "description": "Datadog API key" + "description": "Name of the associated monitor; populated on list responses. Omitted from JSON (undefined to SDKs) on detail responses, treat missing as null.", + "nullable": true }, - "site": { + "serviceName": { "type": "string", - "description": "Datadog site region (e.g. datadoghq.com, datadoghq.eu, us3.datadoghq.com)", + "description": "Name of the associated service; populated on list responses. Omitted from JSON (undefined to SDKs) on detail responses, treat missing as null.", "nullable": true }, - "tags": { + "serviceSlug": { "type": "string", - "description": "Comma-separated tags to attach to events", + "description": "Slug of the associated service; populated on list responses. Omitted from JSON (undefined to SDKs) on detail responses, treat missing as null.", "nullable": true - } - } - }, - "DayIncident": { - "required": [ - "affectedComponentIds", - "affectedComponentNames", - "id", - "impact", - "status", - "title", - "scheduled" - ], - "type": "object", - "properties": { - "id": { + }, + "monitorType": { "type": "string", - "description": "Status page incident UUID", - "format": "uuid" + "description": "Type of the associated monitor; populated on list responses. Omitted from JSON (undefined to SDKs) on detail responses, treat missing as null.", + "nullable": true }, - "title": { + "resourceGroupId": { "type": "string", - "description": "Incident title" + "description": "Resource group that owns this incident; null when not group-managed", + "format": "uuid", + "nullable": true }, - "status": { + "resourceGroupName": { "type": "string", - "description": "Lifecycle status (investigating, identified, monitoring, resolved, …)", - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] + "description": "Name of the resource group; populated on list responses. Omitted from JSON (undefined to SDKs) on detail responses, treat missing as null.", + "nullable": true }, - "impact": { + "triggeringCheckId": { "type": "string", - "description": "Severity bucket (none, minor, major, critical)", - "enum": [ - "NONE", - "MINOR", - "MAJOR", - "CRITICAL" - ] + "description": "Scheduler-minted check execution ID whose result confirmed this incident; joins to check_results, rule_evaluations, and incident_state_transitions. Omitted from JSON (undefined to SDKs) when null, treat missing as null.", + "format": "uuid", + "nullable": true }, - "scheduled": { - "type": "boolean", - "description": "True for a maintenance window; false for an incident" + "triggeredByRuleSnapshotHashHex": { + "type": "string", + "description": "Hex SHA-256 of the canonical policy snapshot that fired; combined with triggeredByRuleIndex points to the exact TriggerRule. Omitted from JSON when null, treat missing as null.", + "nullable": true }, - "startedAt": { + "triggeredByRuleIndex": { + "type": "integer", + "description": "Index of the fired rule inside the policy's trigger_rules array. Omitted from JSON when null, treat missing as null.", + "format": "int32", + "nullable": true + }, + "engineVersion": { "type": "string", - "description": "Incident start timestamp", - "format": "date-time", + "description": "Detection engine semver that evaluated the rule. Omitted from JSON when null, treat missing as null.", "nullable": true }, - "resolvedAt": { + "displayKey": { "type": "string", - "description": "Incident resolved timestamp; null while still active", - "format": "date-time", + "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 }, - "affectedComponentNames": { + "alertCollapsedByResourceGroupIds": { "type": "array", - "description": "Display names of components affected by this incident (deduplicated)", + "description": "Sticky union of resource-group IDs that suppressed a paging dispatch for this member incident; null when never written / legacy", + "nullable": true, "items": { "type": "string", - "description": "Display names of components affected by this incident (deduplicated)" + "description": "Sticky union of resource-group IDs that suppressed a paging dispatch for this member incident; null when never written / legacy", + "format": "uuid" } }, - "affectedComponentIds": { + "peakFailingMemberCount": { + "type": "integer", + "description": "Peak non-operational member count while this RESOURCE_GROUP incident was open; null otherwise", + "format": "int32", + "nullable": true + }, + "failingMembersAtPeak": { "type": "array", - "description": "UUIDs of components this incident affected", + "description": "Frozen failing members at peakFailingMemberCount; null when not a group incident or never snapshotted", + "nullable": true, "items": { - "type": "string", - "description": "UUIDs of components this incident affected", - "format": "uuid" + "$ref": "#/components/schemas/IncidentFailingMemberSnapshotDto" } } }, - "description": "Incident that overlapped the day" + "description": "Incident triggered by a monitor check failure or manual creation" }, - "DekRotationResultDto": { + "IncidentEventDto": { "required": [ - "rotatedAt", - "previousDekVersion", - "newDekVersion", - "secretsReEncrypted", - "channelsReEncrypted" + "incidentId", + "title" ], "type": "object", "properties": { - "previousDekVersion": { - "type": "integer", - "description": "DEK version before rotation", - "format": "int32" - }, - "newDekVersion": { - "type": "integer", - "description": "DEK version after rotation", - "format": "int32" - }, - "secretsReEncrypted": { - "type": "integer", - "description": "Number of secrets re-encrypted with the new DEK", - "format": "int32" - }, - "channelsReEncrypted": { - "type": "integer", - "description": "Number of alert channels re-encrypted with the new DEK", - "format": "int32" - }, - "rotatedAt": { + "incidentId": { "type": "string", - "description": "Timestamp when the rotation was performed", - "format": "date-time" - } - }, - "description": "Result of a data encryption key rotation operation" - }, - "DeleteChannelResult": { - "type": "object", - "properties": { - "affectedPolicies": { - "type": "integer", - "description": "Number of notification policies whose escalation steps were modified", - "format": "int32" + "description": "Vendor catalog incident ID", + "format": "uuid" }, - "disabledPolicies": { - "type": "integer", - "description": "Number of notification policies disabled because they had no remaining channels", - "format": "int32" - } - }, - "description": "Summary of policies affected by channel deletion", - "required": [ - "affectedPolicies", - "disabledPolicies" - ] - }, - "DeliveryAttemptDto": { - "required": [ - "attemptedAt", - "deliveryId", - "id", - "status", - "attemptNumber" - ], - "type": "object", - "properties": { - "id": { + "externalId": { "type": "string", - "format": "uuid" + "description": "Vendor-supplied external incident ID", + "nullable": true }, - "deliveryId": { + "title": { "type": "string", - "format": "uuid" + "description": "Incident title from the vendor status page" }, - "attemptNumber": { - "type": "integer", - "description": "1-based attempt number", - "format": "int32" + "impact": { + "type": "string", + "description": "Vendor impact level (major, minor, none)", + "nullable": true }, "status": { "type": "string", - "description": "Outcome: SUCCESS, FAILED, TIMEOUT, ERROR" + "description": "Vendor lifecycle status (only set on incident.update rows)", + "nullable": true }, - "responseStatusCode": { - "type": "integer", - "description": "HTTP response status code from the external service", - "format": "int32", + "body": { + "type": "string", + "description": "Update body text (only set on incident.update rows)", "nullable": true }, - "requestPayload": { + "shortlink": { "type": "string", - "description": "JSON payload sent to the external service", + "description": "Short public URL for the vendor incident", "nullable": true }, - "responseBody": { + "startedAt": { "type": "string", - "description": "Response body from the external service (truncated)", + "description": "When the vendor incident started", + "format": "date-time", "nullable": true }, - "errorMessage": { + "resolvedAt": { "type": "string", - "description": "Error message if the attempt failed", + "description": "When the vendor incident resolved", + "format": "date-time", "nullable": true }, - "responseTimeMs": { - "type": "integer", - "description": "Round-trip time in milliseconds", - "format": "int32", + "detectedAt": { + "type": "string", + "description": "When DevHelm first detected the incident", + "format": "date-time", "nullable": true }, - "externalId": { + "vendorCreatedAt": { "type": "string", - "description": "External identifier (e.g. PagerDuty dedup_key, SES MessageId, webhook delivery UUID)", + "description": "Vendor-reported creation timestamp", + "format": "date-time", "nullable": true }, - "requestHeaders": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "HTTP request headers sent to the external service", - "nullable": true - }, - "description": "HTTP request headers sent to the external service", + "durationSeconds": { + "type": "integer", + "description": "Total duration in seconds (set on incident.resolved)", + "format": "int64", "nullable": true }, - "attemptedAt": { - "type": "string", - "format": "date-time" + "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": "Single delivery attempt with request/response audit data" + "description": "Vendor incident fields for a status-events rail row" }, - "DeployLockDto": { + "IncidentFailingMemberSnapshotDto": { "required": [ - "expiresAt", - "id", - "lockedAt", - "lockedBy" + "memberType", + "name" ], "type": "object", "properties": { - "id": { + "memberType": { "type": "string", - "description": "Unique lock identifier", - "format": "uuid" + "description": "Member type: monitor or service" }, - "lockedBy": { - "minLength": 1, + "monitorId": { "type": "string", - "description": "Identity of the lock holder (e.g. CLI session ID, username)" + "description": "Monitor ID when memberType is monitor", + "format": "uuid", + "nullable": true }, - "lockedAt": { + "serviceId": { "type": "string", - "description": "Timestamp when the lock was acquired", - "format": "date-time" + "description": "Service ID when memberType is service", + "format": "uuid", + "nullable": true }, - "expiresAt": { + "name": { + "minLength": 1, "type": "string", - "description": "Timestamp when the lock automatically expires", - "format": "date-time" + "description": "Frozen display name at snapshot time" + }, + "membershipId": { + "type": "string", + "description": "Membership row ID when available", + "format": "uuid", + "nullable": true } }, - "description": "Represents an active deploy lock for a workspace" + "description": "Frozen failing member identity at peak failing count for a resource-group incident" }, - "DiscordChannelConfig": { - "required": [ - "channelType", - "webhookUrl" - ], + "IncidentFilterParams": { "type": "object", "properties": { - "channelType": { + "status": { "type": "string", + "description": "Filter by incident lifecycle status; null returns every status", + "nullable": true, "enum": [ - "discord" + "WATCHING", + "TRIGGERED", + "CONFIRMED", + "RESOLVED" ] }, - "webhookUrl": { - "minLength": 1, + "severity": { "type": "string", - "description": "Discord webhook URL" + "description": "Filter by severity; null returns every severity", + "nullable": true, + "enum": [ + "DOWN", + "DEGRADED", + "MAINTENANCE" + ] }, - "mentionRoleId": { - "type": "string", - "description": "Optional Discord role ID to mention in notifications", - "nullable": true - } - } - }, - "Dns": { - "type": "object", - "description": "DNS check-type-specific details", - "properties": { - "check_type": { + "source": { "type": "string", + "description": "Filter by where the incident originated (auto, manual, third-party)", + "nullable": true, "enum": [ - "dns" + "AUTOMATIC", + "MANUAL", + "MONITORS", + "STATUS_DATA", + "RESOURCE_GROUP" ] }, - "hostname": { + "monitorId": { "type": "string", - "description": "Target hostname", + "description": "Only return incidents tied to this monitor ID", + "format": "uuid", "nullable": true }, - "requestedTypes": { - "type": "array", - "description": "Requested DNS record types", - "nullable": true, - "items": { - "type": "string", - "description": "Requested DNS record types", - "nullable": true - } + "serviceId": { + "type": "string", + "description": "Only return incidents tied to this service ID (third-party services)", + "format": "uuid", + "nullable": true }, - "usedResolver": { + "resourceGroupId": { "type": "string", - "description": "Resolver used for lookup", + "description": "Only return incidents owned by this resource group (incidents.resource_group_id)", + "format": "uuid", "nullable": true }, - "records": { - "type": "object", - "additionalProperties": { - "type": "array", - "description": "Resolved DNS records keyed by record type", - "nullable": true, - "items": { - "type": "object", - "additionalProperties": { - "type": "object", - "description": "Resolved DNS records keyed by record type", - "nullable": true - }, - "description": "Resolved DNS records keyed by record type", - "nullable": true - } - }, - "description": "Resolved DNS records keyed by record type", + "tagId": { + "type": "string", + "description": "Only return incidents whose monitor carries this tag", + "format": "uuid", "nullable": true }, - "attempts": { - "type": "array", - "description": "DNS resolution attempts", - "nullable": true, - "items": { - "type": "object", - "additionalProperties": { - "type": "object", - "description": "DNS resolution attempts", - "nullable": true - }, - "description": "DNS resolution attempts", - "nullable": true - } + "environmentId": { + "type": "string", + "description": "Only return incidents whose monitor lives in this environment", + "format": "uuid", + "nullable": true }, - "failureKind": { + "excludeId": { "type": "string", - "description": "Kind of DNS failure, if any", + "description": "Exclude this incident ID from results (related-incident lists)", + "format": "uuid", + "nullable": true + }, + "startedFrom": { + "type": "string", + "description": "Earliest startedAt to include (inclusive, ISO 8601)", + "format": "date-time", + "nullable": true + }, + "startedTo": { + "type": "string", + "description": "Latest startedAt to include (inclusive, ISO 8601)", + "format": "date-time", "nullable": true + }, + "page": { + "minimum": 0, + "type": "integer", + "description": "Zero-based page index (default: 0)", + "format": "int32", + "example": 0 + }, + "size": { + "maximum": 200, + "minimum": 1, + "type": "integer", + "description": "Number of incidents per page (1–200, default: 10)", + "format": "int32", + "example": 10 } }, "required": [ - "check_type" + "page", + "size" ] }, - "DnsExpectedCnameAssertion": { + "IncidentIoChannelConfig": { "required": [ - "type", - "value" + "channelType", + "apiKey" ], "type": "object", "properties": { - "type": { + "channelType": { "type": "string", "enum": [ - "dns_expected_cname" + "incident_io" ] }, - "value": { + "apiKey": { "minLength": 1, "type": "string", - "description": "Expected CNAME target the resolution must include" + "description": "incident.io API key with 'Create incidents' permission" + }, + "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 } } }, - "DnsExpectedIpsAssertion": { + "IncidentPolicyDto": { "required": [ - "type", - "ips" + "confirmation", + "createdAt", + "id", + "monitorId", + "recovery", + "triggerRules", + "updatedAt" ], "type": "object", "properties": { - "type": { + "id": { "type": "string", - "enum": [ - "dns_expected_ips" - ] + "description": "Unique incident policy identifier", + "format": "uuid" }, - "ips": { - "minItems": 1, + "monitorId": { + "type": "string", + "description": "Monitor this policy is attached to", + "format": "uuid" + }, + "triggerRules": { "type": "array", - "description": "Allowed IP addresses; at least one resolved address must match", + "description": "Array of trigger rules defining when an incident should be raised", "items": { - "type": "string", - "description": "Allowed IP addresses; at least one resolved address must match" + "$ref": "#/components/schemas/TriggerRule" } - } - } - }, - "DnsMaxAnswersAssertion": { - "required": [ - "type", - "recordType", - "max" - ], - "type": "object", - "properties": { - "type": { + }, + "confirmation": { + "$ref": "#/components/schemas/ConfirmationPolicy" + }, + "recovery": { + "$ref": "#/components/schemas/RecoveryPolicy" + }, + "createdAt": { "type": "string", - "enum": [ - "dns_max_answers" - ] + "description": "Timestamp when the policy was created", + "format": "date-time" }, - "recordType": { - "minLength": 1, + "updatedAt": { "type": "string", - "description": "DNS record type whose answer count is checked" + "description": "Timestamp when the policy was last updated", + "format": "date-time" }, - "max": { + "monitorRegionCount": { "type": "integer", - "description": "Maximum number of answers allowed for that record type", - "format": "int32" + "description": "Number of regions configured on the monitor (only set in internal API responses)", + "format": "int32", + "nullable": true + }, + "checkFrequencySeconds": { + "type": "integer", + "description": "Monitor check frequency in seconds (only set in internal API responses)", + "format": "int32", + "nullable": true } - } + }, + "description": "Incident detection, confirmation, and recovery policy for a monitor" }, - "DnsMinAnswersAssertion": { + "IncidentRef": { "required": [ - "type", - "recordType", - "min" + "id", + "impact", + "title" ], "type": "object", "properties": { - "type": { + "id": { "type": "string", - "enum": [ - "dns_min_answers" - ] + "description": "Internal incident ID — UUID for status-page incidents, service incident UUID for catalog", + "format": "uuid" }, - "recordType": { - "minLength": 1, + "title": { "type": "string", - "description": "DNS record type whose answer count is checked" + "description": "Incident title at the time of the overlap" }, - "min": { + "impact": { + "type": "string", + "description": "Incident impact level (e.g. minor, major, critical for catalog; NONE/MINOR/MAJOR/CRITICAL for status pages)" + } + }, + "description": "Lightweight reference to an incident overlapping a given uptime day" + }, + "IncidentsSummaryDto": { + "type": "object", + "properties": { + "active": { "type": "integer", - "description": "Minimum number of answers required for that record type", - "format": "int32" + "format": "int64" + }, + "resolvedToday": { + "type": "integer", + "format": "int64" + }, + "mttr30d": { + "type": "number", + "format": "double", + "nullable": true } - } + }, + "description": "Incident summary counters", + "required": [ + "active", + "resolvedToday" + ] }, - "DnsMonitorConfig": { + "IncidentStateTransitionDto": { "required": [ - "hostname" + "affectedRegions", + "checkId", + "details", + "engineVersion", + "fromStatus", + "id", + "monitorId", + "occurredAt", + "policySnapshotHashHex", + "reason", + "toStatus", + "triggeringEvaluationIds" ], "type": "object", "properties": { - "hostname": { + "id": { + "type": "string", + "description": "Forensic row UUID", + "format": "uuid" + }, + "occurredAt": { + "type": "string", + "description": "When the state transition occurred", + "format": "date-time" + }, + "monitorId": { + "type": "string", + "description": "Monitor this transition pertains to", + "format": "uuid" + }, + "incidentId": { + "type": "string", + "description": "Incident this transition belongs to; null for pre-incident (auto-cleared) transitions", + "format": "uuid", + "nullable": true + }, + "fromStatus": { "minLength": 1, "type": "string", - "description": "Domain name to resolve" + "description": "Previous status (WATCHING | TRIGGERED | CONFIRMED | RESOLVED)" }, - "recordTypes": { + "toStatus": { + "minLength": 1, + "type": "string", + "description": "New status (WATCHING | TRIGGERED | CONFIRMED | RESOLVED)" + }, + "reason": { + "minLength": 1, + "type": "string", + "description": "Why the transition fired (trigger | confirm | resolve | auto_clear | reopen)" + }, + "triggeringEvaluationIds": { "type": "array", - "description": "DNS record types to query: A, AAAA, CNAME, MX, NS, TXT, SRV, SOA, CAA, PTR", - "nullable": true, + "description": "rule_evaluation ids that caused this transition (may be empty for timeout-driven edges)", "items": { "type": "string", - "description": "DNS record types to query: A, AAAA, CNAME, MX, NS, TXT, SRV, SOA, CAA, PTR", - "nullable": true, - "enum": [ - "A", - "AAAA", - "CNAME", - "MX", - "NS", - "TXT", - "SRV", - "SOA", - "CAA", - "PTR" - ] + "description": "rule_evaluation ids that caused this transition (may be empty for timeout-driven edges)", + "format": "uuid" } }, - "nameservers": { + "affectedRegions": { "type": "array", - "description": "Custom nameservers to query (uses system defaults if omitted)", - "nullable": true, + "description": "Regions whose evaluations contributed to this transition", "items": { "type": "string", - "description": "Custom nameservers to query (uses system defaults if omitted)", - "nullable": true + "description": "Regions whose evaluations contributed to this transition" } }, - "timeoutMs": { - "type": "integer", - "description": "Per-query timeout in milliseconds", - "format": "int32", - "nullable": true + "policySnapshotHashHex": { + "minLength": 1, + "type": "string", + "description": "Hex-encoded hash of the policy snapshot that governed this transition" }, - "totalTimeoutMs": { - "type": "integer", - "description": "Total timeout for all queries in milliseconds", - "format": "int32", - "nullable": true + "engineVersion": { + "minLength": 1, + "type": "string", + "description": "Detection engine version that emitted this transition" + }, + "checkId": { + "type": "string", + "description": "Scheduler-minted check execution ID (V92) of the triggering result", + "format": "uuid" + }, + "details": { + "$ref": "#/components/schemas/StateTransitionDetails" } - } + }, + "description": "State-machine transitions this check caused (may be empty if nothing fired)" }, - "DnsRecordContainsAssertion": { + "IncidentTimelineDto": { "required": [ - "type", - "recordType", - "substring" + "transitions", + "triggeringEvaluations" ], "type": "object", "properties": { - "type": { - "type": "string", - "enum": [ - "dns_record_contains" - ] + "transitions": { + "type": "array", + "description": "State-machine transitions in chronological order", + "items": { + "$ref": "#/components/schemas/IncidentStateTransitionDto" + } }, - "recordType": { - "minLength": 1, - "type": "string", - "description": "DNS record type to assert on (A, AAAA, CNAME, MX, TXT)" + "triggeringEvaluations": { + "type": "array", + "description": "Rule evaluations that caused any of the transitions above. Correlate via evaluation.triggeringTransitionId == transition.id", + "items": { + "$ref": "#/components/schemas/RuleEvaluationDto" + } }, - "substring": { - "minLength": 1, - "type": "string", - "description": "Substring that must appear in a matching record value" + "policySnapshot": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/PolicySnapshotDto" + } + ] } } }, - "DnsRecordEqualsAssertion": { + "IncidentTriggerDto": { "required": [ - "type", - "recordType", - "value" + "source" ], "type": "object", "properties": { - "type": { + "ruleType": { "type": "string", - "enum": [ - "dns_record_equals" - ] + "description": "Trigger rule type (consecutive_failures, failures_in_window, response_time); null when unknown", + "nullable": true }, - "recordType": { - "minLength": 1, + "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": "DNS record type to assert on (A, AAAA, CNAME, MX, TXT)" + "description": "failure_reason from the triggering check result; null when unavailable", + "nullable": true }, - "value": { - "minLength": 1, + "firstFailedCheckAt": { "type": "string", - "description": "Expected DNS record value for an exact match" - } - } - }, - "DnsResolvesAssertion": { - "type": "object", - "properties": { - "type": { + "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": [ - "dns_resolves" + "forensics", + "checks", + "none" ] } }, - "required": [ - "type" - ] + "description": "Honest trigger metadata for the incident origin tooltip / TTD strip" }, - "DnsResponseTimeAssertion": { + "IncidentUpdateDto": { + "required": [ + "createdAt", + "id", + "incidentId", + "notifySubscribers" + ], "type": "object", "properties": { - "type": { + "id": { "type": "string", - "enum": [ - "dns_response_time" - ] + "format": "uuid" }, - "maxMs": { - "type": "integer", - "description": "Maximum allowed DNS resolution time in milliseconds", - "format": "int32" - } - }, - "required": [ - "type", - "maxMs" - ] - }, - "DnsResponseTimeWarnAssertion": { - "type": "object", - "properties": { - "type": { + "incidentId": { + "type": "string", + "format": "uuid" + }, + "oldStatus": { "type": "string", + "nullable": true, "enum": [ - "dns_response_time_warn" + "WATCHING", + "TRIGGERED", + "CONFIRMED", + "RESOLVED" ] }, - "warnMs": { - "type": "integer", - "description": "DNS resolution time in milliseconds that triggers a warning only", - "format": "int32" - } - }, - "required": [ - "type", - "warnMs" - ] - }, - "DnsTtlHighAssertion": { - "type": "object", - "properties": { - "type": { + "newStatus": { "type": "string", + "nullable": true, "enum": [ - "dns_ttl_high" + "WATCHING", + "TRIGGERED", + "CONFIRMED", + "RESOLVED" ] }, - "maxTtl": { - "type": "integer", - "description": "Maximum TTL in seconds before a high-TTL warning is raised", - "format": "int32" - } - }, - "required": [ - "type", - "maxTtl" - ] - }, - "DnsTtlLowAssertion": { - "type": "object", - "properties": { - "type": { + "body": { + "type": "string", + "nullable": true + }, + "createdBy": { "type": "string", + "nullable": true, "enum": [ - "dns_ttl_low" + "SYSTEM", + "USER" ] }, - "minTtl": { - "type": "integer", - "description": "Minimum acceptable TTL in seconds before a warning is raised", - "format": "int32" + "notifySubscribers": { + "type": "boolean" + }, + "createdAt": { + "type": "string", + "format": "date-time" } - }, - "required": [ - "type", - "minTtl" - ] + } }, - "DnsTxtContainsAssertion": { + "IntegrationConfigSchemaDto": { "required": [ - "type", - "substring" + "channelFields", + "connectionFields" ], "type": "object", "properties": { - "type": { - "type": "string", - "enum": [ - "dns_txt_contains" - ] + "connectionFields": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IntegrationFieldDto" + } }, - "substring": { - "minLength": 1, - "type": "string", - "description": "Substring that must appear in at least one TXT record" + "channelFields": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IntegrationFieldDto" + } } } }, - "EmailChannelConfig": { + "IntegrationDto": { "required": [ - "channelType", - "recipients" + "authType", + "configSchema", + "description", + "lifecycle", + "logoUrl", + "name", + "setupGuideUrl", + "tierAvailability", + "type" ], "type": "object", "properties": { - "channelType": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "logoUrl": { + "type": "string" + }, + "authType": { + "type": "string" + }, + "tierAvailability": { "type": "string", "enum": [ - "email" + "FREE", + "STARTER", + "PRO", + "TEAM", + "BUSINESS", + "ENTERPRISE" ] }, - "recipients": { - "minItems": 1, - "type": "array", - "description": "Email addresses to send notifications to", - "items": { - "type": "string", - "description": "Email addresses to send notifications to", - "format": "email" - } + "lifecycle": { + "type": "string" + }, + "setupGuideUrl": { + "type": "string" + }, + "configSchema": { + "$ref": "#/components/schemas/IntegrationConfigSchemaDto" } } }, - "EntitlementDto": { + "IntegrationFieldDto": { "required": [ "key", - "value", - "defaultValue", - "overridden" + "label", + "required", + "sensitive", + "type" ], "type": "object", "properties": { "key": { + "type": "string" + }, + "label": { + "type": "string" + }, + "type": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "sensitive": { + "type": "boolean" + }, + "placeholder": { "type": "string", - "description": "Entitlement key" + "nullable": true }, - "value": { - "type": "integer", - "description": "Effective limit value (overrides applied)", - "format": "int64" + "helpText": { + "type": "string", + "nullable": true }, - "defaultValue": { - "type": "integer", - "description": "Plan-tier default value before overrides", - "format": "int64" + "options": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + } }, - "overridden": { - "type": "boolean", - "description": "Whether this entitlement has an org-level override" + "default": { + "type": "string", + "nullable": true } - }, - "description": "A single resolved entitlement for the organization" + } }, - "EnvironmentDto": { + "InviteDto": { "required": [ "createdAt", - "id", - "name", - "slug", - "updatedAt", - "variables", - "orgId", - "monitorCount", - "isDefault" + "email", + "expiresAt", + "roleOffered", + "inviteId" ], "type": "object", "properties": { - "id": { - "type": "string", - "description": "Unique environment identifier", - "format": "uuid" - }, - "orgId": { + "inviteId": { "type": "integer", - "description": "Organization this environment belongs to", + "description": "Unique invite identifier", "format": "int32" }, - "name": { - "minLength": 1, + "email": { "type": "string", - "description": "Human-readable environment name" + "description": "Email address the invite was sent to" }, - "slug": { - "minLength": 1, + "roleOffered": { "type": "string", - "description": "URL-safe identifier" - }, - "variables": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Key-value variable pairs available for interpolation" - }, - "description": "Key-value variable pairs available for interpolation" + "description": "Role that will be assigned to the invitee on acceptance", + "enum": [ + "OWNER", + "ADMIN", + "MEMBER" + ] }, "createdAt": { "type": "string", - "description": "Timestamp when the environment was created", + "description": "Timestamp when the invite was created", "format": "date-time" }, - "updatedAt": { + "expiresAt": { "type": "string", - "description": "Timestamp when the environment was last updated", + "description": "Timestamp when the invite expires", "format": "date-time" }, - "monitorCount": { - "type": "integer", - "description": "Number of monitors using this environment", - "format": "int32" + "consumedAt": { + "type": "string", + "description": "Timestamp when the invite was accepted; null if not yet used", + "format": "date-time", + "nullable": true }, - "isDefault": { - "type": "boolean", - "description": "Whether this is the default environment for new monitors" + "revokedAt": { + "type": "string", + "description": "Timestamp when the invite was revoked; null if active", + "format": "date-time", + "nullable": true } }, - "description": "Environment with variable substitutions for monitor configs" + "description": "Organization invite sent to an email address" }, - "ErrorEntry": { + "JiraChannelConfig": { "required": [ - "code", - "message" + "channelType", + "domain", + "email", + "apiToken", + "projectKey" ], "type": "object", "properties": { - "code": { - "minLength": 1, + "channelType": { "type": "string", - "description": "Stable machine-readable code; see ValidationErrorCode for the registry", - "example": "MONITOR_HEARTBEAT_GRACE_EXCEEDS_INTERVAL" + "enum": [ + "jira" + ] }, - "field": { + "domain": { + "minLength": 1, "type": "string", - "description": "JSON-pointer-like path to the offending field, or null for request-wide errors", - "nullable": true, - "example": "config.gracePeriod" + "description": "Atlassian instance domain (e.g. yourteam.atlassian.net)" }, - "message": { + "email": { "minLength": 1, "type": "string", - "description": "Human-readable message; safe to surface to end users" - } - }, - "description": "One structured validation rejection" - }, - "ErrorResponse": { - "required": [ - "code", - "message", - "status", - "timestamp" - ], - "type": "object", - "properties": { - "status": { - "type": "integer", - "description": "HTTP status code (mirrors the response status line)", - "format": "int32", - "example": 404 + "description": "Atlassian account email for API authentication" }, - "code": { + "apiToken": { + "minLength": 1, "type": "string", - "description": "Coarse machine-readable error category (e.g. NOT_FOUND, RATE_LIMITED); stable per status", - "example": "NOT_FOUND" + "description": "Atlassian API token" }, - "message": { + "projectKey": { + "minLength": 1, "type": "string", - "description": "Human-readable error message; safe to surface to end users", - "example": "Monitor not found" - }, - "timestamp": { - "type": "integer", - "description": "Server time when the error was produced (epoch milliseconds)", - "format": "int64", - "example": 1737302400000 + "description": "Jira project key where issues are created (e.g. OPS)" }, - "requestId": { + "issueType": { "type": "string", - "description": "Opaque per-request id; same value as the X-Request-Id response header. Use in support tickets.", - "nullable": true, - "example": "5b6f7a8c-1234-4d5e-9f0a-1b2c3d4e5f6a" - }, - "errors": { - "type": "array", - "description": "Structured per-field rejections; populated for validation errors, null otherwise", - "nullable": true, - "items": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/ErrorEntry" - } - ] - } + "description": "Issue type name (e.g. Bug, Task, Incident)", + "nullable": true } - }, - "description": "Uniform error envelope returned for every non-2xx response", - "example": { - "status": 404, - "code": "NOT_FOUND", - "message": "Monitor not found", - "timestamp": 1737302400000, - "requestId": "5b6f7a8c-1234-4d5e-9f0a-1b2c3d4e5f6a" } }, - "EscalationChain": { + "JsonPathAssertion": { "required": [ - "steps" + "type", + "path", + "expected", + "operator" ], "type": "object", "properties": { - "steps": { - "minItems": 1, - "type": "array", - "description": "Ordered escalation steps, evaluated in sequence", - "items": { - "$ref": "#/components/schemas/EscalationStep" - } + "type": { + "type": "string", + "enum": [ + "json_path" + ] }, - "onResolve": { + "path": { + "minLength": 1, "type": "string", - "description": "Action when the incident resolves", - "nullable": true + "description": "JSONPath expression to extract a value from the response body" }, - "onReopen": { + "expected": { + "minLength": 1, "type": "string", - "description": "Action when a resolved incident reopens", - "nullable": true + "description": "Expected value to compare against" + }, + "operator": { + "type": "string", + "description": "Comparison operator (equals, contains, less_than, greater_than, etc.)", + "enum": [ + "equals", + "contains", + "less_than", + "greater_than", + "matches", + "range" + ] } - }, - "description": "Escalation chain defining which channels to notify; null preserves current" + } }, - "EscalationStep": { + "KeyInfo": { "required": [ - "channelIds", - "delayMinutes" + "createdAt", + "name", + "id" ], "type": "object", "properties": { - "delayMinutes": { - "minimum": 0, + "id": { "type": "integer", - "description": "Minutes to wait before executing this step (0 = immediate)", + "description": "Key ID", "format": "int32" }, - "channelIds": { - "minItems": 1, - "type": "array", - "description": "Alert channel IDs to notify in this step", - "items": { - "type": "string", - "description": "Alert channel IDs to notify in this step", - "format": "uuid" - } + "name": { + "type": "string", + "description": "Human-readable key name" }, - "requireAck": { - "type": "boolean", - "description": "Whether an acknowledgment is required before escalating", - "nullable": true + "createdAt": { + "type": "string", + "description": "When the key was created", + "format": "date-time" }, - "repeatIntervalSeconds": { - "minimum": 1, - "type": "integer", - "description": "Repeat notification interval in seconds until acknowledged", - "format": "int32", - "nullable": true - } - }, - "description": "Ordered escalation steps, evaluated in sequence" - }, - "FailureDetail": { - "required": [ - "monitorId", - "reason" - ], - "type": "object", - "properties": { - "monitorId": { + "expiresAt": { "type": "string", - "description": "Monitor ID that failed", - "format": "uuid" + "description": "When the key expires (null = never)", + "format": "date-time", + "nullable": true }, - "reason": { + "lastUsedAt": { "type": "string", - "description": "Human-readable reason for the failure" + "description": "Last time the key was used", + "format": "date-time", + "nullable": true } }, - "description": "Details about a single monitor that failed the bulk action" + "description": "API key metadata" }, - "GitLabChannelConfig": { + "LinearChannelConfig": { "required": [ "channelType", - "endpointUrl", - "authorizationKey" + "apiKey", + "teamId" ], "type": "object", "properties": { "channelType": { "type": "string", "enum": [ - "gitlab" + "linear" ] }, - "endpointUrl": { + "apiKey": { "minLength": 1, "type": "string", - "description": "GitLab alert integration endpoint URL" + "description": "Linear API key" }, - "authorizationKey": { + "teamId": { "minLength": 1, "type": "string", - "description": "Authorization key from GitLab alert integration settings" + "description": "Team ID to create issues in" + }, + "labelId": { + "type": "string", + "description": "Label ID to attach to created issues", + "nullable": true } } }, - "GlobalStatusSummaryDto": { + "LinkedStatusPageIncidentDto": { "required": [ - "servicesWithIssues", - "totalServices", - "operationalCount", - "degradedCount", - "partialOutageCount", - "majorOutageCount", - "maintenanceCount", - "unknownCount", - "activeIncidentCount" + "connectionMode", + "id", + "impact", + "pageIncidentMode", + "spIncidentId", + "status", + "statusPageId", + "statusPageName", + "statusPageSlug", + "title", + "scheduled" ], "type": "object", "properties": { - "totalServices": { - "type": "integer", - "description": "Total number of services in the catalog", - "format": "int32" + "id": { + "type": "string", + "description": "Status page incident ID (same value as spIncidentId; kept for backwards compatibility)", + "format": "uuid" }, - "operationalCount": { - "type": "integer", - "description": "Number of services currently fully operational", - "format": "int32" + "spIncidentId": { + "type": "string", + "description": "Status page incident ID (alias for id) — use this when the outer context is a monitoring incident", + "format": "uuid" }, - "degradedCount": { - "type": "integer", - "description": "Number of services with degraded status", - "format": "int32" + "statusPageId": { + "type": "string", + "description": "Parent status page ID", + "format": "uuid" }, - "partialOutageCount": { - "type": "integer", - "description": "Number of services with partial outage", - "format": "int32" + "statusPageName": { + "type": "string", + "description": "Parent status page display name" }, - "majorOutageCount": { - "type": "integer", - "description": "Number of services with major outage", - "format": "int32" + "statusPageSlug": { + "type": "string", + "description": "Parent status page URL slug" }, - "maintenanceCount": { - "type": "integer", - "description": "Number of services currently under maintenance", - "format": "int32" + "title": { + "type": "string", + "description": "Customer-facing incident title" }, - "unknownCount": { - "type": "integer", - "description": "Number of services with unknown or null status", - "format": "int32" + "status": { + "type": "string", + "description": "Current lifecycle status (INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED)", + "enum": [ + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" + ] }, - "activeIncidentCount": { - "type": "integer", - "description": "Total number of active incidents across all services", - "format": "int64" + "impact": { + "type": "string", + "description": "Impact level (NONE, MINOR, MAJOR, CRITICAL)", + "enum": [ + "NONE", + "MINOR", + "MAJOR", + "CRITICAL" + ] }, - "servicesWithIssues": { - "type": "array", - "description": "Services that are not fully operational", - "items": { - "$ref": "#/components/schemas/ServiceCatalogDto" - } - } - }, - "description": "Global status summary across all subscribed vendor services" - }, - "GoogleChatChannelConfig": { - "required": [ - "channelType", - "webhookUrl" - ], - "type": "object", - "properties": { - "channelType": { + "scheduled": { + "type": "boolean", + "description": "Scheduled maintenance flag" + }, + "publishedAt": { + "type": "string", + "description": "Publish time; null while draft", + "format": "date-time", + "nullable": true + }, + "connectionMode": { "type": "string", + "description": "Whether the linked SPI was created by automation (AUTO) or by a human/API caller (MANUAL)", "enum": [ - "google_chat" + "AUTO", + "MANUAL" ] }, - "webhookUrl": { - "minLength": 1, + "pageIncidentMode": { "type": "string", - "description": "Google Chat space webhook URL" + "description": "Incident mode of the parent status page at read time (MANUAL, REVIEW, AUTOMATIC)", + "enum": [ + "MANUAL", + "REVIEW", + "AUTOMATIC" + ] } } }, - "GroupComponentOrder": { + "MaintenanceComponentRef": { "required": [ - "groupId", - "positions" + "id", + "name", + "status" ], "type": "object", "properties": { - "groupId": { + "id": { "type": "string", - "description": "Group these components belong to", + "description": "Component identifier", "format": "uuid" }, - "positions": { - "minItems": 1, - "type": "array", - "description": "Ordered component IDs with their within-group display order", - "items": { - "$ref": "#/components/schemas/ComponentPosition" - } + "name": { + "type": "string", + "description": "Component name" + }, + "status": { + "type": "string", + "description": "Component status at the time of the maintenance update" } }, - "description": "Component ordering within a single group" + "description": "A component affected by a scheduled maintenance window" }, - "HeaderAuthConfig": { + "MaintenanceEventDto": { "required": [ - "type", - "headerName" + "externalId", + "maintenanceId", + "status", + "title" ], "type": "object", "properties": { - "type": { + "maintenanceId": { "type": "string", - "enum": [ - "header" - ] + "description": "Vendor catalog maintenance ID", + "format": "uuid" }, - "headerName": { - "minLength": 1, - "pattern": "^[A-Za-z0-9\\-_]+$", + "externalId": { "type": "string", - "description": "Custom HTTP header name for the secret value" + "description": "Vendor-supplied external maintenance ID" }, - "vaultSecretId": { + "title": { "type": "string", - "description": "Vault secret ID for the header value", - "format": "uuid", + "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 - } - } - }, - "HeaderValueAssertion": { - "required": [ - "type", - "headerName", - "expected", - "operator" - ], - "type": "object", - "properties": { - "type": { + }, + "shortlink": { "type": "string", - "enum": [ - "header_value" - ] + "description": "Short public URL for the vendor maintenance", + "nullable": true }, - "headerName": { - "minLength": 1, + "scheduledFor": { "type": "string", - "description": "HTTP header name to assert on" + "description": "Scheduled start; null for undated maintenance", + "format": "date-time", + "nullable": true }, - "expected": { - "minLength": 1, + "scheduledUntil": { "type": "string", - "description": "Expected value to compare against" + "description": "Scheduled end", + "format": "date-time", + "nullable": true }, - "operator": { + "startedAt": { "type": "string", - "description": "Comparison operator (equals, contains, less_than, greater_than, etc.)", - "enum": [ - "equals", - "contains", - "less_than", - "greater_than", - "matches", - "range" - ] - } - } - }, - "HeartbeatIntervalDriftAssertion": { - "required": [ - "type", - "maxDeviationPercent" - ], - "type": "object", - "properties": { - "type": { + "description": "When maintenance actually started", + "format": "date-time", + "nullable": true + }, + "completedAt": { "type": "string", - "enum": [ - "heartbeat_interval_drift" - ] + "description": "When maintenance completed", + "format": "date-time", + "nullable": true }, - "maxDeviationPercent": { - "maximum": 100, - "minimum": 1, - "type": "integer", - "description": "Max percent drift from expected ping interval before warning (non-fatal)", - "format": "int32" + "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" }, - "HeartbeatMaxIntervalAssertion": { + "MaintenanceUpdateDto": { "required": [ - "type", - "maxSeconds" + "id", + "status" ], "type": "object", "properties": { - "type": { + "id": { "type": "string", - "enum": [ - "heartbeat_max_interval" - ] + "description": "Unique update identifier", + "format": "uuid" }, - "maxSeconds": { - "minimum": 1, - "type": "integer", - "description": "Maximum allowed gap in seconds between consecutive heartbeat pings", - "format": "int32" + "status": { + "type": "string", + "description": "Status at the time of this update" + }, + "body": { + "type": "string", + "description": "Update message from the vendor", + "nullable": true + }, + "displayAt": { + "type": "string", + "description": "Timestamp when this update was posted", + "format": "date-time", + "nullable": true } - } + }, + "description": "A status update within a scheduled maintenance lifecycle" }, - "HeartbeatMonitorConfig": { + "MaintenanceWindowDto": { "required": [ - "expectedInterval", - "gracePeriod" + "createdAt", + "endsAt", + "id", + "startsAt", + "organizationId", + "suppressAlerts" ], "type": "object", "properties": { - "expectedInterval": { - "maximum": 86400, - "minimum": 1, - "type": "integer", - "description": "Expected heartbeat interval in seconds", - "format": "int32" + "id": { + "type": "string", + "description": "Unique maintenance window identifier", + "format": "uuid" }, - "gracePeriod": { - "minimum": 1, + "monitorId": { + "type": "string", + "description": "Monitor this window applies to; null for org-wide windows", + "format": "uuid", + "nullable": true + }, + "organizationId": { "type": "integer", - "description": "Grace period in seconds before marking as down", + "description": "Organization this maintenance window belongs to", "format": "int32" - } - } - }, - "HeartbeatPayloadContainsAssertion": { - "required": [ - "type", - "path", - "value" - ], - "type": "object", - "properties": { - "type": { + }, + "startsAt": { "type": "string", - "enum": [ - "heartbeat_payload_contains" - ] + "description": "Scheduled start of the maintenance window", + "format": "date-time" }, - "path": { - "minLength": 1, + "endsAt": { "type": "string", - "description": "JSONPath expression into the heartbeat ping JSON payload" + "description": "Scheduled end of the maintenance window", + "format": "date-time" }, - "value": { + "repeatRule": { "type": "string", - "description": "Expected value to compare against at that path" - } - } - }, - "HeartbeatPingResponse": { - "required": [ - "ok" - ], - "type": "object", - "properties": { - "ok": { + "description": "Reserved: iCal RRULE for recurring windows (stored but not yet honored)", + "nullable": true + }, + "reason": { + "type": "string", + "description": "Human-readable reason for the maintenance", + "nullable": true + }, + "suppressAlerts": { "type": "boolean", - "description": "Always true on a 2xx response", - "example": true - } - }, - "description": "Acknowledgement that a heartbeat ping was accepted" - }, - "HeartbeatReceivedAssertion": { - "type": "object", - "properties": { - "type": { + "description": "Whether alerts are suppressed during this window" + }, + "createdAt": { "type": "string", - "enum": [ - "heartbeat_received" - ] + "description": "Timestamp when the window was created", + "format": "date-time" } }, + "description": "Scheduled maintenance window for a monitor" + }, + "MatchRule": { "required": [ "type" - ] - }, - "Http": { + ], "type": "object", - "description": "HTTP check-type-specific details", "properties": { - "check_type": { + "type": { "type": "string", + "description": "Rule type used to evaluate incidents and status events", "enum": [ - "http" + "severity_gte", + "monitor_id_in", + "region_in", + "incident_status", + "monitor_type_in", + "service_id_in", + "resource_group_id_in", + "component_name_in", + "monitor_tag_in" ] }, - "timing": { + "value": { + "type": "string", + "description": "Comparison value for single-value rules like severity_gte", + "nullable": true + }, + "monitorIds": { + "type": "array", + "description": "Monitor UUIDs to match for monitor_id_in rules", "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/TimingPhasesDto" - } - ] + "items": { + "type": "string", + "description": "Monitor UUIDs to match for monitor_id_in rules", + "format": "uuid" + } }, - "bodyTruncated": { - "type": "boolean", - "description": "Whether the response body was truncated before storage", - "nullable": true + "regions": { + "type": "array", + "description": "Region codes to match for region_in rules", + "nullable": true, + "items": { + "type": "string", + "description": "Region codes to match for region_in rules" + } + }, + "values": { + "type": "array", + "description": "Values list for multi-value rules like monitor_type_in", + "nullable": true, + "items": { + "type": "string", + "description": "Values list for multi-value rules like monitor_type_in" + } } }, - "required": [ - "check_type" - ] + "description": "Match rules to evaluate (all must pass; omit or empty for catch-all)" }, - "HttpMonitorConfig": { + "MattermostChannelConfig": { "required": [ - "method", - "url" + "channelType", + "webhookUrl" ], "type": "object", "properties": { - "url": { - "minLength": 1, - "type": "string", - "description": "Target URL to send requests to" - }, - "method": { + "channelType": { "type": "string", - "description": "HTTP method: GET, POST, PUT, PATCH, DELETE, or HEAD", "enum": [ - "GET", - "POST", - "PUT", - "PATCH", - "DELETE", - "HEAD" + "mattermost" ] }, - "customHeaders": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Additional HTTP headers to include in requests", - "nullable": true - }, - "description": "Additional HTTP headers to include in requests", - "nullable": true - }, - "requestBody": { + "webhookUrl": { + "minLength": 1, "type": "string", - "description": "Request body content for POST/PUT/PATCH methods", - "nullable": true + "description": "Mattermost incoming webhook URL" }, - "contentType": { + "channel": { "type": "string", - "description": "Content-Type header value for the request body", + "description": "Override channel (if webhook allows)", "nullable": true }, - "verifyTls": { - "type": "boolean", - "description": "Whether to verify TLS certificates (default: true)", + "iconUrl": { + "type": "string", + "description": "Custom bot icon URL", "nullable": true } } }, - "Icmp": { - "required": [ - "check_type", - "host" - ], + "McpConnectsAssertion": { "type": "object", - "description": "ICMP (ping) check-type-specific details", "properties": { - "check_type": { + "type": { "type": "string", "enum": [ - "icmp" + "mcp_connects" ] - }, - "host": { - "type": "string", - "description": "Target host", - "example": "1.1.1.1" - }, - "packetsSent": { - "type": "integer", - "description": "Number of ICMP packets sent", - "format": "int32", - "nullable": true - }, - "packetsReceived": { - "type": "integer", - "description": "Number of ICMP packets received", - "format": "int32", - "nullable": true - }, - "packetLoss": { - "type": "number", - "description": "Packet loss percentage", - "format": "double", - "nullable": true, - "example": 0 - }, - "avgRttMs": { - "type": "number", - "description": "Average round-trip time in ms", - "format": "double", - "nullable": true - }, - "minRttMs": { - "type": "number", - "description": "Minimum round-trip time in ms", - "format": "double", - "nullable": true - }, - "maxRttMs": { - "type": "number", - "description": "Maximum round-trip time in ms", - "format": "double", - "nullable": true - }, - "jitterMs": { - "type": "number", - "description": "Jitter in ms", - "format": "double", - "nullable": true } - } + }, + "required": [ + "type" + ] }, - "IcmpMonitorConfig": { + "McpHasCapabilityAssertion": { "required": [ - "host" + "type", + "capability" ], "type": "object", "properties": { - "host": { - "minLength": 1, + "type": { "type": "string", - "description": "Target hostname or IP address to ping" - }, - "packetCount": { - "maximum": 20, - "minimum": 1, - "type": "integer", - "description": "Number of ICMP packets to send", - "format": "int32", - "nullable": true + "enum": [ + "mcp_has_capability" + ] }, - "timeoutMs": { - "type": "integer", - "description": "Ping timeout in milliseconds", - "format": "int32", - "nullable": true + "capability": { + "minLength": 1, + "type": "string", + "description": "Capability name the server must advertise, e.g. tools or resources" } } }, - "IcmpPacketLossAssertion": { + "McpMinToolsAssertion": { + "required": [ + "type", + "min" + ], "type": "object", "properties": { "type": { "type": "string", "enum": [ - "icmp_packet_loss" + "mcp_min_tools" ] }, - "maxPercent": { - "maximum": 100, - "exclusiveMaximum": false, - "minimum": 0, - "exclusiveMinimum": false, - "type": "number", - "description": "Maximum allowed packet loss percentage before the check fails (0–100)", - "format": "double" + "min": { + "type": "integer", + "description": "Minimum number of tools the server must expose", + "format": "int32" } - }, + } + }, + "McpProtocolVersionAssertion": { "required": [ "type", - "maxPercent" - ] - }, - "IcmpReachableAssertion": { + "version" + ], "type": "object", "properties": { "type": { "type": "string", "enum": [ - "icmp_reachable" + "mcp_protocol_version" ] + }, + "version": { + "minLength": 1, + "type": "string", + "description": "Expected MCP protocol version string from the server handshake" } - }, - "required": [ - "type" - ] + } }, - "IcmpResponseTimeAssertion": { + "McpResponseTimeAssertion": { "type": "object", "properties": { "type": { "type": "string", "enum": [ - "icmp_response_time" + "mcp_response_time" ] }, "maxMs": { "type": "integer", - "description": "Maximum average ICMP round-trip time in milliseconds", + "description": "Maximum allowed MCP check duration in milliseconds", "format": "int32" } }, @@ -29840,18 +37363,18 @@ "maxMs" ] }, - "IcmpResponseTimeWarnAssertion": { + "McpResponseTimeWarnAssertion": { "type": "object", "properties": { "type": { "type": "string", "enum": [ - "icmp_response_time_warn" + "mcp_response_time_warn" ] }, "warnMs": { "type": "integer", - "description": "ICMP round-trip time in milliseconds that triggers a warning only", + "description": "MCP check duration in milliseconds that triggers a warning only", "format": "int32" } }, @@ -29860,4707 +37383,4981 @@ "warnMs" ] }, - "IncidentActivityEventDto": { - "required": [ - "at", - "id", - "kind", - "summary" - ], + "McpServer": { "type": "object", + "description": "MCP server check-type-specific details", "properties": { - "id": { - "type": "string", - "description": "Stable event ID (source row ID)", - "format": "uuid" - }, - "at": { - "type": "string", - "description": "When the event occurred (ISO 8601)", - "format": "date-time" - }, - "kind": { + "check_type": { "type": "string", - "description": "Activity event kind in the merged incident activity stream", "enum": [ - "update", - "dispatch", - "delivery", - "forensic_transition", - "status_page_update" + "mcp_server" ] }, - "actor": { + "url": { "type": "string", - "description": "Actor label when known (user email, system, etc.)", + "description": "MCP server URL", "nullable": true }, - "summary": { - "type": "string", - "description": "Human-readable summary of the event" - }, - "payload": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/IncidentActivityPayloadDto" - } - ] - } - }, - "description": "Merged incident activity event (updates, dispatches, deliveries, forensics, SP updates)" - }, - "IncidentActivityPayloadDto": { - "type": "object", - "properties": { - "oldStatus": { + "protocolVersion": { "type": "string", - "description": "Previous incident status on an update", + "description": "MCP protocol version", "nullable": true }, - "newStatus": { - "type": "string", - "description": "New incident status on an update", + "serverInfo": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "MCP server info (name, version, etc.)", + "nullable": true + }, + "description": "MCP server info (name, version, etc.)", "nullable": true }, - "body": { - "type": "string", - "description": "Update or status-page note body", + "toolCount": { + "type": "integer", + "description": "Number of tools exposed", + "format": "int32", "nullable": true }, - "createdBy": { - "type": "string", - "description": "Who created the update (SYSTEM, USER, …)", + "resourceCount": { + "type": "integer", + "description": "Number of resources exposed", + "format": "int32", "nullable": true }, - "phase": { - "type": "string", - "description": "Dispatch lifecycle phase (fired, acked)", + "promptCount": { + "type": "integer", + "description": "Number of prompts exposed", + "format": "int32", "nullable": true - }, - "status": { + } + }, + "required": [ + "check_type" + ] + }, + "McpServerMonitorConfig": { + "required": [ + "command" + ], + "type": "object", + "properties": { + "command": { + "minLength": 1, "type": "string", - "description": "Dispatch, delivery, or status-page status", - "nullable": true + "description": "Command to execute to start the MCP server" }, - "policyId": { - "type": "string", - "description": "Notification policy id for a dispatch row", + "args": { + "type": "array", + "description": "Command-line arguments for the MCP server process", + "nullable": true, + "items": { + "type": "string", + "description": "Command-line arguments for the MCP server process", + "nullable": true + } + }, + "env": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Environment variables to pass to the MCP server process", + "nullable": true + }, + "description": "Environment variables to pass to the MCP server process", "nullable": true + } + } + }, + "McpToolAvailableAssertion": { + "required": [ + "type", + "toolName" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "mcp_tool_available" + ] }, - "policyName": { + "toolName": { + "minLength": 1, "type": "string", - "description": "Notification policy name when resolved", - "nullable": true + "description": "MCP tool name that must appear in the server's tool list" + } + } + }, + "McpToolCountChangedAssertion": { + "required": [ + "type", + "expectedCount" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "mcp_tool_count_changed" + ] }, - "currentStep": { + "expectedCount": { "type": "integer", - "description": "Current escalation step (1-based)", - "format": "int32", - "nullable": true + "description": "Expected tool count; warns when the live count differs", + "format": "int32" + } + } + }, + "MemberDto": { + "required": [ + "createdAt", + "email", + "orgRole", + "status", + "userId" + ], + "type": "object", + "properties": { + "userId": { + "type": "integer", + "description": "User identifier of the member", + "format": "int32" }, - "dispatchId": { + "email": { "type": "string", - "description": "Notification dispatch id", - "nullable": true + "description": "Member email address" }, - "acknowledgedBy": { + "name": { "type": "string", - "description": "Who acknowledged the dispatch", + "description": "Member display name; null if not set", "nullable": true }, - "acknowledgedVia": { + "orgRole": { "type": "string", - "description": "Ack channel (UI, Slack, …)", - "nullable": true + "description": "Member role within this organization (OWNER, ADMIN, MEMBER)", + "enum": [ + "OWNER", + "ADMIN", + "MEMBER" + ] }, - "eventType": { + "status": { "type": "string", - "description": "Alert delivery event type", - "nullable": true - }, - "stepNumber": { - "type": "integer", - "description": "Escalation step that sent this delivery", - "format": "int32", - "nullable": true - }, - "fireCount": { - "type": "integer", - "description": "How many times this delivery has fired", - "format": "int32", - "nullable": true + "description": "Membership status (ACTIVE, PENDING, SUSPENDED)", + "enum": [ + "INVITED", + "ACTIVE", + "SUSPENDED", + "LEFT", + "REMOVED", + "DECLINED" + ] }, - "channelId": { + "createdAt": { "type": "string", - "description": "Alert channel id", - "nullable": true - }, - "channelName": { + "description": "Timestamp when the member was added to the organization", + "format": "date-time" + } + }, + "description": "Organization member with role and status" + }, + "MemberRoleChangedMetadata": { + "required": [ + "kind", + "oldRole", + "newRole" + ], + "type": "object", + "description": "Role transition recorded when an organization member's role changes.", + "properties": { + "kind": { "type": "string", - "description": "Alert channel name", - "nullable": true + "enum": [ + "member_role_changed" + ] }, - "channelType": { + "oldRole": { "type": "string", - "description": "Alert channel type", - "nullable": true + "description": "Role the member held before the change", + "enum": [ + "OWNER", + "ADMIN", + "MEMBER" + ] }, - "errorMessage": { + "newRole": { "type": "string", - "description": "Delivery error message when the send failed", - "nullable": true - }, - "fromStatus": { + "description": "Role the member holds after the change", + "enum": [ + "OWNER", + "ADMIN", + "MEMBER" + ] + } + } + }, + "MonitorAssertionDto": { + "required": [ + "assertionType", + "config", + "id", + "monitorId", + "severity" + ], + "type": "object", + "properties": { + "id": { "type": "string", - "description": "Forensic from-status", - "nullable": true + "format": "uuid" }, - "toStatus": { + "monitorId": { "type": "string", - "description": "Forensic to-status", - "nullable": true + "format": "uuid" }, - "reason": { + "assertionType": { "type": "string", - "description": "Forensic transition reason", - "nullable": true + "enum": [ + "status_code", + "response_time", + "body_contains", + "json_path", + "header_value", + "regex_body", + "dns_resolves", + "dns_response_time", + "dns_expected_ips", + "dns_expected_cname", + "dns_record_contains", + "dns_record_equals", + "dns_txt_contains", + "dns_min_answers", + "dns_max_answers", + "dns_response_time_warn", + "dns_ttl_low", + "dns_ttl_high", + "mcp_connects", + "mcp_response_time", + "mcp_has_capability", + "mcp_tool_available", + "mcp_min_tools", + "mcp_protocol_version", + "mcp_response_time_warn", + "mcp_tool_count_changed", + "ssl_expiry", + "response_size", + "redirect_count", + "redirect_target", + "response_time_warn", + "tcp_connects", + "tcp_response_time", + "tcp_response_time_warn", + "icmp_reachable", + "icmp_response_time", + "icmp_response_time_warn", + "icmp_packet_loss", + "heartbeat_received", + "heartbeat_max_interval", + "heartbeat_interval_drift", + "heartbeat_payload_contains" + ] }, - "affectedRegions": { - "type": "array", - "description": "Regions named on the forensic transition", - "nullable": true, - "items": { - "type": "string", - "description": "Regions named on the forensic transition" - } + "config": { + "oneOf": [ + { + "$ref": "#/components/schemas/BodyContainsAssertion" + }, + { + "$ref": "#/components/schemas/DnsExpectedCnameAssertion" + }, + { + "$ref": "#/components/schemas/DnsExpectedIpsAssertion" + }, + { + "$ref": "#/components/schemas/DnsMaxAnswersAssertion" + }, + { + "$ref": "#/components/schemas/DnsMinAnswersAssertion" + }, + { + "$ref": "#/components/schemas/DnsRecordContainsAssertion" + }, + { + "$ref": "#/components/schemas/DnsRecordEqualsAssertion" + }, + { + "$ref": "#/components/schemas/DnsResolvesAssertion" + }, + { + "$ref": "#/components/schemas/DnsResponseTimeAssertion" + }, + { + "$ref": "#/components/schemas/DnsResponseTimeWarnAssertion" + }, + { + "$ref": "#/components/schemas/DnsTtlHighAssertion" + }, + { + "$ref": "#/components/schemas/DnsTtlLowAssertion" + }, + { + "$ref": "#/components/schemas/DnsTxtContainsAssertion" + }, + { + "$ref": "#/components/schemas/HeaderValueAssertion" + }, + { + "$ref": "#/components/schemas/HeartbeatIntervalDriftAssertion" + }, + { + "$ref": "#/components/schemas/HeartbeatMaxIntervalAssertion" + }, + { + "$ref": "#/components/schemas/HeartbeatPayloadContainsAssertion" + }, + { + "$ref": "#/components/schemas/HeartbeatReceivedAssertion" + }, + { + "$ref": "#/components/schemas/IcmpPacketLossAssertion" + }, + { + "$ref": "#/components/schemas/IcmpReachableAssertion" + }, + { + "$ref": "#/components/schemas/IcmpResponseTimeAssertion" + }, + { + "$ref": "#/components/schemas/IcmpResponseTimeWarnAssertion" + }, + { + "$ref": "#/components/schemas/JsonPathAssertion" + }, + { + "$ref": "#/components/schemas/McpConnectsAssertion" + }, + { + "$ref": "#/components/schemas/McpHasCapabilityAssertion" + }, + { + "$ref": "#/components/schemas/McpMinToolsAssertion" + }, + { + "$ref": "#/components/schemas/McpProtocolVersionAssertion" + }, + { + "$ref": "#/components/schemas/McpResponseTimeAssertion" + }, + { + "$ref": "#/components/schemas/McpResponseTimeWarnAssertion" + }, + { + "$ref": "#/components/schemas/McpToolAvailableAssertion" + }, + { + "$ref": "#/components/schemas/McpToolCountChangedAssertion" + }, + { + "$ref": "#/components/schemas/RedirectCountAssertion" + }, + { + "$ref": "#/components/schemas/RedirectTargetAssertion" + }, + { + "$ref": "#/components/schemas/RegexBodyAssertion" + }, + { + "$ref": "#/components/schemas/ResponseSizeAssertion" + }, + { + "$ref": "#/components/schemas/ResponseTimeAssertion" + }, + { + "$ref": "#/components/schemas/ResponseTimeWarnAssertion" + }, + { + "$ref": "#/components/schemas/SslExpiryAssertion" + }, + { + "$ref": "#/components/schemas/StatusCodeAssertion" + }, + { + "$ref": "#/components/schemas/TcpConnectsAssertion" + }, + { + "$ref": "#/components/schemas/TcpResponseTimeAssertion" + }, + { + "$ref": "#/components/schemas/TcpResponseTimeWarnAssertion" + } + ] }, - "statusPageIncidentId": { + "severity": { "type": "string", - "description": "Linked status-page incident id", - "nullable": true + "enum": [ + "fail", + "warn" + ] + } + } + }, + "MonitorAuthConfig": { + "description": "New authentication configuration (full replacement)", + "discriminator": { + "propertyName": "type", + "mapping": { + "bearer": "#/components/schemas/BearerAuthConfig", + "basic": "#/components/schemas/BasicAuthConfig", + "header": "#/components/schemas/HeaderAuthConfig", + "api_key": "#/components/schemas/ApiKeyAuthConfig" } }, - "description": "Kind-specific activity fields; omitted keys are absent, not null" + "oneOf": [ + { + "$ref": "#/components/schemas/BearerAuthConfig" + }, + { + "$ref": "#/components/schemas/BasicAuthConfig" + }, + { + "$ref": "#/components/schemas/HeaderAuthConfig" + }, + { + "$ref": "#/components/schemas/ApiKeyAuthConfig" + } + ] }, - "IncidentDetailDto": { + "MonitorAuthDto": { "required": [ - "incident", - "updates" + "authType", + "config", + "id", + "monitorId" ], "type": "object", "properties": { - "incident": { - "$ref": "#/components/schemas/IncidentDto" + "id": { + "type": "string", + "format": "uuid" }, - "updates": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IncidentUpdateDto" - } + "monitorId": { + "type": "string", + "format": "uuid" }, - "statusPageIncidents": { - "type": "array", - "nullable": true, - "items": { - "$ref": "#/components/schemas/LinkedStatusPageIncidentDto" - } + "authType": { + "type": "string", + "enum": [ + "bearer", + "basic", + "header", + "api_key" + ] }, - "trigger": { - "nullable": true, - "allOf": [ + "config": { + "oneOf": [ { - "$ref": "#/components/schemas/IncidentTriggerDto" + "$ref": "#/components/schemas/ApiKeyAuthConfig" + }, + { + "$ref": "#/components/schemas/BasicAuthConfig" + }, + { + "$ref": "#/components/schemas/BearerAuthConfig" + }, + { + "$ref": "#/components/schemas/HeaderAuthConfig" } ] } } }, - "IncidentDto": { + "MonitorDto": { "required": [ - "affectedRegions", + "config", "createdAt", "id", - "severity", - "source", - "status", + "managedBy", + "name", + "regions", + "type", "updatedAt", "organizationId", - "reopenCount", - "statusPageVisible", - "suppressDispatch" + "frequencySeconds", + "enabled", + "muted" ], "type": "object", "properties": { "id": { "type": "string", - "description": "Unique incident identifier", + "description": "Unique monitor identifier", "format": "uuid" }, - "monitorId": { - "type": "string", - "description": "Monitor that triggered the incident; null for service or manual incidents", - "format": "uuid", - "nullable": true - }, "organizationId": { "type": "integer", - "description": "Organization this incident belongs to", + "description": "Organization this monitor belongs to", "format": "int32" }, - "source": { + "name": { + "minLength": 1, "type": "string", - "description": "Incident origin: MONITOR, SERVICE, or MANUAL", - "enum": [ - "AUTOMATIC", - "MANUAL", - "MONITORS", - "STATUS_DATA", - "RESOURCE_GROUP" - ] + "description": "Human-readable name for this monitor" }, - "status": { + "type": { "type": "string", - "description": "Current lifecycle status (OPEN, RESOLVED, etc.)", "enum": [ - "WATCHING", - "TRIGGERED", - "CONFIRMED", - "RESOLVED" + "HTTP", + "DNS", + "MCP_SERVER", + "TCP", + "ICMP", + "HEARTBEAT", + "BROWSER", + "MULTI_STEP_API" ] }, - "severity": { - "type": "string", - "description": "Severity level: DOWN, DEGRADED, or MAINTENANCE", - "enum": [ - "DOWN", - "DEGRADED", - "MAINTENANCE" + "config": { + "oneOf": [ + { + "$ref": "#/components/schemas/DnsMonitorConfig" + }, + { + "$ref": "#/components/schemas/HeartbeatMonitorConfig" + }, + { + "$ref": "#/components/schemas/HttpMonitorConfig" + }, + { + "$ref": "#/components/schemas/IcmpMonitorConfig" + }, + { + "$ref": "#/components/schemas/McpServerMonitorConfig" + }, + { + "$ref": "#/components/schemas/ScriptMonitorConfig" + }, + { + "$ref": "#/components/schemas/TcpMonitorConfig" + } ] }, - "title": { - "type": "string", - "description": "Short summary of the incident; null for auto-generated incidents", - "nullable": true - }, - "triggeredByRule": { - "type": "string", - "description": "Human-readable description of the trigger rule that fired", - "nullable": true - }, - "affectedRegions": { - "type": "array", - "description": "Probe regions that observed the failure", - "items": { - "type": "string", - "description": "Probe regions that observed the failure" - } - }, - "reopenCount": { + "frequencySeconds": { "type": "integer", - "description": "Number of times this incident has been reopened", + "description": "Check frequency in seconds (30–86400)", "format": "int32" }, - "createdByUserId": { - "type": "integer", - "description": "User who created the incident (manual incidents only)", - "format": "int32", - "nullable": true - }, - "statusPageVisible": { - "type": "boolean", - "description": "Whether this incident is visible on the status page" - }, - "suppressDispatch": { + "enabled": { "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", - "format": "uuid", - "nullable": true - }, - "serviceId": { - "type": "string", - "description": "Linked service catalog ID; null for monitor incidents", - "format": "uuid", - "nullable": true - }, - "externalRef": { - "type": "string", - "description": "External reference ID (e.g. PagerDuty incident ID)", - "nullable": true + "description": "Whether the monitor is active" }, - "affectedComponents": { + "regions": { "type": "array", - "description": "Service components affected by this incident", - "nullable": true, + "description": "Probe regions where checks are executed", "items": { "type": "string", - "description": "Service components affected by this incident" + "description": "Probe regions where checks are executed" } }, - "shortlink": { - "type": "string", - "description": "Short URL linking to the incident details", - "nullable": true - }, - "resolutionReason": { + "managedBy": { "type": "string", - "description": "How the incident was resolved (AUTO_RECOVERED, MANUAL, etc.)", - "nullable": true, + "description": "Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API", "enum": [ - "MANUAL", - "AUTO_RECOVERED", - "AUTO_RESOLVED" + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" ] }, - "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", - "format": "date-time", - "nullable": true - }, - "confirmedAt": { - "type": "string", - "description": "Timestamp when the incident was confirmed (multi-region confirmation)", - "format": "date-time", - "nullable": true - }, - "resolvedAt": { - "type": "string", - "description": "Timestamp when the incident was resolved", - "format": "date-time", - "nullable": true - }, - "cooldownUntil": { - "type": "string", - "description": "Cooldown window end; new incidents suppressed until this time", - "format": "date-time", - "nullable": true - }, "createdAt": { "type": "string", - "description": "Timestamp when the incident record was created", + "description": "Timestamp when the monitor was created", "format": "date-time" }, "updatedAt": { "type": "string", - "description": "Timestamp when the incident was last updated", + "description": "Timestamp when the monitor was last updated", "format": "date-time" }, - "monitorName": { - "type": "string", - "description": "Name of the associated monitor; populated on list responses. Omitted from JSON (undefined to SDKs) on detail responses, treat missing as null.", - "nullable": true - }, - "serviceName": { - "type": "string", - "description": "Name of the associated service; populated on list responses. Omitted from JSON (undefined to SDKs) on detail responses, treat missing as null.", - "nullable": true - }, - "serviceSlug": { - "type": "string", - "description": "Slug of the associated service; populated on list responses. Omitted from JSON (undefined to SDKs) on detail responses, treat missing as null.", - "nullable": true - }, - "monitorType": { - "type": "string", - "description": "Type of the associated monitor; populated on list responses. Omitted from JSON (undefined to SDKs) on detail responses, treat missing as null.", - "nullable": true - }, - "resourceGroupId": { - "type": "string", - "description": "Resource group that owns this incident; null when not group-managed", - "format": "uuid", - "nullable": true - }, - "resourceGroupName": { - "type": "string", - "description": "Name of the resource group; populated on list responses. Omitted from JSON (undefined to SDKs) on detail responses, treat missing as null.", - "nullable": true - }, - "triggeringCheckId": { - "type": "string", - "description": "Scheduler-minted check execution ID whose result confirmed this incident; joins to check_results, rule_evaluations, and incident_state_transitions. Omitted from JSON (undefined to SDKs) when null, treat missing as null.", - "format": "uuid", - "nullable": true - }, - "triggeredByRuleSnapshotHashHex": { - "type": "string", - "description": "Hex SHA-256 of the canonical policy snapshot that fired; combined with triggeredByRuleIndex points to the exact TriggerRule. Omitted from JSON when null, treat missing as null.", - "nullable": true - }, - "triggeredByRuleIndex": { - "type": "integer", - "description": "Index of the fired rule inside the policy's trigger_rules array. Omitted from JSON when null, treat missing as null.", - "format": "int32", - "nullable": true - }, - "engineVersion": { - "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 - }, - "alertCollapsedByResourceGroupIds": { + "assertions": { "type": "array", - "description": "Sticky union of resource-group IDs that suppressed a paging dispatch for this member incident; null when never written / legacy", + "description": "Assertions evaluated against each check result; null on list responses", "nullable": true, "items": { - "type": "string", - "description": "Sticky union of resource-group IDs that suppressed a paging dispatch for this member incident; null when never written / legacy", - "format": "uuid" + "$ref": "#/components/schemas/MonitorAssertionDto" } }, - "peakFailingMemberCount": { - "type": "integer", - "description": "Peak non-operational member count while this RESOURCE_GROUP incident was open; null otherwise", - "format": "int32", - "nullable": true - }, - "failingMembersAtPeak": { + "tags": { "type": "array", - "description": "Frozen failing members at peakFailingMemberCount; null when not a group incident or never snapshotted", + "description": "Tags applied to this monitor", "nullable": true, "items": { - "$ref": "#/components/schemas/IncidentFailingMemberSnapshotDto" + "$ref": "#/components/schemas/TagDto" } - } - }, - "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": { + "pingUrl": { "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", + "description": "Heartbeat ping URL; populated for HEARTBEAT monitors only", "nullable": true }, - "affectedComponentIds": { - "type": "array", - "description": "Affected component IDs from the vendor incident join", + "environment": { "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" - }, - "IncidentFailingMemberSnapshotDto": { - "required": [ - "memberType", - "name" - ], - "type": "object", - "properties": { - "memberType": { - "type": "string", - "description": "Member type: monitor or service" - }, - "monitorId": { - "type": "string", - "description": "Monitor ID when memberType is monitor", - "format": "uuid", - "nullable": true - }, - "serviceId": { - "type": "string", - "description": "Service ID when memberType is service", - "format": "uuid", - "nullable": true - }, - "name": { - "minLength": 1, - "type": "string", - "description": "Frozen display name at snapshot time" + "allOf": [ + { + "$ref": "#/components/schemas/Summary" + } + ] }, - "membershipId": { - "type": "string", - "description": "Membership row ID when available", - "format": "uuid", - "nullable": true - } - }, - "description": "Frozen failing member identity at peak failing count for a resource-group incident" - }, - "IncidentFilterParams": { - "type": "object", - "properties": { - "status": { - "type": "string", - "description": "Filter by incident lifecycle status; null returns every status", + "auth": { "nullable": true, - "enum": [ - "WATCHING", - "TRIGGERED", - "CONFIRMED", - "RESOLVED" + "allOf": [ + { + "$ref": "#/components/schemas/MonitorAuthConfig" + } ] }, - "severity": { - "type": "string", - "description": "Filter by severity; null returns every severity", + "incidentPolicy": { "nullable": true, - "enum": [ - "DOWN", - "DEGRADED", - "MAINTENANCE" + "allOf": [ + { + "$ref": "#/components/schemas/IncidentPolicyDto" + } ] }, - "source": { + "alertChannelIds": { + "type": "array", + "description": "Alert channel IDs linked to this monitor; populated on single-monitor responses", + "nullable": true, + "items": { + "type": "string", + "description": "Alert channel IDs linked to this monitor; populated on single-monitor responses", + "format": "uuid" + } + }, + "currentStatus": { "type": "string", - "description": "Filter by where the incident originated (auto, manual, third-party)", + "description": "Current operational state. One of UP, DOWN, DEGRADED, PAUSED, or UNKNOWN", "nullable": true, "enum": [ - "AUTOMATIC", - "MANUAL", - "MONITORS", - "STATUS_DATA", - "RESOURCE_GROUP" + "up", + "degraded", + "down", + "paused", + "unknown" ] }, - "monitorId": { + "definitionId": { "type": "string", - "description": "Only return incidents tied to this monitor ID", + "description": "Definition id for a browser or multi-step monitor. Null on probe monitors", "format": "uuid", "nullable": true }, - "serviceId": { - "type": "string", - "description": "Only return incidents tied to this service ID (third-party services)", - "format": "uuid", + "capturePolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CapturePolicy" + } + ] + }, + "fastRetryMaxAttempts": { + "type": "integer", + "description": "Fast-retry max attempts; null/0 = off", + "format": "int32", "nullable": true }, - "resourceGroupId": { + "muted": { + "type": "boolean", + "description": "Whether alert delivery is muted" + }, + "mutedUntil": { "type": "string", - "description": "Only return incidents owned by this resource group (incidents.resource_group_id)", - "format": "uuid", + "description": "Mute expiry; null means indefinite while muted", + "format": "date-time", "nullable": true }, - "tagId": { + "muteReason": { "type": "string", - "description": "Only return incidents whose monitor carries this tag", - "format": "uuid", + "description": "Optional mute reason", "nullable": true }, - "environmentId": { + "pausedAt": { "type": "string", - "description": "Only return incidents whose monitor lives in this environment", - "format": "uuid", + "description": "When the monitor was paused", + "format": "date-time", "nullable": true }, - "excludeId": { + "pauseReason": { "type": "string", - "description": "Exclude this incident ID from results (related-incident lists)", - "format": "uuid", + "description": "Optional pause reason", "nullable": true }, - "startedFrom": { + "pauseExpiresAt": { "type": "string", - "description": "Earliest startedAt to include (inclusive, ISO 8601)", + "description": "Pause expiry", "format": "date-time", "nullable": true }, - "startedTo": { + "quarantineOwnerId": { "type": "string", - "description": "Latest startedAt to include (inclusive, ISO 8601)", + "description": "Quarantine person owner id", + "nullable": true + }, + "quarantineUntil": { + "type": "string", + "description": "Quarantine expiry; non-null means quarantined", "format": "date-time", "nullable": true }, - "page": { - "minimum": 0, - "type": "integer", - "description": "Zero-based page index (default: 0)", - "format": "int32", - "example": 0 + "quarantineReason": { + "type": "string", + "description": "Quarantine reason", + "nullable": true }, - "size": { - "maximum": 200, - "minimum": 1, - "type": "integer", - "description": "Number of incidents per page (1–200, default: 10)", - "format": "int32", - "example": 10 + "upload": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/PackageUploadDto" + } + ] } }, - "required": [ - "page", - "size" - ] + "description": "Full monitor representation" }, - "IncidentIoChannelConfig": { - "required": [ - "channelType", - "apiKey" - ], + "MonitorOverlayRequest": { "type": "object", "properties": { - "channelType": { - "type": "string", - "enum": [ - "incident_io" - ] - }, - "apiKey": { - "minLength": 1, - "type": "string", - "description": "incident.io API key with 'Create incidents' permission" - }, - "severityId": { + "reason": { + "maxLength": 280, + "minLength": 0, "type": "string", - "description": "Severity ID for created incidents (from List Severities API)", + "description": "Optional human-readable reason (max 280)", "nullable": true }, - "visibility": { + "expiresAt": { "type": "string", - "description": "Incident visibility: public or private (default: public)", + "description": "When this overlay expires", + "format": "date-time", "nullable": true } } }, - "IncidentPolicyDto": { + "MonitorPackageSpec": { "required": [ - "confirmation", - "createdAt", - "id", - "monitorId", - "recovery", - "triggerRules", - "updatedAt" + "digest", + "entrypoint", + "files" ], "type": "object", "properties": { - "id": { + "digest": { + "maxLength": 64, + "minLength": 64, "type": "string", - "description": "Unique incident policy identifier", - "format": "uuid" + "description": "SHA-256 hex digest of the package zip (64 characters)" }, - "monitorId": { + "entrypoint": { + "maxLength": 512, + "minLength": 0, "type": "string", - "description": "Monitor this policy is attached to", - "format": "uuid" + "description": "Entrypoint path inside the zip, e.g. tests/login.spec.ts" }, - "triggerRules": { + "files": { + "maxItems": 256, + "minItems": 0, "type": "array", - "description": "Array of trigger rules defining when an incident should be raised", + "description": "Relative file paths included in the zip", "items": { - "$ref": "#/components/schemas/TriggerRule" + "maxLength": 512, + "minLength": 0, + "type": "string", + "description": "Relative file paths included in the zip" } }, - "confirmation": { - "$ref": "#/components/schemas/ConfirmationPolicy" - }, - "recovery": { - "$ref": "#/components/schemas/RecoveryPolicy" + "keys": { + "maxItems": 64, + "minItems": 0, + "type": "array", + "description": "Secret names the zip demanded. PUT: null preserves, [] clears", + "nullable": true, + "items": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Secret names the zip demanded. PUT: null preserves, [] clears" + } }, - "createdAt": { + "gitSha": { + "maxLength": 64, + "minLength": 0, "type": "string", - "description": "Timestamp when the policy was created", - "format": "date-time" + "description": "Commit SHA from the repo that produced this zip. Client-supplied provenance only", + "nullable": true }, - "updatedAt": { + "gitMessage": { + "maxLength": 1024, + "minLength": 0, "type": "string", - "description": "Timestamp when the policy was last updated", - "format": "date-time" + "description": "Commit message from the repo that produced this zip", + "nullable": true }, - "monitorRegionCount": { - "type": "integer", - "description": "Number of regions configured on the monitor (only set in internal API responses)", - "format": "int32", + "gitFile": { + "maxLength": 512, + "minLength": 0, + "type": "string", + "description": "Path of the declaring file in that repo", "nullable": true }, - "checkFrequencySeconds": { - "type": "integer", - "description": "Monitor check frequency in seconds (only set in internal API responses)", - "format": "int32", + "authoredBy": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Author attribution supplied with the package", "nullable": true + }, + "keyLocations": { + "maxItems": 64, + "minItems": 0, + "type": "array", + "description": "Per-key declaring file and location from package scan", + "nullable": true, + "items": { + "required": ["key"], + "type": "object", + "properties": { + "key": { + "maxLength": 255, + "type": "string", + "description": "Secret name the code reads" + }, + "declaringFile": { + "maxLength": 512, + "type": "string", + "description": "Declaring file path inside the zip", + "nullable": true + }, + "declaringLocation": { + "maxLength": 255, + "type": "string", + "description": "Call site from package scan, e.g. signIn(…) · line 6", + "nullable": true + } + }, + "description": "One demanded key plus the package-scan site that declared it" + } } }, - "description": "Incident detection, confirmation, and recovery policy for a monitor" + "description": "New package zip metadata for this environment" }, - "IncidentRef": { + "MonitorReference": { "required": [ "id", - "impact", - "title" + "name" ], "type": "object", "properties": { "id": { "type": "string", - "description": "Internal incident ID — UUID for status-page incidents, service incident UUID for catalog", + "description": "Monitor identifier", "format": "uuid" }, - "title": { - "type": "string", - "description": "Incident title at the time of the overlap" - }, - "impact": { + "name": { "type": "string", - "description": "Incident impact level (e.g. minor, major, critical for catalog; NONE/MINOR/MAJOR/CRITICAL for status pages)" - } - }, - "description": "Lightweight reference to an incident overlapping a given uptime day" - }, - "IncidentsSummaryDto": { - "type": "object", - "properties": { - "active": { - "type": "integer", - "format": "int64" - }, - "resolvedToday": { - "type": "integer", - "format": "int64" - }, - "mttr30d": { - "type": "number", - "format": "double", - "nullable": true + "description": "Monitor name" } }, - "description": "Incident summary counters", - "required": [ - "active", - "resolvedToday" - ] + "description": "Monitors that reference this secret for authentication" }, - "IncidentStateTransitionDto": { - "required": [ - "affectedRegions", - "checkId", - "details", - "engineVersion", - "fromStatus", - "id", - "monitorId", - "occurredAt", - "policySnapshotHashHex", - "reason", - "toStatus", - "triggeringEvaluationIds" - ], + "MonitorRunListParams": { "type": "object", "properties": { - "id": { - "type": "string", - "description": "Forensic row UUID", - "format": "uuid" - }, - "occurredAt": { - "type": "string", - "description": "When the state transition occurred", - "format": "date-time" - }, - "monitorId": { - "type": "string", - "description": "Monitor this transition pertains to", - "format": "uuid" - }, - "incidentId": { + "phase": { "type": "string", - "description": "Incident this transition belongs to; null for pre-incident (auto-cleared) transitions", - "format": "uuid", + "description": "Filter by run phase; omit to return every phase", "nullable": true }, - "fromStatus": { - "minLength": 1, + "outcome": { "type": "string", - "description": "Previous status (WATCHING | TRIGGERED | CONFIRMED | RESOLVED)" + "description": "Filter by persist outcome; omit to return every outcome", + "nullable": true }, - "toStatus": { - "minLength": 1, + "region": { "type": "string", - "description": "New status (WATCHING | TRIGGERED | CONFIRMED | RESOLVED)" + "description": "Filter by probe region", + "nullable": true }, - "reason": { - "minLength": 1, + "source": { "type": "string", - "description": "Why the transition fired (trigger | confirm | resolve | auto_clear | reopen)" - }, - "triggeringEvaluationIds": { - "type": "array", - "description": "rule_evaluation ids that caused this transition (may be empty for timeout-driven edges)", - "items": { - "type": "string", - "description": "rule_evaluation ids that caused this transition (may be empty for timeout-driven edges)", - "format": "uuid" - } - }, - "affectedRegions": { - "type": "array", - "description": "Regions whose evaluations contributed to this transition", - "items": { - "type": "string", - "description": "Regions whose evaluations contributed to this transition" - } + "description": "Filter by what triggered the run", + "nullable": true }, - "policySnapshotHashHex": { - "minLength": 1, + "q": { "type": "string", - "description": "Hex-encoded hash of the policy snapshot that governed this transition" + "description": "Substring match on headline", + "nullable": true }, - "engineVersion": { - "minLength": 1, + "revisionId": { "type": "string", - "description": "Detection engine version that emitted this transition" + "description": "Only runs for this published revision", + "format": "uuid", + "nullable": true }, - "checkId": { + "cursor": { "type": "string", - "description": "Scheduler-minted check execution ID (V92) of the triggering result", - "format": "uuid" + "description": "Opaque cursor from a previous page", + "nullable": true }, - "details": { - "$ref": "#/components/schemas/StateTransitionDetails" + "limit": { + "maximum": 100, + "minimum": 1, + "type": "integer", + "description": "Page size (1–100, default 25)", + "format": "int32" } }, - "description": "State-machine transitions this check caused (may be empty if nothing fired)" + "required": [ + "limit" + ] }, - "IncidentTimelineDto": { + "MonitorSecretRequestsDto": { "required": [ - "transitions", - "triggeringEvaluations" + "environment", + "requests" ], "type": "object", "properties": { - "transitions": { - "type": "array", - "description": "State-machine transitions in chronological order", - "items": { - "$ref": "#/components/schemas/IncidentStateTransitionDto" - } + "environment": { + "$ref": "#/components/schemas/EnvironmentDto" }, - "triggeringEvaluations": { + "requests": { "type": "array", - "description": "Rule evaluations that caused any of the transitions above. Correlate via evaluation.triggeringTransitionId == transition.id", + "description": "Secret keys this monitor requires and their resolve state", "items": { - "$ref": "#/components/schemas/RuleEvaluationDto" + "$ref": "#/components/schemas/SecretRequestDto" } - }, - "policySnapshot": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/PolicySnapshotDto" - } - ] } - } + }, + "description": "Environment and secret keys this monitor requires" }, - "IncidentTriggerDto": { + "MonitorSessionDto": { "required": [ - "source" + "cookieNames", + "lifecycle", + "reusePolicy", + "setupFile", + "storageKeys" ], "type": "object", "properties": { - "ruleType": { + "lifecycle": { "type": "string", - "description": "Trigger rule type (consecutive_failures, failures_in_window, response_time); null when unknown", - "nullable": true + "description": "Current session cache state", + "enum": [ + "active", + "expired", + "failed", + "revoked" + ] }, - "ruleIndex": { - "type": "integer", - "description": "0-based index into the policy trigger_rules array; null when unknown", - "format": "int32", + "reusePolicy": { + "type": "string", + "description": "When the cached session is reused across runs", + "enum": [ + "reuse", + "every_run", + "on_failure" + ] + }, + "setupFile": { + "type": "string", + "description": "Setup file path inside the package zip" + }, + "signsInAs": { + "type": "string", + "description": "Account this cache signed in as", "nullable": true }, - "count": { - "type": "integer", - "description": "Observed failing_streak or failures_in_window from forensics; null when unavailable", - "format": "int32", + "expiresAt": { + "type": "string", + "description": "When the cached session expires", + "format": "date-time", "nullable": true }, - "threshold": { + "cookieNames": { + "type": "array", + "description": "Cookie names in the cached session", + "items": { + "type": "string", + "description": "Cookie names in the cached session" + } + }, + "storageKeys": { + "type": "array", + "description": "Storage key names in the cached session", + "items": { + "type": "string", + "description": "Storage key names in the cached session" + } + }, + "sizeBytes": { "type": "integer", - "description": "Rule required count or threshold_ms from forensics; null when unavailable", + "description": "Cached session size in bytes", "format": "int32", "nullable": true }, - "lastError": { + "lastRejectedRunId": { "type": "string", - "description": "failure_reason from the triggering check result; null when unavailable", + "description": "Run that last rejected this cache", + "format": "uuid", "nullable": true }, - "firstFailedCheckAt": { + "updatedAt": { "type": "string", - "description": "Earliest failing check timestamp in the confirm window when computable; null otherwise", + "description": "When this session row was last written", "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" + "description": "Cached sign-in session for a monitor" }, - "IncidentUpdateDto": { - "required": [ - "createdAt", - "id", - "incidentId", - "notifySubscribers" - ], + "MonitorsSummaryDto": { "type": "object", "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "incidentId": { - "type": "string", - "format": "uuid" - }, - "oldStatus": { - "type": "string", - "nullable": true, - "enum": [ - "WATCHING", - "TRIGGERED", - "CONFIRMED", - "RESOLVED" - ] + "total": { + "type": "integer", + "description": "Total number of monitors in the organization", + "format": "int64" }, - "newStatus": { - "type": "string", - "nullable": true, - "enum": [ - "WATCHING", - "TRIGGERED", - "CONFIRMED", - "RESOLVED" - ] + "up": { + "type": "integer", + "description": "Number of monitors currently passing", + "format": "int64" }, - "body": { - "type": "string", - "nullable": true + "down": { + "type": "integer", + "description": "Number of monitors currently failing (DOWN severity)", + "format": "int64" }, - "createdBy": { - "type": "string", - "nullable": true, - "enum": [ - "SYSTEM", - "USER" - ] + "degraded": { + "type": "integer", + "description": "Number of monitors with degraded status", + "format": "int64" }, - "notifySubscribers": { - "type": "boolean" + "paused": { + "type": "integer", + "description": "Number of disabled monitors", + "format": "int64" }, - "createdAt": { - "type": "string", - "format": "date-time" - } - } - }, - "IntegrationConfigSchemaDto": { - "required": [ - "channelFields", - "connectionFields" - ], - "type": "object", - "properties": { - "connectionFields": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IntegrationFieldDto" - } + "avgUptime24h": { + "type": "number", + "description": "Average uptime percentage across all monitors over last 24h", + "format": "double", + "nullable": true }, - "channelFields": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IntegrationFieldDto" - } + "avgUptime30d": { + "type": "number", + "description": "Average uptime percentage across all monitors over last 30 days", + "format": "double", + "nullable": true } - } - }, - "IntegrationDto": { + }, + "description": "Dashboard summary counters for monitors", "required": [ - "authType", - "configSchema", - "description", - "lifecycle", - "logoUrl", - "name", - "setupGuideUrl", - "tierAvailability", + "total", + "up", + "down", + "degraded", + "paused" + ] + }, + "MonitorTestRequest": { + "required": [ + "config", "type" ], "type": "object", "properties": { "type": { - "type": "string" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "logoUrl": { - "type": "string" - }, - "authType": { - "type": "string" - }, - "tierAvailability": { "type": "string", + "description": "Monitor protocol type to test", "enum": [ - "FREE", - "STARTER", - "PRO", - "TEAM", - "BUSINESS", - "ENTERPRISE" + "HTTP", + "DNS", + "MCP_SERVER", + "TCP", + "ICMP", + "HEARTBEAT", + "BROWSER", + "MULTI_STEP_API" ] }, - "lifecycle": { - "type": "string" - }, - "setupGuideUrl": { - "type": "string" + "config": { + "oneOf": [ + { + "$ref": "#/components/schemas/DnsMonitorConfig" + }, + { + "$ref": "#/components/schemas/HeartbeatMonitorConfig" + }, + { + "$ref": "#/components/schemas/HttpMonitorConfig" + }, + { + "$ref": "#/components/schemas/IcmpMonitorConfig" + }, + { + "$ref": "#/components/schemas/McpServerMonitorConfig" + }, + { + "$ref": "#/components/schemas/ScriptMonitorConfig" + }, + { + "$ref": "#/components/schemas/TcpMonitorConfig" + } + ] }, - "configSchema": { - "$ref": "#/components/schemas/IntegrationConfigSchemaDto" + "assertions": { + "type": "array", + "description": "Optional assertions to evaluate against the test result", + "nullable": true, + "items": { + "$ref": "#/components/schemas/CreateAssertionRequest" + } } } }, - "IntegrationFieldDto": { + "MonitorTestResultDto": { "required": [ - "key", - "label", - "required", - "sensitive", - "type" + "assertionResults", + "passed" ], "type": "object", "properties": { - "key": { - "type": "string" + "passed": { + "type": "boolean" }, - "label": { - "type": "string" + "error": { + "type": "string", + "nullable": true }, - "type": { - "type": "string" + "statusCode": { + "type": "integer", + "format": "int32", + "nullable": true }, - "required": { - "type": "boolean" + "responseTimeMs": { + "type": "integer", + "format": "int64", + "nullable": true }, - "sensitive": { - "type": "boolean" + "responseHeaders": { + "type": "object", + "additionalProperties": { + "type": "array", + "nullable": true, + "items": { + "type": "string", + "nullable": true + } + }, + "nullable": true }, - "placeholder": { + "bodyPreview": { "type": "string", "nullable": true }, - "helpText": { + "responseSizeBytes": { + "type": "integer", + "format": "int64", + "nullable": true + }, + "redirectCount": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "finalUrl": { "type": "string", "nullable": true }, - "options": { + "assertionResults": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AssertionTestResultDto" + } + }, + "warnings": { "type": "array", "nullable": true, "items": { "type": "string" } - }, - "default": { - "type": "string", - "nullable": true } } }, - "InviteDto": { + "MonitorVersionDto": { "required": [ + "changedVia", "createdAt", - "email", - "expiresAt", - "roleOffered", - "inviteId" + "id", + "monitorId", + "snapshot", + "version" ], "type": "object", "properties": { - "inviteId": { + "id": { + "type": "string", + "description": "Unique version record identifier", + "format": "uuid" + }, + "monitorId": { + "type": "string", + "description": "Monitor this version belongs to", + "format": "uuid" + }, + "version": { "type": "integer", - "description": "Unique invite identifier", + "description": "Monotonically increasing version number", "format": "int32" }, - "email": { - "type": "string", - "description": "Email address the invite was sent to" + "snapshot": { + "$ref": "#/components/schemas/MonitorDto" }, - "roleOffered": { + "changedById": { + "type": "integer", + "description": "User ID who made the change; null for automated changes", + "format": "int32", + "nullable": true + }, + "changedVia": { "type": "string", - "description": "Role that will be assigned to the invitee on acceptance", + "description": "Change source (DASHBOARD, CLI, API)", "enum": [ - "OWNER", - "ADMIN", - "MEMBER" + "API", + "DASHBOARD", + "CLI", + "TERRAFORM" ] }, - "createdAt": { + "changeSummary": { "type": "string", - "description": "Timestamp when the invite was created", - "format": "date-time" + "description": "Human-readable description of what changed", + "nullable": true }, - "expiresAt": { + "createdAt": { "type": "string", - "description": "Timestamp when the invite expires", + "description": "Timestamp when this version was recorded", "format": "date-time" + } + }, + "description": "A point-in-time version snapshot of a monitor configuration" + }, + "NearestOtherRegion": { + "required": [ + "artifactId", + "region", + "runId" + ], + "type": "object", + "properties": { + "runId": { + "type": "string", + "description": "Run that holds the other-region shot", + "format": "uuid" }, - "consumedAt": { + "region": { "type": "string", - "description": "Timestamp when the invite was accepted; null if not yet used", - "format": "date-time", - "nullable": true + "description": "Region of that run" }, - "revokedAt": { + "artifactId": { "type": "string", - "description": "Timestamp when the invite was revoked; null if active", - "format": "date-time", - "nullable": true + "description": "Screenshot on that run", + "format": "uuid" } }, - "description": "Organization invite sent to an email address" + "description": "Prior pass of this step in another region" }, - "JiraChannelConfig": { + "NetworkRowDto": { "required": [ - "channelType", - "domain", - "email", - "apiToken", - "projectKey" + "curl", + "id", + "method", + "requestBody", + "requestHeaders", + "resourceType", + "responseBody", + "responseHeaders", + "source", + "url", + "isNavigation", + "requestBodyTruncated", + "responseBodyTruncated" ], "type": "object", "properties": { - "channelType": { + "id": { + "minLength": 1, "type": "string", - "enum": [ - "jira" - ] + "description": "Stable row id from capture" }, - "domain": { + "stepId": { + "type": "string", + "description": "Step this request belonged to", + "nullable": true + }, + "source": { "minLength": 1, "type": "string", - "description": "Atlassian instance domain (e.g. yourteam.atlassian.net)" + "description": "page for browser, request for API_CHECK" }, - "email": { + "method": { "minLength": 1, "type": "string", - "description": "Atlassian account email for API authentication" + "description": "HTTP method" }, - "apiToken": { + "url": { "minLength": 1, "type": "string", - "description": "Atlassian API token" + "description": "Request URL" }, - "projectKey": { + "resourceType": { "minLength": 1, "type": "string", - "description": "Jira project key where issues are created (e.g. OPS)" + "description": "Chromium type, or api for the request fixture" }, - "issueType": { + "isNavigation": { + "type": "boolean", + "description": "Whether this request started a navigation" + }, + "status": { + "type": "integer", + "description": "HTTP status; null while pending", + "format": "int32", + "nullable": true + }, + "durationMs": { + "type": "integer", + "description": "Request duration in milliseconds", + "format": "int32", + "nullable": true + }, + "encodedBodySize": { + "type": "integer", + "description": "Encoded response body size in bytes", + "format": "int32", + "nullable": true + }, + "startedOffsetMs": { + "type": "integer", + "description": "Offset from case start for the waterfall bar", + "format": "int32", + "nullable": true + }, + "failure": { "type": "string", - "description": "Issue type name (e.g. Bug, Task, Incident)", + "description": "Transport or protocol failure", "nullable": true - } - } - }, - "JsonPathAssertion": { - "required": [ - "type", - "path", - "expected", - "operator" - ], - "type": "object", - "properties": { - "type": { + }, + "redirectedFromUrl": { "type": "string", - "enum": [ - "json_path" + "description": "URL this request redirected from", + "nullable": true + }, + "timing": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimingDto" + } ] }, - "path": { - "minLength": 1, + "requestHeaders": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Redacted request headers" + }, + "description": "Redacted request headers" + }, + "responseHeaders": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Redacted response headers" + }, + "description": "Redacted response headers" + }, + "requestBody": { "type": "string", - "description": "JSONPath expression to extract a value from the response body" + "description": "Request body preview, truncated at 256 KiB" }, - "expected": { - "minLength": 1, + "responseBody": { "type": "string", - "description": "Expected value to compare against" + "description": "Response body preview, truncated at 256 KiB" }, - "operator": { + "requestBodyTruncated": { + "type": "boolean", + "description": "Whether requestBody was truncated" + }, + "responseBodyTruncated": { + "type": "boolean", + "description": "Whether responseBody was truncated" + }, + "curl": { + "minLength": 1, "type": "string", - "description": "Comparison operator (equals, contains, less_than, greater_than, etc.)", - "enum": [ - "equals", - "contains", - "less_than", - "greater_than", - "matches", - "range" - ] + "description": "Copy-as-cURL from the redacted record" + }, + "traceActionIndex": { + "type": "integer", + "description": "Playwright trace action index; null on API_CHECK", + "format": "int32", + "nullable": true } - } + }, + "description": "One waterfall request row" }, - "KeyInfo": { - "required": [ - "createdAt", - "name", - "id" - ], + "NetworkTimingDto": { "type": "object", "properties": { - "id": { + "dnsMs": { "type": "integer", - "description": "Key ID", - "format": "int32" + "description": "DNS lookup time in milliseconds", + "format": "int32", + "nullable": true }, - "name": { - "type": "string", - "description": "Human-readable key name" + "connectMs": { + "type": "integer", + "description": "TCP connect time in milliseconds", + "format": "int32", + "nullable": true }, - "createdAt": { - "type": "string", - "description": "When the key was created", - "format": "date-time" + "tlsMs": { + "type": "integer", + "description": "TLS handshake time in milliseconds", + "format": "int32", + "nullable": true }, - "expiresAt": { - "type": "string", - "description": "When the key expires (null = never)", - "format": "date-time", + "waitingMs": { + "type": "integer", + "description": "Time to first byte in milliseconds", + "format": "int32", "nullable": true }, - "lastUsedAt": { - "type": "string", - "description": "Last time the key was used", - "format": "date-time", + "transferMs": { + "type": "integer", + "description": "Response transfer time in milliseconds", + "format": "int32", "nullable": true } }, - "description": "API key metadata" + "description": "Request timing phases in milliseconds" }, - "LinearChannelConfig": { + "NewTagRequest": { "required": [ - "channelType", - "apiKey", - "teamId" + "name" ], "type": "object", "properties": { - "channelType": { - "type": "string", - "enum": [ - "linear" - ] - }, - "apiKey": { - "minLength": 1, - "type": "string", - "description": "Linear API key" - }, - "teamId": { - "minLength": 1, + "name": { + "maxLength": 100, + "minLength": 0, "type": "string", - "description": "Team ID to create issues in" + "description": "Tag name" }, - "labelId": { + "color": { + "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$", "type": "string", - "description": "Label ID to attach to created issues", + "description": "Hex color code (defaults to #6B7280 if omitted)", "nullable": true } - } + }, + "description": "Inline tag creation — creates the tag if it does not already exist" }, - "LinkedStatusPageIncidentDto": { - "required": [ - "connectionMode", - "id", - "impact", - "pageIncidentMode", - "spIncidentId", - "status", - "statusPageId", - "statusPageName", - "statusPageSlug", - "title", - "scheduled" - ], + "NoSlaContext": { "type": "object", "properties": { - "id": { - "type": "string", - "description": "Status page incident ID (same value as spIncidentId; kept for backwards compatibility)", - "format": "uuid" - }, - "spIncidentId": { - "type": "string", - "description": "Status page incident ID (alias for id) — use this when the outer context is a monitoring incident", - "format": "uuid" - }, - "statusPageId": { - "type": "string", - "description": "Parent status page ID", - "format": "uuid" - }, - "statusPageName": { - "type": "string", - "description": "Parent status page display name" - }, - "statusPageSlug": { - "type": "string", - "description": "Parent status page URL slug" - }, - "title": { - "type": "string", - "description": "Customer-facing incident title" - }, - "status": { - "type": "string", - "description": "Current lifecycle status (INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED)", - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] - }, - "impact": { - "type": "string", - "description": "Impact level (NONE, MINOR, MAJOR, CRITICAL)", - "enum": [ - "NONE", - "MINOR", - "MAJOR", - "CRITICAL" - ] - }, - "scheduled": { - "type": "boolean", - "description": "Scheduled maintenance flag" - }, - "publishedAt": { + "reason": { "type": "string", - "description": "Publish time; null while draft", - "format": "date-time", + "description": "Reason no SLA is published", "nullable": true }, - "connectionMode": { - "type": "string", - "description": "Whether the linked SPI was created by automation (AUTO) or by a human/API caller (MANUAL)", - "enum": [ - "AUTO", - "MANUAL" - ] - }, - "pageIncidentMode": { - "type": "string", - "description": "Incident mode of the parent status page at read time (MANUAL, REVIEW, AUTOMATIC)", - "enum": [ - "MANUAL", - "REVIEW", - "AUTOMATIC" - ] - } - } - }, - "MaintenanceComponentRef": { - "required": [ - "id", - "name", - "status" - ], - "type": "object", - "properties": { - "id": { + "historicalClaim": { "type": "string", - "description": "Component identifier", - "format": "uuid" + "description": "Non-binding historical uptime claim", + "nullable": true }, - "name": { + "supportSla": { "type": "string", - "description": "Component name" + "description": "Support response time SLA if different from uptime SLA", + "nullable": true }, - "status": { + "enterpriseNote": { "type": "string", - "description": "Component status at the time of the maintenance update" + "description": "Note about enterprise/custom SLA availability", + "nullable": true } }, - "description": "A component affected by a scheduled maintenance window" + "description": "Context for vendors with no public SLA" }, - "MaintenanceEventDto": { + "NotificationDispatchDto": { "required": [ - "externalId", - "maintenanceId", + "createdAt", + "deliveries", + "id", + "incidentId", + "policyId", "status", - "title" + "updatedAt", + "currentStep" ], "type": "object", "properties": { - "maintenanceId": { + "id": { "type": "string", - "description": "Vendor catalog maintenance ID", + "description": "Unique dispatch record identifier", "format": "uuid" }, - "externalId": { + "incidentId": { "type": "string", - "description": "Vendor-supplied external maintenance ID" + "description": "Incident this dispatch is for", + "format": "uuid" }, - "title": { + "incidentTitle": { "type": "string", - "description": "Maintenance title from the vendor status page" + "description": "Incident title at read time; null if untitled or missing", + "nullable": true }, - "status": { + "policyId": { "type": "string", - "description": "Lifecycle status: scheduled, in_progress, verifying, completed" + "description": "Notification policy that matched this incident", + "format": "uuid" }, - "impact": { + "policyName": { "type": "string", - "description": "Vendor impact level", + "description": "Human-readable name of the matched policy (null if policy has been deleted)", "nullable": true }, - "shortlink": { + "status": { "type": "string", - "description": "Short public URL for the vendor maintenance", + "description": "Current dispatch state", + "enum": [ + "PENDING", + "DISPATCHING", + "DELIVERED", + "ESCALATING", + "ACKNOWLEDGED", + "COMPLETED" + ] + }, + "completionReason": { + "type": "string", + "description": "Why the dispatch reached COMPLETED: EXHAUSTED (all steps ran, no ack), RESOLVED (incident resolved), NO_STEPS (policy had no steps). Null for non-terminal states.", + "nullable": true, + "enum": [ + "EXHAUSTED", + "RESOLVED", + "NO_STEPS" + ] + }, + "currentStep": { + "type": "integer", + "description": "1-based index of the currently active escalation step", + "format": "int32" + }, + "totalSteps": { + "type": "integer", + "description": "Total number of escalation steps in the policy (null if policy has been deleted)", + "format": "int32", "nullable": true }, - "scheduledFor": { + "acknowledgedAt": { "type": "string", - "description": "Scheduled start; null for undated maintenance", + "description": "Timestamp when this dispatch was acknowledged (null if not acknowledged)", "format": "date-time", "nullable": true }, - "scheduledUntil": { + "acknowledgedBy": { "type": "string", - "description": "Scheduled end", - "format": "date-time", + "description": "Actor who acknowledged this dispatch (user email, api-key:, voice:, etc.); null if not acknowledged", "nullable": true }, - "startedAt": { + "acknowledgedVia": { "type": "string", - "description": "When maintenance actually started", + "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)", "format": "date-time", "nullable": true }, - "completedAt": { + "lastNotifiedAt": { "type": "string", - "description": "When maintenance completed", + "description": "Timestamp of the most recent notification delivery", "format": "date-time", "nullable": true }, - "affectedComponentIds": { + "deliveries": { "type": "array", - "description": "Affected component IDs", - "nullable": true, + "description": "Delivery records for all channels associated with this dispatch", "items": { - "type": "string", - "description": "Affected component IDs", - "format": "uuid" + "$ref": "#/components/schemas/AlertDeliveryDto" } + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the dispatch was created", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "description": "Timestamp when the dispatch was last updated", + "format": "date-time" } }, - "description": "Vendor maintenance fields for a status-events rail row" + "description": "Dispatch state for a single (incident, notification policy) pair, with delivery history" }, - "MaintenanceUpdateDto": { + "NotificationDto": { "required": [ + "createdAt", + "title", + "type", "id", - "status" + "read" ], "type": "object", "properties": { "id": { + "type": "integer", + "description": "Unique notification identifier", + "format": "int64" + }, + "type": { "type": "string", - "description": "Unique update identifier", - "format": "uuid" + "description": "Notification category (e.g. incident, monitor, team)" }, - "status": { + "title": { "type": "string", - "description": "Status at the time of this update" + "description": "Short notification title" }, "body": { "type": "string", - "description": "Update message from the vendor", + "description": "Full notification body; null for title-only notifications", "nullable": true }, - "displayAt": { + "resourceType": { "type": "string", - "description": "Timestamp when this update was posted", - "format": "date-time", + "description": "Type of the resource this notification is about", + "nullable": true + }, + "resourceId": { + "type": "string", + "description": "ID of the resource this notification is about", "nullable": true + }, + "read": { + "type": "boolean", + "description": "Whether the notification has been read" + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the notification was created", + "format": "date-time" } }, - "description": "A status update within a scheduled maintenance lifecycle" + "description": "In-app notification for the current user" }, - "MaintenanceWindowDto": { + "NotificationPolicyDto": { "required": [ "createdAt", - "endsAt", + "escalation", "id", - "startsAt", + "matchRules", + "name", + "updatedAt", "organizationId", - "suppressAlerts" + "enabled", + "priority" ], "type": "object", "properties": { "id": { "type": "string", - "description": "Unique maintenance window identifier", + "description": "Unique notification policy identifier", "format": "uuid" }, - "monitorId": { - "type": "string", - "description": "Monitor this window applies to; null for org-wide windows", - "format": "uuid", - "nullable": true - }, "organizationId": { "type": "integer", - "description": "Organization this maintenance window belongs to", + "description": "Organization this policy belongs to", "format": "int32" }, - "startsAt": { - "type": "string", - "description": "Scheduled start of the maintenance window", - "format": "date-time" - }, - "endsAt": { + "name": { + "minLength": 1, "type": "string", - "description": "Scheduled end of the maintenance window", - "format": "date-time" + "description": "Human-readable name for this policy" }, - "repeatRule": { + "description": { "type": "string", - "description": "Reserved: iCal RRULE for recurring windows (stored but not yet honored)", + "description": "Optional note; null when unset", "nullable": true }, - "reason": { - "type": "string", - "description": "Human-readable reason for the maintenance", - "nullable": true + "matchRules": { + "type": "array", + "description": "Match rules (all must pass; empty = catch-all)", + "items": { + "$ref": "#/components/schemas/MatchRule" + } }, - "suppressAlerts": { + "escalation": { + "$ref": "#/components/schemas/EscalationChain" + }, + "enabled": { "type": "boolean", - "description": "Whether alerts are suppressed during this window" + "description": "Whether this policy is active" + }, + "priority": { + "type": "integer", + "description": "Evaluation order; higher value = evaluated first", + "format": "int32" }, "createdAt": { "type": "string", - "description": "Timestamp when the window was created", + "description": "Timestamp when the policy was created", "format": "date-time" - } - }, - "description": "Scheduled maintenance window for a monitor" - }, - "MatchRule": { - "required": [ - "type" - ], - "type": "object", - "properties": { - "type": { - "type": "string", - "description": "Rule type used to evaluate incidents and status events", - "enum": [ - "severity_gte", - "monitor_id_in", - "region_in", - "incident_status", - "monitor_type_in", - "service_id_in", - "resource_group_id_in", - "component_name_in", - "monitor_tag_in" - ] }, - "value": { + "updatedAt": { "type": "string", - "description": "Comparison value for single-value rules like severity_gte", - "nullable": true - }, - "monitorIds": { - "type": "array", - "description": "Monitor UUIDs to match for monitor_id_in rules", - "nullable": true, - "items": { - "type": "string", - "description": "Monitor UUIDs to match for monitor_id_in rules", - "format": "uuid" - } + "description": "Timestamp when the policy was last updated", + "format": "date-time" }, - "regions": { - "type": "array", - "description": "Region codes to match for region_in rules", + "stats7d": { "nullable": true, - "items": { - "type": "string", - "description": "Region codes to match for region_in rules" - } + "allOf": [ + { + "$ref": "#/components/schemas/NotificationPolicyWindowStatsDto" + } + ] }, - "values": { - "type": "array", - "description": "Values list for multi-value rules like monitor_type_in", + "stats30d": { "nullable": true, - "items": { - "type": "string", - "description": "Values list for multi-value rules like monitor_type_in" - } - } - }, - "description": "Match rules to evaluate (all must pass; omit or empty for catch-all)" - }, - "MattermostChannelConfig": { - "required": [ - "channelType", - "webhookUrl" - ], - "type": "object", - "properties": { - "channelType": { - "type": "string", - "enum": [ - "mattermost" + "allOf": [ + { + "$ref": "#/components/schemas/NotificationPolicyWindowStatsDto" + } ] }, - "webhookUrl": { - "minLength": 1, - "type": "string", - "description": "Mattermost incoming webhook URL" - }, - "channel": { + "lastFiredAt": { "type": "string", - "description": "Override channel (if webhook allows)", + "description": "Created-at of the most recent dispatch for this policy; null if never fired", + "format": "date-time", "nullable": true }, - "iconUrl": { + "lastFiredIncidentId": { "type": "string", - "description": "Custom bot icon URL", + "description": "Incident id of the most recent dispatch; null if never fired", + "format": "uuid", "nullable": true } - } - }, - "McpConnectsAssertion": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "mcp_connects" - ] - } }, - "required": [ - "type" - ] + "description": "Org-level notification policy with match rules and escalation chain" }, - "McpHasCapabilityAssertion": { + "NotificationPolicyWindowStatsDto": { "required": [ - "type", - "capability" + "ackableFires", + "acknowledgements", + "expired", + "failedSends", + "fires", + "sends" ], "type": "object", "properties": { - "type": { - "type": "string", - "enum": [ - "mcp_has_capability" - ] - }, - "capability": { - "minLength": 1, - "type": "string", - "description": "Capability name the server must advertise, e.g. tools or resources" - } - } - }, - "McpMinToolsAssertion": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "mcp_min_tools" - ] - }, - "min": { + "fires": { "type": "integer", - "description": "Minimum number of tools the server must expose", + "description": "Dispatches created in the window", "format": "int32" - } - }, - "required": [ - "type", - "min" - ] - }, - "McpProtocolVersionAssertion": { - "required": [ - "type", - "version" - ], - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "mcp_protocol_version" - ] }, - "version": { - "minLength": 1, - "type": "string", - "description": "Expected MCP protocol version string from the server handshake" - } - } - }, - "McpResponseTimeAssertion": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "mcp_response_time" - ] + "acknowledgements": { + "type": "integer", + "description": "Fires in the window that were acknowledged", + "format": "int32" }, - "maxMs": { + "ackableFires": { "type": "integer", - "description": "Maximum allowed MCP check duration in milliseconds", + "description": "Ack ratio denominator: fires when the policy has an ack gate, else 0", "format": "int32" - } - }, - "required": [ - "type", - "maxMs" - ] - }, - "McpResponseTimeWarnAssertion": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "mcp_response_time_warn" - ] }, - "warnMs": { + "expired": { "type": "integer", - "description": "MCP check duration in milliseconds that triggers a warning only", + "description": "Fires that exhausted escalation without acknowledgment", "format": "int32" - } - }, - "required": [ - "type", - "warnMs" - ] - }, - "McpServer": { - "type": "object", - "description": "MCP server check-type-specific details", - "properties": { - "check_type": { - "type": "string", - "enum": [ - "mcp_server" - ] }, - "url": { - "type": "string", - "description": "MCP server URL", - "nullable": true + "sends": { + "type": "integer", + "description": "Alert deliveries linked to fires in the window", + "format": "int32" }, - "protocolVersion": { - "type": "string", - "description": "MCP protocol version", - "nullable": true + "failedSends": { + "type": "integer", + "description": "Linked deliveries with status FAILED", + "format": "int32" }, - "serverInfo": { - "type": "object", - "additionalProperties": { - "type": "object", - "description": "MCP server info (name, version, etc.)", - "nullable": true - }, - "description": "MCP server info (name, version, etc.)", + "medianAckSeconds": { + "type": "integer", + "description": "Median seconds from fire to ack among acknowledged fires; null when none", + "format": "int64", "nullable": true }, - "toolCount": { + "deepestStepReached": { "type": "integer", - "description": "Number of tools exposed", + "description": "Highest escalation step reached in the window; null when no fires", "format": "int32", "nullable": true }, - "resourceCount": { - "type": "integer", - "description": "Number of resources exposed", - "format": "int32", + "lastFiredAt": { + "type": "string", + "description": "Created-at of the most recent fire in the window; null when none", + "format": "date-time", "nullable": true }, - "promptCount": { - "type": "integer", - "description": "Number of prompts exposed", - "format": "int32", + "lastFiredIncidentId": { + "type": "string", + "description": "Incident id of the most recent fire in the window; null when none", + "format": "uuid", "nullable": true } }, - "required": [ - "check_type" - ] + "description": "Time-bounded notification policy activity aggregates" }, - "McpServerMonitorConfig": { - "required": [ - "command" - ], + "OfficialSla": { "type": "object", "properties": { - "command": { - "minLength": 1, + "percentage": { "type": "string", - "description": "Command to execute to start the MCP server" + "description": "Advertised uptime percentage, e.g. '99.99%'", + "nullable": true }, - "args": { + "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": "Command-line arguments for the MCP server process", + "description": "Plan names this SLA applies to, e.g. ['Enterprise']", "nullable": true, "items": { "type": "string", - "description": "Command-line arguments for the MCP server process", - "nullable": true + "description": "Plan names this SLA applies to, e.g. ['Enterprise']" } }, - "env": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Environment variables to pass to the MCP server process", - "nullable": true - }, - "description": "Environment variables to pass to the MCP server process", + "notCovered": { + "type": "string", + "description": "Services/components NOT covered by the SLA", "nullable": true } - } + }, + "description": "The vendor's officially advertised SLA commitment" }, - "McpToolAvailableAssertion": { + "OpsGenieChannelConfig": { "required": [ - "type", - "toolName" + "channelType", + "apiKey" ], "type": "object", "properties": { - "type": { + "channelType": { "type": "string", "enum": [ - "mcp_tool_available" + "opsgenie" ] }, - "toolName": { + "apiKey": { "minLength": 1, "type": "string", - "description": "MCP tool name that must appear in the server's tool list" - } - } - }, - "McpToolCountChangedAssertion": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "mcp_tool_count_changed" - ] + "description": "OpsGenie API key for alert creation" }, - "expectedCount": { - "type": "integer", - "description": "Expected tool count; warns when the live count differs", - "format": "int32" + "region": { + "type": "string", + "description": "OpsGenie API region: us or eu", + "nullable": true } - }, - "required": [ - "type", - "expectedCount" - ] + } }, - "MemberDto": { + "OrganizationDto": { "required": [ - "createdAt", "email", - "orgRole", - "status", - "userId" + "name", + "id" ], "type": "object", "properties": { - "userId": { + "id": { "type": "integer", - "description": "User identifier of the member", + "description": "Unique organization identifier", "format": "int32" }, - "email": { + "name": { "type": "string", - "description": "Member email address" + "description": "Organization name" }, - "name": { + "email": { "type": "string", - "description": "Member display name; null if not set", + "description": "Billing and contact email", "nullable": true }, - "orgRole": { + "size": { "type": "string", - "description": "Member role within this organization (OWNER, ADMIN, MEMBER)", - "enum": [ - "OWNER", - "ADMIN", - "MEMBER" - ] + "description": "Team size range (e.g. 1-10, 11-50)", + "nullable": true }, - "status": { + "industry": { "type": "string", - "description": "Membership status (ACTIVE, PENDING, SUSPENDED)", - "enum": [ - "INVITED", - "ACTIVE", - "SUSPENDED", - "LEFT", - "REMOVED", - "DECLINED" - ] + "description": "Industry vertical (e.g. SaaS, Fintech)", + "nullable": true }, - "createdAt": { + "websiteUrl": { "type": "string", - "description": "Timestamp when the member was added to the organization", - "format": "date-time" + "description": "Organization website URL", + "nullable": true } }, - "description": "Organization member with role and status" - }, - "MemberRoleChangedMetadata": { - "required": [ - "kind", - "oldRole", - "newRole" - ], - "type": "object", - "description": "Role transition recorded when an organization member's role changes.", - "properties": { - "kind": { - "type": "string", - "enum": [ - "member_role_changed" - ] - }, - "oldRole": { - "type": "string", - "description": "Role the member held before the change", - "enum": [ - "OWNER", - "ADMIN", - "MEMBER" - ] - }, - "newRole": { - "type": "string", - "description": "Role the member holds after the change", - "enum": [ - "OWNER", - "ADMIN", - "MEMBER" - ] - } - } + "description": "Organization account details" }, - "MonitorAssertionDto": { + "OrgIncidentAnnotationDto": { "required": [ - "assertionType", - "config", - "id", - "monitorId", - "severity" + "incidentId", + "severity", + "status", + "alerted" ], "type": "object", "properties": { - "id": { + "incidentId": { "type": "string", + "description": "Internal org incident ID", "format": "uuid" }, - "monitorId": { + "displayKey": { "type": "string", - "format": "uuid" + "description": "Human display key (e.g. DEV-42); null until platform INC codes ship", + "nullable": true }, - "assertionType": { + "status": { "type": "string", + "description": "Internal incident lifecycle status", "enum": [ - "status_code", - "response_time", - "body_contains", - "json_path", - "header_value", - "regex_body", - "dns_resolves", - "dns_response_time", - "dns_expected_ips", - "dns_expected_cname", - "dns_record_contains", - "dns_record_equals", - "dns_txt_contains", - "dns_min_answers", - "dns_max_answers", - "dns_response_time_warn", - "dns_ttl_low", - "dns_ttl_high", - "mcp_connects", - "mcp_response_time", - "mcp_has_capability", - "mcp_tool_available", - "mcp_min_tools", - "mcp_protocol_version", - "mcp_response_time_warn", - "mcp_tool_count_changed", - "ssl_expiry", - "response_size", - "redirect_count", - "redirect_target", - "response_time_warn", - "tcp_connects", - "tcp_response_time", - "tcp_response_time_warn", - "icmp_reachable", - "icmp_response_time", - "icmp_response_time_warn", - "icmp_packet_loss", - "heartbeat_received", - "heartbeat_max_interval", - "heartbeat_interval_drift", - "heartbeat_payload_contains" - ] - }, - "config": { - "oneOf": [ - { - "$ref": "#/components/schemas/BodyContainsAssertion" - }, - { - "$ref": "#/components/schemas/DnsExpectedCnameAssertion" - }, - { - "$ref": "#/components/schemas/DnsExpectedIpsAssertion" - }, - { - "$ref": "#/components/schemas/DnsMaxAnswersAssertion" - }, - { - "$ref": "#/components/schemas/DnsMinAnswersAssertion" - }, - { - "$ref": "#/components/schemas/DnsRecordContainsAssertion" - }, - { - "$ref": "#/components/schemas/DnsRecordEqualsAssertion" - }, - { - "$ref": "#/components/schemas/DnsResolvesAssertion" - }, - { - "$ref": "#/components/schemas/DnsResponseTimeAssertion" - }, - { - "$ref": "#/components/schemas/DnsResponseTimeWarnAssertion" - }, - { - "$ref": "#/components/schemas/DnsTtlHighAssertion" - }, - { - "$ref": "#/components/schemas/DnsTtlLowAssertion" - }, - { - "$ref": "#/components/schemas/DnsTxtContainsAssertion" - }, - { - "$ref": "#/components/schemas/HeaderValueAssertion" - }, - { - "$ref": "#/components/schemas/HeartbeatIntervalDriftAssertion" - }, - { - "$ref": "#/components/schemas/HeartbeatMaxIntervalAssertion" - }, - { - "$ref": "#/components/schemas/HeartbeatPayloadContainsAssertion" - }, - { - "$ref": "#/components/schemas/HeartbeatReceivedAssertion" - }, - { - "$ref": "#/components/schemas/IcmpPacketLossAssertion" - }, - { - "$ref": "#/components/schemas/IcmpReachableAssertion" - }, - { - "$ref": "#/components/schemas/IcmpResponseTimeAssertion" - }, - { - "$ref": "#/components/schemas/IcmpResponseTimeWarnAssertion" - }, - { - "$ref": "#/components/schemas/JsonPathAssertion" - }, - { - "$ref": "#/components/schemas/McpConnectsAssertion" - }, - { - "$ref": "#/components/schemas/McpHasCapabilityAssertion" - }, - { - "$ref": "#/components/schemas/McpMinToolsAssertion" - }, - { - "$ref": "#/components/schemas/McpProtocolVersionAssertion" - }, - { - "$ref": "#/components/schemas/McpResponseTimeAssertion" - }, - { - "$ref": "#/components/schemas/McpResponseTimeWarnAssertion" - }, - { - "$ref": "#/components/schemas/McpToolAvailableAssertion" - }, - { - "$ref": "#/components/schemas/McpToolCountChangedAssertion" - }, - { - "$ref": "#/components/schemas/RedirectCountAssertion" - }, - { - "$ref": "#/components/schemas/RedirectTargetAssertion" - }, - { - "$ref": "#/components/schemas/RegexBodyAssertion" - }, - { - "$ref": "#/components/schemas/ResponseSizeAssertion" - }, - { - "$ref": "#/components/schemas/ResponseTimeAssertion" - }, - { - "$ref": "#/components/schemas/ResponseTimeWarnAssertion" - }, - { - "$ref": "#/components/schemas/SslExpiryAssertion" - }, - { - "$ref": "#/components/schemas/StatusCodeAssertion" - }, - { - "$ref": "#/components/schemas/TcpConnectsAssertion" - }, - { - "$ref": "#/components/schemas/TcpResponseTimeAssertion" - }, - { - "$ref": "#/components/schemas/TcpResponseTimeWarnAssertion" - } + "WATCHING", + "TRIGGERED", + "CONFIRMED", + "RESOLVED" ] }, "severity": { "type": "string", + "description": "Internal incident severity", "enum": [ - "fail", - "warn" + "DOWN", + "DEGRADED", + "MAINTENANCE" ] - } - } - }, - "MonitorAuthConfig": { - "description": "New authentication configuration (full replacement)", - "discriminator": { - "propertyName": "type", - "mapping": { - "bearer": "#/components/schemas/BearerAuthConfig", - "basic": "#/components/schemas/BasicAuthConfig", - "header": "#/components/schemas/HeaderAuthConfig", - "api_key": "#/components/schemas/ApiKeyAuthConfig" - } - }, - "oneOf": [ - { - "$ref": "#/components/schemas/BearerAuthConfig" - }, - { - "$ref": "#/components/schemas/BasicAuthConfig" }, - { - "$ref": "#/components/schemas/HeaderAuthConfig" + "alerted": { + "type": "boolean", + "description": "Whether alert channels were eligible to fire (false for AWARENESS silent tracking)" }, - { - "$ref": "#/components/schemas/ApiKeyAuthConfig" + "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" }, - "MonitorAuthDto": { + "OrgInfo": { "required": [ - "authType", - "config", - "id", - "monitorId" + "name", + "id" ], "type": "object", "properties": { "id": { - "type": "string", - "format": "uuid" - }, - "monitorId": { - "type": "string", - "format": "uuid" + "type": "integer", + "description": "Organization ID", + "format": "int32" }, - "authType": { + "name": { "type": "string", - "enum": [ - "bearer", - "basic", - "header", - "api_key" - ] - }, - "config": { - "oneOf": [ - { - "$ref": "#/components/schemas/ApiKeyAuthConfig" - }, - { - "$ref": "#/components/schemas/BasicAuthConfig" - }, - { - "$ref": "#/components/schemas/BearerAuthConfig" - }, - { - "$ref": "#/components/schemas/HeaderAuthConfig" - } - ] + "description": "Organization name" } - } + }, + "description": "Organization the key belongs to" }, - "MonitorDto": { + "OverviewStepCellDto": { "required": [ - "config", - "createdAt", "id", - "managedBy", - "name", - "regions", - "type", - "updatedAt", - "organizationId", - "frequencySeconds", - "enabled" + "outcome" ], "type": "object", "properties": { "id": { "type": "string", - "description": "Unique monitor identifier", - "format": "uuid" - }, - "organizationId": { - "type": "integer", - "description": "Organization this monitor belongs to", - "format": "int32" + "description": "Stable cell id" }, - "name": { + "outcome": { "minLength": 1, "type": "string", - "description": "Human-readable name for this monitor" - }, - "type": { - "type": "string", - "enum": [ - "HTTP", - "DNS", - "MCP_SERVER", - "TCP", - "ICMP", - "HEARTBEAT", - "BROWSER", - "MULTI_STEP_API" - ] - }, - "config": { - "oneOf": [ - { - "$ref": "#/components/schemas/DnsMonitorConfig" - }, - { - "$ref": "#/components/schemas/HeartbeatMonitorConfig" - }, - { - "$ref": "#/components/schemas/HttpMonitorConfig" - }, - { - "$ref": "#/components/schemas/IcmpMonitorConfig" - }, - { - "$ref": "#/components/schemas/McpServerMonitorConfig" - }, - { - "$ref": "#/components/schemas/ScriptMonitorConfig" - }, - { - "$ref": "#/components/schemas/TcpMonitorConfig" - } - ] + "description": "Step outcome for that run" }, - "frequencySeconds": { + "at": { + "type": "string", + "description": "When that step settled", + "nullable": true + } + }, + "description": "One cell on the overview step last-30 strip" + }, + "OverviewStepDto": { + "required": [ + "cells", + "name", + "index", + "failed" + ], + "type": "object", + "properties": { + "index": { "type": "integer", - "description": "Check frequency in seconds (30–86400)", + "description": "0-based step index from the Head revision catalog", "format": "int32" }, - "enabled": { - "type": "boolean", - "description": "Whether the monitor is active" + "name": { + "minLength": 1, + "type": "string", + "description": "Step title from the Head revision catalog" }, - "regions": { - "type": "array", - "description": "Probe regions where checks are executed", - "items": { - "type": "string", - "description": "Probe regions where checks are executed" - } + "p50Ms": { + "type": "number", + "description": "Median duration in ms; null until the step has settled timings", + "format": "double", + "nullable": true }, - "managedBy": { - "type": "string", - "description": "Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API", - "enum": [ - "DASHBOARD", - "CLI", - "TERRAFORM", - "MCP", - "API" - ] + "p95Ms": { + "type": "number", + "description": "p95 duration in ms; null until the step has settled timings", + "format": "double", + "nullable": true }, - "createdAt": { - "type": "string", - "description": "Timestamp when the monitor was created", - "format": "date-time" + "failed": { + "type": "integer", + "description": "Failed first-attempt count in the window", + "format": "int64" }, - "updatedAt": { - "type": "string", - "description": "Timestamp when the monitor was last updated", - "format": "date-time" + "firstTryPercent": { + "type": "number", + "description": "First-try pass percent for this step; null when no settled attempts", + "format": "double", + "nullable": true }, - "assertions": { - "type": "array", - "description": "Assertions evaluated against each check result; null on list responses", - "nullable": true, - "items": { - "$ref": "#/components/schemas/MonitorAssertionDto" - } + "flakeRetries": { + "type": "integer", + "description": "Retry attempts on this step; null when none", + "format": "int32", + "nullable": true }, - "tags": { + "cells": { "type": "array", - "description": "Tags applied to this monitor", - "nullable": true, + "description": "Last 30 outcomes for this step, oldest first", "items": { - "$ref": "#/components/schemas/TagDto" + "$ref": "#/components/schemas/OverviewStepCellDto" } }, - "pingUrl": { + "expected": { "type": "string", - "description": "Heartbeat ping URL; populated for HEARTBEAT monitors only", + "description": "Assertion expected from the latest failure", "nullable": true }, - "environment": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/Summary" - } - ] + "received": { + "type": "string", + "description": "Assertion received from the latest failure", + "nullable": true }, - "auth": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/MonitorAuthConfig" - } - ] + "error": { + "type": "string", + "description": "Error text from the latest failure", + "nullable": true }, - "incidentPolicy": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/IncidentPolicyDto" - } - ] + "region": { + "type": "string", + "description": "Region of the latest failure", + "nullable": true }, - "alertChannelIds": { + "failedAt": { + "type": "string", + "description": "When the latest failure settled", + "nullable": true + }, + "latestFailedRunId": { + "type": "string", + "description": "Run that produced the latest failure", + "format": "uuid", + "nullable": true + } + }, + "description": "One catalog step on the monitor overview table" + }, + "OverviewStepsDto": { + "required": [ + "steps" + ], + "type": "object", + "properties": { + "steps": { "type": "array", - "description": "Alert channel IDs linked to this monitor; populated on single-monitor responses", - "nullable": true, + "description": "Rows in revision order; empty when the monitor has no step catalog", "items": { - "type": "string", - "description": "Alert channel IDs linked to this monitor; populated on single-monitor responses", - "format": "uuid" + "$ref": "#/components/schemas/OverviewStepDto" } - }, - "currentStatus": { - "type": "string", - "description": "Current operational state — UP, DOWN, DEGRADED, PAUSED, or UNKNOWN if no probe data yet", - "nullable": true, - "enum": [ - "up", - "degraded", - "down", - "paused", - "unknown" - ] } }, - "description": "Full monitor representation" + "description": "Overview step catalog joined to run-step aggregates" }, - "MonitorReference": { + "PackageUploadDto": { "required": [ - "id", - "name" + "expiresAt", + "putUrl", + "requiredHeaders" ], "type": "object", "properties": { - "id": { + "putUrl": { + "minLength": 1, "type": "string", - "description": "Monitor identifier", - "format": "uuid" + "description": "Presigned PUT URL for the zip bytes" }, - "name": { + "expiresAt": { "type": "string", - "description": "Monitor name" + "description": "When the signed URL expires", + "format": "date-time" + }, + "requiredHeaders": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Must send Content-Type: application/zip and If-None-Match: *" + }, + "description": "Must send Content-Type: application/zip and If-None-Match: *" } }, - "description": "Monitors that reference this secret; null on create/update responses" + "description": "Signed package upload target" }, - "MonitorsSummaryDto": { + "Pageable": { "type": "object", "properties": { - "total": { - "type": "integer", - "description": "Total number of monitors in the organization", - "format": "int64" - }, - "up": { - "type": "integer", - "description": "Number of monitors currently passing", - "format": "int64" - }, - "down": { - "type": "integer", - "description": "Number of monitors currently failing (DOWN severity)", - "format": "int64" - }, - "degraded": { + "page": { + "minimum": 0, "type": "integer", - "description": "Number of monitors with degraded status", - "format": "int64" + "format": "int32" }, - "paused": { + "size": { + "minimum": 1, "type": "integer", - "description": "Number of disabled monitors", - "format": "int64" - }, - "avgUptime24h": { - "type": "number", - "description": "Average uptime percentage across all monitors over last 24h", - "format": "double", - "nullable": true + "format": "int32" }, - "avgUptime30d": { - "type": "number", - "description": "Average uptime percentage across all monitors over last 30 days", - "format": "double", - "nullable": true + "sort": { + "type": "array", + "items": { + "type": "string" + } } }, - "description": "Dashboard summary counters for monitors", "required": [ - "total", - "up", - "down", - "degraded", - "paused" + "page", + "size", + "sort" ] }, - "MonitorTestRequest": { + "PagerDutyChannelConfig": { "required": [ - "config", - "type" + "channelType", + "routingKey" ], "type": "object", "properties": { - "type": { + "channelType": { "type": "string", - "description": "Monitor protocol type to test", "enum": [ - "HTTP", - "DNS", - "MCP_SERVER", - "TCP", - "ICMP", - "HEARTBEAT", - "BROWSER", - "MULTI_STEP_API" + "pagerduty" ] }, - "config": { - "oneOf": [ - { - "$ref": "#/components/schemas/DnsMonitorConfig" - }, - { - "$ref": "#/components/schemas/HeartbeatMonitorConfig" - }, - { - "$ref": "#/components/schemas/HttpMonitorConfig" - }, - { - "$ref": "#/components/schemas/IcmpMonitorConfig" - }, - { - "$ref": "#/components/schemas/McpServerMonitorConfig" - }, - { - "$ref": "#/components/schemas/ScriptMonitorConfig" - }, - { - "$ref": "#/components/schemas/TcpMonitorConfig" - } - ] + "routingKey": { + "minLength": 1, + "type": "string", + "description": "PagerDuty Events API v2 routing (integration) key" }, - "assertions": { - "type": "array", - "description": "Optional assertions to evaluate against the test result", - "nullable": true, - "items": { - "$ref": "#/components/schemas/CreateAssertionRequest" - } + "severityOverride": { + "type": "string", + "description": "Override PagerDuty severity mapping", + "nullable": true } } }, - "MonitorTestResultDto": { - "required": [ - "assertionResults", - "passed" - ], + "PageSection": { "type": "object", "properties": { - "passed": { - "type": "boolean" - }, - "error": { + "groupId": { "type": "string", + "description": "Group ID when this section is a group", + "format": "uuid", "nullable": true }, - "statusCode": { - "type": "integer", - "format": "int32", + "componentId": { + "type": "string", + "description": "Component ID when this section is an ungrouped component", + "format": "uuid", "nullable": true }, - "responseTimeMs": { + "pageOrder": { "type": "integer", - "format": "int64", - "nullable": true - }, - "responseHeaders": { - "type": "object", - "additionalProperties": { - "type": "array", - "nullable": true, - "items": { - "type": "string", - "nullable": true - } - }, - "nullable": true + "description": "Position on the page (0-based)", + "format": "int32" + } + }, + "description": "A top-level page section (either a group or an ungrouped component)", + "required": [ + "pageOrder" + ] + }, + "PhoneCallChannelConfig": { + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "phone_call" + ] }, - "bodyPreview": { + "phoneNumber": { "type": "string", + "description": "Recipient phone number in E.164 format, e.g. +14155550123", "nullable": true }, - "responseSizeBytes": { + "verifiedPhoneNumberId": { "type": "integer", + "description": "Id of an org verified_phone_number row; alternative to phoneNumber", "format": "int64", "nullable": true }, - "redirectCount": { - "type": "integer", - "format": "int32", - "nullable": true - }, - "finalUrl": { - "type": "string", - "nullable": true - }, - "assertionResults": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AssertionTestResultDto" - } - }, - "warnings": { + "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" + "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" + ] }, - "MonitorVersionDto": { + "PickerItem": { "required": [ - "changedVia", - "createdAt", - "id", - "monitorId", - "snapshot", - "version" + "finishedAt", + "revisionId", + "runId" ], "type": "object", "properties": { - "id": { + "runId": { "type": "string", - "description": "Unique version record identifier", + "description": "Finished run identifier", "format": "uuid" }, - "monitorId": { + "revisionId": { "type": "string", - "description": "Monitor this version belongs to", + "description": "Revision that run executed", "format": "uuid" }, - "version": { - "type": "integer", - "description": "Monotonically increasing version number", - "format": "int32" + "finishedAt": { + "type": "string", + "description": "When that run finished", + "format": "date-time" + } + }, + "description": "Finished run offered as an alternate baseline" + }, + "PlanInfo": { + "required": [ + "entitlements", + "tier", + "usage", + "trialActive" + ], + "type": "object", + "properties": { + "tier": { + "type": "string", + "description": "Resolved plan tier", + "enum": [ + "FREE", + "STARTER", + "PRO", + "TEAM", + "BUSINESS", + "ENTERPRISE" + ] }, - "snapshot": { - "$ref": "#/components/schemas/MonitorDto" + "subscriptionStatus": { + "type": "string", + "description": "Subscription status (null if no subscription)", + "nullable": true }, - "changedById": { - "type": "integer", - "description": "User ID who made the change; null for automated changes", - "format": "int32", + "trialActive": { + "type": "boolean", + "description": "Whether the org is on a trial" + }, + "trialExpiresAt": { + "type": "string", + "description": "Trial expiry (null if not trialing)", + "format": "date-time", "nullable": true }, - "changedVia": { + "entitlements": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/EntitlementDto" + }, + "description": "Entitlement limits keyed by entitlement name" + }, + "usage": { + "type": "object", + "additionalProperties": { + "type": "integer", + "description": "Current usage counters keyed by entitlement name", + "format": "int64" + }, + "description": "Current usage counters keyed by entitlement name" + } + }, + "description": "Billing plan and entitlement state" + }, + "PolicySnapshotDto": { + "required": [ + "engineVersion", + "firstSeenAt", + "hashHex", + "lastSeenAt", + "policy" + ], + "type": "object", + "properties": { + "hashHex": { + "minLength": 1, "type": "string", - "description": "Change source (DASHBOARD, CLI, API)", - "enum": [ - "API", - "DASHBOARD", - "CLI", - "TERRAFORM" - ] + "description": "Hex-encoded SHA-256 of the canonical policy JSON" }, - "changeSummary": { + "policy": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Canonical policy document (snake_case, sorted keys)" + }, + "description": "Canonical policy document (snake_case, sorted keys)" + }, + "engineVersion": { + "minLength": 1, "type": "string", - "description": "Human-readable description of what changed", - "nullable": true + "description": "Detection engine version that observed this policy" }, - "createdAt": { + "firstSeenAt": { "type": "string", - "description": "Timestamp when this version was recorded", + "description": "First time the detection engine evaluated against this policy bytes", + "format": "date-time" + }, + "lastSeenAt": { + "type": "string", + "description": "Most recent time the engine evaluated against this policy bytes", "format": "date-time" } }, - "description": "A point-in-time version snapshot of a monitor configuration" + "description": "Policy snapshot used during this check (all evaluations of a single check are against one policy)", + "nullable": true }, - "NewTagRequest": { + "PollChartBucketDto": { "required": [ - "name" + "bucket", + "totalPolls" ], "type": "object", "properties": { - "name": { - "maxLength": 100, - "minLength": 0, + "bucket": { "type": "string", - "description": "Tag name" + "description": "Start of the time bucket (ISO 8601)", + "format": "date-time" }, - "color": { - "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$", - "type": "string", - "description": "Hex color code (defaults to #6B7280 if omitted)", - "nullable": true + "uptimePercent": { + "type": "number", + "description": "Uptime percentage for this bucket; null when no data", + "format": "double", + "nullable": true, + "example": 100 + }, + "avgResponseTimeMs": { + "type": "number", + "description": "Average response time in milliseconds for this bucket", + "format": "double", + "nullable": true, + "example": 245.3 + }, + "totalPolls": { + "type": "integer", + "description": "Total polls in this bucket", + "format": "int64", + "example": 60 } }, - "description": "Inline tag creation — creates the tag if it does not already exist" + "description": "Aggregated poll metrics for a time bucket" }, - "NoSlaContext": { + "PricingTier": { + "required": [ + "name" + ], "type": "object", "properties": { - "reason": { - "type": "string", - "description": "Reason no SLA is published", - "nullable": true - }, - "historicalClaim": { + "name": { "type": "string", - "description": "Non-binding historical uptime claim", - "nullable": true + "description": "Tier name, e.g. 'Free', 'Pro', 'Enterprise'" }, - "supportSla": { + "slaPercentage": { "type": "string", - "description": "Support response time SLA if different from uptime SLA", + "description": "SLA percentage for this tier, e.g. '99.9%'", "nullable": true }, - "enterpriseNote": { + "priceFrom": { "type": "string", - "description": "Note about enterprise/custom SLA availability", + "description": "Starting price, e.g. '$0', '$25/mo', 'Custom'", "nullable": true } }, - "description": "Context for vendors with no public SLA" + "description": "Pricing tiers with associated SLA levels" }, - "NotificationDispatchDto": { + "PublishRevisionRequest": { "required": [ - "createdAt", - "deliveries", - "id", - "incidentId", - "policyId", - "status", - "updatedAt", - "currentStep" + "revisionId" ], "type": "object", "properties": { - "id": { - "type": "string", - "description": "Unique dispatch record identifier", - "format": "uuid" - }, - "incidentId": { + "revisionId": { "type": "string", - "description": "Incident this dispatch is for", - "format": "uuid" - }, - "incidentTitle": { - "type": "string", - "description": "Incident title at read time; null if untitled or missing", - "nullable": true - }, - "policyId": { - "type": "string", - "description": "Notification policy that matched this incident", + "description": "Existing revision to activate as Head for this monitor's environment", "format": "uuid" - }, - "policyName": { + } + } + }, + "PublishStatusPageIncidentRequest": { + "type": "object", + "properties": { + "title": { + "maxLength": 500, + "minLength": 0, "type": "string", - "description": "Human-readable name of the matched policy (null if policy has been deleted)", + "description": "Customer-facing title; null keeps draft value", "nullable": true }, - "status": { + "impact": { "type": "string", - "description": "Current dispatch state", + "description": "Impact level; null keeps draft value", + "nullable": true, "enum": [ - "PENDING", - "DISPATCHING", - "DELIVERED", - "ESCALATING", - "ACKNOWLEDGED", - "COMPLETED" + "NONE", + "MINOR", + "MAJOR", + "CRITICAL" ] }, - "completionReason": { + "status": { "type": "string", - "description": "Why the dispatch reached COMPLETED: EXHAUSTED (all steps ran, no ack), RESOLVED (incident resolved), NO_STEPS (policy had no steps). Null for non-terminal states.", + "description": "Incident status; null keeps draft value (must be an active status)", "nullable": true, "enum": [ - "EXHAUSTED", - "RESOLVED", - "NO_STEPS" + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" ] }, - "currentStep": { - "type": "integer", - "description": "1-based index of the currently active escalation step", - "format": "int32" - }, - "totalSteps": { - "type": "integer", - "description": "Total number of escalation steps in the policy (null if policy has been deleted)", - "format": "int32", - "nullable": true - }, - "acknowledgedAt": { - "type": "string", - "description": "Timestamp when this dispatch was acknowledged (null if not acknowledged)", - "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": { + "body": { "type": "string", - "description": "Channel used to acknowledge (DASHBOARD, API, PHONE_CALL, INTERNAL, etc.); null if not acknowledged", + "description": "Initial update body; null keeps draft value", "nullable": true }, - "matchedRules": { + "affectedComponents": { "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)\"]", + "description": "Affected components; null keeps draft value", "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)\"]" + "$ref": "#/components/schemas/AffectedComponent" } }, - "nextEscalationAt": { - "type": "string", - "description": "Timestamp when the next escalation step will fire (null if not scheduled)", - "format": "date-time", + "notifySubscribers": { + "type": "boolean", + "description": "Whether to notify subscribers (default: true)", "nullable": true - }, - "lastNotifiedAt": { + } + } + }, + "PushbulletChannelConfig": { + "required": [ + "channelType", + "accessToken" + ], + "type": "object", + "properties": { + "channelType": { "type": "string", - "description": "Timestamp of the most recent notification delivery", - "format": "date-time", - "nullable": true - }, - "deliveries": { - "type": "array", - "description": "Delivery records for all channels associated with this dispatch", - "items": { - "$ref": "#/components/schemas/AlertDeliveryDto" - } + "enum": [ + "pushbullet" + ] }, - "createdAt": { + "accessToken": { + "minLength": 1, "type": "string", - "description": "Timestamp when the dispatch was created", - "format": "date-time" + "description": "Pushbullet access token" }, - "updatedAt": { + "deviceIden": { "type": "string", - "description": "Timestamp when the dispatch was last updated", - "format": "date-time" + "description": "Target device identifier (broadcasts to all if empty)", + "nullable": true } - }, - "description": "Dispatch state for a single (incident, notification policy) pair, with delivery history" + } }, - "NotificationDto": { + "PushoverChannelConfig": { "required": [ - "createdAt", - "title", - "type", - "id", - "read" + "channelType", + "userKey", + "appToken" ], "type": "object", "properties": { - "id": { - "type": "integer", - "description": "Unique notification identifier", - "format": "int64" - }, - "type": { + "channelType": { "type": "string", - "description": "Notification category (e.g. incident, monitor, team)" + "enum": [ + "pushover" + ] }, - "title": { + "userKey": { + "minLength": 1, "type": "string", - "description": "Short notification title" + "description": "Pushover user or group key" }, - "body": { + "appToken": { + "minLength": 1, "type": "string", - "description": "Full notification body; null for title-only notifications", - "nullable": true + "description": "Pushover application API token" }, - "resourceType": { + "priority": { "type": "string", - "description": "Type of the resource this notification is about", + "description": "Notification priority override (-2 to 2)", "nullable": true }, - "resourceId": { + "sound": { "type": "string", - "description": "ID of the resource this notification is about", + "description": "Notification sound override", "nullable": true - }, - "read": { - "type": "boolean", - "description": "Whether the notification has been read" - }, - "createdAt": { - "type": "string", - "description": "Timestamp when the notification was created", - "format": "date-time" } - }, - "description": "In-app notification for the current user" + } }, - "NotificationPolicyDto": { + "QuarantineMonitorRequest": { "required": [ - "createdAt", - "escalation", - "id", - "matchRules", - "name", - "updatedAt", - "organizationId", - "enabled", - "priority" + "expiresAt", + "reason" ], "type": "object", "properties": { - "id": { - "type": "string", - "description": "Unique notification policy identifier", - "format": "uuid" - }, - "organizationId": { - "type": "integer", - "description": "Organization this policy belongs to", - "format": "int32" - }, - "name": { - "minLength": 1, - "type": "string", - "description": "Human-readable name for this policy" - }, - "description": { - "type": "string", - "description": "Optional note; null when unset", - "nullable": true - }, - "matchRules": { - "type": "array", - "description": "Match rules (all must pass; empty = catch-all)", - "items": { - "$ref": "#/components/schemas/MatchRule" - } - }, - "escalation": { - "$ref": "#/components/schemas/EscalationChain" - }, - "enabled": { - "type": "boolean", - "description": "Whether this policy is active" - }, - "priority": { - "type": "integer", - "description": "Evaluation order; higher value = evaluated first", - "format": "int32" - }, - "createdAt": { + "reason": { + "maxLength": 280, + "minLength": 0, "type": "string", - "description": "Timestamp when the policy was created", - "format": "date-time" + "description": "Reason for this hold (max 280)" }, - "updatedAt": { + "expiresAt": { "type": "string", - "description": "Timestamp when the policy was last updated", + "description": "When the hold expires", "format": "date-time" }, - "stats7d": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/NotificationPolicyWindowStatsDto" - } - ] - }, - "stats30d": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/NotificationPolicyWindowStatsDto" - } - ] - }, - "lastFiredAt": { - "type": "string", - "description": "Created-at of the most recent dispatch for this policy; null if never fired", - "format": "date-time", - "nullable": true - }, - "lastFiredIncidentId": { + "fromRunId": { "type": "string", - "description": "Incident id of the most recent dispatch; null if never fired", + "description": "Run that prompted this hold", "format": "uuid", "nullable": true } - }, - "description": "Org-level notification policy with match rules and escalation chain" + } }, - "NotificationPolicyWindowStatsDto": { - "required": [ - "ackableFires", - "acknowledgements", - "expired", - "failedSends", - "fires", - "sends" - ], + "RateLimitInfo": { "type": "object", "properties": { - "fires": { + "requestsPerMinute": { "type": "integer", - "description": "Dispatches created in the window", - "format": "int32" + "description": "Maximum requests allowed per window", + "format": "int64" }, - "acknowledgements": { + "remaining": { "type": "integer", - "description": "Fires in the window that were acknowledged", - "format": "int32" + "description": "Requests remaining in the current window", + "format": "int64" }, - "ackableFires": { + "windowMs": { "type": "integer", - "description": "Ack ratio denominator: fires when the policy has an ack gate, else 0", - "format": "int32" - }, - "expired": { + "description": "Sliding window size in milliseconds", + "format": "int64" + } + }, + "description": "Rate-limit quota for the current sliding window", + "required": [ + "requestsPerMinute", + "remaining", + "windowMs" + ] + }, + "RecoveryPolicy": { + "type": "object", + "properties": { + "consecutiveSuccesses": { "type": "integer", - "description": "Fires that exhausted escalation without acknowledgment", + "description": "Consecutive passing checks required to auto-resolve the incident", "format": "int32" }, - "sends": { + "minRegionsPassing": { "type": "integer", - "description": "Alert deliveries linked to fires in the window", + "description": "Minimum regions that must be passing before recovery can complete", "format": "int32" }, - "failedSends": { + "cooldownMinutes": { "type": "integer", - "description": "Linked deliveries with status FAILED", + "description": "Minutes after resolve before a new incident may open on the same monitor", "format": "int32" + } + }, + "description": "Auto-recovery settings", + "required": [ + "consecutiveSuccesses", + "minRegionsPassing", + "cooldownMinutes" + ] + }, + "RedirectCountAssertion": { + "required": [ + "type", + "maxCount" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "redirect_count" + ] }, - "medianAckSeconds": { + "maxCount": { "type": "integer", - "description": "Median seconds from fire to ack among acknowledged fires; null when none", - "format": "int64", - "nullable": true + "description": "Maximum number of HTTP redirects allowed before the check fails", + "format": "int32" + } + } + }, + "RedirectTargetAssertion": { + "required": [ + "type", + "expected", + "operator" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "redirect_target" + ] }, - "deepestStepReached": { - "type": "integer", - "description": "Highest escalation step reached in the window; null when no fires", - "format": "int32", - "nullable": true + "expected": { + "minLength": 1, + "type": "string", + "description": "Expected final URL after following redirects" }, - "lastFiredAt": { + "operator": { "type": "string", - "description": "Created-at of the most recent fire in the window; null when none", - "format": "date-time", - "nullable": true + "description": "Comparison operator (equals, contains, less_than, greater_than, etc.)", + "enum": [ + "equals", + "contains", + "less_than", + "greater_than", + "matches", + "range" + ] + } + } + }, + "RegexBodyAssertion": { + "required": [ + "type", + "pattern" + ], + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "regex_body" + ] }, - "lastFiredIncidentId": { + "pattern": { + "minLength": 1, "type": "string", - "description": "Incident id of the most recent fire in the window; null when none", - "format": "uuid", - "nullable": true + "description": "Regular expression the response body must match" } - }, - "description": "Time-bounded notification policy activity aggregates" + } }, - "OfficialSla": { + "RegionStatusDto": { + "required": [ + "region", + "timestamp", + "passed" + ], "type": "object", "properties": { - "percentage": { + "region": { "type": "string", - "description": "Advertised uptime percentage, e.g. '99.99%'", - "nullable": true + "description": "Region identifier", + "example": "us-east" }, - "scope": { + "passed": { + "type": "boolean", + "description": "Whether the last check in this region passed", + "example": true + }, + "responseTimeMs": { + "type": "integer", + "description": "Response time in milliseconds for the last check", + "format": "int32", + "nullable": true, + "example": 95 + }, + "timestamp": { "type": "string", - "description": "Scope of the SLA, e.g. 'Monthly uptime per region'", - "nullable": true + "description": "Timestamp of the last check in this region (ISO 8601)", + "format": "date-time" }, - "measurement": { + "severityHint": { "type": "string", - "description": "How the vendor measures uptime for SLA purposes", + "description": "Severity hint: 'down' for hard failures, 'degraded' for warn-only failures, null when passing", "nullable": true + } + }, + "description": "Latest check result for a single region" + }, + "RelatedIncidentsResponse": { + "required": [ + "data", + "total" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "description": "Related incident rows (newest first, capped by limit)", + "items": { + "$ref": "#/components/schemas/IncidentDto" + } }, - "exclusions": { + "total": { + "type": "integer", + "description": "Total matching incidents in the window, excluding the current incident", + "format": "int64" + } + }, + "description": "Related incidents sharing the same origin within a time window" + }, + "RemapSecretRequest": { + "type": "object", + "properties": { + "secretId": { "type": "string", - "description": "Summary of exclusions from SLA calculation", + "description": "Secret to attach; null restores name-match", + "format": "uuid", "nullable": true - }, - "appliesToPlans": { + } + }, + "description": "Attach or clear a remapped secret" + }, + "RemoveMonitorTagsRequest": { + "required": [ + "tagIds" + ], + "type": "object", + "properties": { + "tagIds": { + "minItems": 1, "type": "array", - "description": "Plan names this SLA applies to, e.g. ['Enterprise']", - "nullable": true, + "description": "IDs of the tags to detach from the monitor", "items": { "type": "string", - "description": "Plan names this SLA applies to, e.g. ['Enterprise']" + "description": "IDs of the tags to detach from the monitor", + "format": "uuid" } - }, - "notCovered": { - "type": "string", - "description": "Services/components NOT covered by the SLA", - "nullable": true } }, - "description": "The vendor's officially advertised SLA commitment" + "description": "Request body for removing tags from a monitor" }, - "OpsGenieChannelConfig": { + "ReorderComponentsRequest": { "required": [ - "channelType", - "apiKey" + "positions" ], "type": "object", "properties": { - "channelType": { - "type": "string", - "enum": [ - "opsgenie" - ] - }, - "apiKey": { - "minLength": 1, - "type": "string", - "description": "OpsGenie API key for alert creation" - }, - "region": { - "type": "string", - "description": "OpsGenie API region: us or eu", - "nullable": true + "positions": { + "minItems": 1, + "type": "array", + "description": "Ordered list of component IDs with their new positions", + "items": { + "$ref": "#/components/schemas/ComponentPosition" + } } - } + }, + "description": "Batch component reorder request" }, - "OrganizationDto": { + "ReorderPageLayoutRequest": { "required": [ - "email", - "name", - "id" + "sections" ], "type": "object", "properties": { - "id": { - "type": "integer", - "description": "Unique organization identifier", - "format": "int32" - }, - "name": { - "type": "string", - "description": "Organization name" - }, - "email": { - "type": "string", - "description": "Billing and contact email", - "nullable": true - }, - "size": { - "type": "string", - "description": "Team size range (e.g. 1-10, 11-50)", - "nullable": true - }, - "industry": { - "type": "string", - "description": "Industry vertical (e.g. SaaS, Fintech)", - "nullable": true + "sections": { + "minItems": 1, + "type": "array", + "description": "Top-level sections in their new order", + "items": { + "$ref": "#/components/schemas/PageSection" + } }, - "websiteUrl": { + "groupOrders": { + "type": "array", + "description": "Within-group component ordering; only needed for groups whose internal order changed", + "nullable": true, + "items": { + "$ref": "#/components/schemas/GroupComponentOrder" + } + } + }, + "description": "Reorder page-level layout: groups and ungrouped components share one ordering" + }, + "ResolveIncidentRequest": { + "type": "object", + "properties": { + "body": { "type": "string", - "description": "Organization website URL", + "description": "Optional resolution message or post-mortem notes", "nullable": true } - }, - "description": "Organization account details" + } }, - "OrgIncidentAnnotationDto": { + "ResourceGroupDeleteBlockerDto": { "required": [ - "incidentId", - "severity", - "status", - "alerted" + "componentId", + "componentName", + "statusPageId", + "statusPageName", + "statusPageSlug" ], "type": "object", "properties": { - "incidentId": { + "statusPageId": { "type": "string", - "description": "Internal org incident ID", + "description": "Status page that owns the blocking component", "format": "uuid" }, - "displayKey": { + "statusPageName": { + "minLength": 1, "type": "string", - "description": "Human display key (e.g. DEV-42); null until platform INC codes ship", - "nullable": true + "description": "Human-readable status page name" }, - "status": { + "statusPageSlug": { + "minLength": 1, "type": "string", - "description": "Internal incident lifecycle status", - "enum": [ - "WATCHING", - "TRIGGERED", - "CONFIRMED", - "RESOLVED" - ] + "description": "URL-safe status page slug" }, - "severity": { + "componentId": { "type": "string", - "description": "Internal incident severity", - "enum": [ - "DOWN", - "DEGRADED", - "MAINTENANCE" - ] + "description": "Blocking GROUP-typed status page component ID", + "format": "uuid" }, - "alerted": { - "type": "boolean", - "description": "Whether alert channels were eligible to fire (false for AWARENESS silent tracking)" + "componentName": { + "minLength": 1, + "type": "string", + "description": "Blocking component display name" }, - "startedAt": { + "hostname": { "type": "string", - "description": "When the internal incident started", - "format": "date-time", + "description": "Public hostname when a custom domain is configured; null otherwise", "nullable": true } }, - "description": "Linked internal incident annotation on a vendor status-event row" + "description": "Status-page component that references this resource group (blocks delete; public exposure)" }, - "OrgInfo": { + "ResourceGroupDto": { "required": [ + "createdAt", + "health", + "id", "name", - "id" + "slug", + "updatedAt", + "organizationId", + "suppressMemberAlerts" ], "type": "object", "properties": { "id": { - "type": "integer", - "description": "Organization ID", - "format": "int32" - }, - "name": { "type": "string", - "description": "Organization name" - } - }, - "description": "Organization the key belongs to" - }, - "Pageable": { - "type": "object", - "properties": { - "page": { - "minimum": 0, - "type": "integer", - "format": "int32" + "description": "Unique resource group identifier", + "format": "uuid" }, - "size": { - "minimum": 1, + "organizationId": { "type": "integer", + "description": "Organization this group belongs to", "format": "int32" }, - "sort": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "page", - "size", - "sort" - ] - }, - "PagerDutyChannelConfig": { - "required": [ - "channelType", - "routingKey" - ], - "type": "object", - "properties": { - "channelType": { + "name": { + "minLength": 1, "type": "string", - "enum": [ - "pagerduty" - ] + "description": "Human-readable group name" }, - "routingKey": { + "slug": { "minLength": 1, "type": "string", - "description": "PagerDuty Events API v2 routing (integration) key" + "description": "URL-safe group identifier" }, - "severityOverride": { + "description": { "type": "string", - "description": "Override PagerDuty severity mapping", + "description": "Optional group description", "nullable": true - } - } - }, - "PageSection": { - "type": "object", - "properties": { - "groupId": { + }, + "alertPolicyId": { "type": "string", - "description": "Group ID when this section is a group", + "description": "Notification policy applied to this group", "format": "uuid", "nullable": true }, - "componentId": { + "defaultFrequency": { + "type": "integer", + "description": "Default check frequency in seconds for member monitors", + "format": "int32", + "nullable": true + }, + "defaultRegions": { + "type": "array", + "description": "Default regions for member monitors", + "nullable": true, + "items": { + "type": "string", + "description": "Default regions for member monitors" + } + }, + "defaultRetryStrategy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/RetryStrategy" + } + ] + }, + "defaultAlertChannels": { + "type": "array", + "description": "Default alert channel IDs for member monitors", + "nullable": true, + "items": { + "type": "string", + "description": "Default alert channel IDs for member monitors", + "format": "uuid" + } + }, + "defaultEnvironmentId": { "type": "string", - "description": "Component ID when this section is an ungrouped component", + "description": "Default environment ID for member monitors", "format": "uuid", "nullable": true }, - "pageOrder": { - "type": "integer", - "description": "Position on the page (0-based)", - "format": "int32" - } - }, - "description": "A top-level page section (either a group or an ungrouped component)", - "required": [ - "pageOrder" - ] - }, - "PhoneCallChannelConfig": { - "type": "object", - "properties": { - "channelType": { + "healthThresholdType": { "type": "string", + "description": "Health threshold type: COUNT or PERCENTAGE", + "nullable": true, "enum": [ - "phone_call" + "COUNT", + "PERCENTAGE" ] }, - "phoneNumber": { - "type": "string", - "description": "Recipient phone number in E.164 format, e.g. +14155550123", + "healthThresholdValue": { + "type": "number", + "description": "Health threshold value", "nullable": true }, - "verifiedPhoneNumberId": { + "suppressMemberAlerts": { + "type": "boolean", + "description": "When true, member-level incidents skip notification dispatch; only group alerts fire" + }, + "confirmationDelaySeconds": { "type": "integer", - "description": "Id of an org verified_phone_number row; alternative to phoneNumber", - "format": "int64", + "description": "Seconds to wait after health threshold breach before creating group incident", + "format": "int32", "nullable": true }, - "phoneNumbers": { + "recoveryCooldownMinutes": { + "type": "integer", + "description": "Cooldown minutes after group incident resolves before a new one can open", + "format": "int32", + "nullable": true + }, + "health": { + "$ref": "#/components/schemas/ResourceGroupHealthDto" + }, + "members": { "type": "array", - "description": "Deprecated: use phoneNumber. Accepted as a length-1 list for one release; ignored when phoneNumber or id is set", + "description": "Member list with individual statuses; populated on detail GET only", "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 + "$ref": "#/components/schemas/ResourceGroupMemberDto" } }, - "voiceLanguage": { - "type": "string", - "description": "TTS voice language/locale (default: en-US). See VoiceLanguage for supported values", - "nullable": true + "deleteBlockedBy": { + "type": "array", + "description": "Status-page GROUP components that reference this group (delete blockers / public exposure); populated on detail GET only — omitted on list", + "nullable": true, + "items": { + "$ref": "#/components/schemas/ResourceGroupDeleteBlockerDto" + } }, - "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", - "tier", - "usage", - "trialActive" - ], - "type": "object", - "properties": { - "tier": { + "openRegionIncident": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/IncidentDto" + } + ] + }, + "managedBy": { "type": "string", - "description": "Resolved plan tier", + "description": "Source that created/owns this group: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on groups created before this attribution column existed.", + "nullable": true, "enum": [ - "FREE", - "STARTER", - "PRO", - "TEAM", - "BUSINESS", - "ENTERPRISE" + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" ] }, - "subscriptionStatus": { + "createdAt": { "type": "string", - "description": "Subscription status (null if no subscription)", - "nullable": true - }, - "trialActive": { - "type": "boolean", - "description": "Whether the org is on a trial" + "description": "Timestamp when the group was created", + "format": "date-time" }, - "trialExpiresAt": { + "updatedAt": { "type": "string", - "description": "Trial expiry (null if not trialing)", - "format": "date-time", - "nullable": true - }, - "entitlements": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/EntitlementDto" - }, - "description": "Entitlement limits keyed by entitlement name" - }, - "usage": { - "type": "object", - "additionalProperties": { - "type": "integer", - "description": "Current usage counters keyed by entitlement name", - "format": "int64" - }, - "description": "Current usage counters keyed by entitlement name" + "description": "Timestamp when the group was last updated", + "format": "date-time" } }, - "description": "Billing plan and entitlement state" + "description": "Resource group with health summary and optional member details" }, - "PolicySnapshotDto": { + "ResourceGroupHealthDto": { "required": [ - "engineVersion", - "firstSeenAt", - "hashHex", - "lastSeenAt", - "policy" + "status", + "totalMembers", + "operationalCount", + "activeIncidents" ], "type": "object", "properties": { - "hashHex": { - "minLength": 1, + "status": { "type": "string", - "description": "Hex-encoded SHA-256 of the canonical policy JSON" + "description": "Worst-of health status across all members", + "enum": [ + "operational", + "maintenance", + "degraded", + "down" + ] }, - "policy": { - "type": "object", - "additionalProperties": { - "type": "object", - "description": "Canonical policy document (snake_case, sorted keys)" - }, - "description": "Canonical policy document (snake_case, sorted keys)" + "totalMembers": { + "type": "integer", + "description": "Total number of members in the group", + "format": "int32" }, - "engineVersion": { - "minLength": 1, + "operationalCount": { + "type": "integer", + "description": "Number of members currently in operational status", + "format": "int32" + }, + "activeIncidents": { + "type": "integer", + "description": "Number of members currently non-operational (not an incident-row count)", + "format": "int32" + }, + "thresholdStatus": { "type": "string", - "description": "Detection engine version that observed this policy" + "description": "Computed group health status based on threshold: 'healthy', 'degraded', or 'down'. Null when no health threshold is configured.", + "nullable": true, + "enum": [ + "healthy", + "degraded", + "down" + ] }, - "firstSeenAt": { + "failingCount": { + "type": "integer", + "description": "Number of failing members at time of last evaluation; null when no threshold configured", + "format": "int32", + "nullable": true + }, + "healthBreachedSince": { "type": "string", - "description": "First time the detection engine evaluated against this policy bytes", - "format": "date-time" + "description": "When the health threshold was first breached in the current cycle; null when not breached", + "format": "date-time", + "nullable": true }, - "lastSeenAt": { + "healthEvaluatedAt": { "type": "string", - "description": "Most recent time the engine evaluated against this policy bytes", - "format": "date-time" + "description": "When group health was last evaluated (threshold or stamp-only); null until first evaluation", + "format": "date-time", + "nullable": true } }, - "description": "Policy snapshot used during this check (all evaluations of a single check are against one policy)", - "nullable": true + "description": "Aggregated health summary for a resource group" }, - "PollChartBucketDto": { + "ResourceGroupMemberDto": { "required": [ - "bucket", - "totalPolls" + "createdAt", + "groupId", + "id", + "memberType", + "status" ], "type": "object", "properties": { - "bucket": { + "id": { "type": "string", - "description": "Start of the time bucket (ISO 8601)", - "format": "date-time" + "description": "Unique group member record identifier", + "format": "uuid" }, - "uptimePercent": { - "type": "number", - "description": "Uptime percentage for this bucket; null when no data", - "format": "double", - "nullable": true, - "example": 100 + "groupId": { + "type": "string", + "description": "Resource group this member belongs to", + "format": "uuid" }, - "avgResponseTimeMs": { - "type": "number", - "description": "Average response time in milliseconds for this bucket", - "format": "double", - "nullable": true, - "example": 245.3 + "memberType": { + "type": "string", + "description": "Type of member: 'monitor' or 'service'" }, - "totalPolls": { - "type": "integer", - "description": "Total polls in this bucket", - "format": "int64", - "example": 60 - } - }, - "description": "Aggregated poll metrics for a time bucket" - }, - "PricingTier": { - "required": [ - "name" - ], - "type": "object", - "properties": { - "name": { + "monitorId": { "type": "string", - "description": "Tier name, e.g. 'Free', 'Pro', 'Enterprise'" + "description": "Monitor ID; set when memberType is 'monitor'", + "format": "uuid", + "nullable": true }, - "slaPercentage": { + "serviceId": { "type": "string", - "description": "SLA percentage for this tier, e.g. '99.9%'", + "description": "Service ID; set when memberType is 'service'", + "format": "uuid", "nullable": true }, - "priceFrom": { + "name": { "type": "string", - "description": "Starting price, e.g. '$0', '$25/mo', 'Custom'", + "description": "Display name of the referenced monitor or service", "nullable": true - } - }, - "description": "Pricing tiers with associated SLA levels" - }, - "PublishStatusPageIncidentRequest": { - "type": "object", - "properties": { - "title": { - "maxLength": 500, - "minLength": 0, + }, + "slug": { "type": "string", - "description": "Customer-facing title; null keeps draft value", + "description": "Slug identifier for the service (services only); used for icons and uptime API calls", "nullable": true }, - "impact": { + "subscriptionId": { "type": "string", - "description": "Impact level; null keeps draft value", - "nullable": true, - "enum": [ - "NONE", - "MINOR", - "MAJOR", - "CRITICAL" - ] + "description": "Subscription ID for the service (services only); used to link to the dependency detail page", + "format": "uuid", + "nullable": true }, "status": { "type": "string", - "description": "Incident status; null keeps draft value (must be an active status)", - "nullable": true, + "description": "Computed health status for this member", "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" + "operational", + "maintenance", + "degraded", + "down" ] }, - "body": { + "effectiveFrequency": { "type": "string", - "description": "Initial update body; null keeps draft value", + "description": "Effective check frequency label showing the group default when the monitor inherits it; null for services or when no group default is configured", "nullable": true }, - "affectedComponents": { + "createdAt": { + "type": "string", + "description": "Timestamp when the member was added to the group", + "format": "date-time" + }, + "uptime24h": { + "type": "number", + "description": "24h uptime percentage; populated when includeMetrics=true", + "format": "double", + "nullable": true + }, + "chartData": { "type": "array", - "description": "Affected components; null keeps draft value", + "description": "Uptime tick values (0-100) for last-24h mini chart; populated when includeMetrics=true", "nullable": true, "items": { - "$ref": "#/components/schemas/AffectedComponent" + "type": "number", + "description": "Uptime tick values (0-100) for last-24h mini chart; populated when includeMetrics=true", + "format": "double" } }, - "notifySubscribers": { - "type": "boolean", - "description": "Whether to notify subscribers (default: true)", + "avgLatencyMs": { + "type": "number", + "description": "Average latency in ms (monitors only); populated when includeMetrics=true", + "format": "double", "nullable": true - } - } - }, - "PushbulletChannelConfig": { - "required": [ - "channelType", - "accessToken" - ], - "type": "object", - "properties": { - "channelType": { + }, + "p95LatencyMs": { + "type": "number", + "description": "P95 latency in ms (monitors only); populated when includeMetrics=true", + "format": "double", + "nullable": true + }, + "lastCheckedAt": { "type": "string", - "enum": [ - "pushbullet" - ] + "description": "Timestamp of the most recent health check; populated when includeMetrics=true", + "format": "date-time", + "nullable": true }, - "accessToken": { - "minLength": 1, + "monitorType": { "type": "string", - "description": "Pushbullet access token" + "description": "Monitor type (HTTP, DNS, TCP, ICMP, HEARTBEAT, MCP); monitors only", + "nullable": true }, - "deviceIden": { + "environmentName": { "type": "string", - "description": "Target device identifier (broadcasts to all if empty)", + "description": "Environment name; monitors only", + "nullable": true + }, + "groupMembershipCount": { + "type": "integer", + "description": "Count of resource groups this monitor or service belongs to; detail GET only — omitted on list", + "format": "int32", + "nullable": true + }, + "failingSince": { + "type": "string", + "description": "Start of the current non-operational stretch; null when operational or unknown (services OK); detail GET only — omitted on list", + "format": "date-time", + "nullable": true + }, + "alertCollapsed": { + "type": "boolean", + "description": "True when an active member incident records this group among alertCollapsedByResourceGroupIds; detail GET only — omitted on list", "nullable": true + }, + "incidentMarks": { + "type": "array", + "description": "Incident marks for the trailing 24h strip; null when metrics omitted or failed; detail GET only — omitted on list", + "nullable": true, + "items": { + "$ref": "#/components/schemas/ResourceGroupMemberIncidentMarkDto" + } } - } + }, + "description": "A single member of a resource group with its computed health status" }, - "PushoverChannelConfig": { + "ResourceGroupMemberIncidentMarkDto": { "required": [ - "channelType", - "userKey", - "appToken" + "at" ], "type": "object", "properties": { - "channelType": { - "type": "string", - "enum": [ - "pushover" - ] - }, - "userKey": { - "minLength": 1, - "type": "string", - "description": "Pushover user or group key" - }, - "appToken": { - "minLength": 1, + "at": { "type": "string", - "description": "Pushover application API token" + "description": "Incident startedAt (or first confirmed) within the trailing 24h window", + "format": "date-time" }, - "priority": { + "incidentId": { "type": "string", - "description": "Notification priority override (-2 to 2)", + "description": "Incident ID for navigation; null when unknown", + "format": "uuid", "nullable": true }, - "sound": { + "severity": { "type": "string", - "description": "Notification sound override", + "description": "Optional severity display hint", "nullable": true } - } + }, + "description": "Member incident mark for the trailing 24h uptime strip" }, - "RateLimitInfo": { + "ResponseSizeAssertion": { "type": "object", "properties": { - "requestsPerMinute": { - "type": "integer", - "description": "Maximum requests allowed per window", - "format": "int64" - }, - "remaining": { - "type": "integer", - "description": "Requests remaining in the current window", - "format": "int64" + "type": { + "type": "string", + "enum": [ + "response_size" + ] }, - "windowMs": { + "maxBytes": { "type": "integer", - "description": "Sliding window size in milliseconds", - "format": "int64" + "description": "Maximum response body size in bytes before the check fails", + "format": "int32" } }, - "description": "Rate-limit quota for the current sliding window", "required": [ - "requestsPerMinute", - "remaining", - "windowMs" + "type", + "maxBytes" ] }, - "RecoveryPolicy": { + "ResponseTimeAssertion": { "type": "object", "properties": { - "consecutiveSuccesses": { - "type": "integer", - "description": "Consecutive passing checks required to auto-resolve the incident", - "format": "int32" - }, - "minRegionsPassing": { - "type": "integer", - "description": "Minimum regions that must be passing before recovery can complete", - "format": "int32" + "type": { + "type": "string", + "enum": [ + "response_time" + ] }, - "cooldownMinutes": { + "thresholdMs": { "type": "integer", - "description": "Minutes after resolve before a new incident may open on the same monitor", + "description": "Maximum allowed response time in milliseconds before the check fails", "format": "int32" } }, - "description": "Auto-recovery settings", "required": [ - "consecutiveSuccesses", - "minRegionsPassing", - "cooldownMinutes" + "type", + "thresholdMs" ] }, - "RedirectCountAssertion": { + "ResponseTimeWarnAssertion": { "type": "object", "properties": { "type": { "type": "string", "enum": [ - "redirect_count" + "response_time_warn" ] }, - "maxCount": { + "warnMs": { "type": "integer", - "description": "Maximum number of HTTP redirects allowed before the check fails", + "description": "HTTP response time in milliseconds that triggers a warning only", "format": "int32" } }, "required": [ "type", - "maxCount" + "warnMs" ] }, - "RedirectTargetAssertion": { + "ResultSummaryDto": { "required": [ - "type", - "expected", - "operator" + "chartData", + "currentStatus", + "latestPerRegion" ], "type": "object", "properties": { - "type": { + "currentStatus": { "type": "string", + "description": "Derived current status across all regions", "enum": [ - "redirect_target" + "up", + "degraded", + "down", + "paused", + "unknown" ] }, - "expected": { - "minLength": 1, - "type": "string", - "description": "Expected final URL after following redirects" + "latestPerRegion": { + "type": "array", + "description": "Latest check result per region", + "items": { + "$ref": "#/components/schemas/RegionStatusDto" + } }, - "operator": { - "type": "string", - "description": "Comparison operator (equals, contains, less_than, greater_than, etc.)", - "enum": [ - "equals", - "contains", - "less_than", - "greater_than", - "matches", - "range" - ] + "chartData": { + "type": "array", + "description": "Time-bucketed chart data for the requested window", + "items": { + "$ref": "#/components/schemas/ChartBucketDto" + } + }, + "uptime24h": { + "type": "number", + "description": "Uptime percentage over the last 24 hours; null when no data", + "format": "double", + "nullable": true, + "example": 99.95 + }, + "uptimeWindow": { + "type": "number", + "description": "Uptime percentage for the selected chart window; null when no data", + "format": "double", + "nullable": true, + "example": 99.8 } - } + }, + "description": "Dashboard summary: current status, per-region latest results, and chart data" }, - "RegexBodyAssertion": { + "RetryStrategy": { "required": [ "type", - "pattern" + "maxRetries", + "interval" ], "type": "object", "properties": { "type": { "type": "string", - "enum": [ - "regex_body" - ] + "description": "Retry strategy kind, e.g. fixed interval between attempts" }, - "pattern": { - "minLength": 1, - "type": "string", - "description": "Regular expression the response body must match" + "maxRetries": { + "type": "integer", + "description": "Maximum number of retries after a failed check", + "format": "int32" + }, + "interval": { + "type": "integer", + "description": "Delay between retry attempts in seconds", + "format": "int32" } - } + }, + "description": "Default retry strategy for member monitors; null clears" }, - "RegionStatusDto": { + "RevisionDiffDto": { "required": [ - "region", - "timestamp", - "passed" + "hunks", + "left", + "right" ], "type": "object", "properties": { - "region": { - "type": "string", - "description": "Region identifier", - "example": "us-east" + "left": { + "$ref": "#/components/schemas/RevisionDto" }, - "passed": { - "type": "boolean", - "description": "Whether the last check in this region passed", - "example": true + "right": { + "$ref": "#/components/schemas/RevisionDto" }, - "responseTimeMs": { - "type": "integer", - "description": "Response time in milliseconds for the last check", - "format": "int32", - "nullable": true, - "example": 95 + "hunks": { + "type": "array", + "description": "File and field-level hunks (bounded)", + "items": { + "$ref": "#/components/schemas/RevisionDiffHunkDto" + } + } + }, + "description": "Bounded comparison of two revisions" + }, + "RevisionDiffHunkDto": { + "required": [ + "change", + "path" + ], + "type": "object", + "properties": { + "path": { + "minLength": 1, + "type": "string", + "description": "Path or field name (entrypoint, keys, or file path)" }, - "timestamp": { + "change": { "type": "string", - "description": "Timestamp of the last check in this region (ISO 8601)", - "format": "date-time" + "description": "Whether this path was added, removed, or changed", + "enum": [ + "added", + "removed", + "changed" + ] }, - "severityHint": { + "left": { "type": "string", - "description": "Severity hint: 'down' for hard failures, 'degraded' for warn-only failures, null when passing", + "description": "Left value when present", + "nullable": true + }, + "right": { + "type": "string", + "description": "Right value when present", "nullable": true } }, - "description": "Latest check result for a single region" + "description": "One bounded diff hunk between revisions" }, - "RelatedIncidentsResponse": { + "RevisionDto": { "required": [ - "data", - "total" + "createdAt", + "definitionId", + "digest", + "entrypoint", + "files", + "id", + "keys", + "number" ], "type": "object", "properties": { - "data": { + "id": { + "type": "string", + "description": "Revision identifier", + "format": "uuid" + }, + "definitionId": { + "type": "string", + "description": "Parent definition", + "format": "uuid" + }, + "number": { + "type": "integer", + "description": "Monotonic revision number within the definition", + "format": "int32" + }, + "digest": { + "minLength": 1, + "type": "string", + "description": "SHA-256 hex digest of the zip" + }, + "entrypoint": { + "minLength": 1, + "type": "string", + "description": "Entrypoint file that runs" + }, + "files": { "type": "array", - "description": "Related incident rows (newest first, capped by limit)", + "description": "Paths present in the zip", "items": { - "$ref": "#/components/schemas/IncidentDto" + "type": "string", + "description": "Paths present in the zip" } }, - "total": { - "type": "integer", - "description": "Total matching incidents in the window, excluding the current incident", - "format": "int64" + "keys": { + "type": "array", + "description": "Secret key names the code demands", + "items": { + "type": "string", + "description": "Secret key names the code demands" + } + }, + "downloadUntil": { + "type": "string", + "description": "When package bytes expire for download", + "format": "date-time", + "nullable": true + }, + "gitSha": { + "type": "string", + "description": "Git commit SHA when sourced from Git", + "nullable": true + }, + "gitMessage": { + "type": "string", + "description": "Git commit message", + "nullable": true + }, + "gitFile": { + "type": "string", + "description": "Declaring Git file path", + "nullable": true + }, + "authoredBy": { + "type": "string", + "description": "Who authored this package", + "nullable": true + }, + "createdAt": { + "type": "string", + "description": "When the revision was minted", + "format": "date-time" } }, - "description": "Related incidents sharing the same origin within a time window" + "description": "Definition revision package" }, - "RemoveMonitorTagsRequest": { + "RollbackPreviewDto": { "required": [ - "tagIds" + "affectedMonitors", + "target" ], "type": "object", "properties": { - "tagIds": { - "minItems": 1, + "target": { + "$ref": "#/components/schemas/RevisionDto" + }, + "current": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/DefinitionHeadDto" + } + ] + }, + "affectedMonitors": { "type": "array", - "description": "IDs of the tags to detach from the monitor", + "description": "Monitors sharing this definition and environment", "items": { - "type": "string", - "description": "IDs of the tags to detach from the monitor", - "format": "uuid" + "$ref": "#/components/schemas/MonitorDto" } } }, - "description": "Request body for removing tags from a monitor" + "description": "Consequence preview for rolling back Head in this environment" }, - "ReorderComponentsRequest": { + "RollbackRevisionRequest": { "required": [ - "positions" + "reason", + "revisionId" ], "type": "object", - "properties": { - "positions": { - "minItems": 1, - "type": "array", - "description": "Ordered list of component IDs with their new positions", - "items": { - "$ref": "#/components/schemas/ComponentPosition" - } + "properties": { + "revisionId": { + "type": "string", + "description": "Existing revision to restore as Head for this monitor's environment", + "format": "uuid" + }, + "reason": { + "maxLength": 280, + "minLength": 0, + "type": "string", + "description": "Why this rollback was performed (1–280 chars)" } - }, - "description": "Batch component reorder request" + } }, - "ReorderPageLayoutRequest": { + "RootlyChannelConfig": { "required": [ - "sections" + "channelType", + "apiKey" ], "type": "object", "properties": { - "sections": { - "minItems": 1, - "type": "array", - "description": "Top-level sections in their new order", - "items": { - "$ref": "#/components/schemas/PageSection" - } + "channelType": { + "type": "string", + "enum": [ + "rootly" + ] }, - "groupOrders": { - "type": "array", - "description": "Within-group component ordering; only needed for groups whose internal order changed", - "nullable": true, - "items": { - "$ref": "#/components/schemas/GroupComponentOrder" - } + "apiKey": { + "minLength": 1, + "type": "string", + "description": "Rootly API token with incident creation permission" + }, + "severity": { + "type": "string", + "description": "Severity slug override (e.g. sev0, sev1)", + "nullable": true } - }, - "description": "Reorder page-level layout: groups and ungrouped components share one ordering" + } }, - "ResolveIncidentRequest": { + "Row": { + "required": [ + "title", + "verdict", + "index" + ], "type": "object", "properties": { - "body": { + "index": { + "type": "integer", + "description": "Zero-based step index", + "format": "int32" + }, + "title": { + "minLength": 1, "type": "string", - "description": "Optional resolution message or post-mortem notes", + "description": "Step title" + }, + "thisDurationMs": { + "type": "integer", + "description": "This run's step duration in milliseconds", + "format": "int32", + "nullable": true + }, + "baselineDurationMs": { + "type": "integer", + "description": "Baseline step duration in milliseconds", + "format": "int32", "nullable": true + }, + "deltaMs": { + "type": "integer", + "description": "thisDurationMs minus baselineDurationMs", + "format": "int32", + "nullable": true + }, + "verdict": { + "type": "string", + "description": "unchanged, much_slower, now_failing, or not_reached", + "enum": [ + "unchanged", + "much_slower", + "now_failing", + "not_reached" + ] } - } + }, + "description": "One step compared to the baseline" }, - "ResourceGroupDeleteBlockerDto": { + "RuleEvaluationDto": { "required": [ - "componentId", - "componentName", - "statusPageId", - "statusPageName", - "statusPageSlug" + "checkId", + "engineVersion", + "evaluationDetails", + "id", + "inputResultIds", + "monitorId", + "occurredAt", + "policySnapshotHashHex", + "region", + "ruleScope", + "ruleType", + "ruleIndex", + "outputMatched" ], "type": "object", "properties": { - "statusPageId": { + "id": { "type": "string", - "description": "Status page that owns the blocking component", + "description": "Forensic row UUID", "format": "uuid" }, - "statusPageName": { + "occurredAt": { + "type": "string", + "description": "When the evaluation ran", + "format": "date-time" + }, + "monitorId": { + "type": "string", + "description": "Monitor that produced the input check result", + "format": "uuid" + }, + "region": { "minLength": 1, "type": "string", - "description": "Human-readable status page name" + "description": "Probe region of the input check result" }, - "statusPageSlug": { + "policySnapshotHashHex": { "minLength": 1, "type": "string", - "description": "URL-safe status page slug" + "description": "Hex-encoded hash of the policy snapshot this rule came from" }, - "componentId": { + "ruleIndex": { + "type": "integer", + "description": "Index into the policy's triggerRules array (0-based)", + "format": "int32" + }, + "ruleType": { + "minLength": 1, "type": "string", - "description": "Blocking GROUP-typed status page component ID", - "format": "uuid" + "description": "Rule type (e.g. consecutive_failures, failures_in_window)" }, - "componentName": { + "ruleScope": { "minLength": 1, "type": "string", - "description": "Blocking component display name" + "description": "Rule scope (per_region | multi_region)" }, - "hostname": { + "inputResultIds": { + "minItems": 1, + "type": "array", + "description": "check_results IDs that were inputs to this evaluation (newest first)", + "items": { + "type": "string", + "description": "check_results IDs that were inputs to this evaluation (newest first)", + "format": "uuid" + } + }, + "outputMatched": { + "type": "boolean", + "description": "Whether the rule fired on this evaluation" + }, + "evaluationDetails": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Structured details (e.g. failure counts, response-time aggregates)" + }, + "description": "Structured details (e.g. failure counts, response-time aggregates)" + }, + "engineVersion": { + "minLength": 1, "type": "string", - "description": "Public hostname when a custom domain is configured; null otherwise", + "description": "Detection engine version that ran this evaluation" + }, + "checkId": { + "type": "string", + "description": "Scheduler-minted check execution ID (V92) — the causal chain identifier", + "format": "uuid" + }, + "triggeringTransitionId": { + "type": "string", + "description": "If this evaluation caused a state transition, points to that transition's id", + "format": "uuid", "nullable": true } }, - "description": "Status-page component that references this resource group (blocks delete; public exposure)" + "description": "All rule evaluations that ran for this check" }, - "ResourceGroupDto": { + "RunArtifactDto": { "required": [ "createdAt", - "health", "id", - "name", - "slug", - "updatedAt", - "organizationId", - "suppressMemberAlerts" + "kind", + "lifecycle", + "runId", + "organizationId" ], "type": "object", "properties": { "id": { "type": "string", - "description": "Unique resource group identifier", + "description": "Unique artifact identifier", "format": "uuid" }, "organizationId": { "type": "integer", - "description": "Organization this group belongs to", + "description": "Organization this artifact belongs to", "format": "int32" }, - "name": { - "minLength": 1, + "runId": { "type": "string", - "description": "Human-readable group name" + "description": "Run this artifact belongs to", + "format": "uuid" }, - "slug": { - "minLength": 1, + "stepId": { "type": "string", - "description": "URL-safe group identifier" + "description": "Step this screenshot belongs to; null for whole-run kinds", + "format": "uuid", + "nullable": true }, - "description": { + "kind": { "type": "string", - "description": "Optional group description", + "description": "File kind", + "enum": [ + "screenshot", + "video", + "trace", + "har", + "console", + "runner_log" + ] + }, + "lifecycle": { + "type": "string", + "description": "Whether bytes are available, processing, or gone", + "enum": [ + "available", + "processing", + "failed", + "not_captured", + "suppressed", + "never_reached", + "expired", + "no_browser" + ] + }, + "captureReason": { + "type": "string", + "description": "Why this file was captured", + "nullable": true, + "enum": [ + "on_failure", + "named_step", + "customer" + ] + }, + "byteSize": { + "type": "integer", + "description": "Stored size in bytes", + "format": "int64", "nullable": true }, - "alertPolicyId": { + "contentType": { "type": "string", - "description": "Notification policy applied to this group", - "format": "uuid", + "description": "MIME type of the stored file", "nullable": true }, - "defaultFrequency": { + "durationMs": { "type": "integer", - "description": "Default check frequency in seconds for member monitors", + "description": "Video duration in milliseconds", "format": "int32", "nullable": true }, - "defaultRegions": { - "type": "array", - "description": "Default regions for member monitors", - "nullable": true, - "items": { - "type": "string", - "description": "Default regions for member monitors" - } - }, - "defaultRetryStrategy": { + "viewport": { "nullable": true, "allOf": [ { - "$ref": "#/components/schemas/RetryStrategy" + "$ref": "#/components/schemas/ArtifactViewport" } ] }, - "defaultAlertChannels": { - "type": "array", - "description": "Default alert channel IDs for member monitors", - "nullable": true, - "items": { - "type": "string", - "description": "Default alert channel IDs for member monitors", - "format": "uuid" - } - }, - "defaultEnvironmentId": { - "type": "string", - "description": "Default environment ID for member monitors", - "format": "uuid", - "nullable": true - }, - "healthThresholdType": { + "expiresAt": { "type": "string", - "description": "Health threshold type: COUNT or PERCENTAGE", - "nullable": true, - "enum": [ - "COUNT", - "PERCENTAGE" - ] - }, - "healthThresholdValue": { - "type": "number", - "description": "Health threshold value", + "description": "When stored bytes expire", + "format": "date-time", "nullable": true }, - "suppressMemberAlerts": { - "type": "boolean", - "description": "When true, member-level incidents skip notification dispatch; only group alerts fire" - }, - "confirmationDelaySeconds": { + "expectedByteSize": { "type": "integer", - "description": "Seconds to wait after health threshold breach before creating group incident", - "format": "int32", + "description": "Expected size while a video is encoding", + "format": "int64", "nullable": true }, - "recoveryCooldownMinutes": { + "encodeEtaMs": { "type": "integer", - "description": "Cooldown minutes after group incident resolves before a new one can open", + "description": "Estimated remaining encode time in milliseconds", "format": "int32", "nullable": true }, - "health": { - "$ref": "#/components/schemas/ResourceGroupHealthDto" - }, - "members": { - "type": "array", - "description": "Member list with individual statuses; populated on detail GET only", - "nullable": true, - "items": { - "$ref": "#/components/schemas/ResourceGroupMemberDto" - } - }, - "deleteBlockedBy": { - "type": "array", - "description": "Status-page GROUP components that reference this group (delete blockers / public exposure); populated on detail GET only — omitted on list", - "nullable": true, - "items": { - "$ref": "#/components/schemas/ResourceGroupDeleteBlockerDto" - } - }, - "openRegionIncident": { + "traceMeta": { "nullable": true, "allOf": [ { - "$ref": "#/components/schemas/IncidentDto" + "$ref": "#/components/schemas/ArtifactTraceMeta" } ] }, - "managedBy": { + "createdAt": { "type": "string", - "description": "Source that created/owns this group: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null on groups created before this attribution column existed.", + "description": "When this file row was created", + "format": "date-time" + } + }, + "description": "Run evidence file" + }, + "RunAttemptDto": { + "type": "object", + "properties": { + "attempt": { + "type": "integer", + "description": "1-based attempt number", + "format": "int32" + }, + "outcome": { + "type": "string", + "description": "Attempt outcome; null while the case is open", "nullable": true, "enum": [ - "DASHBOARD", - "CLI", - "TERRAFORM", - "MCP", - "API" + "passed", + "failed", + "execution_error", + "timed_out", + "passed_on_retry", + "cancelled", + "inconclusive" ] }, - "createdAt": { + "startedAt": { "type": "string", - "description": "Timestamp when the group was created", - "format": "date-time" + "description": "When this attempt started", + "format": "date-time", + "nullable": true }, - "updatedAt": { + "finishedAt": { "type": "string", - "description": "Timestamp when the group was last updated", - "format": "date-time" + "description": "When this attempt finished", + "format": "date-time", + "nullable": true } }, - "description": "Resource group with health summary and optional member details" + "description": "In-check attempt", + "required": [ + "attempt" + ] }, - "ResourceGroupHealthDto": { + "RunCaseDto": { "required": [ + "id", + "runId", "status", - "totalMembers", - "operationalCount", - "activeIncidents" + "steps", + "title", + "organizationId", + "attempt", + "index" ], "type": "object", "properties": { - "status": { + "id": { "type": "string", - "description": "Worst-of health status across all members", - "enum": [ - "operational", - "maintenance", - "degraded", - "down" - ] + "description": "Case identifier", + "format": "uuid" }, - "totalMembers": { + "organizationId": { "type": "integer", - "description": "Total number of members in the group", + "description": "Organization this case belongs to", "format": "int32" }, - "operationalCount": { + "runId": { + "type": "string", + "description": "Run this case belongs to", + "format": "uuid" + }, + "attempt": { "type": "integer", - "description": "Number of members currently in operational status", + "description": "Playwright in-case attempt number", "format": "int32" }, - "activeIncidents": { + "index": { "type": "integer", - "description": "Number of members currently non-operational (not an incident-row count)", + "description": "Zero-based case index within the attempt", "format": "int32" }, - "thresholdStatus": { + "title": { "type": "string", - "description": "Computed group health status based on threshold: 'healthy', 'degraded', or 'down'. Null when no health threshold is configured.", - "nullable": true, + "description": "Case title" + }, + "file": { + "type": "string", + "description": "Spec path inside the package", + "nullable": true + }, + "status": { + "type": "string", + "description": "Case status", "enum": [ - "healthy", - "degraded", - "down" + "pending", + "running", + "passed", + "failed", + "timed_out", + "skipped", + "interrupted" ] }, - "failingCount": { + "startedAt": { + "type": "string", + "description": "When the case started", + "format": "date-time", + "nullable": true + }, + "finishedAt": { + "type": "string", + "description": "When the case finished", + "format": "date-time", + "nullable": true + }, + "durationMs": { "type": "integer", - "description": "Number of failing members at time of last evaluation; null when no threshold configured", + "description": "Reporter duration in milliseconds", "format": "int32", "nullable": true }, - "healthBreachedSince": { + "steps": { + "type": "array", + "description": "Steps on this case", + "items": { + "$ref": "#/components/schemas/RunStepDto" + } + } + }, + "description": "Run case with nested steps" + }, + "RunCaseListParams": { + "type": "object", + "properties": { + "attempt": { + "type": "integer", + "description": "Only return cases for this Playwright attempt", + "format": "int32", + "nullable": true + } + } + }, + "RunConsoleDto": { + "required": [ + "groups", + "state" + ], + "type": "object", + "properties": { + "state": { + "minLength": 1, "type": "string", - "description": "When the health threshold was first breached in the current cycle; null when not breached", - "format": "date-time", + "description": "on for browser, no_browser for API_CHECK" + }, + "reason": { + "type": "string", + "description": "Absence copy when state is no_browser", "nullable": true }, - "healthEvaluatedAt": { + "groups": { + "type": "array", + "description": "Grouped messages; empty when ungrouped or no_browser", + "items": { + "$ref": "#/components/schemas/ConsoleGroupDto" + } + }, + "lines": { + "type": "array", + "description": "Raw lines when ungrouped=true", + "nullable": true, + "items": { + "$ref": "#/components/schemas/ConsoleLineDto" + } + } + }, + "description": "Console groups or ungrouped lines" + }, + "RunConsoleParams": { + "type": "object", + "properties": { + "attempt": { + "type": "integer", + "description": "In-check attempt (default selected attempt)", + "format": "int32", + "nullable": true + }, + "ungrouped": { + "type": "boolean", + "description": "Return chronological lines instead of groups", + "nullable": true + }, + "level": { "type": "string", - "description": "When group health was last evaluated (threshold or stamp-only); null until first evaluation", - "format": "date-time", + "description": "Filter error, warning, or info", + "nullable": true + }, + "format": { + "type": "string", + "description": "raw downloads the ungrouped log as text/plain", + "nullable": true + } + } + }, + "RunDiffDto": { + "required": [ + "baselineKind", + "picker", + "readsAs", + "rows" + ], + "type": "object", + "properties": { + "baselineRunId": { + "type": "string", + "description": "Baseline run; null when no prior pass", + "format": "uuid", "nullable": true + }, + "baselineKind": { + "type": "string", + "description": "How the baseline was chosen", + "enum": [ + "last_pass_same_revision_region", + "last_pass_any_revision", + "attempts_in_run", + "none" + ] + }, + "readsAs": { + "minLength": 1, + "type": "string", + "description": "Human-readable baseline sentence" + }, + "rows": { + "type": "array", + "description": "One row per step on this run", + "items": { + "$ref": "#/components/schemas/Row" + } + }, + "picker": { + "type": "array", + "description": "Other finished runs of this monitor for the picker", + "items": { + "$ref": "#/components/schemas/PickerItem" + } } }, - "description": "Aggregated health summary for a resource group" + "description": "Step duration diff against a prior pass" }, - "ResourceGroupMemberDto": { + "RunDto": { "required": [ - "createdAt", - "groupId", + "attempts", + "bindingVersionSnapshot", + "bundleDigest", + "capturePolicySnapshot", + "enqueuedAt", + "evidence", "id", - "memberType", - "status" + "monitorId", + "phase", + "region", + "revisionId", + "source", + "tabCounts", + "organizationId", + "cancelRequested", + "stream", + "attempt", + "attemptOf" ], "type": "object", "properties": { "id": { "type": "string", - "description": "Unique group member record identifier", + "description": "Unique run identifier", "format": "uuid" }, - "groupId": { + "organizationId": { + "type": "integer", + "description": "Organization this run belongs to", + "format": "int32" + }, + "monitorId": { "type": "string", - "description": "Resource group this member belongs to", + "description": "Monitor this run belongs to", "format": "uuid" }, - "memberType": { + "monitorName": { "type": "string", - "description": "Type of member: 'monitor' or 'service'" + "description": "Monitor display name", + "nullable": true }, - "monitorId": { + "monitorType": { "type": "string", - "description": "Monitor ID; set when memberType is 'monitor'", + "description": "Monitor type", + "nullable": true, + "enum": [ + "HTTP", + "DNS", + "MCP_SERVER", + "TCP", + "ICMP", + "HEARTBEAT", + "BROWSER", + "MULTI_STEP_API" + ] + }, + "host": { + "type": "string", + "description": "Target host from the environment BASE_URL", + "nullable": true + }, + "environmentId": { + "type": "string", + "description": "Environment this run executed in", "format": "uuid", "nullable": true }, - "serviceId": { + "environmentName": { + "type": "string", + "description": "Environment display name", + "nullable": true + }, + "revisionId": { + "type": "string", + "description": "Revision this run executed", + "format": "uuid" + }, + "region": { + "minLength": 1, + "type": "string", + "description": "Probe region for this run" + }, + "source": { + "type": "string", + "description": "What triggered this run", + "enum": [ + "schedule", + "run_now", + "ci", + "fast_retry", + "remote_validation", + "deployment_validation", + "session_renew" + ] + }, + "enqueuedAt": { + "type": "string", + "description": "When this run was enqueued", + "format": "date-time" + }, + "evaluationCycleId": { "type": "string", - "description": "Service ID; set when memberType is 'service'", + "description": "Evaluation cycle grouping this run with retries", "format": "uuid", "nullable": true }, - "name": { + "retryOfRunId": { "type": "string", - "description": "Display name of the referenced monitor or service", + "description": "Parent run when this is a fast retry", + "format": "uuid", "nullable": true }, - "slug": { + "retriedFromRunId": { "type": "string", - "description": "Slug identifier for the service (services only); used for icons and uptime API calls", + "description": "Fast-retry parent run", + "format": "uuid", "nullable": true }, - "subscriptionId": { + "phase": { "type": "string", - "description": "Subscription ID for the service (services only); used to link to the dependency detail page", - "format": "uuid", - "nullable": true + "description": "Current run phase", + "enum": [ + "created", + "queued", + "starting", + "running", + "finalizing", + "finished" + ] }, - "status": { + "cancelRequested": { + "type": "boolean", + "description": "Whether cancel was requested" + }, + "outcome": { "type": "string", - "description": "Computed health status for this member", + "description": "Outcome; null until the run is finished", + "nullable": true, "enum": [ - "operational", - "maintenance", - "degraded", - "down" + "passed", + "failed", + "execution_error", + "timed_out", + "passed_on_retry", + "cancelled", + "inconclusive" ] }, - "effectiveFrequency": { + "headline": { "type": "string", - "description": "Effective check frequency label showing the group default when the monitor inherits it; null for services or when no group default is configured", + "description": "Last control headline", "nullable": true }, - "createdAt": { + "executionLine": { "type": "string", - "description": "Timestamp when the member was added to the group", - "format": "date-time" + "description": "Live execution one-liner", + "nullable": true }, - "uptime24h": { - "type": "number", - "description": "24h uptime percentage; populated when includeMetrics=true", - "format": "double", + "metaLine": { + "type": "string", + "description": "Server-composed header meta line", "nullable": true }, - "chartData": { - "type": "array", - "description": "Uptime tick values (0-100) for last-24h mini chart; populated when includeMetrics=true", - "nullable": true, - "items": { - "type": "number", - "description": "Uptime tick values (0-100) for last-24h mini chart; populated when includeMetrics=true", - "format": "double" - } + "bundleDigest": { + "minLength": 1, + "type": "string", + "description": "Package digest frozen at create" }, - "avgLatencyMs": { - "type": "number", - "description": "Average latency in ms (monitors only); populated when includeMetrics=true", - "format": "double", + "startedAt": { + "type": "string", + "description": "When execution claimed a seat", + "format": "date-time", "nullable": true }, - "p95LatencyMs": { - "type": "number", - "description": "P95 latency in ms (monitors only); populated when includeMetrics=true", - "format": "double", + "finishedAt": { + "type": "string", + "description": "When the run finished", + "format": "date-time", "nullable": true }, - "lastCheckedAt": { + "updatedAt": { "type": "string", - "description": "Timestamp of the most recent health check; populated when includeMetrics=true", + "description": "When the run row last changed", "format": "date-time", "nullable": true }, - "monitorType": { + "lastHeartbeatAt": { "type": "string", - "description": "Monitor type (HTTP, DNS, TCP, ICMP, HEARTBEAT, MCP); monitors only", + "description": "Last supervisor heartbeat", + "format": "date-time", "nullable": true }, - "environmentName": { + "cancelledBy": { "type": "string", - "description": "Environment name; monitors only", + "description": "Who requested cancel", "nullable": true }, - "groupMembershipCount": { + "artifactsExpiredAt": { + "type": "string", + "description": "When artifact bytes expired", + "format": "date-time", + "nullable": true + }, + "capturePolicySnapshot": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Capture settings frozen at create" + }, + "description": "Capture settings frozen at create" + }, + "bindingVersionSnapshot": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Resolved secret key names frozen at create" + }, + "description": "Resolved secret key names frozen at create" + }, + "durationMs": { "type": "integer", - "description": "Count of resource groups this monitor or service belongs to; detail GET only — omitted on list", + "description": "Wall time from claim to finish", + "format": "int64", + "nullable": true + }, + "queueWaitMs": { + "type": "integer", + "description": "Time spent waiting for a seat", + "format": "int64", + "nullable": true + }, + "queuePosition": { + "type": "integer", + "description": "Live queue position; null when not queued", "format": "int32", "nullable": true }, - "failingSince": { - "type": "string", - "description": "Start of the current non-operational stretch; null when operational or unknown (services OK); detail GET only — omitted on list", - "format": "date-time", + "heartbeatAgeMs": { + "type": "integer", + "description": "Milliseconds since the last supervisor heartbeat", + "format": "int64", "nullable": true }, - "alertCollapsed": { + "stream": { "type": "boolean", - "description": "True when an active member incident records this group among alertCollapsedByResourceGroupIds; detail GET only — omitted on list", - "nullable": true + "description": "True while the run is still live and clients may stream" }, - "incidentMarks": { + "evidence": { "type": "array", - "description": "Incident marks for the trailing 24h strip; null when metrics omitted or failed; detail GET only — omitted on list", + "description": "List evidence chips in SHOT → TRACE → VIDEO → NET order", + "items": { + "$ref": "#/components/schemas/RunEvidenceDto" + } + }, + "tabCounts": { + "$ref": "#/components/schemas/RunTabCountsDto" + }, + "live": { "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/RunLiveDto" + } + ] + }, + "attempt": { + "type": "integer", + "description": "Selected in-check attempt (1-based)", + "format": "int32" + }, + "attemptOf": { + "type": "integer", + "description": "In-check attempt count", + "format": "int32" + }, + "attempts": { + "type": "array", + "description": "In-check attempts", "items": { - "$ref": "#/components/schemas/ResourceGroupMemberIncidentMarkDto" + "$ref": "#/components/schemas/RunAttemptDto" } + }, + "incidentId": { + "type": "string", + "description": "Open incident for this monitor", + "format": "uuid", + "nullable": true } }, - "description": "A single member of a resource group with its computed health status" + "description": "Code-monitor run" }, - "ResourceGroupMemberIncidentMarkDto": { + "RunEventDto": { "required": [ - "at" + "createdAt", + "id", + "payload", + "runId", + "type", + "organizationId", + "seq" ], "type": "object", "properties": { - "at": { + "id": { "type": "string", - "description": "Incident startedAt (or first confirmed) within the trailing 24h window", - "format": "date-time" + "description": "Event identifier", + "format": "uuid" }, - "incidentId": { + "organizationId": { + "type": "integer", + "description": "Organization this event belongs to", + "format": "int32" + }, + "runId": { "type": "string", - "description": "Incident ID for navigation; null when unknown", + "description": "Run this event belongs to", + "format": "uuid" + }, + "seq": { + "type": "integer", + "description": "Supervisor-monotonic sequence, starts at 1", + "format": "int64" + }, + "type": { + "type": "string", + "description": "Control event type", + "enum": [ + "phase", + "headline", + "case_started", + "case_finished", + "step_started", + "step_finished", + "artifact_ready", + "artifact_lifecycle", + "finished", + "stream_gap" + ] + }, + "caseId": { + "type": "string", + "description": "Case this event refers to", "format": "uuid", "nullable": true }, - "severity": { + "stepId": { "type": "string", - "description": "Optional severity display hint", + "description": "Step this event refers to", + "format": "uuid", + "nullable": true + }, + "artifactId": { + "type": "string", + "description": "Artifact this event refers to", + "format": "uuid", "nullable": true + }, + "payload": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Small typed payload for this event" + }, + "description": "Small typed payload for this event" + }, + "createdAt": { + "type": "string", + "description": "When the event was persisted", + "format": "date-time" } }, - "description": "Member incident mark for the trailing 24h uptime strip" + "description": "Run control event" }, - "ResponseSizeAssertion": { + "RunEventParams": { "type": "object", "properties": { - "type": { + "after": { + "type": "integer", + "description": "Replay events with seq greater than this value", + "format": "int64", + "nullable": true + } + } + }, + "RunEvidenceDto": { + "required": [ + "kind", + "state" + ], + "type": "object", + "properties": { + "kind": { "type": "string", + "description": "Evidence kind in SHOT → TRACE → VIDEO → NET order", "enum": [ - "response_size" + "screenshot", + "trace", + "video", + "network" ] }, - "maxBytes": { - "type": "integer", - "description": "Maximum response body size in bytes before the check fails", - "format": "int32" + "state": { + "type": "string", + "description": "Whether the artifact is usable", + "enum": [ + "present", + "bad", + "processing", + "expired" + ] } }, - "required": [ - "type", - "maxBytes" - ] + "description": "List evidence chip" }, - "ResponseTimeAssertion": { + "RunListParams": { "type": "object", "properties": { - "type": { + "phase": { "type": "string", - "enum": [ - "response_time" - ] + "description": "Filter by run phase; omit to return every phase", + "nullable": true }, - "thresholdMs": { + "outcome": { + "type": "string", + "description": "Filter by persist outcome; omit to return every outcome", + "nullable": true + }, + "region": { + "type": "string", + "description": "Filter by probe region", + "nullable": true + }, + "source": { + "type": "string", + "description": "Filter by what triggered the run", + "nullable": true + }, + "environmentId": { + "type": "string", + "description": "Only return runs whose monitor lives in this environment", + "format": "uuid", + "nullable": true + }, + "from": { + "type": "string", + "description": "Inclusive lower bound on enqueued_at (default now-30m)", + "format": "date-time", + "nullable": true + }, + "to": { + "type": "string", + "description": "Inclusive upper bound on enqueued_at (default now)", + "format": "date-time", + "nullable": true + }, + "q": { + "type": "string", + "description": "Substring match on monitor name or headline", + "nullable": true + }, + "size": { + "maximum": 100, + "minimum": 1, "type": "integer", - "description": "Maximum allowed response time in milliseconds before the check fails", + "description": "Page size (1–100, default 50)", + "format": "int32" + }, + "page": { + "minimum": 0, + "type": "integer", + "description": "Zero-based page index (default 0)", "format": "int32" } }, "required": [ - "type", - "thresholdMs" + "size", + "page" ] }, - "ResponseTimeWarnAssertion": { + "RunLiveDto": { "type": "object", "properties": { - "type": { + "stepIndex": { + "type": "integer", + "description": "Current step index", + "format": "int32", + "nullable": true + }, + "stepTitle": { "type": "string", - "enum": [ - "response_time_warn" - ] + "description": "Current step title", + "nullable": true }, - "warnMs": { + "stepCount": { "type": "integer", - "description": "HTTP response time in milliseconds that triggers a warning only", + "description": "Known step count for this attempt", "format": "int32" + }, + "artifactsUploaded": { + "type": "integer", + "description": "Artifacts already available", + "format": "int32", + "nullable": true + }, + "artifactsExpected": { + "type": "integer", + "description": "Artifacts expected for this run", + "format": "int32", + "nullable": true } }, + "description": "Live run progress", "required": [ - "type", - "warnMs" + "stepCount" ] }, - "ResultSummaryDto": { + "RunnerLogLiveEvent": { "required": [ - "chartData", - "currentStatus", - "latestPerRegion" + "line", + "ts" ], "type": "object", "properties": { - "currentStatus": { + "ts": { "type": "string", - "description": "Derived current status across all regions", - "enum": [ - "up", - "degraded", - "down", - "paused", - "unknown" - ] - }, - "latestPerRegion": { - "type": "array", - "description": "Latest check result per region", - "items": { - "$ref": "#/components/schemas/RegionStatusDto" - } - }, - "chartData": { - "type": "array", - "description": "Time-bucketed chart data for the requested window", - "items": { - "$ref": "#/components/schemas/ChartBucketDto" - } + "description": "Loki timestamp in nanoseconds" }, - "uptime24h": { - "type": "number", - "description": "Uptime percentage over the last 24 hours; null when no data", - "format": "double", - "nullable": true, - "example": 99.95 - }, - "uptimeWindow": { - "type": "number", - "description": "Uptime percentage for the selected chart window; null when no data", - "format": "double", - "nullable": true, - "example": 99.8 + "line": { + "minLength": 1, + "type": "string", + "description": "One runner-log line" } }, - "description": "Dashboard summary: current status, per-region latest results, and chart data" + "description": "Live runner-log line" }, - "RetryStrategy": { + "RunNetworkDto": { "required": [ - "type", - "maxRetries", - "interval" + "data", + "hasMore" ], "type": "object", "properties": { - "type": { - "type": "string", - "description": "Retry strategy kind, e.g. fixed interval between attempts" + "data": { + "type": "array", + "description": "Waterfall rows on this page", + "items": { + "$ref": "#/components/schemas/NetworkRowDto" + } }, - "maxRetries": { + "caseDurationMs": { "type": "integer", - "description": "Maximum number of retries after a failed check", - "format": "int32" + "description": "Case wall time for waterfall bar scale", + "format": "int64", + "nullable": true }, - "interval": { - "type": "integer", - "description": "Delay between retry attempts in seconds", - "format": "int32" + "nextCursor": { + "type": "string", + "description": "Opaque cursor for the next page", + "nullable": true + }, + "hasMore": { + "type": "boolean", + "description": "Whether more rows exist beyond this page" } }, - "description": "Default retry strategy for member monitors; null clears" + "description": "Network waterfall page" }, - "RootlyChannelConfig": { - "required": [ - "channelType", - "apiKey" - ], + "RunNetworkParams": { "type": "object", "properties": { - "channelType": { + "attempt": { + "type": "integer", + "description": "In-check attempt (default selected attempt)", + "format": "int32", + "nullable": true + }, + "failed": { + "type": "boolean", + "description": "Only rows with status >= 400 or a failure", + "nullable": true + }, + "slow": { + "type": "boolean", + "description": "Only rows with durationMs >= 1000", + "nullable": true + }, + "stepId": { "type": "string", - "enum": [ - "rootly" - ] + "description": "Only rows for this step", + "nullable": true }, - "apiKey": { - "minLength": 1, + "xhr": { + "type": "boolean", + "description": "Only xhr, fetch, and api resource types", + "nullable": true + }, + "source": { "type": "string", - "description": "Rootly API token with incident creation permission" + "description": "page or request", + "nullable": true }, - "severity": { + "cursor": { "type": "string", - "description": "Severity slug override (e.g. sev0, sev1)", + "description": "Opaque cursor from the previous page", "nullable": true } } }, - "RuleEvaluationDto": { + "RunStepDto": { "required": [ - "checkId", - "engineVersion", - "evaluationDetails", + "caseId", + "category", "id", - "inputResultIds", - "monitorId", - "occurredAt", - "policySnapshotHashHex", - "region", - "ruleScope", - "ruleType", - "ruleIndex", - "outputMatched" + "runId", + "status", + "title", + "organizationId", + "attempt", + "index" ], "type": "object", "properties": { "id": { "type": "string", - "description": "Forensic row UUID", + "description": "Step identifier", "format": "uuid" }, - "occurredAt": { - "type": "string", - "description": "When the evaluation ran", - "format": "date-time" + "organizationId": { + "type": "integer", + "description": "Organization this step belongs to", + "format": "int32" }, - "monitorId": { + "runId": { "type": "string", - "description": "Monitor that produced the input check result", + "description": "Run this step belongs to", "format": "uuid" }, - "region": { - "minLength": 1, + "caseId": { "type": "string", - "description": "Probe region of the input check result" + "description": "Case this step belongs to", + "format": "uuid" }, - "policySnapshotHashHex": { - "minLength": 1, - "type": "string", - "description": "Hex-encoded hash of the policy snapshot this rule came from" + "attempt": { + "type": "integer", + "description": "Playwright in-case attempt number", + "format": "int32" }, - "ruleIndex": { + "index": { "type": "integer", - "description": "Index into the policy's triggerRules array (0-based)", + "description": "Zero-based index within the case attempt", "format": "int32" }, - "ruleType": { - "minLength": 1, + "title": { "type": "string", - "description": "Rule type (e.g. consecutive_failures, failures_in_window)" + "description": "Step title" }, - "ruleScope": { - "minLength": 1, + "category": { "type": "string", - "description": "Rule scope (per_region | multi_region)" + "description": "Step category", + "enum": [ + "named", + "assertion", + "browser_action" + ] }, - "inputResultIds": { - "minItems": 1, - "type": "array", - "description": "check_results IDs that were inputs to this evaluation (newest first)", - "items": { - "type": "string", - "description": "check_results IDs that were inputs to this evaluation (newest first)", - "format": "uuid" - } + "status": { + "type": "string", + "description": "Step status", + "enum": [ + "pending", + "running", + "passed", + "slow", + "failed", + "skipped", + "suppressed", + "never_reached" + ] }, - "outputMatched": { - "type": "boolean", - "description": "Whether the rule fired on this evaluation" + "startedAt": { + "type": "string", + "description": "When the step started", + "format": "date-time", + "nullable": true }, - "evaluationDetails": { + "finishedAt": { + "type": "string", + "description": "When the step finished", + "format": "date-time", + "nullable": true + }, + "durationMs": { + "type": "integer", + "description": "Reporter duration in milliseconds", + "format": "int32", + "nullable": true + }, + "error": { + "type": "string", + "description": "Error when the step failed", + "nullable": true + }, + "assertion": { "type": "object", "additionalProperties": { "type": "object", - "description": "Structured details (e.g. failure counts, response-time aggregates)" + "description": "Assertion payload when this step is an assertion", + "nullable": true }, - "description": "Structured details (e.g. failure counts, response-time aggregates)" - }, - "engineVersion": { - "minLength": 1, - "type": "string", - "description": "Detection engine version that ran this evaluation" + "description": "Assertion payload when this step is an assertion", + "nullable": true + } + }, + "description": "Run step" + }, + "RunTabCountsDto": { + "type": "object", + "properties": { + "steps": { + "type": "integer", + "description": "Step rows for the selected attempt", + "format": "int32" }, - "checkId": { - "type": "string", - "description": "Scheduler-minted check execution ID (V92) — the causal chain identifier", - "format": "uuid" + "assets": { + "type": "integer", + "description": "Items across asset kinds, excluding dead no-browser rows", + "format": "int32" }, - "triggeringTransitionId": { - "type": "string", - "description": "If this evaluation caused a state transition, points to that transition's id", - "format": "uuid", - "nullable": true + "diff": { + "type": "integer", + "description": "1 when a diff baseline exists or this run passed on retry", + "format": "int32" } }, - "description": "All rule evaluations that ran for this check" + "description": "Run detail tab counts", + "required": [ + "steps", + "assets", + "diff" + ] }, "ScheduledMaintenanceDto": { "required": [ @@ -34642,27 +42439,55 @@ "description": "A scheduled maintenance window from a vendor status page" }, "ScriptMonitorConfig": { - "required": [ - "script" - ], "type": "object", + "additionalProperties": false, "properties": { "script": { "maxLength": 65536, - "minLength": 1, + "minLength": 0, "type": "string", - "description": "Playwright test script source code" + "description": "Legacy inline script on existing rows", + "nullable": true, + "readOnly": true }, "timeoutSeconds": { - "maximum": 120, + "maximum": 240, "minimum": 5, "type": "integer", - "description": "Maximum execution time in seconds (5–120)", + "description": "Maximum execution time in seconds (5–240)", "format": "int32", "nullable": true + }, + "runtimeId": { + "maxLength": 32, + "minLength": 0, + "pattern": "^$|^[A-Za-z0-9._-]+$", + "type": "string", + "description": "Runtime pin YYYY.MM; omit uses workspace default then sole available", + "nullable": true } } }, + "SecretAuditDto": { + "type": "object", + "properties": { + "updatedAt": { + "type": "string", + "description": "When this secret was last updated", + "format": "date-time", + "nullable": true + }, + "updatedBy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/UserDto" + } + ] + } + }, + "description": "Last update time and author for a secret" + }, "SecretDto": { "required": [ "createdAt", @@ -34704,14 +42529,91 @@ }, "usedByMonitors": { "type": "array", - "description": "Monitors that reference this secret; null on create/update responses", + "description": "Monitors that reference this secret for authentication", "nullable": true, "items": { "$ref": "#/components/schemas/MonitorReference" } } }, - "description": "Secret with change-detection hash; plaintext value is never returned" + "description": "Organization secret and its change-detection hash" + }, + "SecretRequestDto": { + "required": [ + "key", + "readiness" + ], + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "Secret key this monitor requires" + }, + "secret": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/SecretDto" + } + ] + }, + "readiness": { + "type": "string", + "description": "Whether this key is resolved or missing", + "enum": [ + "resolved", + "missing" + ] + }, + "fulfilledBy": { + "type": "string", + "description": "Fulfilled from environment variables or a secret", + "nullable": true, + "enum": [ + "env", + "secret" + ] + }, + "declaringFile": { + "type": "string", + "description": "Declaring file path inside the package zip", + "nullable": true + }, + "declaringLocation": { + "type": "string", + "description": "Call site from package scan, e.g. signIn(…) · line 6", + "nullable": true + }, + "lastResolvedAt": { + "type": "string", + "format": "date-time", + "description": "When a run last resolved this key", + "nullable": true + }, + "lastResolvedRunId": { + "type": "string", + "format": "uuid", + "description": "Run that last resolved this key", + "nullable": true + } + }, + "description": "Secret key a monitor requires and how it is fulfilled" + }, + "SecretUsageDto": { + "required": [ + "monitors" + ], + "type": "object", + "properties": { + "monitors": { + "type": "array", + "description": "Monitors that reference this secret", + "items": { + "$ref": "#/components/schemas/MonitorDto" + } + } + }, + "description": "Monitors that reference this secret" }, "SeoMetadataDto": { "type": "object", @@ -35845,6 +43747,17 @@ } } }, + "SingleValueResponseCaptureCompareDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/CaptureCompareDto" + } + } + }, "SingleValueResponseCheckTraceDto": { "required": [ "data" @@ -35867,6 +43780,28 @@ } } }, + "SingleValueResponseDefinitionDetailDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/DefinitionDetailDto" + } + } + }, + "SingleValueResponseDefinitionHeadDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/DefinitionHeadDto" + } + } + }, "SingleValueResponseDekRotationResultDto": { "required": [ "data" @@ -36037,6 +43972,28 @@ } } }, + "SingleValueResponseMonitorSecretRequestsDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/MonitorSecretRequestsDto" + } + } + }, + "SingleValueResponseMonitorSessionDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/MonitorSessionDto" + } + } + }, "SingleValueResponseMonitorTestResultDto": { "required": [ "data" @@ -36059,6 +44016,17 @@ } } }, + "SingleValueResponseNetworkRowDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/NetworkRowDto" + } + } + }, "SingleValueResponseNotificationDispatchDto": { "required": [ "data" @@ -36092,6 +44060,28 @@ } } }, + "SingleValueResponseOverviewStepsDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/OverviewStepsDto" + } + } + }, + "SingleValueResponsePackageUploadDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PackageUploadDto" + } + } + }, "SingleValueResponsePolicySnapshotDto": { "required": [ "data" @@ -36147,6 +44137,83 @@ } } }, + "SingleValueResponseRevisionDiffDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/RevisionDiffDto" + } + } + }, + "SingleValueResponseRevisionDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/RevisionDto" + } + } + }, + "SingleValueResponseRollbackPreviewDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/RollbackPreviewDto" + } + } + }, + "SingleValueResponseRunConsoleDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/RunConsoleDto" + } + } + }, + "SingleValueResponseRunDiffDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/RunDiffDto" + } + } + }, + "SingleValueResponseRunDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/RunDto" + } + } + }, + "SingleValueResponseSecretAuditDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/SecretAuditDto" + } + } + }, "SingleValueResponseSecretDto": { "required": [ "data" @@ -36158,6 +44225,17 @@ } } }, + "SingleValueResponseSecretUsageDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/SecretUsageDto" + } + } + }, "SingleValueResponseServiceDayDetailDto": { "required": [ "data" @@ -36658,6 +44736,10 @@ } }, "SslExpiryAssertion": { + "required": [ + "type", + "minDaysRemaining" + ], "type": "object", "properties": { "type": { @@ -36671,11 +44753,7 @@ "description": "Minimum days before TLS certificate expiry; fails or warns below this threshold", "format": "int32" } - }, - "required": [ - "type", - "minDaysRemaining" - ] + } }, "StateTransitionDetails": { "required": [ @@ -37822,10 +45900,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37858,10 +45932,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37894,10 +45964,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37930,10 +45996,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37966,10 +46028,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38002,9 +46060,37 @@ "type": "integer", "format": "int32", "nullable": true + } + } + }, + "TableValueResultDefinitionDto": { + "required": [ + "data", + "hasNext", + "hasPrev" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DefinitionDto" + } + }, + "hasNext": { + "type": "boolean" + }, + "hasPrev": { + "type": "boolean" + }, + "totalElements": { + "type": "integer", + "format": "int64", + "nullable": true }, - "nextCursor": { - "type": "string", + "totalPages": { + "type": "integer", + "format": "int32", "nullable": true } } @@ -38038,10 +46124,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38074,10 +46156,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38110,10 +46188,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38146,10 +46220,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38182,10 +46252,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38218,10 +46284,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38254,10 +46316,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38290,10 +46348,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38326,10 +46380,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38362,10 +46412,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38398,10 +46444,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38434,10 +46476,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38470,10 +46508,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38506,9 +46540,37 @@ "type": "integer", "format": "int32", "nullable": true + } + } + }, + "TableValueResultRevisionDto": { + "required": [ + "data", + "hasNext", + "hasPrev" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RevisionDto" + } }, - "nextCursor": { - "type": "string", + "hasNext": { + "type": "boolean" + }, + "hasPrev": { + "type": "boolean" + }, + "totalElements": { + "type": "integer", + "format": "int64", + "nullable": true + }, + "totalPages": { + "type": "integer", + "format": "int32", "nullable": true } } @@ -38542,14 +46604,42 @@ "type": "integer", "format": "int32", "nullable": true + } + } + }, + "TableValueResultRunArtifactDto": { + "required": [ + "data", + "hasNext", + "hasPrev" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RunArtifactDto" + } }, - "nextCursor": { - "type": "string", + "hasNext": { + "type": "boolean" + }, + "hasPrev": { + "type": "boolean" + }, + "totalElements": { + "type": "integer", + "format": "int64", + "nullable": true + }, + "totalPages": { + "type": "integer", + "format": "int32", "nullable": true } } }, - "TableValueResultScheduledMaintenanceDto": { + "TableValueResultRunCaseDto": { "required": [ "data", "hasNext", @@ -38560,7 +46650,7 @@ "data": { "type": "array", "items": { - "$ref": "#/components/schemas/ScheduledMaintenanceDto" + "$ref": "#/components/schemas/RunCaseDto" } }, "hasNext": { @@ -38578,14 +46668,42 @@ "type": "integer", "format": "int32", "nullable": true + } + } + }, + "TableValueResultRunDto": { + "required": [ + "data", + "hasNext", + "hasPrev" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RunDto" + } }, - "nextCursor": { - "type": "string", + "hasNext": { + "type": "boolean" + }, + "hasPrev": { + "type": "boolean" + }, + "totalElements": { + "type": "integer", + "format": "int64", + "nullable": true + }, + "totalPages": { + "type": "integer", + "format": "int32", "nullable": true } } }, - "TableValueResultSecretDto": { + "TableValueResultScheduledMaintenanceDto": { "required": [ "data", "hasNext", @@ -38596,7 +46714,7 @@ "data": { "type": "array", "items": { - "$ref": "#/components/schemas/SecretDto" + "$ref": "#/components/schemas/ScheduledMaintenanceDto" } }, "hasNext": { @@ -38614,9 +46732,37 @@ "type": "integer", "format": "int32", "nullable": true + } + } + }, + "TableValueResultSecretDto": { + "required": [ + "data", + "hasNext", + "hasPrev" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SecretDto" + } }, - "nextCursor": { - "type": "string", + "hasNext": { + "type": "boolean" + }, + "hasPrev": { + "type": "boolean" + }, + "totalElements": { + "type": "integer", + "format": "int64", + "nullable": true + }, + "totalPages": { + "type": "integer", + "format": "int32", "nullable": true } } @@ -38650,10 +46796,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38686,10 +46828,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38722,10 +46860,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38758,10 +46892,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38794,10 +46924,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38830,10 +46956,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38866,10 +46988,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38902,10 +47020,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38938,10 +47052,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38974,10 +47084,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39010,10 +47116,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39046,10 +47148,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39082,10 +47180,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39118,10 +47212,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39154,10 +47244,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39190,10 +47276,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39729,6 +47811,80 @@ }, "description": "TLS/SSL certificate details for HTTPS targets" }, + "TraceEntryPoint": { + "required": [ + "actionIndex", + "id", + "label", + "note" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Doorway id", + "enum": [ + "failing_action", + "failing_step", + "first_failed_request", + "case_start" + ] + }, + "actionIndex": { + "type": "integer", + "description": "Action index this doorway opens", + "format": "int32" + }, + "label": { + "minLength": 1, + "type": "string", + "description": "Label shown on the doorway" + }, + "note": { + "minLength": 1, + "type": "string", + "description": "Short note for why this doorway exists" + } + }, + "description": "Four doorways into the downloaded file" + }, + "TraceNearbyAction": { + "required": [ + "actionIndex", + "kind", + "title", + "isTeardown" + ], + "type": "object", + "properties": { + "actionIndex": { + "type": "integer", + "description": "Action index in the Playwright trace", + "format": "int32" + }, + "kind": { + "minLength": 1, + "type": "string", + "description": "Playwright action kind" + }, + "title": { + "minLength": 1, + "type": "string", + "description": "Human title for this action" + }, + "durationMs": { + "type": "integer", + "description": "Action duration in milliseconds", + "format": "int32", + "nullable": true + }, + "isTeardown": { + "type": "boolean", + "description": "Whether this action is teardown" + } + }, + "description": "Actions around the failure, teardown labelled" + }, "TriggerRule": { "required": [ "scope", @@ -40474,7 +48630,7 @@ "maxLength": 255, "minLength": 0, "type": "string", - "description": "New monitor name; null preserves current", + "description": "New monitor name. Null preserves current", "nullable": true }, "config": { @@ -40507,27 +48663,27 @@ "maximum": 86400, "minimum": 10, "type": "integer", - "description": "New check frequency in seconds (10–86400); null preserves current", + "description": "New check frequency in seconds (10–86400). Null preserves current", "format": "int32", "nullable": true }, "enabled": { "type": "boolean", - "description": "Enable or disable the monitor; null preserves current", + "description": "Enable or disable the monitor (pause or resume). Null preserves current", "nullable": true }, "regions": { "type": "array", - "description": "New probe regions; null preserves current. Allowed values are deployment-dependent.", + "description": "New probe regions. Null preserves current. Allowed values are deployment-dependent", "nullable": true, "items": { "type": "string", - "description": "New probe regions; null preserves current. Allowed values are deployment-dependent." + "description": "New probe regions. Null preserves current. Allowed values are deployment-dependent" } }, "managedBy": { "type": "string", - "description": "New ownership source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value", + "description": "New ownership source: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null preserves current", "nullable": true, "enum": [ "DASHBOARD", @@ -40539,7 +48695,7 @@ }, "environmentId": { "type": "string", - "description": "New environment ID; null preserves current (use clearEnvironmentId to unset)", + "description": "New environment; null preserves current", "format": "uuid", "nullable": true }, @@ -40550,7 +48706,7 @@ }, "assertions": { "type": "array", - "description": "Replace all assertions; null preserves current", + "description": "Replace all assertions. Null preserves current", "nullable": true, "items": { "$ref": "#/components/schemas/CreateAssertionRequest" @@ -40579,11 +48735,11 @@ }, "alertChannelIds": { "type": "array", - "description": "Replace alert channel list; null preserves current", + "description": "Replace alert channel list. Null preserves current", "nullable": true, "items": { "type": "string", - "description": "Replace alert channel list; null preserves current", + "description": "Replace alert channel list. Null preserves current", "format": "uuid" } }, @@ -40594,6 +48750,35 @@ "$ref": "#/components/schemas/AddMonitorTagsRequest" } ] + }, + "capturePolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CapturePolicy" + } + ] + }, + "fastRetryMaxAttempts": { + "maximum": 10, + "minimum": 0, + "type": "integer", + "description": "Fast-retry attempts after failure. Null preserves current. 0 disables", + "format": "int32", + "nullable": true + }, + "package": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/MonitorPackageSpec" + } + ] + }, + "status": { + "type": "string", + "description": "Not writable; use pause or resume", + "nullable": true } } }, @@ -41508,6 +49693,35 @@ "channelType" ] }, + "UpsertMonitorSessionRequest": { + "required": [ + "reusePolicy", + "setupFile" + ], + "type": "object", + "properties": { + "reusePolicy": { + "type": "string", + "description": "When to reuse the cached session across runs", + "enum": [ + "reuse", + "every_run", + "on_failure" + ] + }, + "setupFile": { + "minLength": 1, + "type": "string", + "description": "Setup file path inside the package zip" + }, + "expiresAt": { + "type": "string", + "description": "When the cached session expires; null preserves current", + "format": "date-time", + "nullable": true + } + } + }, "UptimeBucketDto": { "required": [ "timestamp", @@ -41585,6 +49799,20 @@ "description": "Number of incidents that started within the requested window", "format": "int64", "example": 2 + }, + "firstTryPercent": { + "type": "number", + "description": "First-try pass percent for settled parent runs in the window; null when the monitor has no run history", + "format": "double", + "nullable": true, + "example": 96.2 + }, + "retryCount": { + "type": "integer", + "description": "Settled retry runs in the window; null when the monitor has no run history", + "format": "int64", + "nullable": true, + "example": 12 } }, "description": "Uptime statistics aggregated from continuous aggregates", @@ -41594,6 +49822,73 @@ "incidentCount" ] }, + "UserDto": { + "required": [ + "createdAt", + "email", + "updatedAt", + "userRole", + "id", + "emailVerified" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Unique user identifier", + "format": "int32" + }, + "email": { + "type": "string", + "description": "User email address" + }, + "emailVerified": { + "type": "boolean", + "description": "Whether the email address has been verified" + }, + "name": { + "type": "string", + "description": "Display name; null if not set", + "nullable": true + }, + "userRole": { + "type": "string", + "description": "Platform role: USER or SUPERADMIN", + "enum": [ + "SUPERADMIN", + "ADMIN", + "USER" + ] + }, + "onboardingStage": { + "type": "string", + "description": "Current onboarding progress stage; null when completed", + "nullable": true, + "enum": [ + "WELCOME", + "FIRST_MONITOR", + "SETUP_COMPLETE", + "COMPLETED" + ] + }, + "imageUrl": { + "type": "string", + "description": "Profile image URL; null if not set", + "nullable": true + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the account was created", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "description": "Timestamp when the account was last updated", + "format": "date-time" + } + }, + "description": "User account details" + }, "VoiceLanguageDto": { "required": [ "code", @@ -41905,6 +50200,19 @@ }, "description": "Workspace within an organization" }, + "WriteSecretEnvironmentValueRequest": { + "required": [ + "value" + ], + "type": "object", + "properties": { + "value": { + "minLength": 1, + "type": "string", + "description": "Plaintext value to encrypt for this environment" + } + } + }, "ZapierChannelConfig": { "required": [ "channelType", diff --git a/src/devhelm/_generated.py b/src/devhelm/_generated.py index 1a01743..dc34b73 100644 --- a/src/devhelm/_generated.py +++ b/src/devhelm/_generated.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Annotated, Any, Literal -from pydantic import ConfigDict, AwareDatetime, BaseModel, EmailStr, Field, RootModel +from pydantic import AwareDatetime, BaseModel, ConfigDict, EmailStr, Field, RootModel from enum import StrEnum from uuid import UUID from datetime import date as date_aliased @@ -465,6 +465,13 @@ class ApiKeyDto(BaseModel): ] = None +class ArtifactViewport(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + width: Annotated[int, Field(description="Viewport width in CSS pixels")] + height: Annotated[int, Field(description="Viewport height in CSS pixels")] + dpr: Annotated[int, Field(description="Device pixel ratio at capture")] + + class AssertionResultDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) type: Annotated[str, Field(description="Assertion type", examples=["status_code"])] @@ -538,6 +545,35 @@ class Action(StrEnum): remove_tag = "REMOVE_TAG" +class Screenshots(StrEnum): + always = "always" + on_failure = "on_failure" + off = "off" + + +class Trace(StrEnum): + always = "always" + on_failure = "on_failure" + off = "off" + + +class Video(StrEnum): + always = "always" + on_failure = "on_failure" + off = "off" + + +class CapturePolicy(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + screenshots: Annotated[ + Screenshots | None, Field(description="When to capture screenshots") + ] = None + trace: Annotated[ + Trace | None, Field(description="When to capture a Playwright trace") + ] = None + video: Annotated[Video | None, Field(description="When to capture video")] = None + + class CategoryDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) category: Annotated[ @@ -811,6 +847,58 @@ class ConfirmationPolicy(BaseModel): ] +class ConsoleGroupDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + level: Annotated[ + str, Field(description="UI bucket: error, warning, or info", min_length=1) + ] + text: Annotated[str, Field(description="Repeated message text", min_length=1)] + count: Annotated[int, Field(description="How many times this message occurred")] + source_url: Annotated[ + str, + Field( + alias="sourceUrl", + description="Source URL of the first occurrence", + min_length=1, + ), + ] + step_id_first: Annotated[ + str | None, + Field(alias="stepIdFirst", description="First step that logged this message"), + ] = None + step_id_last: Annotated[ + str | None, + Field(alias="stepIdLast", description="Last step that logged this message"), + ] = None + + +class ConsoleLineDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[str, Field(description="Stable line id from capture", min_length=1)] + step_id: Annotated[ + str | None, Field(alias="stepId", description="Step this line belonged to") + ] = None + level: Annotated[ + str, Field(description="UI bucket: error, warning, or info", min_length=1) + ] + text: Annotated[str, Field(description="Console message text", min_length=1)] + source_url: Annotated[ + str, + Field( + alias="sourceUrl", + description="Script URL that logged this line", + min_length=1, + ), + ] + line_number: Annotated[ + int, Field(alias="lineNumber", description="Source line number") + ] + column_number: Annotated[ + int, Field(alias="columnNumber", description="Source column number") + ] + ts: Annotated[str, Field(description="When the line was captured", min_length=1)] + + class ManagedBy(StrEnum): dashboard = "DASHBOARD" cli = "CLI" @@ -989,6 +1077,18 @@ class Type(StrEnum): multi_step_api = "MULTI_STEP_API" +class CreatePackageUploadRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + digest: Annotated[ + str, + Field( + description="SHA-256 hex digest of the package zip to upload (64 chars)", + max_length=64, + min_length=64, + ), + ] + + class HealthThresholdType(StrEnum): count = "COUNT" # type: ignore[assignment] percentage = "PERCENTAGE" @@ -1387,6 +1487,31 @@ class DayIncident(BaseModel): ] +class DefinitionDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[UUID, Field(description="Definition identifier")] + organization_id: Annotated[ + int, + Field( + alias="organizationId", + description="Organization this definition belongs to", + ), + ] + name: Annotated[str, Field(description="Human-readable name", min_length=1)] + slug: Annotated[ + str, + Field(description="URL-safe slug unique within the organization", min_length=1), + ] + created_at: Annotated[ + AwareDatetime, + Field(alias="createdAt", description="When the definition was created"), + ] + updated_at: Annotated[ + AwareDatetime, + Field(alias="updatedAt", description="When the definition was last updated"), + ] + + class DekRotationResultDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) previous_dek_version: Annotated[ @@ -3237,12 +3362,225 @@ class MonitorAuthDto(BaseModel): config: ApiKeyAuthConfig | BasicAuthConfig | BearerAuthConfig | HeaderAuthConfig +class MonitorOverlayRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + reason: Annotated[ + str | None, + Field( + description="Optional human-readable reason (max 280)", + max_length=280, + min_length=0, + ), + ] = None + expires_at: Annotated[ + AwareDatetime | None, + Field(alias="expiresAt", description="When this overlay expires"), + ] = None + + +class File(RootModel[str]): + root: Annotated[ + str, + Field( + description="Relative file paths included in the zip", + max_length=512, + min_length=0, + ), + ] + + +class Key(RootModel[str]): + root: Annotated[ + str, + Field( + description="Secret names the zip demanded. PUT: null preserves, [] clears", + max_length=255, + min_length=0, + ), + ] + + +class KeyLocation(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + key: Annotated[str, Field(description="Secret name the code reads", max_length=255)] + declaring_file: Annotated[ + str | None, + Field( + alias="declaringFile", + description="Declaring file path inside the zip", + max_length=512, + ), + ] = None + declaring_location: Annotated[ + str | None, + Field( + alias="declaringLocation", + description="Call site from package scan, e.g. signIn(…) · line 6", + max_length=255, + ), + ] = None + + +class MonitorPackageSpec(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + digest: Annotated[ + str, + Field( + description="SHA-256 hex digest of the package zip (64 characters)", + max_length=64, + min_length=64, + ), + ] + entrypoint: Annotated[ + str, + Field( + description="Entrypoint path inside the zip, e.g. tests/login.spec.ts", + max_length=512, + min_length=0, + ), + ] + files: Annotated[ + list[File], + Field( + description="Relative file paths included in the zip", + max_length=256, + min_length=0, + ), + ] + keys: Annotated[ + list[Key] | None, + Field( + description="Secret names the zip demanded. PUT: null preserves, [] clears", + max_length=64, + min_length=0, + ), + ] = None + git_sha: Annotated[ + str | None, + Field( + alias="gitSha", + description="Commit SHA from the repo that produced this zip. Client-supplied provenance only", + max_length=64, + min_length=0, + ), + ] = None + git_message: Annotated[ + str | None, + Field( + alias="gitMessage", + description="Commit message from the repo that produced this zip", + max_length=1024, + min_length=0, + ), + ] = None + git_file: Annotated[ + str | None, + Field( + alias="gitFile", + description="Path of the declaring file in that repo", + max_length=512, + min_length=0, + ), + ] = None + authored_by: Annotated[ + str | None, + Field( + alias="authoredBy", + description="Author attribution supplied with the package", + max_length=255, + min_length=0, + ), + ] = None + key_locations: Annotated[ + list[KeyLocation] | None, + Field( + alias="keyLocations", + description="Per-key declaring file and location from package scan", + max_length=64, + min_length=0, + ), + ] = None + + class MonitorReference(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: Annotated[UUID, Field(description="Monitor identifier")] name: Annotated[str, Field(description="Monitor name")] +class MonitorRunListParams(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + phase: Annotated[ + str | None, Field(description="Filter by run phase; omit to return every phase") + ] = None + outcome: Annotated[ + str | None, + Field(description="Filter by persist outcome; omit to return every outcome"), + ] = None + region: Annotated[str | None, Field(description="Filter by probe region")] = None + source: Annotated[ + str | None, Field(description="Filter by what triggered the run") + ] = None + q: Annotated[str | None, Field(description="Substring match on headline")] = None + revision_id: Annotated[ + UUID | None, + Field(alias="revisionId", description="Only runs for this published revision"), + ] = None + cursor: Annotated[ + str | None, Field(description="Opaque cursor from a previous page") + ] = None + limit: Annotated[ + int, Field(description="Page size (1–100, default 25)", ge=1, le=100) + ] + + +class MonitorSessionDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + lifecycle: Annotated[str, Field(description="Current session cache state")] + reuse_policy: Annotated[ + str, + Field( + alias="reusePolicy", + description="When the cached session is reused across runs", + ), + ] + setup_file: Annotated[ + str, + Field(alias="setupFile", description="Setup file path inside the package zip"), + ] + signs_in_as: Annotated[ + str | None, + Field(alias="signsInAs", description="Account this cache signed in as"), + ] = None + expires_at: Annotated[ + AwareDatetime | None, + Field(alias="expiresAt", description="When the cached session expires"), + ] = None + cookie_names: Annotated[ + list[str], + Field(alias="cookieNames", description="Cookie names in the cached session"), + ] + storage_keys: Annotated[ + list[str], + Field( + alias="storageKeys", description="Storage key names in the cached session" + ), + ] + size_bytes: Annotated[ + int | None, Field(alias="sizeBytes", description="Cached session size in bytes") + ] = None + last_rejected_run_id: Annotated[ + UUID | None, + Field( + alias="lastRejectedRunId", description="Run that last rejected this cache" + ), + ] = None + updated_at: Annotated[ + AwareDatetime | None, + Field(alias="updatedAt", description="When this session row was last written"), + ] = None + + class MonitorsSummaryDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) total: Annotated[ @@ -3302,6 +3640,40 @@ class MonitorTestResultDto(BaseModel): warnings: list[str] | None = None +class NearestOtherRegion(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + run_id: Annotated[ + UUID, Field(alias="runId", description="Run that holds the other-region shot") + ] + region: Annotated[str, Field(description="Region of that run")] + artifact_id: Annotated[ + UUID, Field(alias="artifactId", description="Screenshot on that run") + ] + + +class NetworkTimingDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + dns_ms: Annotated[ + int | None, Field(alias="dnsMs", description="DNS lookup time in milliseconds") + ] = None + connect_ms: Annotated[ + int | None, + Field(alias="connectMs", description="TCP connect time in milliseconds"), + ] = None + tls_ms: Annotated[ + int | None, + Field(alias="tlsMs", description="TLS handshake time in milliseconds"), + ] = None + waiting_ms: Annotated[ + int | None, + Field(alias="waitingMs", description="Time to first byte in milliseconds"), + ] = None + transfer_ms: Annotated[ + int | None, + Field(alias="transferMs", description="Response transfer time in milliseconds"), + ] = None + + class NewTagRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) name: Annotated[str, Field(description="Tag name", max_length=100, min_length=0)] @@ -3634,54 +4006,165 @@ class OrgInfo(BaseModel): name: Annotated[str, Field(description="Organization name")] -class Pageable(BaseModel): +class OverviewStepCellDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) - page: Annotated[int, Field(ge=0)] - size: Annotated[int, Field(ge=1)] - sort: list[str] + id: Annotated[str, Field(description="Stable cell id")] + outcome: Annotated[ + str, Field(description="Step outcome for that run", min_length=1) + ] + at: Annotated[str | None, Field(description="When that step settled")] = None -class PagerDutyChannelConfig(BaseModel): +class OverviewStepDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) - channel_type: Annotated[Literal["pagerduty"], Field(alias="channelType")] = ( - "pagerduty" - ) - routing_key: Annotated[ + index: Annotated[ + int, Field(description="0-based step index from the Head revision catalog") + ] + name: Annotated[ str, + Field(description="Step title from the Head revision catalog", min_length=1), + ] + p50_ms: Annotated[ + float | None, Field( - alias="routingKey", - description="PagerDuty Events API v2 routing (integration) key", - min_length=1, + alias="p50Ms", + description="Median duration in ms; null until the step has settled timings", ), - ] - severity_override: Annotated[ - str | None, + ] = None + p95_ms: Annotated[ + float | None, Field( - alias="severityOverride", description="Override PagerDuty severity mapping" + alias="p95Ms", + description="p95 duration in ms; null until the step has settled timings", ), ] = None - - -class PageSection(BaseModel): - model_config = ConfigDict(extra="ignore", populate_by_name=True) - group_id: Annotated[ - UUID | None, - Field(alias="groupId", description="Group ID when this section is a group"), + failed: Annotated[ + int, Field(description="Failed first-attempt count in the window") + ] + first_try_percent: Annotated[ + float | None, + Field( + alias="firstTryPercent", + description="First-try pass percent for this step; null when no settled attempts", + ), ] = None - component_id: Annotated[ - UUID | None, + flake_retries: Annotated[ + int | None, Field( - alias="componentId", - description="Component ID when this section is an ungrouped component", + alias="flakeRetries", + description="Retry attempts on this step; null when none", ), ] = None - page_order: Annotated[ - int, Field(alias="pageOrder", description="Position on the page (0-based)") + cells: Annotated[ + list[OverviewStepCellDto], + Field(description="Last 30 outcomes for this step, oldest first"), ] - - -class PhoneCallChannelConfig(BaseModel): - model_config = ConfigDict(extra="ignore", populate_by_name=True) + expected: Annotated[ + str | None, Field(description="Assertion expected from the latest failure") + ] = None + received: Annotated[ + str | None, Field(description="Assertion received from the latest failure") + ] = None + error: Annotated[ + str | None, Field(description="Error text from the latest failure") + ] = None + region: Annotated[str | None, Field(description="Region of the latest failure")] = ( + None + ) + failed_at: Annotated[ + str | None, + Field(alias="failedAt", description="When the latest failure settled"), + ] = None + latest_failed_run_id: Annotated[ + UUID | None, + Field( + alias="latestFailedRunId", + description="Run that produced the latest failure", + ), + ] = None + + +class OverviewStepsDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + steps: Annotated[ + list[OverviewStepDto], + Field( + description="Rows in revision order; empty when the monitor has no step catalog" + ), + ] + + +class PackageUploadDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + put_url: Annotated[ + str, + Field( + alias="putUrl", + description="Presigned PUT URL for the zip bytes", + min_length=1, + ), + ] + expires_at: Annotated[ + AwareDatetime, + Field(alias="expiresAt", description="When the signed URL expires"), + ] + required_headers: Annotated[ + dict[str, str], + Field( + alias="requiredHeaders", + description="Must send Content-Type: application/zip and If-None-Match: *", + ), + ] + + +class Pageable(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + page: Annotated[int, Field(ge=0)] + size: Annotated[int, Field(ge=1)] + sort: list[str] + + +class PagerDutyChannelConfig(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + channel_type: Annotated[Literal["pagerduty"], Field(alias="channelType")] = ( + "pagerduty" + ) + routing_key: Annotated[ + str, + Field( + alias="routingKey", + description="PagerDuty Events API v2 routing (integration) key", + min_length=1, + ), + ] + severity_override: Annotated[ + str | None, + Field( + alias="severityOverride", description="Override PagerDuty severity mapping" + ), + ] = None + + +class PageSection(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + group_id: Annotated[ + UUID | None, + Field(alias="groupId", description="Group ID when this section is a group"), + ] = None + component_id: Annotated[ + UUID | None, + Field( + alias="componentId", + description="Component ID when this section is an ungrouped component", + ), + ] = None + page_order: Annotated[ + int, Field(alias="pageOrder", description="Position on the page (0-based)") + ] + + +class PhoneCallChannelConfig(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) channel_type: Annotated[Literal["phone_call"], Field(alias="channelType")] = ( "phone_call" ) @@ -3722,6 +4205,17 @@ class PhoneCallChannelConfig(BaseModel): ] = None +class PickerItem(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + run_id: Annotated[UUID, Field(alias="runId", description="Finished run identifier")] + revision_id: Annotated[ + UUID, Field(alias="revisionId", description="Revision that run executed") + ] + finished_at: Annotated[ + AwareDatetime, Field(alias="finishedAt", description="When that run finished") + ] + + class Tier(StrEnum): free = "FREE" starter = "STARTER" @@ -3848,6 +4342,17 @@ class PricingTier(BaseModel): ] = None +class PublishRevisionRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + revision_id: Annotated[ + UUID, + Field( + alias="revisionId", + description="Existing revision to activate as Head for this monitor's environment", + ), + ] + + class Status7(StrEnum): investigating = "INVESTIGATING" identified = "IDENTIFIED" @@ -3934,6 +4439,22 @@ class PushoverChannelConfig(BaseModel): ) +class QuarantineMonitorRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + reason: Annotated[ + str, + Field( + description="Reason for this hold (max 280)", max_length=280, min_length=0 + ), + ] + expires_at: Annotated[ + AwareDatetime, Field(alias="expiresAt", description="When the hold expires") + ] + from_run_id: Annotated[ + UUID | None, Field(alias="fromRunId", description="Run that prompted this hold") + ] = None + + class RateLimitInfo(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) requests_per_minute: Annotated[ @@ -4043,6 +4564,16 @@ class RegionStatusDto(BaseModel): ] = None +class RemapSecretRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + secret_id: Annotated[ + UUID | None, + Field( + alias="secretId", description="Secret to attach; null restores name-match" + ), + ] = None + + class RemoveMonitorTagsRequest(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) tag_ids: Annotated[ @@ -4301,6 +4832,83 @@ class RetryStrategy(BaseModel): ] +class RevisionDiffHunkDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + path: Annotated[ + str, + Field( + description="Path or field name (entrypoint, keys, or file path)", + min_length=1, + ), + ] + change: Annotated[ + str, Field(description="Whether this path was added, removed, or changed") + ] + left: Annotated[str | None, Field(description="Left value when present")] = None + right: Annotated[str | None, Field(description="Right value when present")] = None + + +class RevisionDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[UUID, Field(description="Revision identifier")] + definition_id: Annotated[ + UUID, Field(alias="definitionId", description="Parent definition") + ] + number: Annotated[ + int, Field(description="Monotonic revision number within the definition") + ] + digest: Annotated[ + str, Field(description="SHA-256 hex digest of the zip", min_length=1) + ] + entrypoint: Annotated[ + str, Field(description="Entrypoint file that runs", min_length=1) + ] + files: Annotated[list[str], Field(description="Paths present in the zip")] + keys: Annotated[list[str], Field(description="Secret key names the code demands")] + download_until: Annotated[ + AwareDatetime | None, + Field( + alias="downloadUntil", description="When package bytes expire for download" + ), + ] = None + git_sha: Annotated[ + str | None, + Field(alias="gitSha", description="Git commit SHA when sourced from Git"), + ] = None + git_message: Annotated[ + str | None, Field(alias="gitMessage", description="Git commit message") + ] = None + git_file: Annotated[ + str | None, Field(alias="gitFile", description="Declaring Git file path") + ] = None + authored_by: Annotated[ + str | None, Field(alias="authoredBy", description="Who authored this package") + ] = None + created_at: Annotated[ + AwareDatetime, + Field(alias="createdAt", description="When the revision was minted"), + ] + + +class RollbackRevisionRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + revision_id: Annotated[ + UUID, + Field( + alias="revisionId", + description="Existing revision to restore as Head for this monitor's environment", + ), + ] + reason: Annotated[ + str, + Field( + description="Why this rollback was performed (1–280 chars)", + max_length=280, + min_length=0, + ), + ] + + class RootlyChannelConfig(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) channel_type: Annotated[Literal["rootly"], Field(alias="channelType")] = "rootly" @@ -4317,6 +4925,41 @@ class RootlyChannelConfig(BaseModel): ] = None +class Verdict(StrEnum): + unchanged = "unchanged" + much_slower = "much_slower" + now_failing = "now_failing" + not_reached = "not_reached" + + +class Row(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + index: Annotated[int, Field(description="Zero-based step index")] + title: Annotated[str, Field(description="Step title", min_length=1)] + this_duration_ms: Annotated[ + int | None, + Field( + alias="thisDurationMs", + description="This run's step duration in milliseconds", + ), + ] = None + baseline_duration_ms: Annotated[ + int | None, + Field( + alias="baselineDurationMs", + description="Baseline step duration in milliseconds", + ), + ] = None + delta_ms: Annotated[ + int | None, + Field(alias="deltaMs", description="thisDurationMs minus baselineDurationMs"), + ] = None + verdict: Annotated[ + Verdict, + Field(description="unchanged, much_slower, now_failing, or not_reached"), + ] + + class RuleEvaluationDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: Annotated[UUID, Field(description="Forensic row UUID")] @@ -4410,85 +5053,364 @@ class RuleEvaluationDto(BaseModel): ] = None -class ScheduledMaintenanceDto(BaseModel): +class RunAttemptDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) - id: Annotated[UUID, Field(description="Unique maintenance record identifier")] - external_id: Annotated[ - str, - Field(alias="externalId", description="Vendor-assigned maintenance identifier"), - ] - title: Annotated[ - str, Field(description="Maintenance title as reported by the vendor") - ] - status: Annotated[ - str, - Field( - description="Current maintenance status (scheduled, in_progress, completed)" - ), - ] - impact: Annotated[str | None, Field(description="Reported impact level")] = None - shortlink: Annotated[ - str | None, - Field(description="Vendor-provided short URL to the maintenance page"), + attempt: Annotated[int, Field(description="1-based attempt number")] + outcome: Annotated[ + str | None, Field(description="Attempt outcome; null while the case is open") ] = None - scheduled_for: Annotated[ + started_at: Annotated[ AwareDatetime | None, - Field( - alias="scheduledFor", - description="Timestamp when the maintenance is scheduled to begin", - ), + Field(alias="startedAt", description="When this attempt started"), ] = None - scheduled_until: Annotated[ + finished_at: Annotated[ AwareDatetime | None, - Field( - alias="scheduledUntil", - description="Timestamp when the maintenance is scheduled to end", - ), + Field(alias="finishedAt", description="When this attempt finished"), ] = None - started_at: Annotated[ - AwareDatetime | None, - Field( - alias="startedAt", - description="Timestamp when the maintenance actually started", - ), + + +class RunCaseListParams(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + attempt: Annotated[ + int | None, Field(description="Only return cases for this Playwright attempt") ] = None - completed_at: Annotated[ - AwareDatetime | None, + + +class RunConsoleDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + state: Annotated[ + str, Field(description="on for browser, no_browser for API_CHECK", min_length=1) + ] + reason: Annotated[ + str | None, Field(description="Absence copy when state is no_browser") + ] = None + groups: Annotated[ + list[ConsoleGroupDto], + Field(description="Grouped messages; empty when ungrouped or no_browser"), + ] + lines: Annotated[ + list[ConsoleLineDto] | None, Field(description="Raw lines when ungrouped=true") + ] = None + + +class RunConsoleParams(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + attempt: Annotated[ + int | None, Field(description="In-check attempt (default selected attempt)") + ] = None + ungrouped: Annotated[ + bool | None, Field(description="Return chronological lines instead of groups") + ] = None + level: Annotated[ + str | None, Field(description="Filter error, warning, or info") + ] = None + format: Annotated[ + str | None, Field(description="raw downloads the ungrouped log as text/plain") + ] = None + + +class RunDiffDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + baseline_run_id: Annotated[ + UUID | None, Field( - alias="completedAt", - description="Timestamp when the maintenance was completed", + alias="baselineRunId", description="Baseline run; null when no prior pass" ), ] = None - affected_components: Annotated[ - list[MaintenanceComponentRef], + baseline_kind: Annotated[ + str, Field(alias="baselineKind", description="How the baseline was chosen") + ] + reads_as: Annotated[ + str, Field( - alias="affectedComponents", - description="Components affected by this maintenance", + alias="readsAs", + description="Human-readable baseline sentence", + min_length=1, ), ] - updates: Annotated[ - list[MaintenanceUpdateDto], - Field(description="Status updates posted during the maintenance lifecycle"), + rows: Annotated[list[Row], Field(description="One row per step on this run")] + picker: Annotated[ + list[PickerItem], + Field(description="Other finished runs of this monitor for the picker"), ] -class ScriptMonitorConfig(BaseModel): +class RunEventDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) - script: Annotated[ - str, - Field( - description="Playwright test script source code", - max_length=65536, - min_length=1, - ), + id: Annotated[UUID, Field(description="Event identifier")] + organization_id: Annotated[ + int, + Field(alias="organizationId", description="Organization this event belongs to"), ] - timeout_seconds: Annotated[ - int | None, + run_id: Annotated[ + UUID, Field(alias="runId", description="Run this event belongs to") + ] + seq: Annotated[int, Field(description="Supervisor-monotonic sequence, starts at 1")] + type: Annotated[str, Field(description="Control event type")] + case_id: Annotated[ + UUID | None, Field(alias="caseId", description="Case this event refers to") + ] = None + step_id: Annotated[ + UUID | None, Field(alias="stepId", description="Step this event refers to") + ] = None + artifact_id: Annotated[ + UUID | None, + Field(alias="artifactId", description="Artifact this event refers to"), + ] = None + payload: Annotated[ + dict[str, dict[str, Any]], + Field(description="Small typed payload for this event"), + ] + created_at: Annotated[ + AwareDatetime, + Field(alias="createdAt", description="When the event was persisted"), + ] + + +class RunEventParams(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + after: Annotated[ + int | None, Field(description="Replay events with seq greater than this value") + ] = None + + +class RunEvidenceDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + kind: Annotated[ + str, Field(description="Evidence kind in SHOT → TRACE → VIDEO → NET order") + ] + state: Annotated[str, Field(description="Whether the artifact is usable")] + + +class RunListParams(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + phase: Annotated[ + str | None, Field(description="Filter by run phase; omit to return every phase") + ] = None + outcome: Annotated[ + str | None, + Field(description="Filter by persist outcome; omit to return every outcome"), + ] = None + region: Annotated[str | None, Field(description="Filter by probe region")] = None + source: Annotated[ + str | None, Field(description="Filter by what triggered the run") + ] = None + environment_id: Annotated[ + UUID | None, + Field( + alias="environmentId", + description="Only return runs whose monitor lives in this environment", + ), + ] = None + from_: Annotated[ + AwareDatetime | None, + Field( + alias="from", + description="Inclusive lower bound on enqueued_at (default now-30m)", + ), + ] = None + to: Annotated[ + AwareDatetime | None, + Field(description="Inclusive upper bound on enqueued_at (default now)"), + ] = None + q: Annotated[ + str | None, Field(description="Substring match on monitor name or headline") + ] = None + size: Annotated[ + int, Field(description="Page size (1–100, default 50)", ge=1, le=100) + ] + page: Annotated[int, Field(description="Zero-based page index (default 0)", ge=0)] + + +class RunLiveDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + step_index: Annotated[ + int | None, Field(alias="stepIndex", description="Current step index") + ] = None + step_title: Annotated[ + str | None, Field(alias="stepTitle", description="Current step title") + ] = None + step_count: Annotated[ + int, Field(alias="stepCount", description="Known step count for this attempt") + ] + artifacts_uploaded: Annotated[ + int | None, + Field(alias="artifactsUploaded", description="Artifacts already available"), + ] = None + artifacts_expected: Annotated[ + int | None, + Field(alias="artifactsExpected", description="Artifacts expected for this run"), + ] = None + + +class RunnerLogLiveEvent(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + ts: Annotated[str, Field(description="Loki timestamp in nanoseconds")] + line: Annotated[str, Field(description="One runner-log line", min_length=1)] + + +class RunNetworkParams(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + attempt: Annotated[ + int | None, Field(description="In-check attempt (default selected attempt)") + ] = None + failed: Annotated[ + bool | None, Field(description="Only rows with status >= 400 or a failure") + ] = None + slow: Annotated[ + bool | None, Field(description="Only rows with durationMs >= 1000") + ] = None + step_id: Annotated[ + str | None, Field(alias="stepId", description="Only rows for this step") + ] = None + xhr: Annotated[ + bool | None, Field(description="Only xhr, fetch, and api resource types") + ] = None + source: Annotated[str | None, Field(description="page or request")] = None + cursor: Annotated[ + str | None, Field(description="Opaque cursor from the previous page") + ] = None + + +class RunStepDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[UUID, Field(description="Step identifier")] + organization_id: Annotated[ + int, + Field(alias="organizationId", description="Organization this step belongs to"), + ] + run_id: Annotated[ + UUID, Field(alias="runId", description="Run this step belongs to") + ] + case_id: Annotated[ + UUID, Field(alias="caseId", description="Case this step belongs to") + ] + attempt: Annotated[int, Field(description="Playwright in-case attempt number")] + index: Annotated[int, Field(description="Zero-based index within the case attempt")] + title: Annotated[str, Field(description="Step title")] + category: Annotated[str, Field(description="Step category")] + status: Annotated[str, Field(description="Step status")] + started_at: Annotated[ + AwareDatetime | None, + Field(alias="startedAt", description="When the step started"), + ] = None + finished_at: Annotated[ + AwareDatetime | None, + Field(alias="finishedAt", description="When the step finished"), + ] = None + duration_ms: Annotated[ + int | None, + Field(alias="durationMs", description="Reporter duration in milliseconds"), + ] = None + error: Annotated[str | None, Field(description="Error when the step failed")] = None + assertion: Annotated[ + dict[str, dict[str, Any]] | None, + Field(description="Assertion payload when this step is an assertion"), + ] = None + + +class RunTabCountsDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + steps: Annotated[int, Field(description="Step rows for the selected attempt")] + assets: Annotated[ + int, + Field(description="Items across asset kinds, excluding dead no-browser rows"), + ] + diff: Annotated[ + int, + Field(description="1 when a diff baseline exists or this run passed on retry"), + ] + + +class ScheduledMaintenanceDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[UUID, Field(description="Unique maintenance record identifier")] + external_id: Annotated[ + str, + Field(alias="externalId", description="Vendor-assigned maintenance identifier"), + ] + title: Annotated[ + str, Field(description="Maintenance title as reported by the vendor") + ] + status: Annotated[ + str, + Field( + description="Current maintenance status (scheduled, in_progress, completed)" + ), + ] + impact: Annotated[str | None, Field(description="Reported impact level")] = None + shortlink: Annotated[ + str | None, + Field(description="Vendor-provided short URL to the maintenance page"), + ] = None + scheduled_for: Annotated[ + AwareDatetime | None, + Field( + alias="scheduledFor", + description="Timestamp when the maintenance is scheduled to begin", + ), + ] = None + scheduled_until: Annotated[ + AwareDatetime | None, + Field( + alias="scheduledUntil", + description="Timestamp when the maintenance is scheduled to end", + ), + ] = None + started_at: Annotated[ + AwareDatetime | None, + Field( + alias="startedAt", + description="Timestamp when the maintenance actually started", + ), + ] = None + completed_at: Annotated[ + AwareDatetime | None, + Field( + alias="completedAt", + description="Timestamp when the maintenance was completed", + ), + ] = None + affected_components: Annotated[ + list[MaintenanceComponentRef], + Field( + alias="affectedComponents", + description="Components affected by this maintenance", + ), + ] + updates: Annotated[ + list[MaintenanceUpdateDto], + Field(description="Status updates posted during the maintenance lifecycle"), + ] + + +class ScriptMonitorConfig(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + script: Annotated[ + str | None, + Field( + description="Legacy inline script on existing rows", + max_length=65536, + min_length=0, + ), + ] = None + timeout_seconds: Annotated[ + int | None, Field( alias="timeoutSeconds", - description="Maximum execution time in seconds (5–120)", + description="Maximum execution time in seconds (5–240)", ge=5, - le=120, + le=240, + ), + ] = None + runtime_id: Annotated[ + str | None, + Field( + alias="runtimeId", + description="Runtime pin YYYY.MM; omit uses workspace default then sole available", + max_length=32, + min_length=0, + pattern="^$|^[A-Za-z0-9._-]+$", ), ] = None @@ -4526,9 +5448,47 @@ class SecretDto(BaseModel): list[MonitorReference] | None, Field( alias="usedByMonitors", - description="Monitors that reference this secret; null on create/update responses", + description="Monitors that reference this secret for authentication", + ), + ] = None + + +class SecretRequestDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + key: Annotated[str, Field(description="Secret key this monitor requires")] + secret: SecretDto | None = None + readiness: Annotated[ + str, Field(description="Whether this key is resolved or missing") + ] + fulfilled_by: Annotated[ + str | None, + Field( + alias="fulfilledBy", + description="Fulfilled from environment variables or a secret", + ), + ] = None + declaring_file: Annotated[ + str | None, + Field( + alias="declaringFile", + description="Declaring file path inside the package zip", + ), + ] = None + declaring_location: Annotated[ + str | None, + Field( + alias="declaringLocation", + description="Call site from package scan, e.g. signIn(…) · line 6", ), ] = None + last_resolved_at: Annotated[ + AwareDatetime | None, + Field(alias="lastResolvedAt", description="When a run last resolved this key"), + ] = None + last_resolved_run_id: Annotated[ + UUID | None, + Field(alias="lastResolvedRunId", description="Run that last resolved this key"), + ] = None class SeoMetadataDto(BaseModel): @@ -5084,6 +6044,11 @@ class SingleValueResponseMonitorAuthDto(BaseModel): data: MonitorAuthDto +class SingleValueResponseMonitorSessionDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: MonitorSessionDto + + class SingleValueResponseMonitorTestResultDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: MonitorTestResultDto @@ -5099,6 +6064,16 @@ class SingleValueResponseOrganizationDto(BaseModel): data: OrganizationDto +class SingleValueResponseOverviewStepsDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: OverviewStepsDto + + +class SingleValueResponsePackageUploadDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: PackageUploadDto + + class SingleValueResponsePolicySnapshotDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: PolicySnapshotDto @@ -5114,6 +6089,21 @@ class SingleValueResponseResultSummaryDto(BaseModel): data: ResultSummaryDto +class SingleValueResponseRevisionDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: RevisionDto + + +class SingleValueResponseRunConsoleDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: RunConsoleDto + + +class SingleValueResponseRunDiffDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: RunDiffDto + + class SingleValueResponseSecretDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: SecretDto @@ -5766,7 +6756,6 @@ class TableValueResultAlertChannelDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultAlertDeliveryDto(BaseModel): @@ -5776,7 +6765,6 @@ class TableValueResultAlertDeliveryDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultApiKeyDto(BaseModel): @@ -5786,7 +6774,6 @@ class TableValueResultApiKeyDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultCategoryDto(BaseModel): @@ -5796,7 +6783,15 @@ class TableValueResultCategoryDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None + + +class TableValueResultDefinitionDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: list[DefinitionDto] + 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 TableValueResultDeliveryAttemptDto(BaseModel): @@ -5806,7 +6801,6 @@ class TableValueResultDeliveryAttemptDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultEnvironmentDto(BaseModel): @@ -5816,7 +6810,6 @@ class TableValueResultEnvironmentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultInviteDto(BaseModel): @@ -5826,7 +6819,6 @@ class TableValueResultInviteDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultMaintenanceWindowDto(BaseModel): @@ -5836,7 +6828,6 @@ class TableValueResultMaintenanceWindowDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultMemberDto(BaseModel): @@ -5846,7 +6837,6 @@ class TableValueResultMemberDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultNotificationDispatchDto(BaseModel): @@ -5856,7 +6846,6 @@ class TableValueResultNotificationDispatchDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultNotificationDto(BaseModel): @@ -5866,7 +6855,15 @@ class TableValueResultNotificationDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None + + +class TableValueResultRevisionDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: list[RevisionDto] + 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 TableValueResultRuleEvaluationDto(BaseModel): @@ -5876,7 +6873,6 @@ class TableValueResultRuleEvaluationDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultScheduledMaintenanceDto(BaseModel): @@ -5886,7 +6882,6 @@ class TableValueResultScheduledMaintenanceDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultSecretDto(BaseModel): @@ -5896,7 +6891,6 @@ class TableValueResultSecretDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultServiceComponentDto(BaseModel): @@ -5906,7 +6900,6 @@ class TableValueResultServiceComponentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultServiceIncidentDto(BaseModel): @@ -5916,7 +6909,6 @@ class TableValueResultServiceIncidentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultServiceSubscriptionDto(BaseModel): @@ -5926,7 +6918,6 @@ class TableValueResultServiceSubscriptionDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageComponentDto(BaseModel): @@ -5936,7 +6927,6 @@ class TableValueResultStatusPageComponentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageComponentGroupDto(BaseModel): @@ -5946,7 +6936,6 @@ class TableValueResultStatusPageComponentGroupDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageCustomDomainDto(BaseModel): @@ -5956,7 +6945,6 @@ class TableValueResultStatusPageCustomDomainDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageNotificationDeliveryDto(BaseModel): @@ -5966,7 +6954,6 @@ class TableValueResultStatusPageNotificationDeliveryDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageSubscriberDto(BaseModel): @@ -5976,7 +6963,6 @@ class TableValueResultStatusPageSubscriberDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TagDto(BaseModel): @@ -6293,6 +7279,44 @@ class TlsInfoDto(BaseModel): ] = None +class Id(StrEnum): + failing_action = "failing_action" + failing_step = "failing_step" + first_failed_request = "first_failed_request" + case_start = "case_start" + + +class TraceEntryPoint(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[Id, Field(description="Doorway id")] + action_index: Annotated[ + int, Field(alias="actionIndex", description="Action index this doorway opens") + ] + label: Annotated[str, Field(description="Label shown on the doorway", min_length=1)] + note: Annotated[ + str, Field(description="Short note for why this doorway exists", min_length=1) + ] + + +class TraceNearbyAction(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + action_index: Annotated[ + int, + Field(alias="actionIndex", description="Action index in the Playwright trace"), + ] + kind: Annotated[str, Field(description="Playwright action kind", min_length=1)] + title: Annotated[ + str, Field(description="Human title for this action", min_length=1) + ] + duration_ms: Annotated[ + int | None, + Field(alias="durationMs", description="Action duration in milliseconds"), + ] = None + is_teardown: Annotated[ + bool, Field(alias="isTeardown", description="Whether this action is teardown") + ] + + class Type4(StrEnum): consecutive_failures = "consecutive_failures" failures_in_window = "failures_in_window" @@ -7400,21 +8424,53 @@ class UpdateZapierChannelConfig(BaseModel): ] = None -class UptimeBucketDto(BaseModel): - model_config = ConfigDict(extra="ignore", populate_by_name=True) - timestamp: Annotated[ - AwareDatetime, +class ReusePolicy(StrEnum): + reuse = "reuse" + every_run = "every_run" + on_failure = "on_failure" + + +class UpsertMonitorSessionRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + reuse_policy: Annotated[ + ReusePolicy, Field( - description="Start of the bucket interval (ISO 8601)", - examples=["2024-01-01T00:00:00Z"], + alias="reusePolicy", + description="When to reuse the cached session across runs", ), ] - uptime_pct: Annotated[ - float | None, + setup_file: Annotated[ + str, Field( - alias="uptimePct", - description="Uptime percentage for this bucket; null when no polls occurred", - examples=[100], + alias="setupFile", + description="Setup file path inside the package zip", + min_length=1, + ), + ] + expires_at: Annotated[ + AwareDatetime | None, + Field( + alias="expiresAt", + description="When the cached session expires; null preserves current", + ), + ] = None + + +class UptimeBucketDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + timestamp: Annotated[ + AwareDatetime, + Field( + description="Start of the bucket interval (ISO 8601)", + examples=["2024-01-01T00:00:00Z"], + ), + ] + uptime_pct: Annotated[ + float | None, + Field( + alias="uptimePct", + description="Uptime percentage for this bucket; null when no polls occurred", + examples=[100], ), ] = None total_polls: Annotated[ @@ -7485,6 +8541,62 @@ class UptimeDto(BaseModel): examples=[2], ), ] + first_try_percent: Annotated[ + float | None, + Field( + alias="firstTryPercent", + description="First-try pass percent for settled parent runs in the window; null when the monitor has no run history", + examples=[96.2], + ), + ] = None + retry_count: Annotated[ + int | None, + Field( + alias="retryCount", + description="Settled retry runs in the window; null when the monitor has no run history", + examples=[12], + ), + ] = None + + +class UserDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[int, Field(description="Unique user identifier")] + email: Annotated[str, Field(description="User email address")] + email_verified: Annotated[ + bool, + Field( + alias="emailVerified", + description="Whether the email address has been verified", + ), + ] + name: Annotated[str | None, Field(description="Display name; null if not set")] = ( + None + ) + user_role: Annotated[ + str, Field(alias="userRole", description="Platform role: USER or SUPERADMIN") + ] + onboarding_stage: Annotated[ + str | None, + Field( + alias="onboardingStage", + description="Current onboarding progress stage; null when completed", + ), + ] = None + image_url: Annotated[ + str | None, + Field(alias="imageUrl", description="Profile image URL; null if not set"), + ] = None + created_at: Annotated[ + AwareDatetime, + Field(alias="createdAt", description="Timestamp when the account was created"), + ] + updated_at: Annotated[ + AwareDatetime, + Field( + alias="updatedAt", description="Timestamp when the account was last updated" + ), + ] class VoiceLanguageDto(BaseModel): @@ -7654,6 +8766,16 @@ class WorkspaceDto(BaseModel): ] +class WriteSecretEnvironmentValueRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + value: Annotated[ + str, + Field( + description="Plaintext value to encrypt for this environment", min_length=1 + ), + ] + + class ZapierChannelConfig(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) channel_type: Annotated[Literal["zapier"], Field(alias="channelType")] = "zapier" @@ -7696,6 +8818,30 @@ class AddMonitorTagsRequest(BaseModel): ] = None +class ArtifactTraceMeta(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + action_count: Annotated[ + int | None, Field(alias="actionCount", description="Action count in the trace") + ] = None + snapshot_count: Annotated[ + int | None, + Field(alias="snapshotCount", description="Snapshot count in the trace"), + ] = None + nearby_actions: Annotated[ + list[TraceNearbyAction] | None, + Field( + alias="nearbyActions", + description="Actions around the failure, teardown labelled", + ), + ] = None + entry_points: Annotated[ + list[TraceEntryPoint] | None, + Field( + alias="entryPoints", description="Four doorways into the downloaded file" + ), + ] = None + + class AuditMetadata(RootModel[MemberRoleChangedMetadata | None]): root: Annotated[ MemberRoleChangedMetadata | None, @@ -7758,6 +8904,42 @@ class BulkMonitorActionResult(BaseModel): ] +class CaptureCompareDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + this_artifact_id: Annotated[ + UUID, Field(alias="thisArtifactId", description="Screenshot on this run") + ] + baseline_artifact_id: Annotated[ + UUID | None, + Field( + alias="baselineArtifactId", + description="Matching screenshot on the prior pass; null when none", + ), + ] = None + baseline_run_id: Annotated[ + UUID | None, + Field( + alias="baselineRunId", description="Run that owns the baseline screenshot" + ), + ] = None + baseline_kind: Annotated[ + Literal["last_pass_this_step_this_region"], + Field( + alias="baselineKind", description="Always last_pass_this_step_this_region" + ), + ] = "last_pass_this_step_this_region" + empty_reason: Annotated[ + str | None, + Field( + alias="emptyReason", + description="Why the baseline is empty; null when a baseline exists", + ), + ] = None + nearest_other_region: Annotated[ + NearestOtherRegion | None, Field(alias="nearestOtherRegion") + ] = None + + class Code(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) check_type: Literal["code"] = "code" @@ -7952,12 +9134,13 @@ class CreateMonitorRequest(BaseModel): | McpServerMonitorConfig | ScriptMonitorConfig | TcpMonitorConfig - ) + | None + ) = None frequency_seconds: Annotated[ int | None, Field( alias="frequencySeconds", - description="Check frequency in seconds (10–86400); null defaults to plan minimum (60s on most paid plans)", + description="Check frequency in seconds (10–86400). Null defaults to the plan minimum", ge=10, le=86400, ), @@ -7968,21 +9151,21 @@ class CreateMonitorRequest(BaseModel): regions: Annotated[ list[str] | None, Field( - description="Probe regions to run checks from. Allowed values are deployment-dependent; production: us-east, us-west, eu-west, ap-south." + description="Probe regions to run checks from. Allowed values are deployment-dependent. Production: us-east, us-west, eu-west, ap-south" ), ] = None managed_by: Annotated[ ManagedBy | None, Field( alias="managedBy", - description="Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted; set to your surface so audit logs, drift detection, and analytics attribute correctly.", + description="Source that created this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API", ), ] = None environment_id: Annotated[ UUID | None, Field( alias="environmentId", - description="Environment to associate with this monitor", + description="Environment to associate with this monitor. Required for browser and multi-step monitors", ), ] = None assertions: Annotated[ @@ -8001,6 +9184,24 @@ class CreateMonitorRequest(BaseModel): ), ] = None tags: AddMonitorTagsRequest | None = None + capture_policy: Annotated[CapturePolicy | None, Field(alias="capturePolicy")] = None + fast_retry_max_attempts: Annotated[ + int | None, + Field( + alias="fastRetryMaxAttempts", + description="Fast-retry attempts after failure. Null or 0 disables", + ge=0, + le=10, + ), + ] = None + definition_id: Annotated[ + UUID | None, + Field( + alias="definitionId", + description="Existing definition to reuse for a sibling monitor", + ), + ] = None + package: MonitorPackageSpec | None = None class CreateResourceGroupRequest(BaseModel): @@ -8192,6 +9393,32 @@ class CreditPolicy(BaseModel): ] = None +class CursorPageNotificationDispatchDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: Annotated[ + list[NotificationDispatchDto], Field(description="Items on this page") + ] + next_cursor: Annotated[ + str | None, + Field( + alias="nextCursor", + description="Opaque cursor for the next page; null when there are no more results", + ), + ] = None + has_more: Annotated[ + bool, + Field( + alias="hasMore", description="Whether more results exist beyond this page" + ), + ] + total: Annotated[ + int | None, + Field( + description="Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total" + ), + ] = None + + class CursorPageServiceCatalogDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: Annotated[list[ServiceCatalogDto], Field(description="Items on this page")] @@ -8208,6 +9435,12 @@ class CursorPageServiceCatalogDto(BaseModel): alias="hasMore", description="Whether more results exist beyond this page" ), ] + total: Annotated[ + int | None, + Field( + description="Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total" + ), + ] = None class CursorPageServicePollResultDto(BaseModel): @@ -8226,6 +9459,12 @@ class CursorPageServicePollResultDto(BaseModel): alias="hasMore", description="Whether more results exist beyond this page" ), ] + total: Annotated[ + int | None, + Field( + description="Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total" + ), + ] = None class CursorPageStatusEventDto(BaseModel): @@ -8244,6 +9483,12 @@ class CursorPageStatusEventDto(BaseModel): alias="hasMore", description="Whether more results exist beyond this page" ), ] + total: Annotated[ + int | None, + Field( + description="Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total" + ), + ] = None class DashboardOverviewDto(BaseModel): @@ -8252,6 +9497,26 @@ class DashboardOverviewDto(BaseModel): incidents: IncidentsSummaryDto +class DefinitionHeadDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + definition_id: Annotated[ + UUID, Field(alias="definitionId", description="Definition this Head belongs to") + ] + environment: EnvironmentDto + revision: RevisionDto + activated_at: Annotated[ + AwareDatetime, + Field(alias="activatedAt", description="When this Head last activated"), + ] + activated_by: Annotated[ + str | None, + Field(alias="activatedBy", description="Who last activated this Head"), + ] = None + reason: Annotated[ + str | None, Field(description="Rollback reason when this Head was restored") + ] = None + + class EscalationChain(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) steps: Annotated[ @@ -8922,9 +10187,69 @@ class MonitorDto(BaseModel): str | None, Field( alias="currentStatus", - description="Current operational state — UP, DOWN, DEGRADED, PAUSED, or UNKNOWN if no probe data yet", + description="Current operational state. One of UP, DOWN, DEGRADED, PAUSED, or UNKNOWN", + ), + ] = None + definition_id: Annotated[ + UUID | None, + Field( + alias="definitionId", + description="Definition id for a browser or multi-step monitor. Null on probe monitors", + ), + ] = None + capture_policy: Annotated[CapturePolicy | None, Field(alias="capturePolicy")] = None + fast_retry_max_attempts: Annotated[ + int | None, + Field( + alias="fastRetryMaxAttempts", + description="Fast-retry max attempts; null/0 = off", + ), + ] = None + muted: Annotated[bool, Field(description="Whether alert delivery is muted")] + muted_until: Annotated[ + AwareDatetime | None, + Field( + alias="mutedUntil", + description="Mute expiry; null means indefinite while muted", + ), + ] = None + mute_reason: Annotated[ + str | None, Field(alias="muteReason", description="Optional mute reason") + ] = None + paused_at: Annotated[ + AwareDatetime | None, + Field(alias="pausedAt", description="When the monitor was paused"), + ] = None + pause_reason: Annotated[ + str | None, Field(alias="pauseReason", description="Optional pause reason") + ] = None + pause_expires_at: Annotated[ + AwareDatetime | None, Field(alias="pauseExpiresAt", description="Pause expiry") + ] = None + quarantine_owner_id: Annotated[ + str | None, + Field(alias="quarantineOwnerId", description="Quarantine person owner id"), + ] = None + quarantine_until: Annotated[ + AwareDatetime | None, + Field( + alias="quarantineUntil", + description="Quarantine expiry; non-null means quarantined", ), ] = None + quarantine_reason: Annotated[ + str | None, Field(alias="quarantineReason", description="Quarantine reason") + ] = None + upload: PackageUploadDto | None = None + + +class MonitorSecretRequestsDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + environment: EnvironmentDto + requests: Annotated[ + list[SecretRequestDto], + Field(description="Secret keys this monitor requires and their resolve state"), + ] class MonitorTestRequest(BaseModel): @@ -8981,6 +10306,110 @@ class MonitorVersionDto(BaseModel): ] +class NetworkRowDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[str, Field(description="Stable row id from capture", min_length=1)] + step_id: Annotated[ + str | None, Field(alias="stepId", description="Step this request belonged to") + ] = None + source: Annotated[ + str, Field(description="page for browser, request for API_CHECK", min_length=1) + ] + method: Annotated[str, Field(description="HTTP method", min_length=1)] + url: Annotated[str, Field(description="Request URL", min_length=1)] + resource_type: Annotated[ + str, + Field( + alias="resourceType", + description="Chromium type, or api for the request fixture", + min_length=1, + ), + ] + is_navigation: Annotated[ + bool, + Field( + alias="isNavigation", + description="Whether this request started a navigation", + ), + ] + status: Annotated[ + int | None, Field(description="HTTP status; null while pending") + ] = None + duration_ms: Annotated[ + int | None, + Field(alias="durationMs", description="Request duration in milliseconds"), + ] = None + encoded_body_size: Annotated[ + int | None, + Field( + alias="encodedBodySize", description="Encoded response body size in bytes" + ), + ] = None + started_offset_ms: Annotated[ + int | None, + Field( + alias="startedOffsetMs", + description="Offset from case start for the waterfall bar", + ), + ] = None + failure: Annotated[ + str | None, Field(description="Transport or protocol failure") + ] = None + redirected_from_url: Annotated[ + str | None, + Field( + alias="redirectedFromUrl", description="URL this request redirected from" + ), + ] = None + timing: NetworkTimingDto | None = None + request_headers: Annotated[ + dict[str, str], + Field(alias="requestHeaders", description="Redacted request headers"), + ] + response_headers: Annotated[ + dict[str, str], + Field(alias="responseHeaders", description="Redacted response headers"), + ] + request_body: Annotated[ + str, + Field( + alias="requestBody", + description="Request body preview, truncated at 256 KiB", + ), + ] + response_body: Annotated[ + str, + Field( + alias="responseBody", + description="Response body preview, truncated at 256 KiB", + ), + ] + request_body_truncated: Annotated[ + bool, + Field( + alias="requestBodyTruncated", + description="Whether requestBody was truncated", + ), + ] + response_body_truncated: Annotated[ + bool, + Field( + alias="responseBodyTruncated", + description="Whether responseBody was truncated", + ), + ] + curl: Annotated[ + str, Field(description="Copy-as-cURL from the redacted record", min_length=1) + ] + trace_action_index: Annotated[ + int | None, + Field( + alias="traceActionIndex", + description="Playwright trace action index; null on API_CHECK", + ), + ] = None + + class NotificationPolicyDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: Annotated[UUID, Field(description="Unique notification policy identifier")] @@ -9050,134 +10479,444 @@ class RelatedIncidentsResponse(BaseModel): ] -class ResourceGroupMemberDto(BaseModel): +class ResourceGroupMemberDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[UUID, Field(description="Unique group member record identifier")] + group_id: Annotated[ + UUID, + Field(alias="groupId", description="Resource group this member belongs to"), + ] + member_type: Annotated[ + str, + Field(alias="memberType", description="Type of member: 'monitor' or 'service'"), + ] + monitor_id: Annotated[ + UUID | None, + Field( + alias="monitorId", + description="Monitor ID; set when memberType is 'monitor'", + ), + ] = None + service_id: Annotated[ + UUID | None, + Field( + alias="serviceId", + description="Service ID; set when memberType is 'service'", + ), + ] = None + name: Annotated[ + str | None, + Field(description="Display name of the referenced monitor or service"), + ] = None + slug: Annotated[ + str | None, + Field( + description="Slug identifier for the service (services only); used for icons and uptime API calls" + ), + ] = None + subscription_id: Annotated[ + UUID | None, + Field( + alias="subscriptionId", + description="Subscription ID for the service (services only); used to link to the dependency detail page", + ), + ] = None + status: Annotated[str, Field(description="Computed health status for this member")] + effective_frequency: Annotated[ + str | None, + Field( + alias="effectiveFrequency", + description="Effective check frequency label showing the group default when the monitor inherits it; null for services or when no group default is configured", + ), + ] = None + created_at: Annotated[ + AwareDatetime, + Field( + alias="createdAt", + description="Timestamp when the member was added to the group", + ), + ] + uptime24h: Annotated[ + float | None, + Field(description="24h uptime percentage; populated when includeMetrics=true"), + ] = None + chart_data: Annotated[ + list[float] | None, + Field( + alias="chartData", + description="Uptime tick values (0-100) for last-24h mini chart; populated when includeMetrics=true", + ), + ] = None + avg_latency_ms: Annotated[ + float | None, + Field( + alias="avgLatencyMs", + description="Average latency in ms (monitors only); populated when includeMetrics=true", + ), + ] = None + p95_latency_ms: Annotated[ + float | None, + Field( + alias="p95LatencyMs", + description="P95 latency in ms (monitors only); populated when includeMetrics=true", + ), + ] = None + last_checked_at: Annotated[ + AwareDatetime | None, + Field( + alias="lastCheckedAt", + description="Timestamp of the most recent health check; populated when includeMetrics=true", + ), + ] = None + monitor_type: Annotated[ + str | None, + Field( + alias="monitorType", + description="Monitor type (HTTP, DNS, TCP, ICMP, HEARTBEAT, MCP); monitors only", + ), + ] = None + environment_name: Annotated[ + str | None, + Field(alias="environmentName", description="Environment name; monitors only"), + ] = None + group_membership_count: Annotated[ + int | None, + Field( + alias="groupMembershipCount", + description="Count of resource groups this monitor or service belongs to; detail GET only — omitted on list", + ), + ] = None + failing_since: Annotated[ + AwareDatetime | None, + Field( + alias="failingSince", + description="Start of the current non-operational stretch; null when operational or unknown (services OK); detail GET only — omitted on list", + ), + ] = None + alert_collapsed: Annotated[ + bool | None, + Field( + alias="alertCollapsed", + description="True when an active member incident records this group among alertCollapsedByResourceGroupIds; detail GET only — omitted on list", + ), + ] = None + incident_marks: Annotated[ + list[ResourceGroupMemberIncidentMarkDto] | None, + Field( + alias="incidentMarks", + description="Incident marks for the trailing 24h strip; null when metrics omitted or failed; detail GET only — omitted on list", + ), + ] = None + + +class RevisionDiffDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + left: RevisionDto + right: RevisionDto + hunks: Annotated[ + list[RevisionDiffHunkDto], + Field(description="File and field-level hunks (bounded)"), + ] + + +class RollbackPreviewDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + target: RevisionDto + current: DefinitionHeadDto | None = None + affected_monitors: Annotated[ + list[MonitorDto], + Field( + alias="affectedMonitors", + description="Monitors sharing this definition and environment", + ), + ] + + +class RunArtifactDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[UUID, Field(description="Unique artifact identifier")] + organization_id: Annotated[ + int, + Field( + alias="organizationId", description="Organization this artifact belongs to" + ), + ] + run_id: Annotated[ + UUID, Field(alias="runId", description="Run this artifact belongs to") + ] + step_id: Annotated[ + UUID | None, + Field( + alias="stepId", + description="Step this screenshot belongs to; null for whole-run kinds", + ), + ] = None + kind: Annotated[str, Field(description="File kind")] + lifecycle: Annotated[ + str, Field(description="Whether bytes are available, processing, or gone") + ] + capture_reason: Annotated[ + str | None, + Field(alias="captureReason", description="Why this file was captured"), + ] = None + byte_size: Annotated[ + int | None, Field(alias="byteSize", description="Stored size in bytes") + ] = None + content_type: Annotated[ + str | None, + Field(alias="contentType", description="MIME type of the stored file"), + ] = None + duration_ms: Annotated[ + int | None, + Field(alias="durationMs", description="Video duration in milliseconds"), + ] = None + viewport: ArtifactViewport | None = None + expires_at: Annotated[ + AwareDatetime | None, + Field(alias="expiresAt", description="When stored bytes expire"), + ] = None + expected_byte_size: Annotated[ + int | None, + Field( + alias="expectedByteSize", + description="Expected size while a video is encoding", + ), + ] = None + encode_eta_ms: Annotated[ + int | None, + Field( + alias="encodeEtaMs", + description="Estimated remaining encode time in milliseconds", + ), + ] = None + trace_meta: Annotated[ArtifactTraceMeta | None, Field(alias="traceMeta")] = None + created_at: Annotated[ + AwareDatetime, + Field(alias="createdAt", description="When this file row was created"), + ] + + +class RunCaseDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[UUID, Field(description="Case identifier")] + organization_id: Annotated[ + int, + Field(alias="organizationId", description="Organization this case belongs to"), + ] + run_id: Annotated[ + UUID, Field(alias="runId", description="Run this case belongs to") + ] + attempt: Annotated[int, Field(description="Playwright in-case attempt number")] + index: Annotated[int, Field(description="Zero-based case index within the attempt")] + title: Annotated[str, Field(description="Case title")] + file: Annotated[str | None, Field(description="Spec path inside the package")] = ( + None + ) + status: Annotated[str, Field(description="Case status")] + started_at: Annotated[ + AwareDatetime | None, + Field(alias="startedAt", description="When the case started"), + ] = None + finished_at: Annotated[ + AwareDatetime | None, + Field(alias="finishedAt", description="When the case finished"), + ] = None + duration_ms: Annotated[ + int | None, + Field(alias="durationMs", description="Reporter duration in milliseconds"), + ] = None + steps: Annotated[list[RunStepDto], Field(description="Steps on this case")] + + +class RunDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) - id: Annotated[UUID, Field(description="Unique group member record identifier")] - group_id: Annotated[ - UUID, - Field(alias="groupId", description="Resource group this member belongs to"), - ] - member_type: Annotated[ - str, - Field(alias="memberType", description="Type of member: 'monitor' or 'service'"), + id: Annotated[UUID, Field(description="Unique run identifier")] + organization_id: Annotated[ + int, + Field(alias="organizationId", description="Organization this run belongs to"), ] monitor_id: Annotated[ - UUID | None, - Field( - alias="monitorId", - description="Monitor ID; set when memberType is 'monitor'", - ), + UUID, Field(alias="monitorId", description="Monitor this run belongs to") + ] + monitor_name: Annotated[ + str | None, Field(alias="monitorName", description="Monitor display name") ] = None - service_id: Annotated[ + monitor_type: Annotated[ + str | None, Field(alias="monitorType", description="Monitor type") + ] = None + host: Annotated[ + str | None, Field(description="Target host from the environment BASE_URL") + ] = None + environment_id: Annotated[ UUID | None, - Field( - alias="serviceId", - description="Service ID; set when memberType is 'service'", - ), + Field(alias="environmentId", description="Environment this run executed in"), ] = None - name: Annotated[ + environment_name: Annotated[ str | None, - Field(description="Display name of the referenced monitor or service"), + Field(alias="environmentName", description="Environment display name"), ] = None - slug: Annotated[ - str | None, + revision_id: Annotated[ + UUID, Field(alias="revisionId", description="Revision this run executed") + ] + region: Annotated[str, Field(description="Probe region for this run", min_length=1)] + source: Annotated[str, Field(description="What triggered this run")] + enqueued_at: Annotated[ + AwareDatetime, + Field(alias="enqueuedAt", description="When this run was enqueued"), + ] + evaluation_cycle_id: Annotated[ + UUID | None, Field( - description="Slug identifier for the service (services only); used for icons and uptime API calls" + alias="evaluationCycleId", + description="Evaluation cycle grouping this run with retries", ), ] = None - subscription_id: Annotated[ + retry_of_run_id: Annotated[ UUID | None, - Field( - alias="subscriptionId", - description="Subscription ID for the service (services only); used to link to the dependency detail page", - ), + Field(alias="retryOfRunId", description="Parent run when this is a fast retry"), ] = None - status: Annotated[str, Field(description="Computed health status for this member")] - effective_frequency: Annotated[ + retried_from_run_id: Annotated[ + UUID | None, + Field(alias="retriedFromRunId", description="Fast-retry parent run"), + ] = None + phase: Annotated[str, Field(description="Current run phase")] + cancel_requested: Annotated[ + bool, Field(alias="cancelRequested", description="Whether cancel was requested") + ] + outcome: Annotated[ + str | None, Field(description="Outcome; null until the run is finished") + ] = None + headline: Annotated[str | None, Field(description="Last control headline")] = None + execution_line: Annotated[ + str | None, Field(alias="executionLine", description="Live execution one-liner") + ] = None + meta_line: Annotated[ str | None, - Field( - alias="effectiveFrequency", - description="Effective check frequency label showing the group default when the monitor inherits it; null for services or when no group default is configured", - ), + Field(alias="metaLine", description="Server-composed header meta line"), ] = None - created_at: Annotated[ - AwareDatetime, + bundle_digest: Annotated[ + str, Field( - alias="createdAt", - description="Timestamp when the member was added to the group", + alias="bundleDigest", + description="Package digest frozen at create", + min_length=1, ), ] - uptime24h: Annotated[ - float | None, - Field(description="24h uptime percentage; populated when includeMetrics=true"), + started_at: Annotated[ + AwareDatetime | None, + Field(alias="startedAt", description="When execution claimed a seat"), ] = None - chart_data: Annotated[ - list[float] | None, - Field( - alias="chartData", - description="Uptime tick values (0-100) for last-24h mini chart; populated when includeMetrics=true", - ), + finished_at: Annotated[ + AwareDatetime | None, + Field(alias="finishedAt", description="When the run finished"), ] = None - avg_latency_ms: Annotated[ - float | None, - Field( - alias="avgLatencyMs", - description="Average latency in ms (monitors only); populated when includeMetrics=true", - ), + updated_at: Annotated[ + AwareDatetime | None, + Field(alias="updatedAt", description="When the run row last changed"), ] = None - p95_latency_ms: Annotated[ - float | None, - Field( - alias="p95LatencyMs", - description="P95 latency in ms (monitors only); populated when includeMetrics=true", - ), + last_heartbeat_at: Annotated[ + AwareDatetime | None, + Field(alias="lastHeartbeatAt", description="Last supervisor heartbeat"), ] = None - last_checked_at: Annotated[ + cancelled_by: Annotated[ + str | None, Field(alias="cancelledBy", description="Who requested cancel") + ] = None + artifacts_expired_at: Annotated[ AwareDatetime | None, + Field(alias="artifactsExpiredAt", description="When artifact bytes expired"), + ] = None + capture_policy_snapshot: Annotated[ + dict[str, dict[str, Any]], Field( - alias="lastCheckedAt", - description="Timestamp of the most recent health check; populated when includeMetrics=true", + alias="capturePolicySnapshot", + description="Capture settings frozen at create", ), - ] = None - monitor_type: Annotated[ - str | None, + ] + binding_version_snapshot: Annotated[ + dict[str, dict[str, Any]], Field( - alias="monitorType", - description="Monitor type (HTTP, DNS, TCP, ICMP, HEARTBEAT, MCP); monitors only", + alias="bindingVersionSnapshot", + description="Resolved secret key names frozen at create", ), + ] + duration_ms: Annotated[ + int | None, + Field(alias="durationMs", description="Wall time from claim to finish"), ] = None - environment_name: Annotated[ - str | None, - Field(alias="environmentName", description="Environment name; monitors only"), + queue_wait_ms: Annotated[ + int | None, + Field(alias="queueWaitMs", description="Time spent waiting for a seat"), ] = None - group_membership_count: Annotated[ + queue_position: Annotated[ int | None, Field( - alias="groupMembershipCount", - description="Count of resource groups this monitor or service belongs to; detail GET only — omitted on list", + alias="queuePosition", + description="Live queue position; null when not queued", ), ] = None - failing_since: Annotated[ - AwareDatetime | None, + heartbeat_age_ms: Annotated[ + int | None, Field( - alias="failingSince", - description="Start of the current non-operational stretch; null when operational or unknown (services OK); detail GET only — omitted on list", + alias="heartbeatAgeMs", + description="Milliseconds since the last supervisor heartbeat", ), ] = None - alert_collapsed: Annotated[ - bool | None, - Field( - alias="alertCollapsed", - description="True when an active member incident records this group among alertCollapsedByResourceGroupIds; detail GET only — omitted on list", - ), + stream: Annotated[ + bool, + Field(description="True while the run is still live and clients may stream"), + ] + evidence: Annotated[ + list[RunEvidenceDto], + Field(description="List evidence chips in SHOT → TRACE → VIDEO → NET order"), + ] + tab_counts: Annotated[RunTabCountsDto, Field(alias="tabCounts")] + live: RunLiveDto | None = None + attempt: Annotated[int, Field(description="Selected in-check attempt (1-based)")] + attempt_of: Annotated[ + int, Field(alias="attemptOf", description="In-check attempt count") + ] + attempts: Annotated[list[RunAttemptDto], Field(description="In-check attempts")] + incident_id: Annotated[ + UUID | None, + Field(alias="incidentId", description="Open incident for this monitor"), ] = None - incident_marks: Annotated[ - list[ResourceGroupMemberIncidentMarkDto] | None, + + +class RunNetworkDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: Annotated[ + list[NetworkRowDto], Field(description="Waterfall rows on this page") + ] + case_duration_ms: Annotated[ + int | None, Field( - alias="incidentMarks", - description="Incident marks for the trailing 24h strip; null when metrics omitted or failed; detail GET only — omitted on list", + alias="caseDurationMs", description="Case wall time for waterfall bar scale" ), ] = None + next_cursor: Annotated[ + str | None, + Field(alias="nextCursor", description="Opaque cursor for the next page"), + ] = None + has_more: Annotated[ + bool, + Field(alias="hasMore", description="Whether more rows exist beyond this page"), + ] + + +class SecretAuditDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + updated_at: Annotated[ + AwareDatetime | None, + Field(alias="updatedAt", description="When this secret was last updated"), + ] = None + updated_by: Annotated[UserDto | None, Field(alias="updatedBy")] = None + + +class SecretUsageDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + monitors: Annotated[ + list[MonitorDto], Field(description="Monitors that reference this secret") + ] class ServiceIncidentDetailDto(BaseModel): @@ -9239,11 +10978,21 @@ class SingleValueResponseBulkMonitorActionResult(BaseModel): data: BulkMonitorActionResult +class SingleValueResponseCaptureCompareDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: CaptureCompareDto + + class SingleValueResponseDashboardOverviewDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: DashboardOverviewDto +class SingleValueResponseDefinitionHeadDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: DefinitionHeadDto + + class SingleValueResponseGlobalStatusSummaryDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: GlobalStatusSummaryDto @@ -9269,11 +11018,21 @@ class SingleValueResponseMonitorDto(BaseModel): data: MonitorDto +class SingleValueResponseMonitorSecretRequestsDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: MonitorSecretRequestsDto + + class SingleValueResponseMonitorVersionDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: MonitorVersionDto +class SingleValueResponseNetworkRowDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: NetworkRowDto + + class SingleValueResponseNotificationPolicyDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: NotificationPolicyDto @@ -9284,6 +11043,31 @@ class SingleValueResponseResourceGroupMemberDto(BaseModel): data: ResourceGroupMemberDto +class SingleValueResponseRevisionDiffDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: RevisionDiffDto + + +class SingleValueResponseRollbackPreviewDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: RollbackPreviewDto + + +class SingleValueResponseRunDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: RunDto + + +class SingleValueResponseSecretAuditDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: SecretAuditDto + + +class SingleValueResponseSecretUsageDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: SecretUsageDto + + class SingleValueResponseServiceIncidentDetailDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: ServiceIncidentDetailDto @@ -9503,7 +11287,6 @@ class TableValueResultComponentUptimeDayDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultIncidentDto(BaseModel): @@ -9513,7 +11296,6 @@ class TableValueResultIncidentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultIncidentStateTransitionDto(BaseModel): @@ -9523,7 +11305,6 @@ class TableValueResultIncidentStateTransitionDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultIntegrationDto(BaseModel): @@ -9533,7 +11314,6 @@ class TableValueResultIntegrationDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultMonitorDto(BaseModel): @@ -9543,7 +11323,6 @@ class TableValueResultMonitorDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultMonitorVersionDto(BaseModel): @@ -9553,7 +11332,6 @@ class TableValueResultMonitorVersionDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultNotificationPolicyDto(BaseModel): @@ -9563,7 +11341,33 @@ class TableValueResultNotificationPolicyDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None + + +class TableValueResultRunArtifactDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: list[RunArtifactDto] + 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 TableValueResultRunCaseDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: list[RunCaseDto] + 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 TableValueResultRunDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: list[RunDto] + 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 TableValueResultStatusPageDto(BaseModel): @@ -9573,7 +11377,6 @@ class TableValueResultStatusPageDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultStatusPageIncidentDto(BaseModel): @@ -9583,7 +11386,6 @@ class TableValueResultStatusPageIncidentDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultTagDto(BaseModel): @@ -9593,7 +11395,6 @@ class TableValueResultTagDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultTestChannelResult(BaseModel): @@ -9603,7 +11404,6 @@ class TableValueResultTestChannelResult(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultVoiceLanguageDto(BaseModel): @@ -9613,7 +11413,6 @@ class TableValueResultVoiceLanguageDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultWebhookDeliveryDto(BaseModel): @@ -9623,7 +11422,6 @@ class TableValueResultWebhookDeliveryDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultWebhookEndpointDto(BaseModel): @@ -9633,7 +11431,6 @@ class TableValueResultWebhookEndpointDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultWorkspaceDto(BaseModel): @@ -9643,7 +11440,6 @@ class TableValueResultWorkspaceDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TestAlertChannelRequest(BaseModel): @@ -9730,7 +11526,7 @@ class UpdateMonitorRequest(BaseModel): name: Annotated[ str | None, Field( - description="New monitor name; null preserves current", + description="New monitor name. Null preserves current", max_length=255, min_length=0, ), @@ -9749,33 +11545,34 @@ class UpdateMonitorRequest(BaseModel): int | None, Field( alias="frequencySeconds", - description="New check frequency in seconds (10–86400); null preserves current", + description="New check frequency in seconds (10–86400). Null preserves current", ge=10, le=86400, ), ] = None enabled: Annotated[ bool | None, - Field(description="Enable or disable the monitor; null preserves current"), + Field( + description="Enable or disable the monitor (pause or resume). Null preserves current" + ), ] = None regions: Annotated[ list[str] | None, Field( - description="New probe regions; null preserves current. Allowed values are deployment-dependent." + description="New probe regions. Null preserves current. Allowed values are deployment-dependent" ), ] = None managed_by: Annotated[ ManagedBy | None, Field( alias="managedBy", - description="New ownership source: DASHBOARD, CLI, TERRAFORM, MCP, or API; null preserves current value", + description="New ownership source: DASHBOARD, CLI, TERRAFORM, MCP, or API. Null preserves current", ), ] = None environment_id: Annotated[ UUID | None, Field( - alias="environmentId", - description="New environment ID; null preserves current (use clearEnvironmentId to unset)", + alias="environmentId", description="New environment; null preserves current" ), ] = None clear_environment_id: Annotated[ @@ -9787,7 +11584,7 @@ class UpdateMonitorRequest(BaseModel): ] = None assertions: Annotated[ list[CreateAssertionRequest] | None, - Field(description="Replace all assertions; null preserves current"), + Field(description="Replace all assertions. Null preserves current"), ] = None auth: MonitorAuthConfig | None = None clear_auth: Annotated[ @@ -9801,10 +11598,24 @@ class UpdateMonitorRequest(BaseModel): list[UUID] | None, Field( alias="alertChannelIds", - description="Replace alert channel list; null preserves current", + description="Replace alert channel list. Null preserves current", ), ] = None tags: AddMonitorTagsRequest | None = None + capture_policy: Annotated[CapturePolicy | None, Field(alias="capturePolicy")] = None + fast_retry_max_attempts: Annotated[ + int | None, + Field( + alias="fastRetryMaxAttempts", + description="Fast-retry attempts after failure. Null preserves current. 0 disables", + ge=0, + le=10, + ), + ] = None + package: MonitorPackageSpec | None = None + status: Annotated[ + str | None, Field(description="Not writable; use pause or resume") + ] = None class UpdateNotificationPolicyRequest(BaseModel): @@ -9988,6 +11799,44 @@ class CursorPageIncidentActivityEventDto(BaseModel): alias="hasMore", description="Whether more results exist beyond this page" ), ] + total: Annotated[ + int | None, + Field( + description="Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total" + ), + ] = None + + +class CursorPageRunDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: Annotated[list[RunDto], 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" + ), + ] + total: Annotated[ + int | None, + Field( + description="Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total" + ), + ] = None + + +class DefinitionDetailDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + definition: DefinitionDto + heads: Annotated[ + list[DefinitionHeadDto], Field(description="Active Heads per environment") + ] class IncidentDetailDto(BaseModel): @@ -10177,6 +12026,11 @@ class SingleValueResponseCheckTraceDto(BaseModel): data: CheckTraceDto +class SingleValueResponseDefinitionDetailDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: DefinitionDetailDto + + class SingleValueResponseIncidentDetailDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: IncidentDetailDto @@ -10214,7 +12068,6 @@ class TableValueResultAuditEventDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TableValueResultResourceGroupDto(BaseModel): @@ -10224,7 +12077,6 @@ class TableValueResultResourceGroupDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class CheckResultDetailsDto(BaseModel): @@ -10342,3 +12194,9 @@ class CursorPageCheckResultDto(BaseModel): alias="hasMore", description="Whether more results exist beyond this page" ), ] + total: Annotated[ + int | None, + Field( + description="Unfiltered count of retained rows for this collection; null when the endpoint does not compute a total" + ), + ] = None